
function audioPlayer(){
    //store audio data
    var playQueue = new Array();

    var parser = new directiveParse();

    var stateMachine = new APlayerStateMachine();

    var latestStreamToken = "";

	var ProgressReportDelayElapsedValue = 0;
    var ProgressReportIntervalElapsedValue = 0;
    var offsetInMilliseconds = 0;

	var preEventName = "";

    var audioPlayerTimer = new AudioPlayerTimer();
    audioPlayerTimer.reset(0);

    var audioLabel = document.createElement("audio");
    audioLabel.src = "";
	var connectCount = 0;
	var reconnect = 0;
    var loadedmetadataListener;

    var playbackStartedFlag = false;
    var pausePlayingFlag = 0;
    var startTimeFlag = 0;
    var pauseVSstop = 0;
    var sendnearlyFinishFlag = true;
    var canPlaythroughoutFlag = false;
    var playingstatus = false;
    var waitforplaying = false;
    var loadedmetadataFlag = false;
    var cidstartFlag = false;
    var urlCidFlag = false;
    var audioPlayerNativeURL = "file:///opt/hisenseUI/html/hisenseUI/module/Alexa/audioPlayer/audioPlayer.html";
    var cidReqNum = 0;
    var sendErrorFlag = false;
    var settimeoutID = -1;
    var entercid = false;
     audioLabel.addEventListener("playing", function(){
         DBG_INFO("handle playing event");
       if(offsetInMilliseconds > 0 && startTimeFlag == 0)
       {
           DBG_ERROR("playing offset:" +offsetInMilliseconds );
           audioLabel.muted = true;
       }
	  //if(startTimeFlag == 0 && offsetInMilliseconds > 0){
      //    DBG_ERROR("wch add offset:"+ offsetInMilliseconds );
      //    audioLabel.currentTime = offsetInMilliseconds/1000;           
      //    startTimeFlag = 1;
      //}
         if(waitforplaying)
         {
             audioLabel.removeEventListener("canplay",canplayToPlay);
             waitforplaying = false;
         }
         playingstatus = true;
		 connectCount = 0;
		playbackStartedFunc();
         audioPlayerGlobal.stopPlayingFlag = 0;
		preEventName = "playing";
         audioPlayerTimer.start();
    });
    audioLabel.addEventListener("ended", function(){
        DBG_INFO("handle ended event");
        //DBG_INFO("the queue length is "+ playQueue.length);
		audioPlayerTimer.stop();
        resetTime();
        clearTimeout(settimeoutID);
		stateMachine.playbackFinished();
		preEventName = "ended";
        audioPlayerGlobal.stopPlayingFlag = 1;
        setTimeout(function(){audioLabel.removeEventListener("timeupdate", sendEvent,false);}, 1);

        playQueue.shift();
        DBG_INFO("the queue length is "+ playQueue.length);
        if(playQueue.length != 0){
            if(urlCidFlag){
                DBG_INFO("make cid url null");
                sourceBuffer.removeEventListener('updateend', nextSegment);
                //sourceBuffer.removeEventListener('updateend', endstream);
                // AvsMusic.removeEventListener("cid_start",playwithcid);
                ms.removeSourceBuffer(sourceBuffer);
                sourceBuffer = '';
                urlCidFlag = false;
                ms = '';
            }
            setTimeout(function(){
                audioLabel.src = '';
                audioLabel.load();
                startPlay(playQueue[0]);
            },500);
        }else{
            //reset progressBar and currentTime when a song is end and no another one coming
            audioPlayerGlobal.switchPlayPauseIcon(false);
            if(document.getElementById("audioPlayerDiv").style.visibility == "visible"){
                var width = 0;
                $("#pg").css("width", width + "px"); //reset progress bar
                $("#currentTime").text(getTimeText(0)); // reset current time
            }
        }
    });
    audioLabel.addEventListener("pause", function(){
        DBG_INFO("handle pause event");
		audioPlayerTimer.stop();
        if(audioLabel.currentTime < audioLabel.duration) {
            if( 1){
                stateMachine.playbackPaused();
            }
            else{
                stateMachine.playbackStopped();
                pauseVSstop = 0;
            }

        }
		preEventName = "pause";
    });
    audioLabel.addEventListener("abort", function(){
        DBG_INFO("handle abort event");
		audioPlayerTimer.stop();
		//stateMachine.playbackStopped();
		preEventName = "abort";
    });

    reconnect = function () {
        DBG_INFO("reconnect " +connectCount);
        //var audiocurrentTime = audioLabel.currentTime;
        var url = audioLabel.src;
        if(!playingstatus){
            audioLabel.src = url;
            audioLabel.load();
            setTimeout(function(){
                //if(audiocurrentTime == 0){
                    //audioLabel.currentTime = offsetInMilliseconds/1000;
              //  }
              //  else{
                    //audioLabel.currentTime = audiocurrentTime;
              //  }
                //audioLabel.play()
               AvsMusic.sendJsonMessage(JSON.stringify({name:"speech",directive:"isShown"}));
            } ,100);
        }

    };

    reconnect2 = function(){
        DBG_INFO("reconnect2 " +connectCount);
        //var audiocurrentTime = audioLabel.currentTime;
        var url = audioLabel.src;
        playbackStartedFlag = false;
            audioLabel.src = url;
            audioLabel.load();
            setTimeout(function(){
                AvsMusic.sendJsonMessage(JSON.stringify({name:"speech",directive:"isShown"}));
            } ,100);

    }
    audioLabel.addEventListener("error", function(){
		var errorCode = audioLabel.error.code;
        audioPlayerTimer.stop();
		DBG_ALWAYS("handle error event"+errorCode);
        DBG_ALWAYS("handle error event URL "+audioLabel.src);
        if(!urlCidFlag &&(audioLabel.src == audioPlayerNativeURL)){
            DBG_INFO("restart from playQueue");
            return;
        }
        if(!urlCidFlag&& audioLabel.url != ""&& (errorCode == 2 || errorCode ==3)){
            var CTime = audioLabel.currentTime;
            if(connectCount < 2){
                setTimeout(reconnect2,300);
                connectCount = connectCount +1;
            }
            else{
                if(!sendErrorFlag){
                    stateMachine.playbackFailed();
                    sendErrorFlag = true;
                }
            }

        }
        if (!urlCidFlag&& audioLabel.url != "" && audioLabel.readyState == 0){
            if(!loadedmetadataFlag &&errorCode == 4  && connectCount <2){
                DBG_ALWAYS("connect again");
                setTimeout(reconnect,3000);
                connectCount = connectCount +1;
            }
            else{
                if(!playingstatus){
                    audioPlayerTimer.stop();
                    if(!sendErrorFlag){
                        stateMachine.playbackFailed();
                        sendErrorFlag = true;
                    }
                    preEventName = "error";
                }

			}
		}
        if(urlCidFlag && audioLabel.src ==audioPlayerNativeURL &&audioLabel.readyState == 0 ){
            DBG_ALWAYS("cid meet error then play");
            if(!entercid){
                playwithcid();
            }
        }
    });

	audioLabel.addEventListener("canplaythrough", function(){
        DBG_INFO("handle canplaythrough event");
        var duratioTimeS = audioLabel.duration;
        var lengthS = duratioTimeS - offsetInMilliseconds/1000;
        if((!canPlaythroughoutFlag)&&(lengthS <60 || duratioTimeS >3600 )){
            stateMachine.playbackNearlyFinished();
            canPlaythroughoutFlag = true;
        }

		preEventName = "canplaythrough";
    });

	audioLabel.addEventListener("waiting", function(){
        DBG_INFO("handle waiting event");
        audioPlayerTimer.stop();
        if(("canplaythrough" == preEventName) || ("playing" == preEventName)){
            audioPlayerTimer.stop();
            stateMachine.playbackStutterStarted();
            preEventName = "waiting";
        }
    });
    AvsMusic.addEventListener("offset",function(){
        //send offset
        offset = audioPlayerGlobal.getCurrentOffsetInMilliseconds();
        AvsMusic.sendAudioOffsetMsg(offset);
    });
    //var createMSFlag = true;
    var sourceBuffer = '';
    var ms = '';//new MediaSource();

    function startPlayWithCid(){
        AvsMusic.addEventListener("cid_start",function(){
            DBG_INFO("cid_start cidstartFlag :"+ cidstartFlag);
            if(!cidstartFlag ){
                playwithcid();
                cidstartFlag = true;
            }else
            {
                DBG_INFO("cid_start already :"+ cidstartFlag);
            }

        });
    }



    //AvsMusic.addEventListener("cid_start",function(){
    function playwithcid(){
        entercid = true;
        DBG_INFO("enter playwithcid");
        sourceBuffer = "";
        ms = "";
        var ciddataFromB = AvsMusic.getAudioData();
        if(ciddataFromB == ''){
            cidReqNum = cidReqNum+1;
            setTimeout(function(){
                if(cidReqNum <=10){
                    playwithcid();
                }
                else{
                    if(!sendErrorFlag){
                        stateMachine.playbackFailed();
                        sendErrorFlag = true;
                    }

                 //   return;
                }
            },1000)
        }
        //DBG_INFO("ciddataFromB"+ciddataFromB);
        else{
            var ciddataJson = JSON.parse(ciddataFromB);
            DBG_INFO("ciddataJson:"+ciddataJson.status);
            var cidData = ciddataJson.data;

            //if(createMSFlag == true){
            ms = new MediaSource();
            audioLabel.src = window.URL.createObjectURL(ms);
            audioLabel.load();
            ms.addEventListener('sourceopen', onMediaSourceOpen);
            //    createMSFlag = false;
            //}
            // else{
            //   onMediaSourceOpen();
            // sourceBuffer.addEventListener('updateend', nextSegment);

            function onMediaSourceOpen() {
                sourceBuffer = ms.addSourceBuffer('audio/mpeg');
                sourceBuffer.addEventListener('updateend', nextSegment);

                appendToBuffer(cidData );
                AvsMusic.sendJsonMessage(JSON.stringify({name:"speech",directive:"isShown"}));
                //audioLabel.play();
            };
        }

    };
        function nextSegment() {
            var nextCidDataFromB =  AvsMusic.getAudioData();
            if (nextCidDataFromB == ''){
                //sourceBuffer.removeEventListener('updateend', nextSegment);
                setTimeout(function(){
                    nextSegment();
                },1000)
            }
            else{
                sourceBuffer.removeEventListener('updateend', nextSegment);
                var  nextciddataJson = JSON.parse(nextCidDataFromB);
                var nextcidData = nextciddataJson.data;
                DBG_INFO("nextciddataJson"+nextciddataJson.status);
                if(nextciddataJson.status == 3){
                    DBG_INFO("nextciddataJson.status == 3");
					ms.endOfStream(); 
                   // sourceBuffer.addEventListener('updateend',endstream );
                   // appendToBuffer(nextcidData);
                }
                else{
                    sourceBuffer.addEventListener('updateend', nextSegment);
                    appendToBuffer(nextcidData);
                }
            }
        };

        function appendToBuffer(audioChunk) {
            var arraybuffer = new Uint8Array(audioChunk);
            if (arraybuffer) {
                sourceBuffer.appendBuffer(arraybuffer);
            }
            else{
                    DBG_ERROR("create arraybuffer");
            }
        };

    function endstream(){
        DBG_INFO("end  of stream");
        ms.endOfStream();
        return;
    }
	function resetTime(){
        ProgressReportDelayElapsedValue = 0;
        ProgressReportIntervalElapsedValue = 0;
        offsetInMilliseconds = 0;
        audioPlayerTimer.reset(0);
    }
	function playbackStartedFunc(){
        if(preEventName == "waiting"){
            DBG_INFO("handle PlaybackStutterFinished event");
            stateMachine.playbackStutterFinished();
            preEventName = "playbackStutterFinished";
        }
        else if(playbackStartedFlag &&(preEventName == "pause")){
            DBG_INFO("handle PlaybackResumed event");
            stateMachine.playbackResumed();
            preEventName = "playbackResumed";
        }
        if (audioPlayerGlobal.getAudioTotalLength() > 3600) {
//                $("#currentTime").css("margin-left", "470px");
            $("#duration").html(getTimeTextWithHour(audioPlayerGlobal.getAudioTotalLength()));
        }
        else {
//                $("#currentTime").css("margin-left", "550px");
            $("#duration").html(getTimeText(audioPlayerGlobal.getAudioTotalLength()));
        }
        if(playbackStartedFlag == false){
            DBG_INFO("handle start playing event");

            if(1){
                //audioLabel.pause();


                stateMachine.playbackStarted();
                playbackStartedFlag  = true;

                DBG_INFO("offsetInMilliseconds =" + offsetInMilliseconds);
                DBG_INFO(" DelayElapsedValue ="+ ProgressReportDelayElapsedValue);
                DBG_INFO(" ProgressReportIntervalElapsedValue ="+ProgressReportIntervalElapsedValue );
                sendProgressReportElapsedEvent();
            }
            else{

            }

        }
    }
    function sendProgressReportElapsedEvent(){
        delayMseconds = ProgressReportDelayElapsedValue;
        intervalMseconds = ProgressReportIntervalElapsedValue;
       /* if(ProgressReportIntervalElapsedValue != 0){
            tmpinterval = (ProgressReportIntervalElapsedValue-offsetInMilliseconds)%ProgressReportIntervalElapsedValue;
            intervalMseconds = (tmpinterval +ProgressReportIntervalElapsedValue )%ProgressReportIntervalElapsedValue;
            if(intervalMseconds == 0){
                intervalMseconds = ProgressReportIntervalElapsedValue;
            }
        }
*/
        sendDelayFlag = true;
        sendIntervalFlag = true;
        preCurrentMseconds = 0;//audioPlayerTimer.getOffsetInMilliSeconds();
        if (audioPlayerGlobal.getAudioTotalLength() > 3600) {
            //duration is infinity,
        }
        audioLabel.addEventListener('timeupdate',  sendEvent,false) ;
	}
	function sendEvent() {
       if(startTimeFlag == 0 && audioLabel.currentTime > 0.5 && offsetInMilliseconds >0){
           DBG_ERROR("wch add offset:"+ offsetInMilliseconds );
           audioLabel.currentTime = offsetInMilliseconds/1000;
           audioLabel.muted = false;
           startTimeFlag = 1;
       }
        else{}
        // preCurrentMseconds = audioPlayerTimer.getOffsetInMilliSeconds();
        var currentMseconds = audioLabel.currentTime * 1000;
        var cunrrentToInterval =  currentMseconds%intervalMseconds;

        if(sendDelayFlag && (currentMseconds>(delayMseconds-300)) &&(currentMseconds < (delayMseconds+ 300)))
        if(delayMseconds >= 0){
            DBG_INFO("currentMseconds = " + currentMseconds);
            DBG_INFO("delayMseconds = " + delayMseconds);
            stateMachine.delayProgressReport();
            DBG_INFO("handle sendProgressReportDelayElapsed Event");
            sendDelayFlag = false;
        }

        if(sendIntervalFlag && (cunrrentToInterval>0)&&(cunrrentToInterval <600)){
            DBG_ALWAYS("currentMseconds = " + currentMseconds);
            DBG_ALWAYS("cunrrentToInterval = " + cunrrentToInterval);
            if((currentMseconds - preCurrentMseconds) > (0.5*ProgressReportIntervalElapsedValue)){
                stateMachine.intervalProgressReport();
                DBG_INFO("handle sendProgressReportIntervalElapsedEvent first");
                //intervalMseconds = intervalMseconds + ProgressReportIntervalElapsedValue;
				preCurrentMseconds = currentMseconds;
            }
            if(audioLabel.currentTime  >= audioLabel.duration){
                sendIntervalFlag = false;
                DBG_INFO("add the condition of stoping to send ");
            }
        }
        DBG_INFO("audioPlayerGlobal.getAudioCurrentTime is " + audioPlayerGlobal.getAudioCurrentTime());
        // getProgress(audioPlayerGlobal.getAudioCurrentTime());

        var currentS = audioLabel.currentTime;
        var durationS = audioLabel.duration ;
        var lengths = durationS - offsetInMilliseconds/1000;
        var nearlyFinishLimit = durationS -30;
        if(sendnearlyFinishFlag && (lengths>=60)&&(lengths <= 3600) && (currentS > nearlyFinishLimit)){
            DBG_ALWAYS("nearly finish ");
            stateMachine.playbackNearlyFinished();
            sendnearlyFinishFlag = false;
        }
    }
    document.body.appendChild(audioLabel);

    var setCurrentStreamToken = function(token){
        latestStreamToken = token;
    };

    var analysisURL = function(para, url){
        var connectCount = 0;
        var  urltext ='';
        var a = '';// a is array

        if(url.indexOf(".mp3")>=0 || url.indexOf(".aac")>=0 || url.indexOf(".MP3")>=0 || url.indexOf(".AAC")>=0){
            DBG_INFO("audio/mpeg url: " + para.url);
            audioLabel.src = para.url;
            audioLabel.type = "audio/mpeg";
            strartPlayWithhttps();
        }
        else if(url.indexOf("iheartradioversion")>=0 && (url.indexOf(".m3u8")<0 ||url.indexOf(".pls")<0 )){
            DBG_INFO("audio/AAC url: " + para.url);
            audioLabel.src = para.url;
            audioLabel.type = "audio/AAC";
            strartPlayWithhttps();
        }
        else if(url.indexOf(".m4a")>=0 && url.indexOf(".m3u8")){
            DBG_INFO("audio/m4a url: " + para.url);
            audioLabel.src = para.url;
            audioLabel.type = "audio/m4a";
            strartPlayWithhttps();
        }
        else if(url.indexOf(".m3u8")>=0 ||url.indexOf(".m3u")>=0 ||url.indexOf(".pls")>=0 || url.indexOf("formats=")>=0){
            urltext = new XMLHttpRequest();
            urltext.onreadystatechange = function(){
                if(urltext.readyState == 4){
                    if((urltext.status >=200 &&urltext.status<300) || urltext == 304){

                    }else{
                        if(connectCount == 0){
                            setTimeout(function(){
                                //urltext = new XMLHttpRequest();
                                urltext.open("GET",url,true);
                                urltext.send()
                            },300);
                            connectCount = connectCount +1;
                        }
                        DBG_INFO("what , reconnect again");
                    }
                    var text = urltext.responseText;
                    a = text.split("\n");
                    DBG_INFO("a"+a);

                if(url.indexOf(".pls")>=0 || url.indexOf(".PLS")>=0){
                    var plsFlag = 0;
                    for(var i=0; i<=a.length-1; i++){
                        if(a[i]==0 || a[i].indexOf("#")>=0){

                        }else if(a[i].indexOf("File")>=0){
                            var b = a[i].indexOf("http");
                            var c = a[i].slice(b);
                            DBG_INFO("a["+i+"]:"+c+"\n");
                            //add url(c) to queue
                            if(plsFlag == 0){
                                DBG_INFO("audio/pls url: " + c);
                                audioLabel.src = c;
                                plsFlag = 1;
                            }else{
                                var plsmsg = para;
                                plsmsg.url = c;
                                plsmsg.expectedPreviousToken ='';
                                DBG_INFO("push queue"+plsmsg);
                                playQueue.push(plsmsg);
                            }
                        }
                    }
                }
                else //(url.indexOf(".m3u8")>=0 ||url.indexOf(".m3u")>=0 || url.indexOf(".M3U8")>=0 || url.indexOf(".M3U")>=0)
                {
                    var m3u8Flag = 0;
                    for(var i=0; i<=a.length-1; i++){
                        if(a[i]==0 || a[i].indexOf("#")>=0){

                        }else{
                            DBG_INFO("a["+i+"]:"+a[i]+"\n");
                            // add url(a[i]) to queue
                            if(a[i].indexOf(".pls")>=0 || a[i].indexOf(".PLS")>=0){
                                analysisURL(para,a[i]);
                            }
                            else{
                                if(m3u8Flag == 0){
                                    DBG_INFO("audio/m3u8 url: " + a[i]);
                                    audioLabel.src = a[i];
                                    m3u8Flag = 1;
                                }else{
                                    var m3u8msg = para;
                                    m3u8msg.url = a[i];
                                    m3u8msg.expectedPreviousToken = '';
                                    DBG_INFO("push queue"+m3u8msg);
                                    playQueue.push(m3u8msg);
                                }
                            }
                        }
                    }
                    if(0 == a.length){
                      //  audioLabel.src = url; // use url in Play directive
                    }
                    audioLabel.type = "application/vnd.apple.mpegurl";
                }
                    strartPlayWithhttps();
                    urltext = null;

                }
            };
            urltext.open("GET",url,true);
            urltext.send();


        }
        else{
            audioLabel.src = url;
            audioLabel.type =  "audio/mpeg";
            strartPlayWithhttps();
        }

    }
    function tearDown() {
        try {
            audioLabel.removeEventListener("loadedmetadata", loadedMetadataListener, false);
        } catch (ignore) {}
    }
    function isLoaded(){
//if music hava not played, then send fail event
        if(loadedmetadataFlag){
            DBG_INFO("loadedmetadataFlag is true, and have load");
        }else{
            if(audioLabel.src &&(audioLabel.src != audioPlayerNativeURL)){
                DBG_INFO("send fail event");
                if(!sendErrorFlag){
                    stateMachine.playbackFailed();
                    sendErrorFlag = true;
                }

            }
        }
    }
    function startPlay(para){
        DBG_INFO("start play");
        if(settimeoutID >=0){
            clearTimeout(settimeoutID);
        }
        ProgressReportDelayElapsedValue = para.delayMSeconds;
        ProgressReportIntervalElapsedValue = para.intervalMSeconds;
        offsetInMilliseconds  = para.offsetInMilliseconds;

        setCurrentStreamToken(para.token);
        if(document.getElementById("audioPlayerDiv").style.visibility == "visible"){
            var width = 0;
            $("#pg").css("width", width + "px"); //reset progress bar
            $("#currentTime").text(getTimeText(0)); // reset current time
            //audioPlayerGlobal.switchPlayPauseIcon(true);
        }
        DBG_INFO("audio url is: " + para.url);
        settimeoutID = setTimeout(isLoaded,30*1000);
        var url = para.url;
        playbackStartedFlag = false;
        startTimeFlag = 0;
        sendnearlyFinishFlag = true;
        canPlaythroughoutFlag = false;

        playingstatus = false;
        loadedmetadataFlag = false;
        cidReqNum = 0;
        sendErrorFlag = false;
        entercid = false;
        DBG_INFO("url.indexOf http:: " + url.indexOf("http:"));
        DBG_INFO("url.indexOf https:: " + url.indexOf("https:"));
        DBG_INFO("url.indexOf cid:: " + url.indexOf("cid:"));
        if(0 != url.indexOf("cid:")){

            //strartPlayWithhttps(para,url);
            urlCidFlag = false;
            analysisURL(para, url);
            DBG_INFO("strartPlayWithhttps");
        }
        else {
            urlCidFlag = true;
            if(!entercid){
                playwithcid();
            }

            DBG_INFO("startPlayWithCid");
        }

    }

    function strartPlayWithhttps(){
        // var url = para.url;
        //analysisURL(para, url);
        // audioLabel.appendChild(source_elem);

        try{
            audioLabel.addEventListener("loadedmetadata",loadedmetadataListener,false);
        }catch(err){
            DBG_ERROR("loadedmetadata event.error: "+err.message);
            return;
        }

        try{
            audioLabel.load();
        }catch(err){
            DBG_ERROR("load function err: " + err.message);
            tearDown();
        }
    }

    loadedmetadataListener = function(){
        var mpdDuration;
        DBG_INFO("HTMLVideoElement 'loadedmetadata' event received");
        loadedmetadataFlag = true;
       // AvsMusic.sendJsonMessage(JSON.stringify({name:"speech",directive:"isShown"}));
        try {
            mpdDuration = audioLabel.duration;
        } catch (err) {
            DBG_ERROR( "Exception getting video duration on " +
                "HTMLVideoElement. Error: " + err.message);
            tearDown();
            return;
        }
        try {
            audioLabel.removeEventListener("loadedmetadata",loadedmetadataListener , false);
        } catch (err) {
            DBG_ERROR( "Exception unsubscribing from " +
                "'loadedmetadata' event. Error: " + err.message);
            tearDown();
            return;
        }
        setTimeout(onAfterLoad(),1000);
        //onAfterLoad();
    };

    function onAfterLoad() {
        try {

            //audioLabel.currentTime = offsetInMilliseconds/1000;
            //audioLabel.play();
            AvsMusic.sendJsonMessage(JSON.stringify({name:"speech",directive:"isShown"}));
            //setTimeout(audioStartPlay(), 500);
           // audioLabel.currentTime = offsetInMilliseconds/1000;
        } catch (err) {
            DBG_ERROR("Exception starting playback of the video associated with the HTMLVideoElement. Error: " +
                err.message);
            tearDown();
        }
    }
    var isPlaying = function(){
        return (stateMachine.getState() == AudioPlayerState.PLAYING ||
            stateMachine.getState() == AudioPlayerState.BUFFER_UNDERRUN);
    };
    var isPlayingOrPaused = function(){
        return isPlaying() || stateMachine.getState() == AudioPlayerState.PAUSED;
    };
    var isStoped = function(){
        return stateMachine.getState() == AudioPlayerState.STOPPED;
    }
    var stop = function(){
        DBG_INFO("length"+playQueue.length);
        DBG_INFO("isPlayingOrPaused()"+ isPlayingOrPaused());
        DBG_INFO("curent state :"+ stateMachine.getState());
        if(isStoped() || (playQueue.length && isPlayingOrPaused())){
            DBG_INFO("clean current URL");
            audioLabel.src = "";
            audioLabel.load();
        }
    };

    var add = function(msg){
        var startPlaying = playQueue.length;
        if(!startPlaying || !msg.expectedPreviousToken || !playQueue[playQueue.length -1].token ||
            msg.expectedPreviousToken == playQueue[playQueue.length -1].token ){
            DBG_INFO("playInfo is push");
            // if(0 != msg.url.indexOf("cid:")){
            if("" != msg.url){
                playQueue.push(msg);
            }else{
                DBG_INFO("cid:  is included in url");
            }
        }

        if(!startPlaying && playQueue.length){
            //An element is just added
            startPlay(playQueue[0]);
        }
    };

    var handlePlay = function(playMsg){
        DBG_INFO("play directive coming");
        var playInfo = parser.parsePlayDirectiveInfo(playMsg);
        var length = playQueue.length;
        DBG_INFO("play directive playBehavior is: " + playInfo.playBehavior);
        if(playInfo.playBehavior == "REPLACE_ALL"){
            stateMachine.playReplaceAll();
            stop();
            playQueue.splice(0, length); //clear all element
        }else if(playInfo.playBehavior == "REPLACE_ENQUEUED"){
            if(length > 0){
                playQueue.splice(1, length-1); //clear all element except first element
            }
        }
        add(playInfo);
    };
    var handleStop = function(stopMsg){
        DBG_INFO("stop directive is coming");
        stateMachine.playbackStopped();
        pauseVSstop = 1;
        audioLabel.pause();
        audioPlayerGlobal.stopPlayingFlag = 1;
        audioPlayerGlobal.switchPlayPauseIcon(false);
    };
    var audioStartPlay = function(){
        DBG_INFO("audio start play :"+ audioLabel.readyState);
        var loopCount = 0;
        if(audioLabel.readyState >=2){
            audioLabel.play();
            DBG_INFO("directly play");
        }
        else{
            /*
             if(audioLabel.readyState == 0  && loopCount <2){
             setTimeout(reconnect,500);
             loopCount  = loopCount +1
             DBG_INFO("refresh the URL");
             }
             */          DBG_INFO("the url is starting:"+audioLabel.src);
            if(urlCidFlag && audioLabel.src ==audioPlayerNativeURL &&audioLabel.readyState == 0 ){
                DBG_ALWAYS("cid meet error then play at hide");
                if(!entercid){
                    playwithcid();
                }
            }
            if(!waitforplaying){
                DBG_INFO("listener canplay");
                audioLabel.addEventListener("canplay",canplayToPlay);
                setTimeout(function(){
                    if(audioLabel.readyState == 0  && loadedmetadataFlag ){
                        //stateMachine.playbackFailed();
                        DBG_INFO("send fail event");
                        if(!sendErrorFlag){
                            stateMachine.playbackFailed();
                            sendErrorFlag = true;
                        }
                        DBG_ERROR("loadedmetadata but time out");
                    }
                },10*1000)
            }
            if(urlCidFlag  && audioLabel.readyState == 1){
                audioLabel.currentTime = audioLabel.currentTime +0.1;
            }

            waitforplaying = true;
        }
    }
    function canplayToPlay (){
        DBG_INFO("audioLabel.readyState: "+audioLabel.readyState);
        if(audioLabel.readyState >=2){
            audioLabel.play();
            DBG_INFO("directly play");
        }
        else{
            setTimeout(audioLabel.play(),500);
        }
    }
    var handleClearQueue = function(clearQueueMsg){
        DBG_INFO("clearQueue directive is coming");
        var clearQueueInfo = parser.parseClearQueueInfo(clearQueueMsg);
        var length = playQueue.length;
        DBG_INFO("clearQueue directive clearBehavior is: " + clearQueueInfo.clearBehavior);
        if(clearQueueInfo.clearBehavior == "CLEAR_ALL"){
            stop();
            playQueue.splice(0, length); //clear all element
            stateMachine.clearQueueAll();
        }else if(clearQueueInfo.clearBehavior == "CLEAR_ENQUEUED"){
            if(length > 0){
                playQueue.splice(1, length-1); //clear all element except first element
            }
            stateMachine.clearQueueEnqueued();
        }
    };
    var err_flag = false
    var handleRenderPlayerInfo = function(renderPlayerInfoMsg){
        DBG_INFO("renderPlayerInfoMsg is " + JSON.stringify(renderPlayerInfoMsg) );
        //update RenderPlayerInfo(if renderPlayerInfoMsg is empty, draw default page)
        if(JSON.stringify(renderPlayerInfoMsg) == "{}"){
            DBG_INFO("draw default page");
            $("#instruction_list_default").css("visibility","visible");
            $("#audioPlayerDiv").css("visibility","hidden");
            currentId = "instruction_default_1";
            index = 1;
            $("#instruction_default_1").children("img").attr("src",pic[0][1]);
            $("#instruction_default_0").children("img").attr("src",pic[1][0]);
            $("#instruction_default_2").children("img").attr("src",pic[1][3]);
        }else{
            $("#instruction_list_default").css("visibility","hidden");
            $("#audioPlayerDiv").css("visibility","visible");
        }

        if(document.getElementById("audioPlayerDiv").style.visibility == "visible"){
            var artURL = "", artX_Small = "", artSmall = "", artMedium = "", artLarge = "", artX_Large = "";
            var logURL = "";
            DBG_INFO("update music card");
            var audioPlayerDivPageMsg = parser.parseRenderPlayerInfo(renderPlayerInfoMsg);
            for(var i=0; i<audioPlayerDivPageMsg.artSource.length; i++){
                if("x-small" == audioPlayerDivPageMsg.artSource[i].size){
                    artX_Small = audioPlayerDivPageMsg.artSource[i].url;
                }else if("small" == audioPlayerDivPageMsg.artSource[i].size){
                    artSmall = audioPlayerDivPageMsg.artSource[i].url;
                }else if("medium" == audioPlayerDivPageMsg.artSource[i].size){
                    artMedium = audioPlayerDivPageMsg.artSource[i].url;
                }else if("large" == audioPlayerDivPageMsg.artSource[i].size){
                    artLarge = audioPlayerDivPageMsg.artSource[i].url;
                }else if("x-large" == audioPlayerDivPageMsg.artSource[i].size){
                    artX_Large = audioPlayerDivPageMsg.artSource[i].url;
                }
            }
            if(artX_Large.length){
                artURL = artX_Large; //X_Large is our best choice TODO
            }else if(artLarge.length){
                artURL = artLarge;
            }else if(artMedium.length){
                artURL = artMedium;
            }else if(artSmall.length){
                artURL = artSmall;
            }else if(artX_Small.length){
                artURL = artX_Small;
            }else{
                // no label of size
                try{
                    artURL = audioPlayerDivPageMsg.artSource[0].url;
                }catch(e){
                    DBG_ERROR("art url is empty");
                }
            }

            DBG_INFO("audioPlayerDivPageMsg.title is " + audioPlayerDivPageMsg.title + "audioPlayerDivPageMsg.titleSubtext1 "+ audioPlayerDivPageMsg.titleSubtext1 + "audioPlayerDivPageMsg.titleSubtext2 "+ audioPlayerDivPageMsg.titleSubtext2 );
            if(audioPlayerDivPageMsg.logo.length){
                logURL = !!audioPlayerDivPageMsg.logo[0].url ? audioPlayerDivPageMsg.logo[0].url : "img/blank.png";
            }
            if(audioPlayerDivPageMsg.header.length > 45){
                $("#header").html('<marquee style="width: 1009px" scrollAmount=5 scrollDelay=0>' + audioPlayerDivPageMsg.header + '</marquee>');
            }else{
                $("#header").html(audioPlayerDivPageMsg.header);
            }
//            if (audioPlayerDivPageMsg.title.length > 22) {
//                $("#Title").html('<marquee style="width: 1009px" scrollAmount=5 scrollDelay=0>' + audioPlayerDivPageMsg.title + '</marquee>');
//            }
//            else {
                $("#Title").html(audioPlayerDivPageMsg.title);
//            }

            if (audioPlayerDivPageMsg.titleSubtext1.length > 45) {
                $("#titleSubtext1").html('<marquee style="width: 1009px" scrollAmount=5 scrollDelay=0>' + audioPlayerDivPageMsg.titleSubtext1 + '</marquee>');
            }
            else {
                $("#titleSubtext1").html(audioPlayerDivPageMsg.titleSubtext1);
            }

            if (audioPlayerDivPageMsg.titleSubtext2.length > 45) {
                $("#titleSubtext2").html('<marquee style="width: 1009px" scrollAmount=5 scrollDelay=0>' + audioPlayerDivPageMsg.titleSubtext2 + '</marquee>');
            }
            else {
                $("#titleSubtext2").html(audioPlayerDivPageMsg.titleSubtext2);
            }
            $("#providerLogo").attr("src",logURL);
//            $("#musicIcon").attr("src",artURL);
//            $("#providerLogo").css("background-image","url("+logURL+")");
//             $("#musicIcon").css("background-image","url("+artURL+")");

            function getImgNaturalDimensions(url, callback) {
                var image = new Image();
                image.src = url;
                image.onload = function() {
                    callback(image.width, image.height)
                };
                image.onerror= function() {
                    if(err_flag) {
                        DBG_ERROR("image[" + url + "] load err, never try");
                        return;
                    }
                    DBG_INFO("image[" + url + "] load err, try again");
                    err_flag = true;
                    getImgNaturalDimensions(url, callback);
                };
            }
            function resizeImg(img, url, width, height) {
                var calculateImageSize = function (imgH, imgW, containerH, containerW) {
                    var rateH = containerH/imgH;
                    var rateW = containerW/imgW;
                    var targetH = rateW*imgH;
                    var targetW = rateH*imgW;
                    var ret = {
                        W: 0,
                        H: 0
                    };
                    if (targetH > containerH) {
                        ret.H = containerH;
                        ret.W = targetW;
                    } else {
                        ret.H = targetH;
                        ret.W = containerW;
                    }
                    return ret;
                };
                var ret = calculateImageSize(height, width, 600, 600);
                if (ret.H == 600) {
                    img.css("height", "100%");
                } else {
                    img.css("width", "100%");
                }
                img.attr("src", url);
            }
            // artURL = "http://img.blog.csdn.net/20171009110133581";
            //use default page
            $("#iconImg").attr("src", "img/bg_music_default.png");
            getImgNaturalDimensions(artURL, function (width, height) {
                resizeImg($("#iconImg"), artURL ,width,height);
            });

            controlsButton.play_pause = false;
            controlsButton.next = false;
            controlsButton.previous = false;
            for(var i=0; i<audioPlayerDivPageMsg.controls.length; i++){
                if("PLAY_PAUSE" == audioPlayerDivPageMsg.controls[i].name){
                    controlsButton.play_pause = true;
                }else if("NEXT" == audioPlayerDivPageMsg.controls[i].name){
                    controlsButton.next = true;
                }else if("PREVIOUS" == audioPlayerDivPageMsg.controls[i].name){
                    controlsButton.previous = true;
                }
            }
            showControlsButton();
        }
    };
    var handleAudioPlayerDirective = function(APDMsg){
        var name = parser.parseName(APDMsg);
        if(name == "Play"){
            handlePlay(APDMsg);
        }else if(name == "Stop"){
            handleStop(APDMsg);
        }else if(name == "ClearQueue"){
            handleClearQueue(APDMsg);
        }
    };
    var handleRenderPlayerInfoDirective = function(RPIDMsg){
        var name = parser.parseName(RPIDMsg);
        if(name == "RenderPlayerInfo"){
            handleRenderPlayerInfo(RPIDMsg);
        }
    };
    //receive Msg from AvsMusic plugin
    var  timeflag = 0;
    this.onReceiveMessage = function(Msg){
        var msgJSON = {},  header = "";
        if("" == Msg){
            var empty = {};
            DBG_INFO("draw default page here");
            handleRenderPlayerInfo(empty); //draw default page here
            return;
        }
        if(Config.tv){
            msgJSON = parser.parse(Msg);
            //directiveJSON = directiveMsg;
        }else{
            msgJSON = Msg; // directiveMsg have already been a JSON
        }
        header = parser.parseHeader(msgJSON);
        switch (header){
            case "network":
                DBG_INFO("network msgJson:"+msgJSON.network);
                if(msgJSON.network == "disconnect"){
                   $("#networkMessage").css("visibility","visible");
                    DBG_INFO("enter disconnect");
                    clearTimeout(timeflag);
                    timeflag = setTimeout(function(){
                        $("#networkMessage").css("visibility","hidden");
                    },5*1000);

                }
                else if(msgJSON.network == "connect"){
                  //  $("#networkMessage").css("visibility","hidden");
                    DBG_INFO("enter connect");
                }
                break;
            case "PlayController":
                DBG_INFO("receive PlayController from remoteApp :" + msgJSON.PlayController);
                if(msgJSON.PlayController == "next"){
                    playbackController.handlePlaybackAction("next");
                }else if(msgJSON.PlayController == "previous"){
                    playbackController.handlePlaybackAction("previous");
                }
                break;
            case "voiceChrome":
                DBG_INFO("msgJSON "+msgJSON.voiceChrome);
                DBG_INFO("playbackStartedFlag:"+playbackStartedFlag);
                //DBG_INFO("stopPlayingFlag");
               // DBG_INFO("resume music\n");
                if((msgJSON.voiceChrome == "hide")){
                    DBG_INFO("resume music\n");
                    if((playbackStartedFlag == false)||(audioPlayerGlobal.stopPlayingFlag == 0 && pausePlayingFlag == 1)){
                       // audioLabel.play();
                        if(!sendErrorFlag){
                            setTimeout(audioStartPlay(), 500);
                            audioPlayerGlobal.switchPlayPauseIcon(true);
                        }
                    }
                    pausePlayingFlag = 0;
                }else if (msgJSON.voiceChrome == "show"){
                    DBG_ALWAYS("pause music\n");
                    audioLabel.pause();
                    pausePlayingFlag = 1;
                    audioPlayerGlobal.switchPlayPauseIcon(false);
                }else if(msgJSON.voiceChrome == "before"){
                    DBG_INFO("send timeoffset");
                    var offset = audioPlayerGlobal.getAudioCurrentTime()*1000;
                    var token = audioPlayerGlobal.getCurrentStreamToken();
                    AvsMusic.sendAudioOffsetMsg(offset,token);
                }
                break;
            case "directive":
                var nameSpace = parser.parseNameSpace(msgJSON);
                if(nameSpace == "AudioPlayer"){
                    var audioItemId = parser.parseAudioItemId(msgJSON);
                    var playBehaviour = parser.parsePlayBehaviour(msgJSON);
                    DBG_INFO("handle directive about audio audioItemId: " + audioItemId);
                    DBG_INFO("audioPlayerGlobal.audioItemId: " + audioPlayerGlobal.audioItemId);
                    if("REPLACE_ALL" == playBehaviour){
                        var gid = "group_id";
                        var locationGID = audioItemId.lastIndexOf(gid);
                        if(locationGID >= 0 && audioPlayerGlobal.audioItemId.length){
                            var gidValue = audioItemId.slice(locationGID + gid.length);
                            DBG_INFO("play.audioItemId gidValue: " + gidValue);
                            if(audioPlayerGlobal.audioItemId.lastIndexOf(gidValue) < 0){
                                //new play directive is coming
                                audioPlayerGlobal.changeTimerID = setTimeout(function(){
                                    DBG_INFO("maybe change to audio book");
                                    audioPlayerGlobal.onReceiveMessage("");
                                }, 5000);
                            }
                        }else if(audioPlayerGlobal.audioItemId.length  && audioItemId != audioPlayerGlobal.audioItemId){
                            //new play directive is coming
                            audioPlayerGlobal.changeTimerID = setTimeout(function(){
                                DBG_INFO("maybe change to audio book");
                                audioPlayerGlobal.onReceiveMessage("");
                            }, 5000);
                        }
                        audioPlayerGlobal.audioItemId = audioItemId;
                    }
                    handleAudioPlayerDirective(msgJSON);
                }else if(nameSpace == "TemplateRuntime"){
                    var audioItemId2 = parser.parseAudioItemId(msgJSON);
                    DBG_INFO("handle directive about renderPlayInfo audioItemId2: " + audioItemId2);
                    DBG_INFO("renderPlayInfo audioPlayerGlobal.audioItemId: " + audioPlayerGlobal.audioItemId);
                    if(audioPlayerGlobal.audioItemId.length && audioItemId2.length){
                        if(audioPlayerGlobal.audioItemId == audioItemId2){
                            DBG_INFO("paired RenderPlayerInfo coming, clear changeTimerID");
                            clearTimeout(audioPlayerGlobal.changeTimerID); //paired RenderPlayerInfo coming
                        }else{
                            var gid2 = "group_id";
                            var locationGID2 = audioPlayerGlobal.audioItemId.lastIndexOf(gid2);
                            if(locationGID2 >= 0){
                                var gidValue2 = audioPlayerGlobal.audioItemId.slice(locationGID2 + gid2.length);
                                DBG_INFO("renderPlayInfo audioPlayerGlobal.audioItemId gidValue: " + gidValue2);
                                if(audioItemId2.lastIndexOf(gidValue2) >= 0){
                                    DBG_INFO("paired RenderPlayerInfo coming(group_id), clear changeTimerID");
                                    clearTimeout(audioPlayerGlobal.changeTimerID); //paired RenderPlayerInfo coming
                                }
                            }else{
                                audioPlayerGlobal.audioItemId = audioItemId2;
                            }
                        }
                    }else if(audioItemId2.length){
                        audioPlayerGlobal.audioItemId = audioItemId2; // renderPlayerInfo coming firstly
                    }
                    clearTimeout(audioPlayerGlobal.timerID); //The first one time is valuable

                    handleRenderPlayerInfoDirective(msgJSON);
                }
                break;
        }
    };
    //when exit or back,
    opera_omi.addPlatformEventListener(function(){
        DBG_INFO("wch  exit");
        var offset = audioPlayerGlobal.getAudioCurrentTime()*1000;
        var token = audioPlayerGlobal.getCurrentStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(8,0,"");
        var state = audioPlayerGlobal.getAudioPlayerStatus();
        if(state != "ended"){
            DBG_INFO("not ended then send finished, forbide double");
            stateMachine.playbackStopped();
        }
    });
    //send event to AVS by AvsMusic
    this.setEventToAVS = function(event){
        DBG_INFO("event is: " + event);
        try{
            AvsMusic.sendMsg(6,event);
            //6 is MSG_SRV_ID_SEND_TO_AVS
        }catch (e){
            DBG_ERROR("failed to set Event to AVS: " + e.message);
        }
    };

    this.uuid = function(){
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
        s[8] = s[13] = s[18] = s[23] = "-";

        return s.join("");
    };

    this.getStateMachine = function(){
        return stateMachine;
    };

    this.getCurrentStreamToken = function(){
        return latestStreamToken;
    };
    this.getAudioOffsetFromPlay = function(){
        return offsetInMilliseconds;
    };
    this.getCurrentOffsetInMilliseconds = function(){
        return (stateMachine.getState() != AudioPlayerState.IDLE ? audioPlayerTimer.getOffsetInMilliSeconds() : 0);
       // return audioLabel.currentTime*1000;
    };

    this.getAudioPlayerStatus = function(){
        return preEventName;
    };
    this.getAudioTotalLength = function(){
        if(audioLabel.duration == 'Infinity' || isNaN(audioLabel.duration)){
            return 0;
        }
        return audioLabel.duration;
    };
    this.getAudioCurrentTime = function(){
        return audioLabel.currentTime;
    };
    this.getAudioLabel = function(){
        return audioLabel;
    };
    this.killMySelf = function(){
        /*
        var audioPlayerURL = "file:///3rd_rw/UI/module/Alexa/audioPlayer/audioPlayer.html";
        try{
            modeljs.sendam(":am,opera4x,:pause=[-s,opera,-u," + audioPlayerURL + "]");
        }catch (e){
            DBG_ERROR("failed to kill myself: " + e.message);
        }*/
        DBG_ALWAYS("send close msg");
        AvsMusic.sendJsonMessage(JSON.stringify({name:"audioPlayer",directive:"onClose"}));
    };

    this.switchPlayPauseIcon = function(isPlay){
        DBG_INFO("currentId is: " + currentId);
        var isPlayFlag = 2, defaultPageFlag = "instruction_default_1";
        if(isPlay){
            isPlayFlag = 1; //pauseIcon
        }
        if(document.getElementById("audioPlayerDiv").style.visibility == "visible"){
            defaultPageFlag = "instruction_1"; //normal page
        }

        if(defaultPageFlag == currentId){
            $("#"+defaultPageFlag).children("img").attr("src",pic[0][isPlayFlag]);
        }else{
            $("#"+defaultPageFlag).children("img").attr("src",pic[1][isPlayFlag]);
        }
    };

    this.timerID = 0;
    this.changeTimerID = 0;
    this.audioItemId = "";
}

var index = 1;
var currentId = "instruction_1";
var controlsButton = {
    play_pause: false,
    next: false,
    previous: false
};

var pic = [
    ["img/control-prev-focus.png","img/control-pause-focus.png","img/control-play-focus.png","img/control-next-focus.png"],
    ["img/control-prev-default.png","img/control-pause-default.png","img/control-play-default.png","img/control-next-default.png"],
    ["img/control-prev-disabled.png","img/control-pause-default.png","img/control-play-default.png","img/control-next-disabled.png"]
];
var playbackController = {};
playbackController.CommandIssue = {
    PLAY:"PlayCommandIssued",
    PAUSE:"PauseCommandIssued",
    NEXT:"NextCommandIssued",
    PREVIOUS:"PreviousCommandIssued"
};
playbackController.createCommandIssueEvent = function(name){
    var eventJSON = {}, eventStr = "", temp = {};
    eventJSON.context =[];
    eventJSON.event = {};
    eventJSON.event.header = {};
    eventJSON.event.payload = {};
    eventJSON.event.header.namespace = "PlaybackController";
    eventJSON.event.header.name = name;
    eventJSON.event.header.messageId = audioPlayerGlobal.uuid();

    temp.header = {};
    temp.payload = {};
    temp.header.namespace = "AudioPlayer";
    temp.header.name = "PlaybackState";
    temp.payload.token = audioPlayerGlobal.getCurrentStreamToken();
    temp.payload.offsetInMilliseconds = audioPlayerGlobal.getCurrentOffsetInMilliseconds();
    temp.payload.playerActivity = audioPlayerGlobal.getStateMachine().getState();
    eventJSON.context.push(temp);

    temp = {};
    temp.header = {};
    temp.payload = {};
    temp.header.namespace = "Speaker";
    temp.header.name = "VolumeState";
    try{
        temp.payload.volume = parseInt(model.sound.getMainVolume()); //TODO
    }catch (e){
        DBG_ERROR("failed to getMainVolume: " + e.message);
    }
    try{
        temp.payload.muted = parseInt(model.sound.getMainMute()); //TODO
    }catch (e){
        DBG_ERROR("failed to getMainMute: " + e.message);
    }
    eventJSON.context.push(temp);

    eventStr = JSON.stringify(eventJSON);
    audioPlayerGlobal.setEventToAVS(eventStr);
};
playbackController.handlePlaybackAction = function(action){
    DBG_INFO("playbackAction is: " + action);
    if("play" == action){
        playbackController.createCommandIssueEvent(playbackController.CommandIssue.PLAY);
    }else if("pause" == action){
        playbackController.createCommandIssueEvent(playbackController.CommandIssue.PAUSE);
    }else if("next" == action){
        playbackController.createCommandIssueEvent(playbackController.CommandIssue.NEXT);
    }else if("previous" == action){
        playbackController.createCommandIssueEvent(playbackController.CommandIssue.PREVIOUS);
    }
};
document.onkeyup=function(event){
    var VK_ENTER = 13;
    var VK_BACK = 8;
    var VK_LEFT = 37;
    var VK_RIGHT = 39;
    var VK_ESCAPE = 27;
    var VK_PLAY = 415;
    var VK_STOP = 413;
    var VK_PAUSE = 19;
    var VK_PLAY_PAUSE_BTN = 578;
    var VK_PLAY_PAUSE_BTN_FLAG = false;

    var playerState = audioPlayerGlobal.getAudioPlayerStatus();
    DBG_INFO("playerState is: " + playerState);

    if(index > 2){
        index = 2;
    }
    if(index < 0 ){
        index = 0;
    }

    var e = event || window.event || arguments.callee.caller.arguments[0];
    if(document.getElementById("audioPlayerDiv").style.visibility == "visible"){
        currentId = "instruction_" + index;
        DBG_INFO("keyCode is: " + e.keyCode + " currentId is: " + currentId);
        if(e && e.keyCode==VK_ENTER){
            switch (currentId){
                case "instruction_1":
                    if(("pause" == playerState) || ("ended" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[0][1]);
                        //todo play
                        audioPlayerGlobal.getAudioLabel().play();
                        //playbackController.handlePlaybackAction("play");
                    }else if(("playing" == playerState) || ("canplaythrough" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[0][2]);
                        //todo pause
                        audioPlayerGlobal.getAudioLabel().pause();
                        audioPlayerGlobal.stopPlayingFlag = 1;
                        //playbackController.handlePlaybackAction("pause");
                    }else{

                    }
                    break;
                case "instruction_2":
                    // refresh UI data
                    if(controlsButton.next){
                        playbackController.handlePlaybackAction("next");
                    }
                    break;
                case "instruction_0":
                    //refresh UI data
                    if(controlsButton.previous){
                        playbackController.handlePlaybackAction("previous");
                    }
                    break;
                default:
                    break;
            }
            return;
        }else if(e && e.keyCode==VK_LEFT){
            switch (currentId){
                case "instruction_1":
                    if(controlsButton.previous){
                        if(("pause" == playerState) || ("ended" == playerState)){//pause
                            $("#"+currentId).children("img").attr("src",pic[1][2]);
                        }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                            "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                            $("#"+currentId).children("img").attr("src",pic[1][1]);
                        }else{
                            $("#"+currentId).children("img").attr("src",pic[1][2]);
                        }
                        index--;
                        currentId = "instruction_"+ index;
                        $("#"+currentId).children("img").attr("src",pic[0][0]);
                    }
                    break;
                case "instruction_2":
                    if(controlsButton.play_pause){
                        $("#"+currentId).children("img").attr("src",pic[1][3]);
                        index--;
                        currentId = "instruction_"+ index;
                        if(("pause" == playerState) || ("ended" == playerState)){//pause
                            $("#"+currentId).children("img").attr("src",pic[0][2]);
                        }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                                "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                            $("#"+currentId).children("img").attr("src",pic[0][1]);
                        }else{
                            $("#"+currentId).children("img").attr("src",pic[0][2]);
                        }
                    }
                    break;
                case "instruction_0":

                    break;
                default:
                    break;
            }
            return;
        }else if(e && e.keyCode==VK_RIGHT){
            switch (currentId){
                case "instruction_1":
                    if(controlsButton.next){
                        if(("pause" == playerState) || ("ended" == playerState)){//pause
                            $("#"+currentId).children("img").attr("src",pic[1][2]);
                        }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                                "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                            $("#"+currentId).children("img").attr("src",pic[1][1]);
                        }else{
                            $("#"+currentId).children("img").attr("src",pic[1][2]);
                        }
                        index++;
                        currentId = "instruction_"+ index;
                        $("#"+currentId).children("img").attr("src",pic[0][3]);
                    }
                    break;
                case "instruction_2":

                    break;
                case "instruction_0":
                    if(controlsButton.play_pause){
                        $("#"+currentId).children("img").attr("src",pic[1][0]);
                        index++;
                        currentId = "instruction_"+ index;
                        if(("pause" == playerState) || ("ended" == playerState)){//pause
                            $("#"+currentId).children("img").attr("src",pic[0][2]);
                        }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                                "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                            $("#"+currentId).children("img").attr("src",pic[0][1]);
                        }else{
                            $("#"+currentId).children("img").attr("src",pic[0][2]);
                        }
                    }
                    break;
                default:
                    break;
            }
            return;
        }
    }else{
        currentId = "instruction_default_" + index;
        DBG_INFO("keyCode is: " + e.keyCode + " currentId is: " + currentId);
        if(e && e.keyCode==VK_ENTER){
            switch (currentId){
                case "instruction_default_1":
                    if(("pause" == playerState) || ("ended" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[0][1]);
                        //todo play
                        audioPlayerGlobal.getAudioLabel().play();
                        //playbackController.handlePlaybackAction("play");
                    }else if(("playing" == playerState) || ("canplaythrough" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[0][2]);
                        //todo pause
                        audioPlayerGlobal.getAudioLabel().pause();
                        audioPlayerGlobal.stopPlayingFlag = 1;
                        //playbackController.handlePlaybackAction("pause");
                    }else{

                    }
                    break;
                case "instruction_default_2":
                    // refresh UI data
                    playbackController.handlePlaybackAction("next");
                    break;
                case "instruction_default_0":
                    //refresh UI data
                    playbackController.handlePlaybackAction("previous");
                    break;
                default:
                    break;
            }
            return;
        }else if(e && e.keyCode==VK_LEFT){
            switch (currentId){
                case "instruction_default_1":
                    if(("pause" == playerState) || ("ended" == playerState)){//pause
                        $("#"+currentId).children("img").attr("src",pic[1][2]);
                    }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                            "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[1][1]);
                    }else{
                        $("#"+currentId).children("img").attr("src",pic[1][2]);
                    }
                    index--;
                    currentId = "instruction_default_"+ index;
                    $("#"+currentId).children("img").attr("src",pic[0][0]);
                    break;
                case "instruction_default_2":
                    $("#"+currentId).children("img").attr("src",pic[1][3]);
                    index--;
                    currentId = "instruction_default_"+ index;
                    if(("pause" == playerState) || ("ended" == playerState)){//pause
                        $("#"+currentId).children("img").attr("src",pic[0][2]);
                    }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                            "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[0][1]);
                    }else{
                        $("#"+currentId).children("img").attr("src",pic[0][2]);
                    }
                    break;
                case "instruction_0":

                    break;
                default:
                    break;
            }
            return;
        }else if(e && e.keyCode==VK_RIGHT){
            switch (currentId){
                case "instruction_default_1":
                    if(("pause" == playerState) || ("ended" == playerState)){//pause
                        $("#"+currentId).children("img").attr("src",pic[1][2]);
                    }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                            "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[1][1]);
                    }else{
                        $("#"+currentId).children("img").attr("src",pic[1][2]);
                    }
                    index++;
                    currentId = "instruction_default_"+ index;
                    $("#"+currentId).children("img").attr("src",pic[0][3]);
                    break;
                case "instruction_default_2":

                    break;
                case "instruction_default_0":
                    $("#"+currentId).children("img").attr("src",pic[1][0]);
                    index++;
                    currentId = "instruction_default_"+ index;
                    if(("pause" == playerState) || ("ended" == playerState)){//pause
                        $("#"+currentId).children("img").attr("src",pic[0][2]);
                    }else if(("playing" == playerState) || ("canplaythrough" == playerState) || ("ended" == playerState) || (
                            "waiting" == playerState) || ("playbackStutterFinished" == playerState) || ("playbackResumed" == playerState)){
                        $("#"+currentId).children("img").attr("src",pic[0][1]);
                    }else{
                        $("#"+currentId).children("img").attr("src",pic[0][2]);
                    }
                    break;
                default:
                    break;
            }
            return;
        }
    }

    if(e && e.keyCode==VK_BACK){
        audioPlayerGlobal.killMySelf();
    }else if(e && e.keyCode==VK_ESCAPE){
        audioPlayerGlobal.killMySelf();
    }else if(e && e.keyCode==VK_PLAY){
        audioPlayerGlobal.stopPlayingFlag = 0;
        audioPlayerGlobal.switchPlayPauseIcon(true);
        audioPlayerGlobal.getAudioLabel().play();
    }else if(e && e.keyCode==VK_PAUSE){
        audioPlayerGlobal.stopPlayingFlag = 1;
        audioPlayerGlobal.switchPlayPauseIcon(false);
        audioPlayerGlobal.getAudioLabel().pause();
    }else if(e && e.keyCode==VK_STOP){
        audioPlayerGlobal.switchPlayPauseIcon(false);
        audioPlayerGlobal.getAudioLabel().pause();
        audioPlayerGlobal.stopPlayingFlag = 1;
        audioPlayerGlobal.getStateMachine().playbackStopped();
    }else if((e && e.keyCode==VK_PLAY_PAUSE_BTN) && VK_PLAY_PAUSE_BTN_FLAG){
        audioPlayerGlobal.switchPlayPauseIcon(true);
        audioPlayerGlobal.getAudioLabel().play();
        VK_PLAY_PAUSE_BTN_FLAG = false;
    }else if((e && e.keyCode==VK_PLAY_PAUSE_BTN) && (!VK_PLAY_PAUSE_BTN_FLAG)){
        audioPlayerGlobal.switchPlayPauseIcon(false);
        audioPlayerGlobal.getAudioLabel().pause();
        VK_PLAY_PAUSE_BTN_FLAG = true;
    }
};

var audioPlayerGlobal;
function audioPlayerInit(){
    DBG_ALWAYS("audioPlayerInit enter");
    var directive = "";
    audioPlayerGlobal = new audioPlayer();
    try{
        AvsMusic.init(1);
        AvsMusic.addEventListener("message",function(data){  // receive directive from AVS server
            DBG_INFO("wch receive message: " + data);
            audioPlayerGlobal.onReceiveMessage(data);  //process data
        });
    }catch (e){
        DBG_ERROR("failed to AvsMusic.init(1): " + e.message);
    }

    if(Config.tv){
        directive = Hisense.File.read("launcher/alexa_music_play", 1);
    }else{
        directive = testData("Play_ENQUEUE");
    }
    if("" != directive){
        //We should read first play directive from file
        DBG_INFO("play directive is: " + directive);
        audioPlayerGlobal.onReceiveMessage(directive);
        audioPlayerGlobal.timerID = setTimeout(function(){
            DBG_INFO("maybe play audio book first time");
            audioPlayerGlobal.onReceiveMessage("");
        }, 5000); // 5s TODO
    }


    directive = "";
    if(Config.tv){
        directive = Hisense.File.read("launcher/alexa_music_card", 1);
    }else{
        directive = testData("RenderPlayerInfo");
    }
    DBG_INFO("renderPlayerInfo directive is: " + directive);

    Hisense.File.write("launcher/alexa_music_card","",1);

    audioPlayerGlobal.onReceiveMessage(directive);

   AvsMusic.sendJsonMessage(JSON.stringify({name:"audioPlayer",directive:"onInit"}));
}


//for test
function testData(directiveName){
    var directiveJSON = {};
    if(directiveName == "Play_ENQUEUE"){
        directiveJSON ={
            "directive":{
                "header":{
                    "namespace": "AudioPlayer",
                    "name": "Play"
                },
                "payload":{
                    "playBehavior": "ENQUEUE",
                    "audioItem":{
                        "stream":{
                            "url":"http://listen.shoutcast.com:80/LasMasBailadas",
                            "token":"abc"
                        }
                    }
                }
            }
        };
    }else if(directiveName == "Play_REPLACE_ENQUEUED"){
        directiveJSON ={
            "directive":{
                "header":{
                    "namespace": "AudioPlayer",
                    "name": "Play"
                },
                "payload":{
                    "playBehavior": "REPLACE_ENQUEUED",
                    "audioItem":{
                        "stream":{
                            "url":"http://listen.shoutcast.com:80/LasMasBailadas",
                            "token": "def",
                            "expectedPreviousToken": "abc"
                        }
                    }
                }
            }
        };
    }else if(directiveName == "Play_REPLACE_ALL"){
        directiveJSON ={
            "directive":{
                "header":{
                    "namespace": "AudioPlayer",
                    "name": "Play"
                },
                "payload":{
                    "playBehavior": "REPLACE_ALL",
                    "audioItem":{
                        "stream":{
                            "url":"http://listen.shoutcast.com:80/LasMasBailadas"
                        }
                    }
                }
            }
        };
    }else if(directiveName == "Stop"){
        directiveJSON = {
            "directive":{
                "header":{
                    "namespace": "AudioPlayer",
                    "name": "Stop"
                },
                "payload":{

                }
            }
        };
    }else if(directiveName == "ClearQueue"){
        directiveJSON ={
            "directive":{
                "header":{
                    "namespace": "AudioPlayer",
                    "name": "ClearQueue"
                },
                "payload":{
                    "clearBehavior": "CLEAR_ENQUEUED"
                }
            }
        };
    }else if(directiveName == "RenderPlayerInfo"){
        directiveJSON = {
            "directive":{
                "header":{
                    "namespace": "TemplateRuntime",
                    "name": "RenderPlayerInfo"
                },
                "payload":{
                    "content":{
                        "title": "Smoke & Retribution",
                        "titleSubtext1": "Flume",
                        "titleSubtext2": "Skin",
                        "art" : {
                            "sources" : [
                                {
                                    "size" : "medium",
                                    "url" : "img/music-icon.png"
                                }
                            ]
                        },
                        "provider": {
                            "name": "Amazon Music",
                            "logo" : {
                                "sources" : [
                                    {
                                        "url" : "img/effects.png"
                                    }
                                ]
                            }
                        }
                    },
                    "controls":[
                        {
                            "type": "BUTTON",
                            "name": "PLAY_PAUSE",
                            "enabled": true,
                            "selected": false
                        },
                        {
                            "type": "BUTTON",
                            "name": "NEXT",
                            "enabled": true,
                            "selected": false
                        }
                    ]
                }
            }
        };
    }
    return directiveJSON;
}

function getProgress (currentTime) {
    currentTime = audioPlayerGlobal.getAudioCurrentTime();
    var totalTime = audioPlayerGlobal.getAudioTotalLength();
    if (totalTime > 3600) {
        $("#currentTime").text(getTimeTextWithHour(currentTime));
//        $("#currentTime").css("margin-left", "570px");
//        $("#duration").html(HiAudioPlayer.getTimeTextWithHour(totalTime));
    }
    else {
        $("#currentTime").text(getTimeText(currentTime));
//        $("#currentTime").css("margin-left", "650px");
//        $("#duration").html(HiAudioPlayer.getTimeText(totalTime));
    }
    var progressWidth;
    if (totalTime != 0) {
        progressWidth = Math.floor(1009 * currentTime / totalTime);
    }
    else {
        progressWidth = 0;
    }
    $("#pg").css("width", progressWidth + "px");
}

function getTimeText(c){
    var d = Math.floor(c);
    var b = Math.floor(d / 3600);
    var e = Math.floor((d % 3600) / 60);
    var a = Math.floor(d % 60);

    return formatTimeHMS(e, a);
}

function getTimeTextWithHour(c){
    var d = Math.floor(c);
    var b = Math.floor(d / 3600);
    var e = Math.floor((d % 3600) / 60);
    var a = Math.floor(d % 60);

    //return HiAudioPlayer.formatTimeHMS(e, a);

    return checkTime(b) + ":" + checkTime(e) + ":" + checkTime(a);
}

function formatTimeHMS (a, b) {
    return checkTime(a) + ":" +checkTime(b);
}

function checkTime (a) {
    return(a < 10 ? "0" : "") + a;
}


function showControlsButton(){
    if(controlsButton.play_pause){
        currentId = "instruction_1";   //make sure focus on Play_Pause button
        index = 1;
        audioPlayerGlobal.switchPlayPauseIcon(true);
        $("#instruction_1").css("display","block");
    }else{
        //It is bad(Amazon bug)
        $("#instruction_0").css("display","none");
        $("#instruction_1").css("display","none");
        $("#instruction_2").css("display","none");
        $("#progressBar").css("display","none");
        $("#currentTime").css("display","none");
        $("#duration").css("display","none");
        $("#pg").css("display","none");
        return;
    }
    $("#instruction_0").css("display","block");
    $("#instruction_2").css("display","block");
    if(controlsButton.next){
        if("instruction_2" == currentId){
            $("#instruction_2").children("img").attr("src",pic[0][3]);
        }else{
            $("#instruction_2").children("img").attr("src",pic[1][3]);
        }
    }else{
        $("#instruction_2").children("img").attr("src",pic[2][3]);
    }
    if(controlsButton.previous){
        if("instruction_0" == currentId){
            $("#instruction_0").children("img").attr("src",pic[0][0]);
        }else{
            $("#instruction_0").children("img").attr("src",pic[1][0]);
        }
    }else{
        $("#instruction_0").children("img").attr("src",pic[2][0]); //for example iheart radio
    }

    if(controlsButton.next || controlsButton.previous){
        $("#progressBar").css("display","block");  // progress bar should display
        $("#currentTime").css("display","block");
        $("#duration").css("display","block");
        $("#pg").css("display","block");
        clearInterval(progress_timer);
        progress_timer = setInterval(getProgress, 1000);
        if (audioPlayerGlobal.getAudioTotalLength() > 3600) {
            $("#duration").html(getTimeTextWithHour(audioPlayerGlobal.getAudioTotalLength()));
        }
        else {
            $("#duration").html(getTimeText(audioPlayerGlobal.getAudioTotalLength()));
        }
    }else{
        $("#progressBar").css("display","none");  // progress bar should not display
        $("#currentTime").css("display","none");
        $("#duration").css("display","none");
        $("#pg").css("display","none");
    }
}
var progress_timer = null;
