function AudioPlayerState(){
}
{
    AudioPlayerState.IDLE = "IDLE";
    AudioPlayerState.PLAYING = "PLAYING";
    AudioPlayerState.STOPPED = "STOPPED";
    AudioPlayerState.PAUSED = "PAUSED";
    AudioPlayerState.BUFFER_UNDERRUN = "BUFFER_UNDERRUN";
    AudioPlayerState.FINISHED = "FINISHED";
}

function eventName(){
}
{
    eventName.START = "PlaybackStarted";
    eventName.STOP = "PlaybackStopped";
    eventName.PAUSE = "PlaybackPaused";
    eventName.RESUME = "PlaybackResumed";
    eventName.FINISHED = "PlaybackFinished";
    eventName.NEARLYFINISHED = "PlaybackNearlyFinished";
    eventName.STUTTERS = "PlaybackStutterStarted";
    eventName.STUTTERF = "PlaybackStutterFinished";
    eventName.FAILED = "PlaybackFailed";
    eventName.QCLEARED = "PlaybackQueueCleared";
    eventName.DELAYREPORT = "ProgressReportDelayElapsed";
    eventName.INTERVALREPORT = "ProgressReportIntervalElapsed";
}


function APlayerStateMachine(){
    var state = AudioPlayerState.IDLE;
    var stutterS, stutterF;

    this.getState = function(){
        return state;
    };

    var getCurrentState = function(){
        return state;
    };

    var setState = function(currentState){
        state = currentState;
    };

    var getStutterDuration = function(){
        return stutterF - stutterS;  //TODO
    };

    var sendEventToAVS = function(event){
        audioPlayerGlobal.setEventToAVS(event);
    };

    var getCrtStreamToken = function(){
        return audioPlayerGlobal.getCurrentStreamToken();
    };
    var getCrtOffsetInMilliseconds = function(){
        return audioPlayerGlobal.getCurrentOffsetInMilliseconds();
    };
    var getCrtCurrentTime = function(){
        return audioPlayerGlobal.getAudioCurrentTime() *1000;
    };
    var getCrtOffsetFromPlay = function(){
        return audioPlayerGlobal.getAudioOffsetFromPlay();
    };
    var getUUID = function(){
        return   audioPlayerGlobal.uuid();
    };
    var createAudioPlayerContext = function(name){
        var eventJSON = {}, temp = {};

        eventJSON.context =[];

        temp.header = {};
        temp.payload = {};
        temp.header.namespace = "AudioPlayer";
        temp.header.name = "PlaybackState";
        temp.payload.token = getCrtStreamToken();
        temp.payload.offsetInMilliseconds = getCrtCurrentTime();
        temp.payload.playerActivity = getCurrentState();
        eventJSON.context.push(temp);

        return JSON.stringify(eventJSON);  //convert json to string
    }
    var createAudioPlayerEvent = function(name){
        var eventJSON = {};
        eventJSON.event = {};
        eventJSON.event.header = {};
        eventJSON.event.payload = {};
        eventJSON.event.header.namespace = "AudioPlayer";
        eventJSON.event.header.messageId = getUUID();
        eventJSON.event.header.name = name;
        switch (name){
            case eventName.START:
                eventJSON.event.payload.token = getCrtStreamToken();
                eventJSON.event.payload.offsetInMilliseconds = getCrtOffsetFromPlay();
                break;
            case eventName.STOP:
            case eventName.PAUSE:
            case eventName.RESUME:
            case eventName.FINISHED:
            case eventName.STUTTERS:
            case eventName.NEARLYFINISHED:
            case eventName.DELAYREPORT:
            case eventName.INTERVALREPORT:
                eventJSON.event.payload.token = getCrtStreamToken();
                eventJSON.event.payload.offsetInMilliseconds = getCrtCurrentTime();
                break;
            case eventName.QCLEARED:
                //eventJSON.event.payload = {};
                break;
            case eventName.FAILED:
			eventJSON.event.payload.token = getCrtStreamToken();
                eventJSON.event.payload.currentPlaybackState = {};
                eventJSON.event.payload.currentPlaybackState.token = getCrtStreamToken();
                eventJSON.event.payload.currentPlaybackState.offsetInMilliseconds = getCrtCurrentTime();
                eventJSON.event.payload.currentPlaybackState.playerActivity = getCurrentState();
                eventJSON.event.payload.error = {};
                eventJSON.event.payload.error.type = "MEDIA_ERROR_UNKNOWN"; //TODO
                eventJSON.event.payload.error.message = "An unknown error occurred";
                break;
            case eventName.STUTTERF:
                eventJSON.event.payload.token = getCrtStreamToken();
                eventJSON.event.payload.offsetInMilliseconds = getCrtCurrentTime();
                eventJSON.event.payload.stutterDurationInMilliseconds = getStutterDuration();//TODO
                break;
        }
        return JSON.stringify(eventJSON);  //convert json to string
    };

    this.playbackStarted = function(){
        var event = createAudioPlayerEvent(eventName.START);
        setState(AudioPlayerState.PLAYING);
        //var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
        //sendEventToAVS(context);
        //send playbackStarted Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(1,0,"");
        sendEventToAVS(event);
    };

    this.delayProgressReport = function(){
        var event = createAudioPlayerEvent(eventName.DELAYREPORT);
        setState(AudioPlayerState.PLAYING);
        //var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
       // sendEventToAVS(context);
        //send delayProgressReport Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        sendEventToAVS(event);
    };

    this.intervalProgressReport = function(){
        var event = createAudioPlayerEvent(eventName.INTERVALREPORT);
        setState(AudioPlayerState.PLAYING);
        //var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
        //sendEventToAVS(context);
        //send intervalProgressReport Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        sendEventToAVS(event);
    };

    this.playbackFailed = function(){
        var event = createAudioPlayerEvent(eventName.FAILED);
        setState(AudioPlayerState.STOPPED);
        //var context = createAudioPlayerContext(AudioPlayerState.STOPPED);
        //sendEventToAVS(context);
        //send playbackFailed Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(3,0,"MEDIA_ERROR_UNKNOWN");
        sendEventToAVS(event);
    };

    this.playbackNearlyFinished = function(){
        var event = createAudioPlayerEvent(eventName.NEARLYFINISHED);
        //var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
        //sendEventToAVS(context);
        //send PlaybackNearlyFinished Event
        sendEventToAVS(event);
    };

    this.playbackFinished = function(){
        var event = createAudioPlayerEvent(eventName.FINISHED);
        setState(AudioPlayerState.FINISHED);
        //var context = createAudioPlayerContext(AudioPlayerState.FINISHED);
        //sendEventToAVS(context);
        //send PlaybackFinished Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(2,0,"");
        sendEventToAVS(event);
    };

    this.clearQueueEnqueued = function(){
        var event = createAudioPlayerEvent(eventName.QCLEARED);
        //var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
        //sendEventToAVS(context);
        //send ClearQueueEnqueued Event
        sendEventToAVS(event);
    };

    this.clearQueueAll = function(){
        var currentState = getCurrentState();
        if(currentState == AudioPlayerState.PLAYING || currentState == AudioPlayerState.PAUSED ||
            currentState == AudioPlayerState.BUFFER_UNDERRUN){
            setState(AudioPlayerState.STOPPED);
            //var context = createAudioPlayerContext(AudioPlayerState.STOPPED);
            //sendEventToAVS(context);
            //send playbackStopped Event
            var event = createAudioPlayerEvent(eventName.STOP);
            sendEventToAVS(event);
        }
    };

    this.playReplaceAll = function(){
        var currentState = getCurrentState();
        if(currentState == AudioPlayerState.PLAYING || currentState == AudioPlayerState.PAUSED ||
            currentState == AudioPlayerState.BUFFER_UNDERRUN){
            setState(AudioPlayerState.STOPPED);
           // var context = createAudioPlayerContext(AudioPlayerState.STOPPED);
           // sendEventToAVS(context);
            //send playbackStopped Event
            var offset = getCrtCurrentTime();
            var token = getCrtStreamToken();
            AvsMusic.sendAudioOffsetMsg(offset,token);
            AvsMusic.sendAudioStatusMsg(8,0,"");
            var event = createAudioPlayerEvent(eventName.STOP);
            sendEventToAVS(event);
        }
    };

    this.playbackStutterStarted = function(){
        stutterS = Date.now();
        var event = createAudioPlayerEvent(eventName.STUTTERS);
        setState(AudioPlayerState.BUFFER_UNDERRUN);
        //var context = createAudioPlayerContext(AudioPlayerState.BUFFER_UNDERRUN);
       // sendEventToAVS(context);
        //send playbackStutterStarted Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(6,0,"");
        sendEventToAVS(event);
    };

    this.playbackStutterFinished = function(){
        stutterF = Date.now();
        var event = createAudioPlayerEvent(eventName.STUTTERF);
        setState(AudioPlayerState.PLAYING);
        //var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
        //sendEventToAVS(context);
        //send playbackStutterFinished Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(7,0,"");
        sendEventToAVS(event);
    };

    this.playbackPaused = function(){
        var event = createAudioPlayerEvent(eventName.PAUSE);
        setState(AudioPlayerState.PAUSED);
        //var context = createAudioPlayerContext(AudioPlayerState.PAUSED);
       // sendEventToAVS(context);
        //send playbackPaused Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(4,0,"");
        sendEventToAVS(event);
    };

    this.playbackResumed = function(){
        var event = createAudioPlayerEvent(eventName.RESUME);
        setState(AudioPlayerState.PLAYING);
       // var context = createAudioPlayerContext(AudioPlayerState.PLAYING);
       // sendEventToAVS(context);
        //send playbackResumed Event
        var offset = getCrtCurrentTime();
        var token = getCrtStreamToken();
        AvsMusic.sendAudioOffsetMsg(offset,token);
        AvsMusic.sendAudioStatusMsg(5,0,"");
        sendEventToAVS(event);
    };

    this.playbackStopped = function(){
        var currentState = getCurrentState();
        if(currentState != AudioPlayerState.IDLE){
            setState(AudioPlayerState.STOPPED);
            var offset = getCrtCurrentTime();
            var token = getCrtStreamToken();
            AvsMusic.sendAudioOffsetMsg(offset,token);
            AvsMusic.sendAudioStatusMsg(8,0,"");
            var event = createAudioPlayerEvent(eventName.STOP);
            sendEventToAVS(event);
        }
    }
}