// 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;



export enum moduleState {
        INIT1 = 0,
        INIT2 = 1,
        Ready = 2,
        SetSpin = 3,
        Spining = 4,
        Stopping = 5,

    };

export interface columnCondition {
        finalResult:Array<number>; // 預期的最後結果 可為空
        delayTime:number; // 轉動前的延遲 單位 ms
        accelerateTime:number; // 加速時間  單位 s
        slowdownTime:number; // 減速時間 單位 s
        holdspeedTime:number; // delete
        N:number; // 持平速度的item數量    (-1 表示永動 需要手動停)
    };



@ccclass("gameMY")
export class gameMY extends cc.Component {

    @property
    columnCount:number = 5;

    @property
    itemSize:number = 240;

    @property(cc.Label)
    betString: cc.Label = null;

    @property(cc.Label)
    bigFrameString: cc.Label = null;

    @property(cc.Label)
    balanceString: cc.Label = null;

    @property({type: cc.Prefab})
    columnPrefab: cc.Prefab | null = null;

    @property(cc.Node)
    slotBoard: cc.Node = null;

    


    private betNumber: number;
    private balanceNumber: number;
    private bigFrameNumber: number;

    private isColumnSpin = {}; // 記錄各個 column 的是否旋轉
    private columnsID: Array<string> = []; // 記錄各個 column 的 node name

    keepSpin:boolean = false;

    columnConditionList = {};   // 放置所有 column spin codition

    nowState: moduleState = moduleState.INIT1; // 狀態機

    // item 圖片資源存放區
    itemNameMapping = {
        'item_01':1, 'item_02':2, 'item_03':3, 'item_04':4, 'item_9':5, 
        'item_10':6, 'item_j':7,  'item_k':8,  'item_q':9,  'item_a':10, 
        'item_scatter':51, 'item_wild':52
    } as const;

    item_spriteFrame = {};
    itemBlur_spriteFrame = {};



    protected onLoad () {

        this.unitTestInit(); // for engineer use

        this.onColumnsSignal();

        // 讀取 item 圖片資源
        cc.resources.loadDir('item',cc.SpriteFrame, (err: any, sF) => {
            sF.forEach( (eachSpriteFrame)=>{
                this.item_spriteFrame[ this.itemNameMapping[eachSpriteFrame.name] ] = eachSpriteFrame;
            })
        } );
        cc.resources.loadDir('item_blur',cc.SpriteFrame, (err: any, sF) => {
            sF.forEach( (eachSpriteFrame)=>{
                this.itemBlur_spriteFrame[ this.itemNameMapping[eachSpriteFrame.name] ] = eachSpriteFrame;
            })
        } );

    }



    protected start () {
        this.betNumber = 50;
        
        this.slotBoard.children[0].name = "0";
        this.slotBoard.addChild( cc.instantiate(this.columnPrefab), 1 , "1");
        this.slotBoard.addChild( cc.instantiate(this.columnPrefab), 2 , "2");
        this.slotBoard.addChild( cc.instantiate(this.columnPrefab), 3 , "3");
        this.slotBoard.addChild( cc.instantiate(this.columnPrefab), 4 , "4");
    }

    protected update (dt) {

        let isAnySpin:boolean = false;
        let isAllSpin:boolean = true;
        switch(this.nowState){
            case moduleState.INIT1:
                // 檢查圖片載入完成後
                // 將必要資訊餵給 column 後再 active column 
                // 再完成初始化
                if((Object.keys(this.item_spriteFrame).length === Object.keys(this.itemNameMapping).length)){
                    for(let i=0; i<this.columnCount; i++){
                        this.slotBoard.children[i].getComponent('columnControl').gameModule = this.node;
                        this.slotBoard.children[i].active = true;
                        this.nowState = moduleState.INIT2;
                    }
                }
                break;
            case moduleState.INIT2:
                for(let i=0; i<this.columnCount; i++){
                    this.columnsID.push(this.slotBoard.children[i].name); // 直接取位置資訊當ID    
                    this.isColumnSpin[this.slotBoard.children[i].name] = false;
                }
                this.simulateCondition(); // dev
                // cc.log(this.columnsID) // dev
                // cc.log(this.isColumnSpin) // dev
                this.nowState = moduleState.Ready;
                break;
            case moduleState.Ready:
                break;
            case moduleState.SetSpin:
                Object.values(this.isColumnSpin).forEach((x:boolean)=>{
                    isAllSpin = isAllSpin && x;
                });
                if(isAllSpin) {
                    this.nowState = moduleState.Spining;
                    // TODO: 避免重複使用 columnConditionList 應該適當處理
                }
                break;
            case moduleState.Spining:
                Object.values(this.isColumnSpin).forEach((x:boolean)=>{
                    isAnySpin = isAnySpin || x;
                });
                if( !isAnySpin ){
                    if(this.keepSpin){
                        // get new condition
                        this.nowState = moduleState.SetSpin;
                        break;
                    }else{
                        this.nowState = moduleState.Stopping;
                    }
                }
                break;
            case moduleState.Stopping:
                Object.values(this.isColumnSpin).forEach((x:boolean)=>{
                    isAnySpin = isAnySpin || x;
                });
                if( !isAnySpin ) this.nowState = moduleState.Ready;
                
                break;
            default:
                break;
        }

    } 


    onBetBtnClick(e: cc.Event.EventTouch): void {
        // let a = e.getCurrentTarget().name
        // cc.log(a)
        if(e.getCurrentTarget().name == 'btn_plus'){
            this.betNumber += 50;
        }
        else{
            this.betNumber -= 50;
        }
        this.betString.string = "" + this.betNumber;

    }

    onSpinBtnClick():void {

        switch(this.nowState){
            case moduleState.Ready:
                this.nowState = moduleState.SetSpin;
                break;
            case moduleState.Spining:
                this.nowState = moduleState.Stopping;
                break;
            default:
                cc.log("do nothing");
                break;
        }

    }

    onColumnsSignal():void {
        this.node.on('AColumnStop', (ID)=>{
            this.isColumnSpin[ID] = false;
        }, this)

        this.node.on('AColumnStart',(ID)=>{
            this.isColumnSpin[ID] = true;
        } ,this)
    }








    simulateCondition():void {
        for(let i=0; i<this.columnCount; i++){
            let a:columnCondition = {        
                finalResult:[i+1,i+1,i+1],
                delayTime:200*i,
                accelerateTime:5,
                slowdownTime:2,
                holdspeedTime:0.5,
                N:3}
            this.columnConditionList[this.columnsID[i]]=a
        }
    }

    unitTestInit():void {
        // for unitTest 1
        this.node.on('Bob', (arg1)=>{
            cc.log("gameModule Recieve Bob say " + arg1);
        }, this)
    }




}
