/**
 * Creates a fully featured video player with controls and monitoring, attached to a specific HTML node
 * @class Represents a video player with complete UI/controls. Behaviour is adopted to the TV 2 Sumo requirements.
 * @constructor
 * @param {int} index A number matching the HTML nodes' ID endings. For example, if the Media Player object has 'video123' as ID, index should be 123
 * @param {boolean} miniOnly Optional parameter. When set to true, the player behaviour will be modified for use as thumbnail/secondary player only
 * @param {boolean} delayedAttach Will not attach to HTML DOM element before "use", i.e. video start
 * @param {object} callbacks An optional object whose properties are pointers to callback functions. Zero or more of these callbacks can be attached: onSwitchClick, onSelectorClick, onMouseOver, onMouseOut, onVideoEnd, onHide
 * @param {function} playerImplementation an implementation of the VideoPlayer interface to use. Default is HTMLPlayer.
 * @author Tor Erik Alræk
 * @version 3.0
 */

function VideoPlayer(index,miniOnly,delayedAttach,callbacks,playerImplementation,betaTree,closeOnEnd) {
	// callbacks = {
	// 		onSwitchClick, - when user presses the switch button (if any)
	// 		onSelectorClick, - when user presses the select button (if any)
	// 		onMouseOver, - when user mouses over the video area
	// 		onMouseOut,
	// 		onVideoEnd, - when video stops by itself (program finished or live stream ended)
	// 		onHide, - when the hide method is called
	// 		onItemChange, - when video position is moving 
	// 		onError, - when user clicks for error details
	// 		onQualityClick, - when user clicks for quality details settings
	// 		onReplay, - when users presses play again after having stopped the stream (live only)
	// 		playerContainer, - html target element for reloading the player when onReplay event fires
	// 		onMuteChange, - when user presses the mute button
	// 		onPlayerClick - when user clicks in the video area
	//    getStartAd
	//    getEndAd
	//    getAds
	//  }
	// CONSTRUCTOR

	var player;
	var me = this;
	var publicMembers = ['attach','detach','reset','start','startVideo','show','hide','isPlaying','isLive','isMuted','setVolume','getVolume','mute','unmute','gotoFullscreen','gotoPos','getPos','getProgId','getCurrentItemId','adEnded'];
	
	// Decide which video technology to use
	/*
	if (readCookie('webtv.playerPlatform') == '1' && !miniOnly && window.userNav) {
		playerImplementation = SilverlightPlayer;
	} else {
		playerImplementation = HtmlPlayer;
	}
	*/
	
	if (!playerImplementation) {
		playerImplementation = HtmlPlayer;
	}
	player = new playerImplementation(index,miniOnly,delayedAttach,callbacks,betaTree,closeOnEnd);
	publicMembers.each(function(n){me[n] = player[n]});

	

	if (window.SpringStreams) {
		window.springSensors = new SpringStreams('tv2stream');
		if (window.addEventListener) {
			window.addEventListener('unload',window.springSensors.unload,false);  
		} else if (window.attachEvent){
			window.attachEvent('unload', window.springSensors.unload);
		}

		if (!util.isIE() && window.console) {
			window.springSensors.debug = function(v) {
				console.debug(v);  
			}
		} else {
			window.springSensors.debug = function(v) {
				debug(v);  
			}
		}
	}

	
}

function ItemList(progId,offset) {
	this.addItem = addItem;
	this.getItem = getItem;
	this.getNextItem = getNextItem;
	this.getPrevItem = getPrevItem;
	this.checkForItemChange = checkForItemChange;
	this.getItemCount = getItemCount;
	
  var items = new Array();
  var emptyItem = new Item(0,0,100000);
 
  function Item(id, timeBegin, timeEnd, title) {
    this.id = id;
    this.timeBegin = timeBegin - offset;
    this.timeEnd = timeEnd - offset;
    this.duration = timeEnd - timeBegin;
    this.title = title;
  }

	function getItemCount() {
		return items.length;
	}
  
  function addItem(id, timeBegin, timeEnd, title) {
    items[items.length] = new Item(id,timeBegin,timeEnd,title,offset);
  }

  function getItem(id) {
    for (var i=0; i<items.length; i++) {
      if (id == items[i].id) {
        return items[i];
      }
   }
    return false;
  }

	function getNextItem(time) {
    for (var i=0; i<items.length; i++) {
      if (items[i].timeBegin > time) {
		    logDebug('VideoPlayer','Found next item starting at ' + items[i].timeBegin + ', following ' + time);
        return items[i];
      }
    }
    return false;
	}

	function getPrevItem(time) {
    for (var i=items.length-1; i>=0; i--) {
      if (items[i].timeEnd < time) {
		    logDebug('VideoPlayer','Found previous item ending at ' + items[i].timeEnd + ', preceding ' + time);
        return items[i];
      }
    }
    return false;
	}

  function checkForItemChange(time,currentItem) {  
    var itemToReturn;
    for (var i=0; i<items.length; i++) {
      if ((time > items[i].timeBegin) && (time < items[i].timeEnd)) {   
        itemToReturn = items[i];
        break;
      }
    }
    
    if (!itemToReturn) {
    	itemToReturn = emptyItem;
    }
    
    if (currentItem && currentItem.id == itemToReturn.id) {
    	return false;
    } else {
      logDebug('VideoPlayer','Found item: ' + itemToReturn.id);
    	return itemToReturn;
    }
  }

}

function DrmManager() {
	var drmObj;

	function getDrmObj() {
		try {
			if (util.isIE()) {
				if (!drmObj) {
					drmObj = new ActiveXObject('DRM.GetLicense');
				}
			}
			return drmObj;
		} catch(e) {
			logError('DrmManager.getDrmObj',e);
		}
	}

	this.getSystemInfo = function() {
		try {
			logDebug(getDrmObj().GetSystemInfo());
			return getDrmObj().GetSystemInfo();
		} catch(e) {
			logError('DrmManager.getDrmObj',e);
		}
	}

	this.getDRMVersion = function() {
		try {
			logDebug(getDrmObj().GetDRMVersion());
			return getDrmObj().GetDRMVersion();	
		} catch(e) {
			logError('DrmManager.getDrmObj',e);
		}
	}

	this.getDRMSecurityVersion = function() {
		try {
			logDebug(getDrmObj().GetDRMSecurityVersion());
			return getDrmObj().GetDRMSecurityVersion();
		} catch(e) {
			logError('DrmManager.getDrmObj',e);
		}
	}
	
	this.storeLicense = function(lic) {
		try {
			getDrmObj().StoreLicense(lic);
			logDebug('Storing license for DRM protected video.');
		} catch(e) {
			logError('DrmManager.getDrmObj',e);
		}
	}
}


function MultiPlayer(players) {
	this.subPlay = subPlay;
	this.swapVideos = swapVideos;
	this.switchSound = switchSound;
	this.setDefaultProgram = setDefaultProgram;
	this.resetSubPlayers = resetSubPlayers;
	this.mainToMini = mainToMini;
	
	
	
	var defaultPrograms = new Array();
	var lastMutedIndex;
	
	function setDefaultProgram(index,progId) {
		defaultPrograms[index] = progId;
	}
	 
	function subPlay(index,target,progId,autostart,pos,bw) {
		debug('Play in player' + index + '/' + progId);
		try {
			if (progId) {
				if (!(index && target)) {
					var sub = findSubPlayer(progId,true);
					if (sub) {
						index = sub.index;
						target = sub.target;
					}
				}
				
				if (players[index] && players[index].detach) {
					players[index].detach();
				}
				var params = 'progId=' + progId + '&playerIndex=' + index + '&scope=request';
				if (autostart != null && autostart == false) {
					params += '&autostart=false';
				}
				if (pos) {
					params += '&startPos=' + pos;
				}
				if (bw) {
					params += '&bandwidth=' + bw;
				}
				var url = 'ajax/playSub.do';
				if (progId)
					userNav.open(url, target, params);
			} else {

			}
		} catch(e) {
			logError('MultiPlayer.subPlay',e);
		}
	}


	function resetSubPlayers() {
		for (var i=1;i<players.length;i++) { // start på 1, ikke 0
			if (players[i] && players[i].detach) {
				players[i].detach();			
			}
		}
	}

	function swapVideos(index,target,subProgId,subPos) {
		try {
			var mainProgId = mainPlayer.getProgId();
			var mainPlaying = mainPlayer.isPlaying() || !util.isIE();
			var mainLive = mainPlayer.isLive();
			var mainPos = mainPlayer.getPos();
			if (mainLive) mainPos = null;
			debug('Switching ' + mainProgId + ' in main player with ' + subProgId + ' in player ' + index );
			userNav.play(subProgId,null,subPos,false);
	
			if (mainProgId && mainLive) {
				subPlay(index,target,mainProgId,mainPlaying,mainPos);
			}	else if (defaultPrograms[index]) {
				subPlay(index,target,defaultPrograms[index]);
			} else {
				players[index].hide();
				if (!refreshNewsSubPlayers())
					$(target).innerHTML = '';
			}		} catch(e) {
			logError('MultiPlayer.swapVideos',e);
		}
	}

	function mainToMini() {
		if (mainPlayer.isPlaying() && mainPlayer.isLive()) {
			var sub = findSubPlayer(mainPlayer.getProgId());
			if (sub) {
				subPlay(sub.index,sub.target,mainPlayer.getProgId());
			}
		}
	}

	function findSubPlayer(progId,force) {
		// bygg ut slik at element-id-ene det refereres til hentes inn via constructor
		//if ((players[1] && players[1].isPlaying() && players[1].getProgId()==progId) || (players[2] && players[2].isPlaying() && players[2].getProgId()==progId)) {
		//	return null;
		//}
		if (!($('nettavisen') || (players[2] && players[2].isPlaying && players[2].isPlaying()))) {
			tiles.stopTextFeed('nettavisen');
			return {index: 2, target: 'videoContainer2'};
		} else if (!(players[1] && players[1].isPlaying && players[1].isPlaying())) {
			return {index: 1, target: 'videoContainer1'};		
		} else if (force) {
			tiles.stopTextFeed('nettavisen');
			return {index: 2, target: 'videoContainer2'};
		} else {
			return null;
		}
	}
	
	function refreshNewsSubPlayers() {
		var refreshAllowed = true;
		for (var i=1; i<players[i];i++) {
			if (players[i].isPlaying && players[i].isPlaying()) {
				refreshAllowed = false;				
			}
		}
		if (refreshAllowed && $('leftTab')) {
			var url = 'ajax/leftTab.do?pngStyle=dark';
			userNav.open(url, 'leftTab');
		}
		return refreshAllowed;		
	}

	function switchSound(index,muted) {
		try {
			debug('Muted: ' + muted + ' - ' + index);
			if (muted) {
				if (lastMutedIndex!=null && index != 0 && lastMutedIndex != index) {
					if (!players[lastMutedIndex].isMuted(true)) {
						players[lastMutedIndex].unmute();
						debug('X multiPlayer is unmuting player ' + lastMutedIndex);
					}
				}
				lastMutedIndex = index;
			} else {
				for (var i=0; i< players.length;i++) {
					if (i != index && players[i] && players[i].mute) {
						if (!players[i].isMuted(true) && i != index) {
							players[i].mute();
							lastMutedIndex = i;
							debug('Y multiPlayer is muting player ' + i);
						}
					}
				}
				players[index].unmute();
				debug('Z multiPlayer is unmuting player ' + index);
			}
			debug('lastMutedIndex: ' + lastMutedIndex);
		} catch(e) {
			logError('MultiPlayer.switchSound',e);
		}
	}
	
}

function DummyPlayer(index,callbacks) {
	if (callbacks && callbacks.onClick)
		Event.observe('videoPanel' + index,'click',function(e){callbacks.onClick();Event.stop(e);}, false);
	else 
		Event.observe('videoPanel' + index,'click',function(e){Event.stop(e);}, false);
}


function BandwidthTester(bitrates,messages,bwLimit,fallbackDelay,small,logErrorFunc,logDebugFunc) {
	if (logErrorFunc)
		logError = logErrorFunc;
	if (logDebugFunc)
		logDebug = logDebugFunc;
	
	this.runBwTest = runBwTest;
	this.run = run;
	this.ee = ee;
	this.displayResult = displayResult;

	var testImgVisibility = 'hidden';
	var testImgHeight = '0px';
	var className = '';
	var keep = false;

	var imgPath = 'http://webtv.tv2.no/multimedia/webtv/images/bandwidth/bwtest850.jpg';
	var fileSize =  861137;
	var imgPathSmall = 'http://webtv.tv2.no/multimedia/webtv/images/bandwidth/bwtest150.jpg';
	var fileSizeSmall = 156518;

	var hhiConstant = 1.1;


	if (small) {
		imgPath = imgPathSmall;
		fileSize = fileSizeSmall;
	}

	if (!fallbackDelay) {
		fallbackDelay = 25000; // ms	
	}

	function runBwTest() {
		ee();
		run({
			formField: $('bandwidth'),
			onStart: function() {
				Element.hide($('resultText'));
				Element.hide($('testDelayed'));
				Element.hide($('testFailed'));
				/*Element.hide($('bwManual'));*/
				Element.show($('bwStartMessage'));
				Element.hide($('bandwidthSubmit'));
				Element.hide($('startButton'));
			},
			onComplete: function(bw) {
				try {
					displayResult(bw);
					Element.hide($('testDelayed'));
					Element.hide($('testFailed'));
					Element.hide($('bwStartMessage'));
					Element.show($('resultText'));
					Element.show($('startButton'));
					Element.show($('measureText'));
					Element.show($('bandwidthSubmit'));
					if (keep) Element.hide('bwManual');
					$('bwSelect').options[0].selected = true;
				} catch (e) {
					logError('BandwidthTester.runBwTest',e);
				}
			},
			onTimeout: function() {
				Element.hide($('resultText'));
				Element.hide($('testFailed'));
				Element.show($('bwStartMessage'));
				Element.show($('testDelayed'));
				Element.show($('bwManual'));			
				Element.hide($('bandwidthSubmit'));
				Element.hide($('startButton'));
			},
			onError: function(code,message) {
				Element.hide($('resultText'));
				Element.hide($('bwStartMessage'));
				Element.hide($('testDelayed'));
				Element.show($('testFailed'));
				Element.show($('bwManual'));
				Element.hide($('bandwidthSubmit'));
				Element.hide($('startButton'));
			}		
		});
	}

	function ee() {
		if (window.event && window.event.ctrlKey && window.event.altKey && window.event.shiftKey) {
			testImgVisibility = 'visible';
			testImgHeight = '';
			className = 'bwtestImg';
			keep = true;
		}
	}

	function run(props) { // formField, onComplete, onTimeout, onError
		try {

			var bwTimer;					
			var bwImg = document.createElement('img');
			bwImg.id = 'bwtestImg';
			bwImg.style.visibility = testImgVisibility;
			bwImg.style.height = testImgHeight;
			bwImg.className = className;
			if (keep) {
				//Event.observe(bwImg,'click',function() {document.getElementsByTagName('body')[0].removeChild($('bwtestImg'));Element.show('bwManual');},false);
				Event.observe(bwImg,'click',function() {document.body.removeChild($('bwtestImg'));Element.show('bwManual');},false);

			}
			
			document.body.appendChild(bwImg);
	
			if (props.onTimeout) {
				bwTimer = window.setTimeout(function(){props.onTimeout()},fallbackDelay);
			}
			try {
				if (videoPlayers) {
					videoPlayers.each(function(player) {
					  if (player && player.hide) player.hide();
					});
				}
			} catch(e) {}
			if (props.onStart) {
				props.onStart();
			}		
			var startTime = new Date();
		
			bwImg.src = imgPath + '?' + Math.round(Math.random()*10000);
			logDebug('bwtest started', startTime);
			Event.observe('bwtestImg','load',function() {
				try {
					var endTime = new Date();
					clearInterval(bwTimer);
					logDebug('bwtest finished', endTime);
					var downloadTime = (endTime - startTime)/1000;
					if (bwImg.fileSize > 0) {
						fileSize = bwImg.fileSize;
					}
					var bandwidth = Math.round(fileSize*8*hhiConstant/(100*(endTime - startTime)))*100;
					if (bandwidth > 10000) bandwidth = Math.round(bandwidth / 1000) * 1000;
					if (props.formField) {
						if (props.formField.value!=null) {
							props.formField.value = bandwidth;
						} else {
							props.formField.innerHTML = bandwidth;
						}
					} else {
						logDebug('runBwTest.finished','No valid form field to update.');
					}

					logDebug('Bandwidth: ', bandwidth);
					if (props.onComplete) {
						props.onComplete(bandwidth);
					}
				
					if (!keep) document.body.removeChild(bwImg);
				} catch(e) {
					logError('runBwTest.finished',e);
				}
			}, false);
		} catch(e) {
			logError('BandwidthTester.run',e);
		}
	}
	
	function displayResult(bw) {
		try {
			var message = '';
			var limitedBw = bw;
	
			if (limitedBw > bwLimit) {
				limitedBw = bwLimit;
			}
			
			for (var i=bitrates.length-1; i>=0; i--) {
				if (limitedBw >= bitrates[i]) {
	
					limitedBw = bitrates[i];
					message = messages[i];
					break;
				}
			}
	
			$('highestBw').innerHTML = limitedBw;
			$('bwDescription').innerHTML = message;
			$('bw').innerHTML = bw;
		} catch (e) {
			logError('BandwidthTester.displayResult',e);
		}
		

	}

}

function getFlashVersion() {
  var isIE = navigator.userAgent.indexOf("MSIE")>=0 && navigator.userAgent.indexOf("Opera")<0 && navigator.userAgent.indexOf("Mac")<0;

  function getAxVersion()
  {
  	var version;
  	var axo;
  	var e;
  
  	try {	axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");	version = major(axo.GetVariable("$version"));	} catch (e) {}
    if (!version) { try {	axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");version = 6;axo.AllowScriptAccess = "always";version = major(axo.GetVariable("$version"));} catch (e) {}}	
    if (!version) { try {	axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");version = major(axo.GetVariable("$version"));} catch (e) {}}
   	if (!version)	{	try {	axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");version = 3;} catch (e) {}}
   	if (!version)	{	try {	axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");version = 2;} catch (e) {version = -1;}}
  	return version;
  }

  function major(versionStr) {
  	try {
      tempArray = versionStr.split(" ");
    	return tempArray[1].split(",")[0];

    } catch(e) {
      return -1;
    }
  }

	var version = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			version = flashDescription.split(" ")[2].split(".")[0];
			//var tempArrayMajor = descArray[2].split(".");			
			//version = tempArrayMajor[0];
		}
	}
	else if (isIE) {
		version = getAxVersion();
	}	
	return version;
}





