// Narrowstep Player 1.2/2.0/2.6 javascript functions

//----------------------
// mmm, more cookies!


function checkCookie() {
	setCookie(gCookiePrefix + "CookieTest", "OK");
	var v = getCookie(gCookiePrefix + "CookieTest");
	setCookie(gCookiePrefix + "CookieTest", "");
	return (v == "OK");
}

function getCookie(inName) {
	var search = inName + "=";
	if (document.cookie.length > 0) {
		var offset = document.cookie.indexOf(search);
		if (offset != -1) {
			offset += search.length;
			var end = document.cookie.indexOf(";", offset);
			if (end == -1) {
				end = document.cookie.length;
			}
			return unescape(document.cookie.substring(offset, end));
		}
	}
}

function setCookie(inName, inVal, inTime, inPeriodInSecond) {
	if (!inPeriodInSecond) { inPeriodInSecond = 86400; }	// 24 hours
	if (!inTime && (document.location.href.indexOf("localhost") > -1 ||
			document.location.href.indexOf("127.0.0.1") > -1)) {
		inTime = 6;					// on IIS localhost non expiring cookies don't seem to work?
		inPeriodInSecond = 3600;	// so lets have 6 hours instead
	}
	var expire = "";
	if (inTime) {
		var today = new Date();
		today.setTime(today.getTime() + (inTime * inPeriodInSecond * 1000)); 
		expire = ";expires=" + today.toGMTString();
	}
	var domain = "";
	if (typeof gCookieDomain != "undefined" && gCookieDomain) {
		domain = ";domain="+ escape(gCookieDomain);
	}
	document.cookie = inName + "=" + escape(inVal) + expire + domain + ";path=/;";
}

function GetSessionCookieName() {
	var oStr = "";
	if (window.location.search.match(/player=([^&]*)/i)) {
		oStr = RegExp.$1;
	} else if (window.location.search.indexOf("list=on") > -1 || debugMode) {
		oStr = "list";
	}
	return gCookiePrefix + "PSC_" + oStr;
}

function TabDelimStringToObject(inString) {
	var ob = new Object();
	var ar = inString.split("\t");
	
	for (var key in ar) {
		var ar2 = ar[key].split("=");
		var offs = ar[key].indexOf("=");
		ob[ar[key].substr(0, offs)] = ar[key].substr(offs+1);
	}
	return ob;
}

//------------------------------

var LineEnd = "\n\r";

function findMenuIndex( inMenu, inString ) {
	for (var i = 0; i < inMenu.options.length; i++) {
		if (inMenu.options[ i ].value == inString ) { return i; }
	}
	return -1;
}

function Trim(inString) {
	var retVal = "";
	var start = 0;
	while ((start < inString.length) && (inString.charAt(start) == ' ')) {
		++start;
	}
	var end = inString.length;
	while ((end > 0) && (inString.charAt(end - 1) == ' ')) {
		--end;
	}
	retVal = inString.substring(start, end);
	return retVal;
}	// Trim(inString) end

function hex(n) {
	var h=parseInt(n,10).toString(16);
	return h.toUpperCase();
}

function Truncate(inString, inMaxLen, inPad) {
	if (!inPad) { inPad = "..."; }
	var oString = "";
	if (inString.length > inMaxLen) {
		oString = inString.substr(0, inMaxLen - inPad.length) + inPad;
	} else {
		oString = inString;
	}
	return oString;
}


// ---- dhtml funcs

function setTextID(inID, inText) {
	var el = findElement(inID);
	try {
		if (el) {
			el.innerHTML = inText;
			return true;
		}
		//else if (debugMode) alert("(debug) No ID = " + inID + LineEnd + el + LineEnd + window.location);
	} catch(e) {
		if (debugMode) { alert("(debug exception?) No ID = " + inID + LineEnd + el + LineEnd + window.location); }
	}
	return false;
}	// setTextID(inID, inText) end

function newImage(inName) {
	if (document.images) {
		var im = document.createElement('img');
		if (inName.indexOf("**") !== 0) {	// not file missing
			im.src = inName;
		}		
		return im;
	}
}
var userAgent = window.navigator.userAgent;
var browserVers = parseInt(userAgent.charAt(userAgent.indexOf("/")+1),10);
var mustInitImg = true;
function initImgID() { 
	var di = document.images; 
	if (mustInitImg && di) { 
		for (var i=0; i<di.length; i++) { 
			if (!di[i].id) { 
				di[i].id=di[i].name; 
			} 
		} 
		mustInitImg = false;
	}
}

function findElement(n,ly) {
	var d = document;
	if (browserVers < 4) { 
		return d[n]; 
	}
	if ((browserVers >= 5) && (d.getElementById)) {
		initImgID(); 
		return d.getElementById(n);
	}
	var cd = ly ? ly.document : d;
	var elem = cd[n];
	if (!elem && cd.all) { elem=cd.all[n]; }	// added by JB - odd!
	if (!elem && cd.layers) {
		for (var i=0;i<cd.layers.length;i++) {
			elem = findElement(n,cd.layers[i]);
			if (elem) { return elem; }
		}
	}
	return elem;
}

function changeImages() {
	var d = document;
	var argv = arguments;
	
	if (d.images) {
		var img;
		for (var i=0; i<argv.length; i+=2) {
			img = null;
			if (d.layers) {img = findElement(argv[i],0);}
			else {img = d.images[argv[i]];}
			if (img) {img.src = argv[i+1];}
		}
	}
}

function CSClickReturn () {
	var bAgent = window.navigator.userAgent; 
	var bAppName = window.navigator.appName;
	if ((bAppName.indexOf("Explorer") >= 0) && (bAgent.indexOf("Mozilla/3") >= 0) && (bAgent.indexOf("Mac") >= 0)) {
		return true; // dont follow link
	} else { 
		return false; // dont follow link
	}
}

var CSAg = window.navigator.userAgent;

function IsIE() { 
	return CSAg.indexOf("MSIE") > 0;
}

var CSBVers = parseInt(CSAg.charAt(CSAg.indexOf("/")+1),10);
var CSIsW3CDOM = ((typeof document.getElementById != "undefined" && document.getElementById) && !(IsIE() && CSBVers<6)) ? true : false;

function CSIEStyl(s) { 
	return document.all.tags("div")[s].style; 
}

var CSIImg=false;

function CSInitImgID() {
	if (!CSIImg && document.images) { 
		for (var i=0; i<document.images.length; i++) { 
			if (!document.images[i].id) { 
				document.images[i].id = document.images[i].name; 
			} 
			CSIImg = true;
		}
	}
}

function CSFindElement(n,ly) { 
	if (CSBVers<4) { 
		return document[n]; 
	}
	if (CSIsW3CDOM) {
		CSInitImgID();
		return(document.getElementById(n));
	}
	var curDoc = ly?ly.document:document; var elem = curDoc[n];
	if (!elem) {
		for (var i=0;i<curDoc.layers.length;i++) {
			elem = CSFindElement(n,curDoc.layers[i]); 
			if (elem) { 
				return elem; 
			} 
		}
	}
	return elem;
}

function CSNSStyl(s) { 
	if (CSIsW3CDOM) { 
		return document.getElementById(s).style;
	} else { 
		return CSFindElement(s,0); 
	}
}

function CSGetImage(n) {
	if(document.images) {
		return ((!IsIE() && CSBVers < 5) ? CSFindElement(n,0) : document.images[n]);
	} else { return null; }
}

var CSDInit=false;

function CSICSS2Prop(id) { 
	var n = document.getElementsByTagName('STYLE');
	for (var i=0;i<n.length;i++) { 
		var cn = n[i].childNodes; 
		for (var j=0;j<cn.length;j++) { 
			CSSetCSS2Props(CSFetchStyle(cn[j].data, id),id); 
		}
	}
}

function CSIDOM() { 
	if (CSDInit) { 
		return; 
	} 
	CSDInit=true; 
	if (document.getElementsByTagName) {
		var n = document.getElementsByTagName('DIV'); 
		for (var i=0;i<n.length;i++) {
			CSICSS2Prop(n[i].id);
		}
	}
}


function CSFetchStyle(sc, id) {
	var s=sc; 
	while(s.indexOf("#")!=-1) { 
		s=s.substring(s.indexOf("#")+1,sc.length); 
		if (s.substring(0,s.indexOf("{")).toUpperCase().indexOf(id.toUpperCase())!=-1) { 
			return(s.substring(s.indexOf("{")+1,s.indexOf("}")));
		}
	}
	return "";
}

function CSGetStyleAttrValue (si, id) {
	var s=si.toUpperCase();
	var myID=id.toUpperCase()+":";
	var id1=s.indexOf(myID);
	if (id1==-1) { 
		return ""; 
	}
	s=s.substring(id1+myID.length+1,si.length);
	var id2=s.indexOf(";");
	return ((id2==-1)?s:s.substring(0,id2));
}

function CSSetCSS2Props(si, id) {
	var el = document.getElementById(id);
	if (el === null) { 
		return;
	}
	var style=document.getElementById(id).style;
	if (style) {
		if (style.left === "") { style.left=CSGetStyleAttrValue(si,"left"); }
		if (style.top === "") { style.top=CSGetStyleAttrValue(si,"top"); }
		if (style.width === "") { style.width=CSGetStyleAttrValue(si,"width"); }
		if (style.height === "") { style.height=CSGetStyleAttrValue(si,"height"); }
		if (style.visibility === "") { style.visibility=CSGetStyleAttrValue(si,"visibility"); }
		if (style.zIndex === "") { style.zIndex=CSGetStyleAttrValue(si,"z-index"); }
	}
}

function setStyleVis(s,v) {
	if (CSIsW3CDOM) { 
		CSIDOM();
		document.getElementById(s).style.visibility = (v===0) ? "hidden" : "visible";
	} else if (IsIE()) {
		CSIEStyl(s).visibility = (v===0) ? "hidden" : "visible";
	} else {
		CSNSStyl(s).visibility = (v===0) ? 'hide' : 'show';
	}
}
function getStyleVis(s) {
	if (CSIsW3CDOM) {CSIDOM();return(document.getElementById(s).style.visibility=="hidden")?0:1;}
	else if(IsIE()) { return(CSIEStyl(s).visibility=="hidden")?0:1; }
	else { return(CSNSStyl(s).visibility=='hide')?0:1; }
}

// window resizing func. Thanks to: Mihai Bazon (http://dynarch.com/mishoo/) for the start! JB

function setClientSize(inWidth, inHeight) {

	if (this.self != this.top || (typeof debugMode != "undefined" && debugMode)) { return; }	// not if i'm in a frame

    if (inWidth < 0 || inHeight < 0) {	// fullscreen
		return;
		//inWidth = window.screen.width;
		//inHeight = window.screen.height;
	}
	var dw = 0;	// delta width & height
	var dh = 0;
	var current_width = 0;
	var current_height = 0;
	var offX = 0;
	var offY = 0;
    
	if (!IsIE()) {
//		window.innerWidth = inWidth;
//		window.innerHeight = inHeight;

//		if (window.innerWidth != inWidth || window.innerHeight != inHeight) { // didn't work?
//			window.resizeBy(inWidth-window.innerWidth, inHeight-window.innerHeight);
//			// other way dont seem to work in Safari! This does!
//		}

		dw = inWidth-window.innerWidth;
		dh = inHeight-window.innerHeight;

	} else {	// is IE and a right pain!
    
//alert(inWidth +"x"+ inHeight);

		// move the window onto the screen for the first (wrong) resize
		if (inWidth + window.screenLeft > window.screen.availWidth) {
			offX = window.screen.availWidth - (inWidth + window.screenLeft) - 20;
			if (window.screenLeft + offX < 0) {
				offX = -window.screenLeft;
			}
		}
		if (inHeight + window.screenTop > window.screen.availHeight) {
			offY = window.screen.availHeight - (inHeight + window.screenTop) - 30;
			if (window.screenTop + offY < 0) {
				offY = -window.screenTop + 20;
			}
		}
		// it is important to resize the window to the
		// wanted values first, even if we won't get them.
		window.resizeTo(inWidth, inHeight);
		window.scrollTo(0,0);
		// do the move and reset for next time
		if (offX || offY) {
			window.moveBy(offX, offY);
			offX = 0; offY = 0;
		}

		// create the checkpoint element
		var cp = document.createElement("div");
		cp.style.position = "absolute";
		cp.style.width = "0px";
		cp.style.height = "0px";
		cp.style.right = "0px";
		cp.style.bottom = "0px";
		//cp.style.backgroundColor = "000";
		//cp.style.fontSize = "0px";
		
		// we can only read it's position after we
		// insert it into the document
		document.body.appendChild(cp);
		
		// here we get the actual client size
		current_width = cp.offsetLeft;
		current_height = cp.offsetTop;
		
		if (findElement("divPlayerMain")) {	// can't do this to all cos all the old players have work-arounds for this
			// however IE decides to make this at least 2px tall to fit the non-existant text in so...
			current_height = current_height + cp.offsetHeight;
			// and while we're there...
			current_width = current_width + cp.offsetWidth;
		}
			
		// here we find out how much more we need
		// in order to get to the needed inWidth x inHeight size
		// (or in other words, we compute the size of
		// window decorations: border, scroll bars, title)
		dw = inWidth - current_width;
		dh = inHeight - current_height;
				
		// we can safely delete the checkpoint now
		document.body.removeChild(cp);
		
		// for the curious, return to see how much
		// did IE miss it
//		return; nah! no returns { missed_width: dw, missed_height: dh };
	} // if IsIE
	
	// check for repositioning on screen

	// move it back on screen if over sides
	if (IsIE()) {
	// for IE try using the size it should be afterwards...?
		//if (current_width + window.screenLeft + dw > window.screen.availWidth) {
		if (inWidth + window.screenLeft > window.screen.availWidth) {
			offX = window.screen.availWidth - (inWidth + window.screenLeft);
			if (window.screenLeft + offX < 0) {
				offX = -window.screenLeft;
			}
		}
		if (inHeight + window.screenTop > window.screen.availHeight) {
			offY = window.screen.availHeight - (inHeight + window.screenTop);
			if (window.screenTop + offY < 0) {
				offY = -window.screenTop + 20;
			}
		}
	} else {
		if (window.outerWidth + window.screenX + dw > window.screen.availWidth) {
			offX = window.screen.availWidth - (window.outerWidth + window.screenX + dw);
			if (window.screenX + offX < 0) {
				offX = -window.screenX;
			}
		}
		if (window.outerHeight + window.screenY + dh > window.screen.availHeight) {
			offY = window.screen.availHeight - (window.outerHeight + window.screenY + dh);
			if (window.screenY + offY < 0) {
				offY = -window.screenY + 20;
			}
		}
	}
	if (offX || offY) {
		window.moveBy(offX, offY);
	}

	window.resizeBy(dw, dh);
	
}


//This code is in the public domain. Feel free to link back to http://jan.moesen.nu/
function sprintf() {
	if (!arguments || arguments.length < 1 || !RegExp) {
		return "";
	}
	var str = arguments[0];
	var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
	var a = [], b = [], numSubstitutions = 0, numMatches = 0;
	a = re.exec(str);	// jb less efficient but no warning?
	while (a)
	{
		var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
		var pPrecision = a[5], pType = a[6], rightPart = a[7];
		
		//alert(a + '\n' + [a[0], leftpart, pPad, pJustify, pMinLength, pPrecision);

		numMatches++;
		if (pType == '%')
		{
			subst = '%';
		}
		else
		{
			numSubstitutions++;
			if (numSubstitutions >= arguments.length)
			{
				alert('Error! Not enough function arguments (' + (arguments.length - 1) + ', excluding the string)\nfor the number of substitution parameters in string (' + numSubstitutions + ' so far).');
			}
			var param = arguments[numSubstitutions];
			var pad = '';
			if (pPad && pPad.substr(0,1) == "'") {
				pad = leftpart.substr(1,1);
			} else if (pPad) {
				pad = pPad;
			}
			var justifyRight = true;
			if (pJustify && pJustify === "-") { justifyRight = false; }
			var minLength = -1;
			if (pMinLength) { minLength = parseInt(pMinLength,10); }
			var precision = -1;
			if (pPrecision && pType == 'f') { precision = parseInt(pPrecision.substring(1),10); }
			var subst = param;
			if (pType == 'b') { subst = parseInt(param,10).toString(2); }
			else if (pType == 'c') { subst = String.fromCharCode(parseInt(param,10)); }
			else if (pType == 'd') { subst = parseInt(param,10) ? parseInt(param,10) : 0; }
			else if (pType == 'u') { subst = Math.abs(param); }
			else if (pType == 'f') { subst = (precision > -1) ? Math.round(parseFloat(param) * Math.pow(10, precision)) / Math.pow(10, precision): parseFloat(param); }
			else if (pType == 'o') { subst = parseInt(param,10).toString(8); }
			else if (pType == 's') { subst = param; }
			else if (pType == 'x') { subst = ('' + parseInt(param,10).toString(16)).toLowerCase(); }
			else if (pType == 'X') { subst = ('' + parseInt(param,10).toString(16)).toUpperCase(); }
		}
		str = leftpart + subst + rightPart;
		a = re.exec(str);	// jb
	}
	return str;
}


function rot13(inText) {
	var rot13text_rotated = ""; /* the function will return this string */

	for (var i = 1 ; i < (inText.length + 1); i++) {
		var k = inText.charCodeAt(i-1);
		if (k >= 97 && k <= 109) {
			k = k + 13;
		} else if (k >= 110 && k <= 122) {
			k = k - 13;
		} else if (k >= 65 && k <= 77) {
			k = k + 13;
		} else if (k >= 78 && k <= 90) {
			k = k - 13;
		}
		rot13text_rotated = rot13text_rotated + String.fromCharCode(k);
	}
	return rot13text_rotated;
}

// addEvent and removeEvent with thanks to John Resig and quirksmode.org's competition
function addEvent( obj, type, fn )
{
	if (obj.addEventListener) {
		obj.addEventListener( type, fn, false );
	} else if (obj.attachEvent) {
		//obj["e"+type+fn] = fn;
		//obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		//obj.attachEvent( "on"+type, obj[type+fn] );
		obj.attachEvent( "on"+type, fn );		// TODO FIXME suspected memory leaks or something in here - my memory leaked
	}
}

function removeEvent( obj, type, fn )
{
	if (obj.removeEventListener) {
		obj.removeEventListener( type, fn, false );
	} else if (obj.detachEvent) {
		//obj.detachEvent( "on"+type, obj[type+fn] );	 this dont seem to work
		//obj[type+fn] = null;
		//obj["e"+type+fn] = null;
		obj.detachEvent( "on"+type, fn );
	}
}


// left-pad val with num times ch, if val.length < num
function padLeft(val, ch, num) {
  var re = new RegExp(".{" + num + "}$");
  var pad = "";
  do {
      pad += ch;
  } while(pad.length < num);
  return re.exec(pad + val);
}

// format time in seconds using a formatString.
// * formatString is optional, but if defined must contain 3 %d's, and will be processed like hours minutes seconds.
// TODO: make cleverer so it can cope with a C#-like string.Format...?
function secs2Time(numSecs, formatString) {
	if (!formatString) {
		formatString = "%s:%s:%s";
	}
	var h = padLeft(Math.floor(numSecs / 3600), "0", 2);
	var m = padLeft(Math.floor((numSecs / 60) % 60), "0", 2);
	var s = padLeft(Math.floor(numSecs % 60), "0", 2);
	return sprintf(formatString, h, m, s);
}

function createAjaxRequest () {
	var outReq = null;
	if (window.XMLHttpRequest) {// Mozilletc
		outReq = new XMLHttpRequest();
	} else if (window.ActiveXObject) { // if IE
		try {
			outReq = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e){	// make your mind up...
			try{
				outReq = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e){}
		}
	}
	return outReq;
}

function imgChangeState(img, inState, inOldStateList) {
	if (typeof img == "string") {
		img = findElement(img);
	}
	if (!img) { return; }
	
	if (!inState) { inState = ""; }
	if (!inOldStateList) { inOldStateList = "_over"; }	// only "over" is default - pass in other vals for funny stuff
	
	var fn = img.src;
	var p = fn.lastIndexOf(".");
	var base = fn.substr(0, p);
	var re = new RegExp(inOldStateList + "$", "ig");
	var str = base.replace(re, "");
	
	img.src = str + ((!inState) ? "" : "_") + inState + fn.substr(p);
}

// get the value of the specified computed-style property on the specified element
function getStyle(elId,styleProp)
{
	var x, y;
	if (typeof elId == "string") {
		x = findElement(elId);
	} else {
		x = elId;
	}
	if (x && x.currentStyle) {
		y = x.currentStyle[styleProp];
	} else if (x && document.defaultView) {
		var s = document.defaultView.getComputedStyle(x,null);
		if (s) { y = s.getPropertyValue(styleProp); }	// not always there in Fx
		else {
		  y = "";
		  if (typeof debugMode != "undefined" && debugMode) { alert("(debug) getStyle(" + (x && x.name ? x.name : elId) +",'"+ styleProp +"')"); }
		}								// hmmm, FIXME please
	} else {
		if (typeof debugMode != "undefined" && debugMode) { alert("(debug) getStyle(" + (x && x.name ? x.name : elId) +",'"+ styleProp +"') no defaultView"); }
	}
	return y;
}

function snipPx(str) {
	return str ? parseInt(str.substring(0, str.indexOf("px")), 10) : 0;
}


// func to make a new iframe filling the container div (cleanly
function createIframe(inContainer, inName, inSrc) {
	var el = findElement(inContainer);
	// this is all for IE's benefit really - others don't flicker like that! :)
	
	var fr = findElement(inName);	// frame el might be already there (WMP URL triggers need this)
	var attach = false;
	
	if (!fr) {
		fr = document.createElement("iframe");
		fr.setAttribute("id", inName);
		fr.setAttribute("name", inName);
		fr.setAttribute("frameBorder", "0");
		fr.setAttribute("scrolling", "no");
		attach = true;
	} else {
		if (typeof fr.frameElement != "undefined") {
			fr = fr.frameElement;
		}
	}
	fr.setAttribute("width", getStyle( el, "width" ));
	fr.setAttribute("height", getStyle( el, "height" ));

	if (attach) {
		el.appendChild(fr);
		fr = findElement(inName);
	}
	fr = (fr.frameElement) ? fr.frameElement : fr;
	
	if (inSrc) { fr.setAttribute("src", inSrc); }
	
	$(fr).ready(function () { showIframeDiv(el, fr); });
}

function showIframeDiv(inFrameContainer, inFrame) {
	try {
		var fr = (inFrame.frameElement) ? inFrame.frameElement : inFrame;
		$(fr).unbind("ready");
	} catch (e) {
		// access denied if the doc is in another domain
	}
}


// .NET-like string.format function for L10n of strings
// usage: 
//		"this {0} a nice test for the {1} thing".format("is", "string.format");
//		messageThatIsAString.format(placeholder, placeholder .... );
String.prototype.format = function() { 
	var params = String.prototype.format.arguments;
	var toReturn = this;
	for(var i=0; i<params.length; i++) {
		var regex = new RegExp('\\{'+i+'\\}','g');
		toReturn = toReturn.replace(regex,params[i].toString());
	}
	return toReturn;
};

// handle \" in tooltips to just ".
function fixTooltips() {
	$("a[@title]").each(function() {
		var broken = $(this).attr("title");
		var fixed = broken.replace(/\\\"/g, "\"");
		$(this).attr("title", fixed);
	});
}


function swallowEscape(eSrc) {
	var kc = 0;
	
	if (typeof eSrc != "undefined") {
		kc = eSrc.which;
	} else if (typeof event != "undefined" && event) {
		kc = event.keyCode;
	}
	if (kc == 27) {
		return false;
	}
	return true;
}
