﻿ // JScript File

var theEventTimer=0;
var theEventTimerCount=-1;
var theUpdateEventsTimer=-1;
var lastEventIndex=-1;
var nextEventIndex=-1;
var startPos=-1;
var isStarted=false;
var jumpingInFile=false;
var oldLiveStatusId=-1;

var oldTime = new Date(0);
var startTC = "";
var currentSegment = -1;
var SpeakerInsteadOfDCNChecked = false;
var SpeakerInsteadOfDCN = false;
var LiveStatusNames = new Array ( "Off", "Ready", "Idle", "Pre live", "Live", "Pre indexed", "Indexed" );

function DoScriptCommand(aType, aValue){
  myUrl=new String(aValue);
  var sp = myUrl.indexOf("?t=");
  if ( sp >0 ){
      var tmp = myUrl.slice(sp + 3);
      theEventTimerCount = 0;
      Addon_Debug_TimeCodeFromStream(tmp);
      SyncStreamEvents(tmp);
  }
}

function Addon_SYSTEM_doEvent(aCmd,aValue){
    if( aCmd.substr(0,14) == 'FORCE_BITRATE_' && theClientIP == aValue){
        Addon_Options_doEvent('BITRATE', aCmd.substr(14) );
        DoDebug(' Force BITRATE to ' + aCmd.substr(14),"#aaeeaa");
    }
}

function OnLiveStatusChanged(newLiveStatus) {
    var oldLiveStatusId = theLiveStatusId;
    if(newLiveStatus==0)theLiveStatusId=LS_OFF;
    if( newLiveStatus>0 && newLiveStatus!=theLiveStatusId ){
        oldLiveStatusId=theLiveStatusId
        /*if(theLiveStatusId!=oldLiveStatusId){
            for(var j=0;j<addonsArr.length;j++)try{ eval("Addon_"+addonsArr[j]+"_LiveStatusChanged();"); }catch(ex){}}*/
        theLiveStatusId=newLiveStatus;
        setTimeout("DoPlayList()",20000);
        Addon_Debug_LiveStatus(oldLiveStatusId,theLiveStatusId);
    }
}

function SyncStreamEvents(aTimeCode) {
    DoStreamEvents( GetTimeFromCode(aTimeCode) );

    if(playStarted){
        DoDebug("PLAY STARTED","#aaffaa");
        playStarted = false;
        lastEventIndex = -1;
        if(startTC==""){
            for(var i=0;i<eventsArr.length;i++){
	            if(eventsArr[i][2]=="LIVE") startTC=eventsArr[i][0];break;
	        }
	    }
        for(var i=0;i<addonsArr.length;i++){
            ExecuteLastEvent(aTimeCode,addonsArr[i]);
        }
    }
    jumpingInFile=false;
}

function ExecuteLastEvent(aTimeCode, aType){
    for(var i=eventsArr.length-1; i>=0; i--){
        if( eventsArr[i][0]<aTimeCode && eventsArr[i][1].toUpperCase()==aType.toUpperCase() ){
            //DoDebug("LastEvent "+aType+" "+i + " > " + eventsArr[i]);
            if (jumpingInFile && aType == 'Index') DoDebug("RESYNC:jumping in file, Not selecting index");
            else if (jumpingInFile && aType == 'Slides') DoDebug("RESYNC:jumping in file, Not selecting slide");
            else {
                DoDebug("RESYNC:" + eventsArr[i], "#bbbbff");
                ExecuteEvent(i);
            }
            if(eventsArr[i][2]=="UPDATE" && eventsArr[i][3]=="")DoDebug("Find next event after '"+aType+"' UPDATE");
            else return;
        }
    }
    if(jumpingInFile && aType=='Index') return;
    try {
        eval("Addon_" + aType + "_Clear();");
        DoDebug("RESYNC:clearing " + aType, "#ccccff");
    }catch(e){}
}

function OnUpdateEventsComplete(result){
    if (result!=""){
        var newArr=eval(result);
        if(newArr.length>0){
            eventsArr = eventsArr.concat(newArr );
            var outp="";
            for(var i=0;i<newArr.length;i++)
                outp += newArr[i][0] + " " + newArr[i][1] + " " + newArr[i][2] + " " + newArr[i][3] + "; ";
            DoDebug("new events:" + outp, "#cccccc");
            Addon_Debug_UpdateEvents();
        }
    }
}

function DoGuiEvent(aCmd,aId){
    if(theLiveStatusId>LS_PREINDEXED){
        for(var i=0;i<eventsArr.length;i++){
            if(eventsArr[i][2]==aCmd && eventsArr[i][3]==aId){
                JumpInFile(eventsArr[i][0]);
                for(var j=0;j<addonsArr.length;j++)try{ eval("Addon_"+addonsArr[j]+"_Clear();"); }catch(ex){}
                break;
            }
        }
    }
}

function JumpInFile(aTimeCode) {
    try {
        clearTimeout(theEventTimer);
        //jumpingInFile=true;
        var Gaps = GetStreamGaps();
        if (Gaps.length > 0 && Gaps[2] > 0 && Gaps[3].length) {
            startTC = "" + Gaps[2];
            DoDebug("streampgaps:" + Gaps[3].length);
        }

        var myDate1 = GetTimeFromCode(aTimeCode);
        var myDate2 = GetTimeFromCode(startTC);
        var newPos = (myDate1 - myDate2);

        var CorrectedPos = newPos;
        if (Gaps.length > 0) {
            for (var i = 0; i < Gaps[3].length; i++) {
                if (newPos > Gaps[3][i][0])
                    CorrectedPos = CorrectedPos - Gaps[3][i][1];
            }
        }
        CorrectedPos /= 1000;
        DoDebug("jump:" + aTimeCode + " - " + startTC + " > " + (CorrectedPos) + " /" + theVideoPlayer.GetDuration(), "#ccccff");
        theVideoPlayer.SetPosition(CorrectedPos );
    } catch (e) { DoDebug("Error jumping in file: " + e.message); }
}

function GetStreamGaps(){
    for(var i=0;i<streamGaps.length;i++){
        if (streamGaps[i][0] == theLanguageId && streamGaps[i][1] == theBitrateId) return streamGaps[i];
    }
    return new Array();
}

function GetTimeFromCode(timeCode) {
    var tmp = new String(timeCode);
    return new Date(
        tmp.substr(0, 4),
        tmp.substr(4, 2)-1,
        tmp.substr(6, 2),
        tmp.substr(8, 2),
        tmp.substr(10, 2),
        tmp.substr(12, 2));
}

function DoStreamEvents(time) {
    clearTimeout(theEventTimer);
    if (startTC != "") {

        var newTime = new Date(time);
        var outp = "[" + ( (newTime - GetTimeFromCode(startTC)) / 1000 ) + "] " + newTime.getHours() + ":" + newTime.getMinutes() + ":" + newTime.getSeconds() + " > ";

        // time dif in milliseconds since last call to DoStreamEvents
        var deltaMs = (newTime - oldTime);

        //delta should not be >5 seconds, if not, we assume a jump hads happened and we need to resync
        if (deltaMs < -5000 || deltaMs > 5000) {
            playStarted = true;
            if (oldTime.getTime() > 0) DoDebug("Jumped " + Math.round( deltaMs  / 60000) + " minutes to "+ newTime, "#ffff00"); 
        }

        //Calculate current segment and log if its a new one
        var segment = Math.floor((newTime - GetTimeFromCode(startTC)) / 60000);
        if (segment >= 0 && segment != currentSegment) {
            currentSegment = segment;
            DoDebug("Entered segment " + currentSegment );
            PlayerService_QueueServerEvent("log", { "currentSegment": currentSegment }, PlayerService_Priority.low, null);
        }

        //synchronize addons
        var found = false;
        for (var i = (lastEventIndex + 1); i < eventsArr.length; i++) {
            // check for skipped events in the last 5 seconds(timing fault) and for a current event
            var eventTime = GetTimeFromCode(eventsArr[i][0]);
            var tmpTime = new Date(time);
            tmpTime.setSeconds(tmpTime.getSeconds() - 5);
            if (eventTime >= tmpTime && eventTime <= newTime) {
                DoDebug( eventsArr[i], "#aaaaff");
                outp += ExecuteEvent(i);
                found = true;
            }
        }
                
        //Show next event on debug screen
        for (var i = 0; i < eventsArr.length; i++) {
            if (GetTimeFromCode(eventsArr[i][0]) > newTime) {
                if (nextEventIndex != i) {
                    nextEventIndex = i;
                    var t = eventsArr[i][0];
                    if (t.length == 14) t = t.substr(0, 8) + " " + t.substr(8, 2) + ":" + t.substr(10, 2) + ":" + t.substr(12, 2);
                    var d = eventsArr[i][3];
                    if (d.length > 30) d = d.substr(0, 30) + "...";
                    Addon_Debug_NextEvent(t + " > " + eventsArr[i][1] + ":" + eventsArr[i][2] + " " + d);
                }
                break;
            }
        } 
        
        //set oldTime to new Time (reparse, cant use newTime reference)
        oldTime = new Date(time);

        //add 1 second and (re)start timer
        newTime.setSeconds(newTime.getSeconds() + 1);
        if (++theEventTimerCount < 5) theEventTimer = setTimeout("DoStreamEvents('" + newTime + "')", 1000);
        DoDebug(outp, "#ccffdd", true);
    }
}

function ExecuteEvent(aIndex){
    Addon_Debug_NextEvent("");
    var addon= eventsArr[aIndex][1];
    var cmd  = eventsArr[aIndex][2];
    var data = eventsArr[aIndex][3];
    
    if(addon=="DcnSpeakers" ){
        if(!SpeakerInsteadOfDCNChecked){
            var found=false;
            for(var j=0;j<addonsArr.length;j++)if(addonsArr[j]=="DCNSpeakers")found=true;
            SpeakerInsteadOfDCN=!found;
            SpeakerInsteadOfDCNChecked=true;
         }
         if(SpeakerInsteadOfDCN) addon="Speakers";
    }
    
    try{eval("Addon_"+addon+"_doEvent('"+cmd+"','"+data+"');");}catch(ex){}
    
    lastEventIndex=aIndex;
    return "<b>"+eventsArr[aIndex][0]+"</b> <i>"+aIndex+"</i> "+addon+ " " +cmd+ " "  + data;
}