cc.Class({
    extends: cc.Component,
    properties: {},

    getData(callBack) {
        const uri = 'syllabus/v1/getdata';
        const data = {
            syllabusid: this.syllabus_id
        };
        console.log('data = ' + JSON.stringify(data));
        this.callNetworkApiGet(uri, data, callBack);
    },

    onHomeworkFinish(callBack) {
        if (this.role == 'teacher') {
            return;
        }
        const uri = 'app_source/v1/student/homework/finished';
        const data = {
            syllabus_id: this.syllabus_id,
            homework_id: this.homework_id,
            token: this.token,
            score: 100
        };
        console.log('data = ' + JSON.stringify(data));
        this.callNetworkApiPost(uri, data, callBack);
    },

    callNetworkApiGet(uri, data, callBack) {
        let queryStr = '?';
        for (const key in data) {
            if (Object.hasOwnProperty.call(data, key)) {
                const value = data[key];
                queryStr += `${key}=${value}`;
            }
        }
        const xhr = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
                const responseData = JSON.parse(xhr.responseText);
                callBack(JSON.parse(responseData.data));
            }
        };
        const url = `${this.baseUrl}${uri}${queryStr}`;
        console.log('url = ' + url);
        xhr.open('GET', url, true);
        xhr.send();
    },

    callNetworkApiPost(uri, data, callBack) {
        const xhr = new XMLHttpRequest();
        const url = `${this.baseUrl}${uri}`;
        xhr.open("POST", url, true);
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.onreadystatechange = () => {
            if (xhr.readyState == 4) {
                callBack(JSON.parse(xhr.responseText));
            }
        }
        xhr.send(JSON.stringify(data));
    },

    start() {
        this.node.zIndex = 9999;
        this.showWaitingLetters();
        cc.game.addPersistRootNode(this.node);

        this.initListener();

        this.getBundleInfoList();
    },

    getBundleInfoList() {
        const jsonStr = this.callNativeFunction({ name: 'loadSceneList', value: '' });

        const { bundleInfoList, defaultBundleIdx } = JSON.parse(jsonStr);

        this.bundleInfoList = bundleInfoList;

        if (this.bundleInfoList.length < 2) {
            const btnLeft = this.node.getChildByName('BtnLeft');
            const btnRight = this.node.getChildByName('BtnRight');
            btnLeft.active = false;
            btnRight.active = false;
        }

        this.jumpToBundleByIndex(defaultBundleIdx);
    },

    jumpToBundleByIndex(index) {
        this.currentBundleIndex = index;
        const currentBundleInfo = this.bundleInfoList[this.currentBundleIndex];

        this.baseUrl = currentBundleInfo.baseUrl;
        this.token = currentBundleInfo.token;
        this.homework_id = currentBundleInfo.homework_id;
        this.syllabus_id = currentBundleInfo.syllabus_id;
        this.role = currentBundleInfo.role;
        cc.assetManager.loadBundle(currentBundleInfo.bondleUrl, { version: currentBundleInfo.version }, (err, bundle) => {
            if (err) {
                return console.error(err);
            }
            bundle.loadScene(currentBundleInfo.sceneName, (err, scene) => {
                this.hideWaitingLetters();
                cc.director.runScene(scene);
            });
        });
    },

    loadDefaultBundle() {
        const jsonStr = this.callNativeFunction({ name: 'loadScene', value: '' });
        const {
            sceneName,
            version,
            bondleUrl,
            token,
            baseUrl,
            homework_id,
            syllabus_id,
            role
        } = JSON.parse(jsonStr);

        this.baseUrl = baseUrl;
        this.token = token;
        this.homework_id = homework_id;
        this.syllabus_id = syllabus_id;
        this.role = role;

        cc.assetManager.loadBundle(bondleUrl, { version: version }, (err, bundle) => {
            if (err) {
                return console.error(err);
            }
            bundle.loadScene(sceneName, (err, scene) => {
                this.hideWaitingLetters();
                cc.director.runScene(scene);
            });
        });
    },

    initListener() {
        const exitBtn = this.node.getChildByName('ExitBtn');
        exitBtn.on('click', () => {
            cc.tween(exitBtn)
                .to(0.1, { scaleX: 0.9, scaleY: 1.1 })
                .to(0.1, { scaleX: 1.1, scaleY: 0.9 })
                .to(0.1, { scaleX: 1, scaleY: 1 })
                .call(() => {
                    cc.game.removePersistRootNode(this.node);
                    cc.director.loadScene("emptyScene", () => {
                        this.callNativeFunction({ name: 'exit', value: '' });
                    });
                })
                .start();
        });

        const btnLeft = this.node.getChildByName('BtnLeft');
        btnLeft.on('click', () => {
            if (this.currentBundleIndex - 1 < 0) {
                this.jumpToBundleByIndex(this.bundleInfoList.length - 1);
            } else {
                this.jumpToBundleByIndex(this.currentBundleIndex - 1);
            }
        });

        const btnRight = this.node.getChildByName('BtnRight');
        btnRight.on('click', () => {
            if (this.currentBundleIndex + 1 >= this.bundleInfoList.length) {
                this.jumpToBundleByIndex(0);
            } else {
                this.jumpToBundleByIndex(this.currentBundleIndex + 1);
            }
        });
    },

    callNativeFunction(param) {
        const paramStr = JSON.stringify(param);
        if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
            return jsb.reflection.callStaticMethod('CocosMng', 'cocosWithNativeProtocol:', paramStr);
        } else if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID) {
            return jsb.reflection.callStaticMethod('com/iplayabc/cocos/AppActivity', 'cocosWithNativeProtocol', '(Ljava/lang/String;)Ljava/lang/String;', paramStr);
        } else {
            throw ('非源生环境');
        }
    },

    showWaitingLetters() {
        const colorList = this.getRainbowColorList();
        const layout = cc.find('middleLayer/layout');
        layout.active = true;
        const str = 'Now Loading...';
        str.split('').forEach((word, idx) => {
            const node = new cc.Node();
            const label = node.addComponent(cc.Label);
            label.string = word;
            node.parent = layout;
            node.color = colorList[idx];
            cc.tween(node)
                .delay(idx / 4)
                .by(0.3, { y: 50 }, { easing: 'sineOut' })
                .by(0.3, { y: -50 }, { easing: 'sineIn' })
                .delay((str.length - idx) / 4)
                .union()
                .repeatForever()
                .start();
        });
        const totalWidth = layout.children.reduce((width, node, idx) => {
            return width + node.width;
        }, 0);
        layout.width = totalWidth;
    },

    hideWaitingLetters() {
        const layout = cc.find('middleLayer/layout');
        layout.active = false;
    },

    showLog(str) {
        console.log('str = ' + str);
        const node = new cc.Node();
        const label = node.addComponent(cc.RichText);
        label.string = `<outline color=black width=3>${str}</outline>`;
        label.maxWidth = this.node.width / 2;
        node.x = this.node.width / 2;
        node.y = this.node.height / 2;
        node.parent = this.node;
        cc.tween(node)
            .to(5, { y: this.node.height })
            .call(() => {
                node.removeFromParent();
            })
            .start();
    },

    getRainbowColorList() {
        return [
            cc.color(128, 0, 255),
            cc.color(255, 0, 255),
            cc.color(255, 0, 128),

            cc.color(0, 0, 0),

            cc.color(255, 0, 0),
            cc.color(255, 128, 0),
            cc.color(255, 255, 0),
            cc.color(128, 255, 0),
            cc.color(0, 255, 0),
            cc.color(0, 255, 128),
            cc.color(0, 255, 255),

            cc.color(0, 128, 255),
            cc.color(0, 0, 255),
            cc.color(128, 0, 255),
        ];
    }
});
