"use strict";

import {MyDocItem} from "../model/MyDocItem.js";
import {MyMapItem} from "../model/MyMapItem.js";

export class MyUtils {
    //todo 判断是哪一种浏览器类型。以及是否是手机
    //todo 初始化屏幕宽高比


    MyBrowser = null

    constructor() {
        /**
         * 提供浏览器检测的模块
         * @unfile
         * @module UE.browser
         */
        window.browser = ((function () {
            var agent = navigator.userAgent.toLowerCase(),
                opera = window.opera,
                browser = {
                    /**
                     * @property {boolean} ie 检测当前浏览器是否为IE
                     * @example
                     * ```javascript
                     * if ( UE.browser.ie ) {
                     *     console.log( '当前浏览器是IE' );
                     * }
                     * ```
                     */
                    ie: /(msie\s|trident.*rv:)([\w.]+)/i.test(agent),

                    /**
                     * @property {boolean} opera 检测当前浏览器是否为Opera
                     * @example
                     * ```javascript
                     * if ( UE.browser.opera ) {
                     *     console.log( '当前浏览器是Opera' );
                     * }
                     * ```
                     */
                    opera: !!opera && opera.version,

                    /**
                     * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器
                     * @example
                     * ```javascript
                     * if ( UE.browser.webkit ) {
                     *     console.log( '当前浏览器是webkit内核浏览器' );
                     * }
                     * ```
                     */
                    webkit: agent.indexOf(" applewebkit/") > -1,

                    /**
                     * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下
                     * @example
                     * ```javascript
                     * if ( UE.browser.mac ) {
                     *     console.log( '当前浏览器运行在mac平台下' );
                     * }
                     * ```
                     */
                    mac: agent.indexOf("macintosh") > -1,

                    /**
                     * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下
                     * @example
                     * ```javascript
                     * if ( UE.browser.quirks ) {
                     *     console.log( '当前浏览器运行处于“怪异模式”' );
                     * }
                     * ```
                     */
                    quirks: document.compatMode == "BackCompat"
                }

            /**
             * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核
             * @example
             * ```javascript
             * if ( UE.browser.gecko ) {
             *     console.log( '当前浏览器内核是gecko内核' );
             * }
             * ```
             */
            browser.gecko =
                navigator.product == "Gecko" &&
                !browser.webkit &&
                !browser.opera &&
                !browser.ie

            var version = 0

            // Internet Explorer 6.0+
            if (browser.ie) {
                var v1 = agent.match(/(?:msie\s([\w.]+))/)
                var v2 = agent.match(/(?:trident.*rv:([\w.]+))/)
                if (v1 && v2 && v1[1] && v2[1]) {
                    version = Math.max(v1[1] * 1, v2[1] * 1)
                } else if (v1 && v1[1]) {
                    version = v1[1] * 1
                } else if (v2 && v2[1]) {
                    version = v2[1] * 1
                } else {
                    version = 0
                }

                browser.ie11Compat = document.documentMode == 11
                /**
                 * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式
                 * @warning 如果浏览器不是IE, 则该值为undefined
                 * @example
                 * ```javascript
                 * if ( UE.browser.ie9Compat ) {
                 *     console.log( '当前浏览器运行在IE9兼容模式下' );
                 * }
                 * ```
                 */
                browser.ie9Compat = document.documentMode == 9

                /**
                 * @property { boolean } ie8 检测浏览器是否是IE8浏览器
                 * @warning 如果浏览器不是IE, 则该值为undefined
                 * @example
                 * ```javascript
                 * if ( UE.browser.ie8 ) {
                 *     console.log( '当前浏览器是IE8浏览器' );
                 * }
                 * ```
                 */
                browser.ie8 = !!document.documentMode

                /**
                 * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式
                 * @warning 如果浏览器不是IE, 则该值为undefined
                 * @example
                 * ```javascript
                 * if ( UE.browser.ie8Compat ) {
                 *     console.log( '当前浏览器运行在IE8兼容模式下' );
                 * }
                 * ```
                 */
                browser.ie8Compat = document.documentMode == 8

                /**
                 * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式
                 * @warning 如果浏览器不是IE, 则该值为undefined
                 * @example
                 * ```javascript
                 * if ( UE.browser.ie7Compat ) {
                 *     console.log( '当前浏览器运行在IE7兼容模式下' );
                 * }
                 * ```
                 */
                browser.ie7Compat =
                    (version == 7 && !document.documentMode) || document.documentMode == 7

                /**
                 * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式
                 * @warning 如果浏览器不是IE, 则该值为undefined
                 * @example
                 * ```javascript
                 * if ( UE.browser.ie6Compat ) {
                 *     console.log( '当前浏览器运行在IE6模式或者怪异模式下' );
                 * }
                 * ```
                 */
                browser.ie6Compat = version < 7 || browser.quirks

                browser.ie9above = version > 8

                browser.ie9below = version < 9

                browser.ie11above = version > 10

                browser.ie11below = version < 11
            }

            // Gecko.
            if (browser.gecko) {
                var geckoRelease = agent.match(/rv:([\d\.]+)/)
                if (geckoRelease) {
                    geckoRelease = geckoRelease[1].split(".")
                    version =
                        geckoRelease[0] * 10000 +
                        (geckoRelease[1] || 0) * 100 +
                        (geckoRelease[2] || 0) * 1
                }
            }

            /**
             * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本号
             * @warning 如果浏览器不是chrome, 则该值为undefined
             * @example
             * ```javascript
             * if ( UE.browser.chrome ) {
             *     console.log( '当前浏览器是Chrome' );
             * }
             * ```
             */
            if (/chrome\/(\d+\.\d)/i.test(agent)) {
                browser.chrome = +RegExp["\x241"]
            }

            /**
             * @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本号
             * @warning 如果浏览器不是safari, 则该值为undefined
             * @example
             * ```javascript
             * if ( UE.browser.safari ) {
             *     console.log( '当前浏览器是Safari' );
             * }
             * ```
             */
            if (
                /(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) &&
                !/chrome/i.test(agent)
            ) {
                browser.safari = +(RegExp["\x241"] || RegExp["\x242"])
            }

            // Opera 9.50+
            if (browser.opera) version = parseFloat(opera.version())

            // WebKit 522+ (Safari 3+)
            if (browser.webkit)
                version = parseFloat(agent.match(/ applewebkit\/(\d+)/)[1])

            /**
             * @property { Number } version 检测当前浏览器版本号
             * @remind
             * <ul>
             *     <li>IE系列返回值为5,6,7,8,9,10等</li>
             *     <li>gecko系列会返回10900,158900等</li>
             *     <li>webkit系列会返回其build号 (如 522等)</li>
             * </ul>
             * @example
             * ```javascript
             * console.log( '当前浏览器版本号是: ' + UE.browser.version );
             * ```
             */
            browser.version = version

            /**
             * @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容
             * @example
             * ```javascript
             * if ( UE.browser.isCompatible ) {
             *     console.log( '浏览器与UEditor能够良好兼容' );
             * }
             * ```
             */
            browser.isCompatible =
                !browser.mobile &&
                ((browser.ie && version >= 6) ||
                    (browser.gecko && version >= 10801) ||
                    (browser.opera && version >= 9.5) ||
                    (browser.air && version >= 1) ||
                    (browser.webkit && version >= 522) ||
                    false)
            return browser
        })())
        //快捷方式
        window.ie = window.browser.ie;
        window.webkit = window.browser.webkit;
        window.gecko = window.browser.gecko;
        window.opera = window.browser.opera;
        //log
        console.log("browser : ", window.browser,
            "\nie: ", window.ie,
            "\nwindow.webkit: ", window.webkit,
            "\nwindow.gecko: ", window.gecko,
            "\nwindow.opera: ", window.opera)
        let testDiv = document.getElementById("testDevice")
        testDiv.innerText = testDiv.innerText +
            "\n ie: " + window.ie +
            "\n window.webkit: " + window.webkit +
            "\n window.gecko: " + window.gecko +
            "\n window.opera: " + window.opera
    }

    /**
     * 刷新跟节点 front-size
     * @constructor
     */
    RefreshRootFrontSize() {
        let curDoc = document.documentElement;//当前文档的 root 元素
        let curClientW = curDoc.clientWidth;
        if (!curClientW) {
            return
        }

        let designWidth = window.myEdit.ctx.designWith;
        //set 1rem = viewWidth/10 (支持响应式)
        let nowFrontSize = ((curClientW / designWidth) / 10) + 'px';
        curDoc.style.fontSize = nowFrontSize;
        console.log("curClientW :", curClientW, "designWidth: ", designWidth, "-> ", nowFrontSize);
        let testDiv = document.getElementById("testDevice")
        testDiv.innerText = testDiv.innerText + "\n curClientW :" + curClientW + " \n designWidth: " + designWidth + "\n -> " + nowFrontSize
    }


    RefreshEditFrontSize() {
        let dpr = window.devicePixelRatio || 1;//当前设置下 物理像素和虚拟像素的比值
        if (!dpr) {
            //devicePixelRatio这个属性是可以获取到设备的dpr
            let devicePixelRatio = win.devicePixelRatio;
            //判断dpr是否为整数
            let isRegularDpr = devicePixelRatio.toString().match(/^[1-9]\d*$/g)
            if (isRegularDpr) {
                // 对于是整数的dpr,对dpr进行操作
                if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
                    dpr = 3;
                } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
                    dpr = 2;
                } else {
                    dpr = 1;
                }
            } else {
                // 其他设备下,仍旧使用1倍的方案
                dpr = 1;
            }
        }

        let myEditFrontSize = document.getElementById("noteshare");
        if (document.documentElement.clientWidth <= 720) {
            myEditFrontSize.style.fontSize = window.myEdit.ctx.editFrontSize + 'px';
        } else {
            myEditFrontSize.style.fontSize = window.myEdit.ctx.editFrontSize * dpr + 'px';
        }

        console.log("body-frontSize: ", myEditFrontSize.style.fontSize);
    }

    /**
     *
     * @returns 生产uuid
     */
    Uuid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
            .replace(/[xy]/g, function (c) {
                const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8)
                return v.toString(16)
            }).split("-")[0]
    }

    /**
     * 阻止默认事件
     * @constructor
     */
    ProhibitDefaultEvent(event) {
        event.preventDefault()
        event.returnValue = false
    }


    /**
     * 获取 触发事件的元素
     * @param event
     * @constructor
     */
    GetEventTarget(event) {
        return event.target
    }


    ParseEvent(e) {
        return e || window.event  //标准化事件处理
    }


    GetKeyCode(event) {
        return event.keyCode || event.which || event.charCode
    }

    /**
     * 当前选区。 兼容不同浏览器
     * @returns {Selection|*}
     */
    GetSelection() {
        return window.getSelection() || document.selection
    }

    /**
     * 是否是数字
     * @param value
     * @returns {boolean}
     */
    IsNum(value) {
        return !isNaN(parseFloat(value)) && isFinite(value)
    }

    /**
     * 在节点node后面插入新节点newNode
     * @method InsertAfter
     * @param { Node } node 目标节点
     * @param { Node } newNode 新插入的节点, 该节点将置于目标节点之后
     * @return { Node } 新插入的节点
     */
    InsertAfter(node, newNode) {
        return node.nextSibling
            ? node.parentNode.insertBefore(newNode, node.nextSibling)
            : node.parentNode.appendChild(newNode)
    }

    /**
     * 新增一个元素
     * @param newParagraph
     */
    AddNewParagraph(newParagraph) {
        //docRoot
        window.myEdit.ctx.MyRoot.appendChild(newParagraph);

        //mapRoot
        let myP = new MyDocItem(newParagraph);
        let curOrder = myP.parseOrder();
        let uuid = myP.parseUuid();
        window.myEdit.ctx.MyDocMap.set(curOrder, new MyMapItem(uuid))

        //收起选区到一个点,光标落在一个可编辑元素上
        window.myEdit.utils.GetSelection().setPosition(newParagraph, 0);
    }

    /**
     * 同步某一行数据到对应的 map节点
     * @param docP
     * @constructor
     */
    SyncMapItemChildrenStyle(docP) {
        //子元素为空不处理
        let items = docP.childNodes;
        if (items.length <= 0) {
            return
        }

        //构造参数
        let curMyP = new MyDocItem(docP);
        let mapItem = window.myEdit.ctx.getMapItem(curMyP.parseOrder());

        //清空重置
        // console.log(mapItem);
        mapItem.getStyle().setChildrenStyleMapNull();
        //遍历
        for (let i = 0; i < items.length; i++) {
            let curItem = items[i];
            let tmpClassList = curItem.classList;
            if (tmpClassList != null && tmpClassList.length > 0) {
                mapItem.getStyle().setChildrenStyle(i, tmpClassList);
            }
        }

        // console.log("sync docP : ", docP, " children: ", docP.children, " childrenMap: ", mapItem.getStyle().getChildrenStyleMap())
    }


    /**
     * A4纸
     */
    GetDPI() {
        let tempDiv = document.createElement("div");
        tempDiv.style.width = "1in";
        tempDiv.style.visibility = "hidden";
        document.body.appendChild(tempDiv);
        let dpi = tempDiv.offsetWidth;
        document.body.removeChild(tempDiv);
        return dpi;
    }

    MmToPixel(mm, dpi) {
        // 1 inch = 25.4 mm
        let inches = mm / 25.4;
        let pixels = inches * dpi;
        return Math.round(pixels);
    }

    A4SizeInPixels() {
        let dpi = window.myEdit.utils.GetDPI();
        let width_mm = 210; // A4纸宽度,单位:毫米
        let height_mm = 297; // A4纸高度,单位:毫米
        let width_px = window.myEdit.utils.MmToPixel(width_mm, dpi);
        let height_px = window.myEdit.utils.MmToPixel(height_mm, dpi);
        return {width: width_px, height: height_px};
    }


}