// ----------------------------------------------------------
//
//		               Configuration
//
// ----------------------------------------------------------

// Player windows size, the larger the size the better the quality that is retrieved, at least in PD case
var playerWidth = '1200';
var playerHeight = '750';
var quality = 'large';

// Host for sending the event messages to the DLL
var dummyHost = "http://www.youtube.com/";	// can be changed; as long as host can be reached

// Enable pop up window for debugging (reporting)
var enableReportWindow = false;

var playerErrCode="";


// ----------------------------------------------------------

// --- Global variables ---
var msgIdx = 0;
var curState = "None";
var done = false;
var init = false; 
var qArrayGot = false;
var running = true;
var stopped = false;
var lastState = -1;
var mTimerCount = 0;
var intialized = false;
var qualitySet = false;
var startedPlaying = false;
var videoID = "";
var startedPlaying = false;
var player = null;




function StartMeasurement(curVideoID, w, h)
{
	playerWidth = w;
	playerHeight = h;
	videoID = curVideoID;
	
	// --- Create Initial Buffering Message ---
	var curDate = new Date();
	var time_epoch = curDate.getTime()/1000;
	var stateStr = "InitialBuffering";
	var httpMsg = createHttpPseudoMsg(stateStr, time_epoch);
	sendPseudoMsg(httpMsg);
	reportStateToScreen(stateStr, curDate);	
	
	// --- Set up YT API ---
	var tag = document.createElement('script');
	tag.src = "http://www.youtube.com/iframe_api";
	var firstScriptTag = document.getElementsByTagName('script')[0];	
	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}

function StartMeasurementHttps(curVideoID, w, h)
{
	playerWidth = w;
	playerHeight = h;
	videoID = curVideoID;
	try{
	  sessionStorage.clear();
	  localStorage.clear();
	}catch(err){
		writeErr(err);
	}
	// --- Create Initial Buffering Message ---
	var curDate = new Date();
	var time_epoch = curDate.getTime()/1000;
	var stateStr = "InitialBuffering";
	var httpMsg = createHttpPseudoMsg(stateStr, time_epoch);
	sendPseudoMsg(httpMsg);
	reportStateToScreen(stateStr, curDate);	
	// --- Set up YT API ---
	var tag = document.createElement('script');
	tag.src = "https://www.youtube.com/iframe_api";
	var firstScriptTag = document.getElementsByTagName('script')[0];
	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}

var player = null;
function onYouTubeIframeAPIReady() 
{
	// --- Set up player ---
	initialized();
	player = new YT.Player('playerDiv', {
		height: playerHeight,
		width: playerWidth,
		videoId: videoID,
		events: {
			'onReady': onPlayerReady,
			'onStateChange': onPlayerStateChange,
			'onPlaybackQualityChange': onPlayerQualityChange,
			'onError': onPlayerError
		}
	});
}

function onPlayerReady(event) 
{
	event.target.playVideo();
	startTime();
}



// ----------------------------------------------------------
//
//		      Event handling for playout events
//
// ----------------------------------------------------------	  


// --- Global variables ---
var msgIdx = 0;
var curState = "None"


// --- Create Pop up for reporting ---
if(enableReportWindow)
{
	rs_window = window.open('', '' , 'left = 1000, top=50, width=800, height=600');
	rs_document = rs_window.document;
}


// Function to create a string passed as a URL to communicate the player events to PEVQ-S
function createHttpPseudoMsg(stateStr, epocheTime)
{

	var msg = stateStr + "_" + msgIdx + "_" + epocheTime.toFixed(3) + "_"+playerErrCode 
	msgIdx += 1;
	
	return msg;
}

// Send a generated player event message
function sendPseudoMsg(msgStr)
{
	try
	{
		curState = msgStr;
		
		var xmlHttp = new XMLHttpRequest();
		
		// Send a POST message with URL created from msgStr and and also carrying the msgStr as payload
		xmlHttp.open("POST", dummyHost.concat(msgStr), true );
		xmlHttp.send(msgStr);
	}
	catch(err)
	{
		if(enableReportWindow)
		{
			rs_document.write(err);
		}
	}	  
}

// Converts integer number to string and pads to fixed length with leading zeroes
//	Currently supports only positive numbers and padding up to 4 digits
function padToLength(number, nrDigitsString)
{
	if(number < 0 || number >= 10000)
		return number.toString();
		
	var nrDigitsNumber = 0
		
	if(number < 10)
		nrDigitsNumber = 1;
	else if(number < 100)
		nrDigitsNumber = 2;
	else if(number < 1000)
		nrDigitsNumber = 3;
	else if(number < 10000)
		nrDigitsNumber = 4;
		
	if(nrDigitsNumber > nrDigitsString)
		return number.toString();
	
	var str = "0000".slice(0, nrDigitsString -nrDigitsNumber);
	str += number.toString();
	
	return str;
}


// Print events to pop up screen
function reportStateToScreen(stateStr, curDate)
{
	if(enableReportWindow)
	{
		var dateStr = 
			curDate.getHours() + ":" + 
			padToLength(curDate.getMinutes(), 2) + ":" + 
			padToLength(curDate.getSeconds(), 2) + "." + 
			padToLength(curDate.getMilliseconds(), 3);
		
		var reportMsg = stateStr + " : " + dateStr + "<br />";
		rs_document.write(reportMsg);
	}
}


// Player event handler
var startedPlaying = false;
function onPlayerStateChange(event) 
{
info();

	if(event.data == YT.PlayerState.BUFFERING)
	{
		if(startedPlaying)
		{
			//player_time=player.getCurrentTime();
			vol_begin=player.getVideoLoadedFraction();
			
			var curDate = new Date();
			
			var stateStr = "Buffering";
			var time_epoch = curDate.getTime()/1000;
			
			var httpMsg = createHttpPseudoMsg(stateStr, time_epoch);
			sendPseudoMsg(httpMsg);
			
			reportStateToScreen(stateStr, curDate);
		}
	}
	
	// Playout event, this includes first start of playing after initial buffering as well as
	// resuming playout after rebuffering (stalling)
	else if(event.data == YT.PlayerState.PLAYING)
	{
		var curDate = new Date();
		
		var stateStr = "Playing";
		var time_epoch = curDate.getTime()/1000;
		
		var httpMsg = createHttpPseudoMsg(stateStr, time_epoch);
		sendPseudoMsg(httpMsg);
		
		reportStateToScreen(stateStr, curDate);
		
		startedPlaying = true;
	}
	
	// End event, reaching end of video after playout
	else if(event.data == YT.PlayerState.ENDED)
	{
		var curDate = new Date();
		
		var stateStr = "End";
		var time_epoch = curDate.getTime()/1000;
		
		var httpMsg = createHttpPseudoMsg(stateStr, time_epoch);
		sendPseudoMsg(httpMsg);
		running = false;
		completed();
		
		reportStateToScreen(stateStr, curDate);
	}
}

function startTime() {
			
	if(running)
		t = setTimeout(function(){startTime()}, 1000);

	if (player.getPlayerState() == YT.PlayerState.PLAYING){
		info();
	}
}


function info() {
	var state = player.getPlayerState();
	var quality = player.getPlaybackQuality();
	var dur = player.getDuration();
	var play = player.getCurrentTime();
	var transf = player.getVideoLoadedFraction();
	var tB = player.getVideoStartBytes();
	var trB = player.getVideoBytesLoaded();
	if(tB != 0){
		var transf2 = (trB/tB)*100;
		
	}
	var text = "videodata,"+state+","+play+","+dur+","+transf+","+quality+"\nEND\n";
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST","http://localhost:6020",true);
    xmlhttp.send(text);
    	
}


function initialized() {

	var text = "initialized\nEND\n";

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST","http://localhost:6020",true);
    xmlhttp.send(text);
    	
}


function writeErr(err) {

	var text = "error: "+err+"\nEND\n";

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST","http://localhost:6020",true);
    xmlhttp.send(text);
    	
}

function completed() {

	var text = "completed\nEND\n";

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST","http://localhost:6020",true);
    xmlhttp.send(text);
    	
}

function onPlayerError(event)
{
    // This event fires if an error occurs in the player. The API will pass an event object to the event listener function.
    // That object's data property will specify an integer that identifies the type of error that occurred.
	playerErrCode = event.data;
	var curDate = new Date();
		
	var stateStr = "Error";
	
	var time_epoch = curDate.getTime()/1000;
	
	var httpMsg = createHttpPseudoMsg(stateStr, time_epoch);
	sendPseudoMsg(httpMsg);
	writeErr(playerErrCode);
	
	reportStateToScreen(stateStr, curDate);
}


function onPlayerQualityChange(event)
{
	// No handling at the moment
}
