// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property({type: cc.Float, displayName: "键盘高度"})
    height: number = 800;

    @property({displayName: "系统键盘"})
    sysKeyboard: boolean = false;

    canvas: cc.Node = null; // 根节点
    text: string = ""; // 显示当前输入的字符
    textLabel: cc.Node = null; // 显示框的Label控件
    isShow: boolean = false; // 正在显示？
    lowerCase: cc.Node = null; // 小写字母
    upperCase: cc.Node = null; // 大写字母
    symbol: cc.Node = null; // 符号
    number: cc.Node = null; // 数字
    maskBg: cc.Node = null; // 半透明背景
    buttonContainer: cc.Node = null; // 编辑框
    editBoxContainer: cc.Node = null; // 编辑框
    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    start () {
        // 初始化显示控件
        this.textLabel = cc.find("main_container/text_show/text", this.node);

        // 各个实例
        this.lowerCase = cc.find("main_container/key_group/LowerCase", this.node);
        this.upperCase = cc.find("main_container/key_group/UpperCase", this.node);
        this.symbol = cc.find("main_container/key_group/Symbol", this.node);
        this.number = cc.find("main_container/key_group/Number", this.node);
        this.buttonContainer = cc.find("main_container", this.node);
        this.editBoxContainer = cc.find("SysEditbox", this.node);
        this.canvas = cc.find("Canvas");

        // 遮罩层
        this.maskBg = cc.find("mask_bg", this.node);
        this.initMask();

        // 设置尺寸
        if(this.sysKeyboard) {
            this.initSysKeyboard();
        } else {
            // 初始化背景
            this.initBg();
            // 初始化键盘核心区域
            this.initSoftKeyboard();
        }

        // 添加事件监听
        this.initEventListener();
    }

    // 遮罩层
    initMask() {
        this.maskBg.width = 999999;
        this.maskBg.height = 999999;
    }

    // 背景节点
    initBg() {
        const bg = cc.find("bg", this.node);
        bg.scaleX = this.canvas.width / bg.width;
        bg.scaleY = this.node.height / bg.height;
    }


    // 初始化系统键盘
    initSysKeyboard() {
        // 默认隐藏键盘
        this.node.active = false;
        this.node.x = 0;
        this.node.y = 0
        this.editBoxContainer.x = 0;
        this.editBoxContainer.y = 0;

        this.buttonContainer.active = false;
        this.editBoxContainer.active = true;

        this.editBoxContainer.y = this.canvas.height / 2 * this.canvas.scaleY - this.editBoxContainer.height / 2 - 150;
        const bg = cc.find("bg", this.node);
        bg.active = false;

        const editBox = cc.find("textEditBox", this.editBoxContainer);

        // 默认显示返回图标
        const btnOK = cc.find("btnSubmit/ok", this.editBoxContainer);
        const btnReturn = cc.find("btnSubmit/return", this.editBoxContainer);
        btnOK.active = false;
        btnReturn.active = true;

        // 注册文字改变事件
        editBox.on("text-changed", (labelText)=>{
            // 更新输入图标 空字符显示返回 非空显示对号
            if(labelText.string == "") {
                btnOK.active = false;
                btnReturn.active = true;
            } else {
                btnOK.active = true;
                btnReturn.active = false;
            }
        })

        // 注册回车事件
        editBox.on("editing-return", (labelText)=>{
            this.enter(labelText.string)
        })
    }

    // 初始化软键盘
    initSoftKeyboard() {
        // 默认隐藏键盘
        this.node.active = false;
        // 默认键盘高
        this.node.height = this.height?this.height:500;

        this.node.x = 0;
        this.node.y = -1 * (this.canvas.height - this.node.height) / 2

        this.buttonContainer.active = true;
        this.editBoxContainer.active = false;
        const bg = cc.find("bg", this.node);
        bg.active = true;

        // 键盘核心区
        const sx = this.canvas.width / this.buttonContainer.width;
        const sy = this.node.height / this.buttonContainer.height;
        const s = Math.min(sx, sy)
        this.buttonContainer.scale = s;

        // 默认显示小写字母
        this.lowerCase.active = true;
        this.upperCase.active = false;
        this.symbol.active = false;
        this.number.active = false;
    }

    // 显示键盘
    show(defaultText = "") {
        if(this.isShow) {
            // 如果正在显示 不处理
            return;
        }
        if(this.sysKeyboard) {
            // 使用系统键盘
            // 隐藏背景
            this.maskBg.opacity = 1;
            // 隐藏节点
            this.node.opacity = 1;
            // 显示组件
            this.node.active = true;
            // 显示标记位置为true
            this.isShow = true;
            // 获取Editbox组件
            const editBox = cc.find("textEditBox", this.editBoxContainer).getComponent(cc.EditBox);

            // 设置默认显示文字
            editBox.string = defaultText;
            // 更新输入图标 空字符显示返回 非空显示对号
            const btnOK = cc.find("btnSubmit/ok", this.editBoxContainer);
            const btnReturn = cc.find("btnSubmit/return", this.editBoxContainer);
            if(defaultText == "") {
                btnOK.active = false;
                btnReturn.active = true;
            } else {
                btnOK.active = true;
                btnReturn.active = false;
            }

            // 默认让输入框获取焦点 - 一定要先设置默认显示 再获取焦点
            editBox.focus();

            cc.tween(this.maskBg).to(0.1, {opacity: 255}).start();
            cc.tween(this.node).to(0.1, {opacity: 255}).start();
        } else {
            // 使用软件盘
            const capslockBtn = cc.find("main_container/key_group/key_capslock", this.node);
            const symbolBtnText = cc.find("main_container/key_group/key_symbol/text", this.node);
            const symbolLableText = symbolBtnText.getComponent(cc.Label);

            // 目标Y位置
            const targetY = -this.canvas.height / 2 + this.node.height / 2;
            // 定位到屏幕外 缓动移入
            this.node.y = -this.canvas.height / 2 - this.node.height / 2;
            // 显示组件
            this.node.active = true;
            // 隐藏背景
            this.maskBg.opacity = 1;
            // 默认显示小写键盘
            this.lowerCase.active = true;
            this.upperCase.active = false;
            this.symbol.active = false;
            this.number.active = false;
            capslockBtn.active = true;
            symbolLableText.string = "!?#";
            
            // 显示默认传进来的字符串
            this.text = defaultText;
            // 显示默认传进来的字符串
            this.inputText("");
            // 显示标记位置为true
            this.isShow = true;
            // 执行缓动移入动画
            cc.tween(this.maskBg).to(0.1, {opacity: 255}).start();
            cc.tween(this.node).to(0.1, {y: targetY}).start();
        }
        
    }

    // 隐藏键盘
    hide() {
        if(!this.isShow) {
            // 如果已经隐藏 不做处理
            return;
        }
        if(this.sysKeyboard) {
            // 系统键盘 淡出屏幕
            // 显示标记位置为 false
            this.isShow = false;
            cc.tween(this.node).to(0.1, {opacity: 1}).call(()=>{
                this.node.active = false;
            }).start();
            cc.tween(this.maskBg).to(0.1, {opacity: 1}).start();
        } else {
            // 软键盘 向下移出屏幕
            // 目标Y位置
            const targetY = -this.canvas.height / 2 - this.node.height / 2
            // 当前位置
            this.node.y = -this.canvas.height / 2 + this.node.height / 2;
            // 显示标记位置为 false
            this.isShow = false;
            // 执行缓动移入动画
            cc.tween(this.node).to(0.1, {y: targetY}).call(()=>{
                // 移出以后 清除显示
                this.text = "";
                this.inputText("");
                // 隐藏控件
                this.node.active = false;
            }).start();
            cc.tween(this.maskBg).to(0.1, {opacity: 1}).start();
        }
    }
    
    // 事件注册
    initEventListener() {
        if(this.sysKeyboard) {
            // 注册系统键盘事件
            this.initSysKeyboardEvent()
        } else {
            // 注册软键盘时间监听
            this.initSoftKeyboardEvent();        
        }

        // 订阅节点事件监听 - 外部调用键盘时会发送事件消息
        this.node.on("show", (defaultText)=>{
            this.show(defaultText);
        })

        // 设置点击背景遮罩层的回调 - 用户偶儿误触 暂时禁用这段逻辑
        // this.maskBg.on("click", ()=>{
        //     if(this.sysKeyboard) {
        //         const editBox = cc.find("textEditBox", this.editBoxContainer);
        //         editBox.getComponent(cc.EditBox).focus()
        //     }
        // })
    }

    // 注册软键盘事件
    initSysKeyboardEvent() {
        const submitBtn = cc.find("btnSubmit", this.editBoxContainer)
        const editBox = cc.find("textEditBox", this.editBoxContainer);
        submitBtn.on("click", ()=>{
            const text = editBox.getComponent(cc.EditBox).textLabel;
            if(text) {
                // 退出键盘 完成输入
                this.enter(text.string);
                // 清空当前输入字符串
                text.string = ";"
            } else {
                this.enter("")
            }
        })
    }

    // 注册软键盘时间监听
    initSoftKeyboardEvent() {
        // 正则匹配一位数字或字母 用于从节点名字中获取按键功能
        let reg = /^[A-Za-z0-9]{1}$/
        const keyGroup = cc.find("main_container/key_group", this.node);
        const numGroup = cc.find("main_container/key_group/Number", this.node);
        const lowerCaseLetterGroup_1 = cc.find("main_container/key_group/LowerCase/line1", this.node);
        const lowerCaseLetterGroup_2 = cc.find("main_container/key_group/LowerCase/line2", this.node);
        const lowerCaseLetterGroup_3 = cc.find("main_container/key_group/LowerCase/line3", this.node);
        const upperCaseLetterGroup_1 = cc.find("main_container/key_group/UpperCase/line1", this.node);
        const upperCaseLetterGroup_2 = cc.find("main_container/key_group/UpperCase/line2", this.node);
        const upperCaseLetterGroup_3 = cc.find("main_container/key_group/UpperCase/line3", this.node);
        const symbolGroup_1 = cc.find("main_container/key_group/Symbol/line1", this.node);
        const symbolGroup_2 = cc.find("main_container/key_group/Symbol/line2", this.node);
        const delBtn = cc.find("main_container/key_group/key_del", this.node);
        const enterBtn = cc.find("main_container/key_group/key_enter", this.node);
        const capslockBtn = cc.find("main_container/key_group/key_capslock", this.node);
        const symbolSwitchBtn = cc.find("main_container/key_group/key_symbol", this.node);
        const spaceBtn = cc.find("main_container/key_group/key_space", this.node);
        
        let allKeyNodes = numGroup.children.concat(lowerCaseLetterGroup_1.children)
        .concat(lowerCaseLetterGroup_2.children)
        .concat(lowerCaseLetterGroup_3.children)
        .concat(upperCaseLetterGroup_1.children)
        .concat(upperCaseLetterGroup_2.children)
        .concat(upperCaseLetterGroup_3.children)
        .concat(symbolGroup_1.children)
        .concat(symbolGroup_2.children)

        allKeyNodes.push(delBtn);
        allKeyNodes.push(enterBtn);
        allKeyNodes.push(capslockBtn);
        allKeyNodes.push(spaceBtn);
        allKeyNodes.push(symbolSwitchBtn);

        // 遍历keyGroup的所有节点
        allKeyNodes.forEach(node=>{
            // 找到_字符后面的 文字
            let key = node.name.split("_");
            // 添加按钮控件
            node.addComponent(cc.Button);
            // 添加点击事件
            node.on("click", ()=>{
                if(reg.test(key[1])) {
                    // 如果是1位数字或字母 则为普通输入按键
                    this.inputText(key[1])
                } else {
                    // 功能按键 删除 空格 回车 符号
                    switch(key[1]) {
                        case "del": this.delText(); break;
                        case "space": this.inputText(" "); break;
                        case "enter": this.enter(); break;
                        case "capslock": this.switchCase(); break;
                        case "symbol": this.switchSymbol(); break;
                        case "apostrophe": this.inputText("'"); break;
                        case "colon": this.inputText(":"); break;
                        case "comma": this.inputText(","); break;
                        case "exclamation": this.inputText("!"); break;
                        case "hyphen": this.inputText("-"); break;
                        case "parentheses1": this.inputText("("); break;
                        case "parentheses2": this.inputText(")"); break;
                        case "period": this.inputText("."); break;
                        case "question": this.inputText("?"); break;
                        case "quotation1": this.inputText('"'); break;
                        case "quotation2": this.inputText('"'); break;
                        case "semicolon": this.inputText(";"); break;
                        case "slash": this.inputText('/'); break;
                        case "triple": this.inputText("..."); break;
                        default:;
                    }
                }
            })
        })
    }

    // 输入文字
    inputText(str) {
        this.text += str;
        this.textLabel.getComponent(cc.Label).string = this.text;
    }

    // 删除文字
    delText() {
        this.text = this.text.slice(0, this.text.length-1);
        this.textLabel.getComponent(cc.Label).string = this.text;
    }

    // 回车
    enter(text) {
        // 发送消息给订阅者
        this.node.emit("onEnter", text?text:this.text);
        // 隐藏键盘
        this.hide();
    }

    // 切换大小写
    switchCase() {
        if(this.lowerCase.active) {
            this.lowerCase.active = false;
            this.upperCase.active = true;
        } else {
            this.lowerCase.active = true;
            this.upperCase.active = false;
        }
    }

    // 切换符号键盘
    switchSymbol() {
        const capslockBtn = cc.find("main_container/key_group/key_capslock", this.node);
        const symbolBtnText = cc.find("main_container/key_group/key_symbol/text", this.node);
        const lableText = symbolBtnText.getComponent(cc.Label);
        if(lableText.string == "!?#") {
            this.upperCase.active = false;
            this.lowerCase.active = false;
            capslockBtn.active = false;
            this.symbol.active = true;
            this.number.active = true;
            lableText.string = "ABC";
        } else {
            this.upperCase.active = false;
            this.lowerCase.active = true;
            capslockBtn.active = true;
            this.symbol.active = false;
            this.number.active = false;
            lableText.string = "!?#";
        }
    }

    // update (dt) {}
}
