UI.moduleBuilder['Alexa']['voiceService'] = function(){
    var voiceServiceData = {
        btn1bgImg: UI.item_bg,
        cover: "Alexa/cover.png",
        barBgImg:"Alexa/blueCircle.png",
        barBgImg1:"Alexa/greenCircle.png",
        barBgImg2:"Alexa/gradualColor.png",
        barImg:"Alexa/gradualColor.png",
//        logoBg:"Alexa/logo_bg.png",
        avsLogo:"Alexa/avs_logo.png",
        barBgImgError:"Alexa/error.png",
        barBgImgTimeout:"Alexa/greenCircle.png",
        voiceServiceBg:UI.item_bg,
        voiceServiceText:"",
        mike:"Alexa/ic_mike.png"
    };
    var template = Util.readJson("module/Alexa/voiceService.json");
    var voiceService =  SubModule.create(voiceServiceData, template);


    var barBgImg = UI.getItem(voiceService, "barBgImg");
    var barBgImg1 = UI.getItem(voiceService, "barBgImg1");
    var barImg = UI.getItem(voiceService, "barImg");
    var barBgImgError = UI.getItem(voiceService, "barBgImgError");
    var barBgImgTimeout = UI.getItem(voiceService, "barBgImgTimeout");
    var progressBar = UI.getItem(voiceService, "progressBar");
    var logoBg = UI.getItem(voiceService, "logoBg");
    var voiceServiceText = UI.getItem(voiceService, "voiceServiceText");
    var voiceServiceBg = UI.getItem(voiceService, "voiceServiceBg");
    var mike = UI.getItem(voiceService, "mike");

    voiceService.speakingTimer = null;
    voiceService.thinkingTimer = null;
    voiceService.activeListeningTimer = null;
    voiceService.listeningTimer = null;
    voiceService.errorTimer = null;
    voiceService.timeoutTimer = null;
    voiceService.timeoutStayTimer = null;
    voiceService.currFocus = barBgImg;
    voiceService.status = 0;

    voiceService.onPush = function(){
        UIObserver.subscribeMessage(UIObserver.MESSAGE_NAME.AVS_ONSPEECHSTATECHANGED,speechStateChanged);
        // UIObserver.subscribeMessage(UIObserver.MESSAGE_NAME.AVS_ERROR_CODE,errorCodeChanged);
        DBG_ERROR("push voiceService");
        AVSClient.speech.notifyOtherModuleChromeShown();
        // registerKeyCodesForUI();
        if(null != UI.getGhostModule(APPMODULE.CONTROL) || isCECByPass()) {
            var play_btns = [CONST.KEY.VK_PLAY, CONST.KEY.VK_STOP, CONST.KEY.VK_PAUSE, CONST.KEY.VK_LAST, CONST.KEY.VK_NEXT, CONST.KEY.VK_FAST_FWD, CONST.KEY.VK_FAST_BKW]
            var keys = Object.keys(CONST.KEY);
            keys.forEach(function (k) {
                if (play_btns.indexOf(CONST.KEY[k]) < 0) {
                    UI.keySet[CONST.KEY[k]] = true;
                }
            });
            UI.setKeyGroup(7);
        }
        showcommonStatus();
        showHelpMessage(0,"",0);
        barBgImg.alpha = 1;
        barBgImg1.alpha = 0;
        progressBar.y = 146 + 73;
        addCircleMask(progressBar,146,146,73);
        logoBg.removeAllChildren();
        var shape = new PIXI.Graphics();
        logoBg.redraw = function (g) {
            g.clear();
            g.beginFill(0x000000);
            g.lineStyle(1, 0x000000, 1);
            g.drawCircle(73,73,65);
            g.endFill();
        };
        logoBg.addChild(shape);
        logoBg.redraw(shape);
        UI.updateStage();
//        var ret = Config.tv ? model.network.getEnumNetworkAvailable() : 0;
//        DBG_ERROR("ret is " + ret);
//        if (!ret) {
//            errorState();
//            showHelpMessage(1,"We are unable to connect to Amazon services.Please check your Internet connection or try again later.");
//        }
    }


    voiceService.onPop = function(){
        DBG_ERROR("pop voiceService");
        voiceService.status = 0;
        AVSClient.speech.notifyOtherModuleChromeHiden();
        if (checkIsAppOn() && UI.getCurrSubModule().name == "blank") {
            registerKeyCodesForApp();
        }
        UIObserver.unsubscribeMessage(UIObserver.MESSAGE_NAME.AVS_ONSPEECHSTATECHANGED,speechStateChanged);
        // UIObserver.unsubscribeMessage(UIObserver.MESSAGE_NAME.AVS_ERROR_CODE,errorCodeChanged);
        clearAllTimer();

    }

    voiceService.onkey = function(focus, evt){
        DBG_ERROR("receive key ");
        if(evt.keyCode == CONST.KEY.VK_VOICE_UP) {
            return true;
        }
        if (voiceService.status > 0) {
            if (voiceService.status != AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_ALARM) {
                AVSClient.speech.cancel();
                voiceService.status = AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_IDLE;
            }
        }
        if (!!voiceService.timeoutTimer) {
            AVSClient.speech.cancelAlarm();
        }
        UI.popGhostModule("voiceService");
        return (Alexa_globalKeys.indexOf(evt.keyCode) >= 0);
    }
    function showcommonStatus(){
        barBgImgError.alpha = 0;
        barBgImgTimeout.alpha = 0;
    }

    function showHelpMessage(alpha ,text ,mikealpha ,timeoutFlag){
        voiceServiceBg.alpha = alpha;
        voiceServiceText.alpha = alpha;
        UI.setText(voiceServiceText,text);
        mike.alpha = mikealpha;
        UI.updateStage();
        if(timeoutFlag){
            clearTimeout(voiceService.timeoutStayTimer);
            voiceService.timeoutStayTimer = setTimeout(function(){
                DBG_ERROR("Time out of the text prompt");
                voiceServiceBg.alpha = 0;
                voiceServiceText.alpha = 0;
                mike.alpha = 0;
                UI.updateStage();
            },5000);
        }
    }

    function clearAllTimer(){

        if(!!voiceService.speakingTimer){
            clearInterval(voiceService.speakingTimer);
            voiceService.speakingTimer = null;
        }
        if(!!voiceService.thinkingTimer){
            clearInterval(voiceService.thinkingTimer);
            voiceService.thinkingTimer = null;
        }
        if(!!voiceService.listeningTimer){
            clearInterval(voiceService.listeningTimer);
            voiceService.listeningTimer = null;
        }
        if(!!voiceService.activeListeningTimer){
            clearInterval(voiceService.activeListeningTimer);
            voiceService.activeListeningTimer = null;
        }
        if(!!voiceService.errorTimer){
            clearInterval(voiceService.errorTimer);
            voiceService.errorTimer = null;
        }
        if(!!voiceService.timeoutTimer ){
            clearInterval(voiceService.timeoutTimer);
            voiceService.timeoutTimer = null;
        }
        if(!!voiceService.timeoutStayTimer){
            clearTimeout(voiceService.timeoutStayTimer);
            voiceService.timeoutStayTimer = null;
        }


    }

    function errorCodeChanged(status){
        DBG_ERROR("errorCodeChanged status is " + status);
        if(status == 3){// press voice key and relaese
            showHelpMessage(1,"Press and hold the remote button               , then speak after the tone, such as 'What's the weather today?', 'Search 'Comedy''.",1);
            mike.x = -435;
            AVSClient.logReport.reportFailure(AVSClient.logReport.CONST.ERR_CODE_PRESSTOOSHORT, AVSClient.logReport.CONST.ERR_TYPE_USING);
        }else if(status == 4){//network error
            showHelpMessage(1,"We are unable to connect to Amazon services.Please check your Internet connection or try again later.",0);
            AVSClient.logReport.reportFailure(AVSClient.logReport.CONST.ERR_CODE_USINGNETERROR, AVSClient.logReport.CONST.ERR_TYPE_USING);
        }else if(status == 6 || status == 5 ){//thinking beyond 20s||   beyond 20s in listening state
            showHelpMessage(1,"We are unable to respond to your request. Please try again later.",0);
            AVSClient.logReport.reportFailure(AVSClient.logReport.CONST.ERR_CODE_SERVICEERR, AVSClient.logReport.CONST.ERR_TYPE_USING);
        }else{
            return;
        }
        errorState();
    }

    function speechStateChanged(status){
        DBG_ERROR("voiceService status is " + status);
        // if (!!voiceService.timeoutTimer){
        //     AVSClient.speech.cancelAlarm();
        // }
        if(status == voiceService.status){
            DBG_ERROR("repeat status: abandon");
            return;
        }
        voiceService.status = status;
        if (status < 0) {
            errorCodeChanged(-1*status);
            return;
        }
        showHelpMessage(0,"",0);
         switch(status){
             case AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_IDLE://idle
                 UI.popGhostModule("voiceService");
                 break;
             case AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_LISTENING://ENUM_SL2_TVAPI_AVS_RECOG_STATE_LISTENING
                 listeningState();
//                 setTimeout(function(){
//                     activeListeningState();
//                 },300);
                 break;
             case AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_THINKING://ENUM_SL2_TVAPI_AVS_RECOG_STATE_THINKING
                 thinkingState();
                 break;
             case AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_SPEAKING://ENUM_SL2_TVAPI_AVS_RECOG_STATE_SPEAKING
                 speakingState();
                 break;
             case AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_ALARM:
                 timeoutState();//AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_ALARM
                 showHelpMessage(1,"Press any button on remote control (except vol +/- and mute) to stop the timer or alarm.",0,true);
                 mike.x = -630;
                 break;
             case 5:
                 break;
             case 6:
                 break;
             case AvsModelDefines.ENUM_SL2_TVAPI_AVS_RECOG_STATE_INTERACTON://Multi-turn interaction
                 errorState();
                 showHelpMessage(1,"Press and hold the remote button              ,then speak after the tone.",1,true);
                 mike.x = -435;
                 UI.updateStage();
                 break;
             default :
                 break;
         }
    }

    function listeningState(){
        DBG_ERROR("listeningState begin");
        showcommonStatus();
        clearAllTimer();
        createjs.Tween.removeTweens(progressBar);
        barBgImg1.alpha = 0;
        barBgImg.alpha = 1;
        progressBar.y = 146 + 73;
        UI.getTween(progressBar).to({y: progressBar.y - 146 }, 300);
        UI.updateStage();
        DBG_ERROR("listeningState END");
    }

    function activeListeningState(){
        DBG_ERROR("activeListeningState begin");
//        if(voiceServiceBg.alpha == 1){
            showHelpMessage(0,"",0);
//        }
        showcommonStatus();
        clearAllTimer();
        createjs.Tween.removeTweens(progressBar);
        barBgImg1.alpha = 0;
        barBgImg.alpha = 1;
        voiceService.activeListeningTimer = setInterval(function(){
            progressBar.y = 73 + 146 +73 + 30 ;
            UI.getTween(progressBar)
                .to({y:progressBar.y + 5}, 150)
                .to({y:progressBar.y - 5}, 150)
                .to({y:progressBar.y + 10}, 150)
                .to({y:progressBar.y - 10}, 150)
                .to({y:progressBar.y + 15}, 150)
                .to({y:progressBar.y - 15}, 150)
            },900);
        UI.updateStage();
        DBG_ERROR("activeListeningState end");
    }

    function thinkingState(){
        showcommonStatus();
        clearAllTimer();
        createjs.Tween.removeTweens(progressBar);
        barBgImg1.alpha = 0;
        barBgImg.alpha = 1;
        voiceService.thinkingTimer = setInterval(function(){
//            DBG_ERROR(" progressBar.y is " +  progressBar.y);
            createjs.Tween.removeTweens(progressBar);
            progressBar.y = 146 + 73 +73 ;
            UI.getTween(progressBar).to({y: progressBar.y +  73}, 1000, UI.ease.quadIn);
        },1000);
        UI.updateStage();
    }

    function speakingState(){
        showcommonStatus();
        clearAllTimer();
        createjs.Tween.removeTweens(progressBar);
        progressBar.y = 146 + 73;
        barBgImg.alpha = 1;
        voiceService.speakingTimer = setInterval(function(){
            barBgImg1.alpha = 0;
            UI.getTween(barBgImg1).to({alpha:1}, 1000);//up
        },1000);
        UI.updateStage();
    }

    function errorState(){
        clearAllTimer();
        createjs.Tween.removeTweens(progressBar);
        progressBar.y = 146+ 73;
        barBgImg.alpha = 0;
        barBgImg1.alpha =1;
        barBgImgTimeout.alpha =0;
        barBgImgError.alpha = 0;
        UI.getTween(barBgImgError).to({alpha:1}, 1000);
        UI.updateStage();
//        showHelpMessage(1,"We are unable to connect to Amazon services.Please check your Internet connection or try again later.");
    }

    function timeoutState(){
        clearAllTimer();
        createjs.Tween.removeTweens(progressBar);
        progressBar.y = 146+ 73;
        barBgImg.alpha = 1;
        barBgImg1.alpha =0;
        barBgImgError.alpha = 0;
        voiceService.timeoutTimer = setInterval(function(){
            barBgImgTimeout.alpha = 0;
            UI.getTween(barBgImgTimeout).to({alpha:1}, 1000);//up
        },1000);
        UI.updateStage();
    }


    function addCircleMask(target, width, height, radius,offsetX, offsetY) {
        if (undefined == offsetX) {
            offsetX = 0;
        }
        if (undefined == offsetY) {
            offsetY = 0;
        }
        var mask;
        if (target.mask) {
            mask = target.mask;
        } else {
            mask = new PIXI.Graphics();
            target.parent.addChild(mask);
            target.mask = mask;
        }
        mask.clear()// function (x, y, radius)
            .beginFill(0x0000FF, 0.5)
            .drawCircle(width/2 + offsetX * 2, height/2 + offsetY * 2,radius)
            .endFill();
        if (target.initSequence) {
            mask.position.x = target.initPos.x - offsetX;
            mask.position.y = target.initPos.y - offsetY;
        } else {
            mask.position.x = target.x - target.pivot.x - offsetX;
            mask.position.y = target.y - target.pivot.y - offsetY;
        }
        mask.rectWidth = width;
        mask.rectHeight = height;
    }

    function resetVoiceService(v){
        DBG_ERROR("resetVoiceService");
        if (1 == v) {
            if(UI.getGhostModule("voiceService") != null) {
                AVSClient.speech.cancel();
                UI.popGhostModule("voiceService");
            }

        }
    }

    UIObserver.subscribeMessage(UIObserver.MESSAGE_NAME.ENTER_SUSPEND_MODE, resetVoiceService);

}

