

import { AppConst } from "../ConstDefine/AppConst"
import UIUtil from "../Util/UIUtil"
import Manager from "./Manager"
/**
 * @params 管理分辨率 层级
 */

const PoolLayer = "PoolLayer"
const WindowLayer="WindowLayer"
const BangScreenOffSet = 70

const FAR_POS = cc.v3(-10000, -10000)

export default class LayerMgr extends Manager {

    static get TypeName(): string { return "LayerMgr" }
    private uiRoot: cc.Node = null
    public get UIRoot(): cc.Node { return this.uiRoot }
    private root: cc.Node
    public get Root(): cc.Node { return this.root }

    //对象池池层级
    private poolLayer: cc.Node = null
    public get PoolLayer() { return this.poolLayer }

    //场景层start
    //背景图
    private sceneBackLayer: cc.Node = null
    public get SceneBackLayer() { return this.sceneBackLayer }
    //场景层
    private sceneLayer: cc.Node = null
    public get SceneLayer() { return this.sceneLayer }
    //场景底层
    private sceneTopLayer: cc.Node
    public get SceneTopLayer() { return this.sceneTopLayer }
    //场景层end

    //ui层start
    //飘血
    private flybllodLayer: cc.Node = null
    public get FlybllodLayer() { return this.flybllodLayer }
    private uiLayer: cc.Node = null
    //ui图标层
    public get UiLayer() { return this.uiLayer }
    //窗口
    private windowLayer: cc.Node = null
    public get WindowLayer() { return this.windowLayer }
    private windowTopLayer: cc.Node = null
    public get WindowTopLayer() { return this.windowTopLayer }
    //广播
    private broadcastLayer: cc.Node = null
    public get BroadcastLayer() { return this.broadcastLayer }
    //弹窗
    private tipViewLayer: cc.Node = null
    public get TipViewLayer() { return this.tipViewLayer }
    //引导
    private guideLayer: cc.Node = null
    public get GuideLayer() { return this.guideLayer }
    //顶层
    private topLayer: cc.Node = null
    public get TopLayer() { return this.topLayer }
    //ui层end

    private layers: cc.Node[] = null
    private index: number = 1
    private uiViews: Array<cc.Node> = null


    public async start() {
        // cc.view.enableAutoFullScreen(false)

        this.uiRoot = cc.find("Canvas")
        cc.game.addPersistRootNode(this.uiRoot)

        this.root = cc.find("Root")
        if(this.root){
            cc.game.addPersistRootNode(this.root)
        }
        else
        {
            this.root=this.uiRoot;
        }

        // 小程序设置无效
        // let screen=cc.view.getFrameSize()
        // cc.view.setFrameSize(screen.width*0.5,screen.height*0.5)
        //手机设备和pc返回的不一样【神经病，pc返回width/height，应该是height/widg】
        //let cRatio=cc.view.getDevicePixelRatio()
        let policy = this.isFitWidth() && cc.ResolutionPolicy.FIXED_WIDTH || cc.ResolutionPolicy.FIXED_HEIGHT
        // cc.view.setDesignResolutionSize(720, 1280, policy)
        cc.view.setDesignResolutionSize(AppConst.Width, AppConst.Height, policy)

        this.layers = new Array()
        this.createLayers()

        this.uiViews = [this.flybllodLayer, this.uiLayer, this.windowLayer, this.windowTopLayer, this.tipViewLayer, this.guideLayer, this.topLayer]
        console.log("LayerMgr onStart")
    }

    public release() {
        console.log("LayerMgr onRelease")

        this.uiViews.length = 0
        if (cc.isValid(this.uiRoot)) {
            this.uiRoot.destroyAllChildren()
        }
        this.uiRoot = null
        this.layers.length = 0
        this.index = 1
    }

    private createLayers(): void {
        this.poolLayer = this.createLayer(PoolLayer, cc.v2(-100000, -100000))
        //场景层
        this.sceneBackLayer = this.createLayer("SceneBackLayer")
        this.sceneLayer = this.createLayer("SceneLayer")
        this.sceneTopLayer = this.createLayer("SceneTopLayer")
        //ui层
        this.flybllodLayer = this.createLayer("FlybllodLayer")
        this.uiLayer = this.createLayer("UiLayer")
        this.windowLayer = this.createLayer(WindowLayer)
        this.windowTopLayer = this.createLayer("WindowTopLayer")
        this.broadcastLayer = this.createLayer("BroadcastLayer")
        this.tipViewLayer = this.createLayer("TipViewLayer")
        this.guideLayer = this.createLayer("GuideLayer")
        this.topLayer = this.createLayer("TopLayer")
    }

    private createLayer(layerName: string, pos: cc.Vec2 = cc.Vec2.ZERO): cc.Node {
        let node = new cc.Node(layerName)
        this.layers.push(node)
        node.setParent(this.uiRoot)
        if (layerName != PoolLayer) {
            UIUtil.autoFitCanvas(node)
        }
        node.setSiblingIndex(this.index++)
        node.setPosition(pos)

        return node
    }


    /**
     * setSiblingIndex 设置同节点层级排序
     * zIndex和zOrder是同一个东西。设置渲染顺序,只能影响同一级节点
     * 节点渲染都是先渲染自己再渲染子节点
     */
    public setLayer(node: cc.Node, layer: cc.Node, offset: number = -1) {
        if (!cc.isValid(node)) return
        node.parent = layer
        node.setSiblingIndex(layer.childrenCount + offset)
    }

    public pushPool(node: cc.Node) {
        if (!cc.isValid(node)) return
        node.setParent(this.poolLayer)
        node.setPosition(FAR_POS)
    }

    /**
     * @param 是否是刘海屏幕
     */
    public isHasBangScreen() {
        return this.getDeviceRatio() >= 2
    }

    /**
     * @param 刘海屏偏移 
     */
    public bangScreenTopOffset(): number {
        if (this.isHasBangScreen()) {
            return BangScreenOffSet
        }
        return 0
    }

    /**
     *  //手机设备和pc返回的不一样【神经病，pc返回width/height，应该是height/widg】
        //let cRatio=cc.view.getDevicePixelRatio()
    */
    public getDeviceRatio(): number {
        let size = cc.view.getFrameSize()
        let ratio = Math.max(size.height, size.width) / Math.min(size.height, size.width)
        return ratio
    }

    public findNode(path: string): cc.Node {
        return cc.find(path, this.uiRoot)
    }

    /**
     * uiViews 中的是ui界面，永远显示在屏幕上
     */
    public foreverShowUiView(cameraLocPos: cc.Vec3) {
        for (let view of this.uiViews) {
            view.position = cameraLocPos
        }
    }

    //适配后的分辨率 用cc.winSize就可以了
    public getFitedSceneResolution(): cc.Size {
        return this.sceneLayer.getContentSize()
    }

    /** 是否是宽度适配 */
    public isFitWidth(): boolean {
        let cRatio = this.getDeviceRatio()
        let dsize = cc.view.getDesignResolutionSize()
        let dRatio = dsize.height / dsize.width
        let isFitWidth = cRatio > dRatio
        return isFitWidth
    }

    //全屏特效需要适配屏幕
    public fitScreen(node: cc.Node) {
        if (!node?.isValid) return
        let cRatio = this.getDeviceRatio()
        let dsize = cc.view.getDesignResolutionSize()
        let dRatio = dsize.height / dsize.width
        let paramScale = node.scale || 1
        if (this.isFitWidth()) {
            node.scale = paramScale * (cRatio / dRatio)
        } else {
            node.scale = paramScale * (dRatio / cRatio)
        }
    }
}