//------------------------------------------------------------------------
// Written by Ray Wilson
// Copyright Music From Outer Space LLC 2010.
// http://www.musicfromouterspace.com/mfosweb/home.action
// Mini-Browser Independent DOM API
// Utility Object Pack.
// Javascript DEBUGGER
// Author: Ray Wilson 11-2010
//----------------------------------------------------------------
var mozilla = document.getElementById && !document.all;
var ie = document.all;
var chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;

function IsRightButtonClicked(e) // e : mouse event
{
	var rightclick = false;
	e = e || window.event;
	if (e.which)
	{
		rightclick = (e.which == 3);
	}
	else if (e.button)
	{
		rightclick = (e.button == 2);
	}
	return rightclick;
}

function disableSelection(target)
{
	if (typeof target.onselectstart!="undefined")
	{
		// IE
		target.onselectstart=function(){return false}
	}
	else if (typeof target.style.MozUserSelect!="undefined")
	{
		// Firefox
		target.style.MozUserSelect="none"
	}
	else 
	{
		// Others...
		target.onmousedown=function(){return false}
	}
	target.style.cursor = "default"
}

// ---------------------------------------------------
// Load a script on demand.
// Example usage: loadscript("myscript.js");
// ---------------------------------------------------
var GLOBAL_SCRIPTSLOADED = [];
function loadscript(scriptsrc, callback)
{
	if(scriptloaded(scriptsrc))
	{
		callback();
		return;
	}
	
	var fileref = document.createElement('script');
	if(typeof fileref!="undefined")
	{
		GLOBAL_SCRIPTSLOADED.push(scriptsrc);
	}
	
	fileref.setAttribute("type","text/javascript")
	fileref.setAttribute("src", scriptsrc);
	if(document.all && callback)
	{
		fileref.onreadystatechange = function() 
		{
			if (fileref.readyState == 'loaded' || fileref.readyState == 'complete') 
			{
				fileref.onreadystatechange = "";
				callback();
			} 
		};
	}
	else
	{
		fileref.onload = (callback || function(){return;});
	}
	document.getElementsByTagName("head")[0].appendChild(fileref)
	
	//------------------------------------------------------------
	// Uncomment to see post script add innerHTML of the HEAD tag.
	//------------------------------------------------------------
	/*
	DEBUGWRITE(document.getElementsByTagName("head")[0].innerHTML);
	*/
}

function scriptloaded(scriptsrc)
{
	for(var i=0; i<GLOBAL_SCRIPTSLOADED.length; ++i)
	{
		if(GLOBAL_SCRIPTSLOADED[i] == scriptsrc)
			return true;
	}
	return false;
}

function getValidString(m)
{
	return (m && (m.length > 0) && (m != "EMPTY")) ? m : "";
}

function isSupportedBrowser()
{
	return (ie || mozilla || chrome);
}

function has_scrollbar(elem)
{
	return (elem.clientHeight < elem.scrollHeight);
} 

function hasChildren(elem)
{
    return elem.hasChildNodes();
}

function getElementParent(elem)
{
    return (mozilla) ? elem.parentNode : elem.parentElement;
}

function getElementChildren(elem)
{
    return (mozilla) ? elem.childNodes : elem.children;
}

function setElementAttribute(elem, attname, attvalue)
{
	elem.setAttribute(attname, attvalue);
}

function getElementAttribute(elem, attname)
{
    if(elem.hasAttribute || elem.attributes)        
    {
	    if(mozilla)
	    {
	        if(elem.hasAttribute(attname))
			{
	        	return elem.getAttribute(attname);
			}
	    }
	    else
	    {
	        if(elem.attributes[attname])
	        {
	            return elem.attributes[attname].value;
	        }
	    }
    }
    return null;
}

function getEvent(e)
{
    if(!e)
    {
        return window.event;
    }
    return e;
}

// ---------------------------------------
// e MUST BE AN EVENT ALREADY.
// e = getEvent(e) ALREADY CALLED.
// ---------------------------------------
function stopEventBubble(e)
{
	if (mozilla)
	{
	    e.stopPropagation();
	    if(e.preventDefault)
	    {
	    	e.preventDefault();
	    }
	}
	else if (ie)
	{
	    e.cancelBubble = true;
	    e.returnValue = false;
	}    
}

function getEventSource(e)
{
    return (mozilla) ? e.target : e.srcElement;
}

//--------------------------------------------------------
//
//
// BINDING AND ADDING EVENT LISTENER CODE.
//
//
//--------------------------------------------------------
Function.prototype.bindEventListenerWithArgs = function (object) {
    var method = this;
    var oldArguments = pseudoArrayToArray(arguments).slice(1);
    return function (e) {return method.apply(object, [e || window.event].concat(oldArguments));};
};

Function.prototype.bind = function(object){
	var method = this;
	return function(){method.apply(object, arguments)};
};

Function.prototype.bindEventListener = function(object){
	var method = this;
	return function(event){method.call(object, event || window.event)};
};

function pseudoArrayToArray(pseudoArray) 
{
    var result = [];
    for (var i = 0; i < pseudoArray.length; i++)
    {
    	result.push(pseudoArray[i]);
    }
    return result;
}

function addEvent(obj, evType, fn)
{
	if(obj.addEventListener)
	{
    	obj.addEventListener(evType, fn, false);
    	return true;
 	} 
 	else if (obj.attachEvent)
 	{
    	var r = obj.attachEvent("on"+evType, fn);
    	return r;
 	} 
 	else 
 	{
    	return false;
 	}
}
function removeEvent(obj, evType, fn, useCapture)
{
	if (obj.removeEventListener)
	{
    	obj.removeEventListener(evType, fn, useCapture);
    	return true;
	} 
	else if (obj.detachEvent)
	{
    	var r = obj.detachEvent("on"+evType, fn);
    	return r;
  	} 
  	else
  	{
    	return false;
  	}
}

function ignorethis(e)
{
	e = getEvent(e);
    var target = getEventSource(e);
    stopEventBubble(e);
    return false;
}

function getViewportHeight() 
{
	if (window.innerHeight!=window.undefined) 
		return window.innerHeight;
	if (document.compatMode=='CSS1Compat')
		return document.documentElement.clientHeight;
	if (document.body) 
		return document.body.clientHeight;
		 
	return window.undefined; 
}

function getViewportWidth() {
	var offset = 17;
	var width = null;
	if (window.innerWidth!=window.undefined)
		return window.innerWidth; 
	if (document.compatMode=='CSS1Compat')
		return document.documentElement.clientWidth; 
	if (document.body)
		return document.body.clientWidth; 
}

function getScrollTop() 
{
	if (self.pageYOffset)
	{
		return self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	{
		return document.documentElement.scrollTop;
	}
	else if (document.body)
	{
		return document.body.scrollTop;
	}
}

function getScrollLeft() 
{
	if (self.pageXOffset)
	{
		return self.pageXOffset;
	}
	else if (document.documentElement && document.documentElement.scrollLeft)
	{
		return document.documentElement.scrollLeft;
	}
	else if (document.body)
	{
		return document.body.scrollLeft;
	}
}

function getUpperLeftPoint(o)
{
	return new Point(getPosition_LEFT(o), getPosition_TOP(o));
}

function getPosition_LEFT(htmlObj) 
{ 
	var iLeftPixel = 0; 
	while ( htmlObj != null ) 
	{ 
		iLeftPixel += htmlObj.offsetLeft; 
		htmlObj = htmlObj.offsetParent; 
	} 
	return iLeftPixel; 
} 

function getPosition_TOP(htmlObj) 
{	
	var iTopPixel = 0; 
	while ( htmlObj != null ) 
	{ 
		iTopPixel += htmlObj.offsetTop; 
		htmlObj = htmlObj.offsetParent; 
	} 
	return iTopPixel; 
}

function getNewId()
{
    var alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var nums = "1234567890";
    var newid = "";
    for(var i=0; i<16; ++i)
    {   
        newid += alpha.charAt(Math.floor(Math.random() * alpha.length));
        newid += nums.charAt(Math.floor(Math.random() * nums.length));
    }
    return newid;
}

// ********************************************
// Point object
// ********************************************
function Point(x,y)
{
	this.x = parseInt(x);
	this.y = parseInt(y);
}
Point.prototype.toString = function()
{
	return this.x + "," + this.y;
};
Point.prototype.myToString = function()
{
	return "X:" + this.x + ",Y:" + this.y;
};
Point.prototype.isEqual = function(pt)
{
	return (this.x == pt.x && this.y == pt.y);
};

// ********************************************
// Size object
// ********************************************
function Size(width, height)
{
	this.width = width;
	this.height = height;
}
Point.prototype.toString = function()
{
	return this.width + ',' + this.height;
};
Point.prototype.isEqual = function(sz)
{
	return (this.width == sz.width && this.height == sz.height);
};

// ********************************************
// ArrayList object
// ********************************************
function ArrayList()
{
	this.data = new Array();
}
ArrayList.prototype.empty = function()
{
	for(var i=0;i<this.data.length; ++i)
	{
		this.data[i] = null;
	}
	this.data.length = 0;
}
ArrayList.prototype.size = function()
{
	return this.data.length; 
};
ArrayList.prototype.add = function(o)
{
	var m = this.data.length + 1;
	this.data.length = m;
	this.data[m-1] = o;
};
ArrayList.prototype.get = function(i)
{
	if(i >= 0 && i < this.data.length)
	{
		return this.data[i];
	}
	return null;
};
ArrayList.prototype.pop = function()
{
	if(this.data.length > 0)
	{
		return this.data.pop(); 
	}
	return null;
}

// -----------------------------------------------------------------------------------------
// Remove an object reference from the ArrayList and return the removed object
// reference.
// -----------------------------------------------------------------------------------------
ArrayList.prototype.remove = function(obj)
{
	var objref = null;
	var len = this.data.length - 1;
	for(var i=0; i<this.data.length; ++i)
	{
		if(obj === this.data[i])
		{
			objref = this.data[i]; 
			for(var m=i; m<len; ++m)
			{
				this.data[m] = this.data[m + 1]; 
			}
			this.data.length = len;
			break;			
		}
	}
	return objref;
};

// ********************************************
// RowCol object
// ********************************************
function RowCol(row, col)
{
	this.row = row;
	this.col = col;
}
RowCol.prototype.toString = function()
{
	return 'row=' + this.row + ', col=' + this.col;
};
RowCol.prototype.isEqual = function(rc)
{
	return (this.row == rc.row && this.col == rc.col);
};


// ********************************************
// Rectangle object
// ********************************************
function Rectangle(x, y, width, height)
{
	this.x = x;
	this.y = y;
	this.width = parseInt(width);
	this.height = parseInt(height);
}
Rectangle.fromDomObject = function(o)
{
	var x = parseInt(getIntegers(o.style.left));
	var y = parseInt(getIntegers(o.style.top));
	var w = parseInt(getIntegers(o.style.width));
	var h = parseInt(getIntegers(o.style.height));
	
	return new Rectangle(x, y, w, h);
};
Rectangle.prototype.toString = function()
{
	return this.x + ',' + this.y + ',' + this.width + ',' + this.height;
};
Rectangle.prototype.containsPoint = function(pt)
{
	return pt.x >= this.x && pt.x <= (this.x + this.width) && pt.y >= this.y && pt.y <= (this.y + this.height);
};


// ********************************************
// String trim
// ********************************************
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

// ********************************************
// StringBuffer object
// ********************************************
function StringBuffer()
{ 
	this.buffer = []; 
} 
StringBuffer.prototype.append = function(s)
{ 
	this.buffer.push(s); 
};
StringBuffer.prototype.toString = function()
{ 
	return this.buffer.join("");
};
StringBuffer.prototype.clear = function()
{ 
	this.buffer.length = 0;
};
StringBuffer.prototype.getLength = function()
{ 
	return this.buffer.length;
};

// ---------------------------------------
// Return any of "0123456789" found in s
// ---------------------------------------
function getIntegers(s)
{
	var m = "";
	for(var i=0; i<s.length; ++i)
	{
		if("0123456789".indexOf(s.charAt(i)) < 0)
		{
			continue;
		}
		m += s.charAt(i);
	}
	return m;
}

function getInternetExplorerVersion()
{
	var rv = -1;
	if (navigator.appName == 'Microsoft Internet Explorer')
	{
		var ua = navigator.userAgent;
		var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
		if (re.exec(ua) != null)
		{
			rv = parseFloat( RegExp.$1 );
		}
	}
	return rv;
}

var MFOS_DEBUGWINDOW = null;
function DEBUGWRITE(debugstring)
{
	try
	{
		if(MFOS_DEBUGWINDOW)
		{
			MFOS_DEBUGWINDOW.showMessage(debugstring);
		}
		else
		{
			var htmlArray = new Array();
			htmlArray.push("<html>");
			htmlArray.push("<head>");
			htmlArray.push("<title>MFOS Debug Window</title>");
			htmlArray.push("<style type='text/css'>");
			htmlArray.push(".btn {border:1px solid #999999;font-size:8pt;font-family:Verdana;}");
			htmlArray.push("body {background-color:#DDDDDD; margin:0px;}");
			htmlArray.push("td   {font-size:8pt;font-family:Verdana;}");
			htmlArray.push("</style>");
			htmlArray.push("<scr" + "ipt type='text/javascript'>");
			htmlArray.push("function showMessage(msg)");
			htmlArray.push("{");
			htmlArray.push("    var debugtext = document.getElementById('DEBUGTEXT');");
			htmlArray.push("    if(!document.getElementById('RUN').checked)");
			htmlArray.push("        return;");
			htmlArray.push("    var content = msg;");	
			htmlArray.push("    var txtNode = document.createTextNode(content);");
			htmlArray.push("    var brNode = document.createElement('br');");
			htmlArray.push("    if(!document.getElementById('APPEND').checked)");
			htmlArray.push("    {");
			htmlArray.push("        debugtext.innerHTML = \"\";");
			htmlArray.push("    }");
			htmlArray.push("    debugtext.appendChild(txtNode);");
			htmlArray.push("    debugtext.appendChild(brNode);");
			htmlArray.push("    debugtext.scrollTop = debugtext.scrollHeight;");
			htmlArray.push("}");
			htmlArray.push("</scr" + "ipt>");
			htmlArray.push("</head>");
			htmlArray.push("<body>");
			htmlArray.push("<table style='width:100%;height:90%' cellpadding='5' cellspacing='0' border='0'>");
			htmlArray.push("<tr>");
			htmlArray.push("<td>");
			htmlArray.push("<div ID='DEBUGTEXT' style='border:solid 1px black;background-color:white;height:500px;width:100%;font-family:Courier New;font-size:8pt;overflow:auto;color:black;'></div>");
			htmlArray.push("</td>");
			htmlArray.push("</tr>");
			htmlArray.push("<tr style='height:24px;background-color:#DDDDDD;'><td>");
			htmlArray.push("<table><tr>");
			htmlArray.push("<td><input class='btn' type='BUTTON' value=' Clear ' onclick='document.getElementById(\"DEBUGTEXT\").innerHTML=\"\";'></td>");
			htmlArray.push("<td><input CHECKED type='CHECKBOX' id='RUN'></td>");
			htmlArray.push("<td>Active</td>");
			htmlArray.push("<td><input CHECKED type='CHECKBOX' id='APPEND'></td>");
			htmlArray.push("<td>Append</td>");
			htmlArray.push("</tr></table>");
			htmlArray.push("</td></tr>");
			htmlArray.push("</table>");
			htmlArray.push("</body>");
			htmlArray.push("</html>");
			
			MFOS_DEBUGWINDOW = window.open("", "DEBUGGER", "width=350,height=560,resizable",false);
			MFOS_DEBUGWINDOW.document.open();
			MFOS_DEBUGWINDOW.document.write(htmlArray.join("\n"));
			MFOS_DEBUGWINDOW.document.close();
			
			MFOS_DEBUGWINDOW.showMessage(debugstring);
		}
	}
	catch(e)
	{
		MFOS_DEBUGWINDOW = null;
	}
}

function getHTMLFragmentFromServer(url, clickTarget)
{
	var req;
	if(mozilla)
	{
	    req = new XMLHttpRequest();        
	}
	else
	{
	    req = new ActiveXObject("Microsoft.XMLHTTP");
	}
	req.open('GET', url, true);
	req.onreadystatechange = function () {
	    if (req.readyState == 4) 
	    {
	        if(req.status == 200)
	        {		
	            var htmlString = req.responseText;
	            insertHTMLAfterElement(clickTarget, htmlString);
	            postHTMLInsert(clickTarget);
	        } 
	        else
	        {
	            alert("Method getHTMLFragmentFromServer failed.");
	        }
	    }
	};
	req.send(null);
}

function insertHTMLAfterElement(clickTarget, htmlString)
{
	if(mozilla)
	{
	    var parent = getElementParent(clickTarget)
	    var range = document.createRange();
	    range.selectNode(parent);
	    var documentFragment = range.createContextualFragment(htmlString);
	    parent.appendChild(documentFragment);
	}
	else
	{
	    getElementParent(clickTarget).insertAdjacentHTML("BeforeEnd", htmlString);
	}
}

function parseQueryString()
{
	var queryString = new Object();
	var qs = self.location.search;
	if(qs.charAt(0) == "?")
	{
	    qs = qs.substring(1);
	}
	if (qs.length == 0)
	{
	    return queryString;
	}
	qs = qs.replace(/\+/g, ' ');
	var args = qs.split('&');
	for (var i=0; i<args.length; ++i) 
	{
		var value;
		var pair = args[i].split('=');
		var name = unescape(pair[0]);
		if (pair.length == 2)
		{
			value = unescape(pair[1]);
	    }
		else
		{
			value = name;
		}
		queryString[name] = value;
	}
	return queryString;
}


/*******************************************************************************
 * Cookie code from QuirksMode.org Personal site of Peter-Paul Koch
 * http://www.quirksmode.org
 ******************************************************************************/
function createCookie(name, value, days) 
{
	var expires;
	if (days) 
	{
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		expires = "; expires="+date.toGMTString();
	}
	else
	{
		expires = "";
	}
	document.cookie = name+"="+value+expires+"; path=/";
}

function getCookieOrDefault(cookiename, defaultvalue) 
{
	var cookievalue = readCookie(cookiename);
	if(cookievalue)
	{
		if(cookievalue.length > 0)
		{
			return cookievalue; 
		}
	}
	return defaultvalue;
}

function readCookie(name) 
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) 
	{
		var c = ca[i];
		while (c.charAt(0)==' ')
		{
			c = c.substring(1,c.length);
		}
		if (c.indexOf(nameEQ) == 0)
		{
			return c.substring(nameEQ.length,c.length);
		}
	}
	return null;
}

function eraseCookie(name) 
{
	createCookie(name,"",-1);
}

function contact(subj)
{
	var href = "mailto:" +
	"raywilson" +
	"@" +
	"musicfromouterspace" + 
	"." +
	"com";
	
	if(subj != "")
	{
		subj = subj.replace(/ /g,"%20");
		href += "?subject=" + subj;
	}
	document.location.href = href;
}

// ------------------------------------------------------------------
// Adjust the centerElement's top and left so that it is centered
// in the BODY element.
// If vertOffset and/or horzOffset are present add them to the
// top and left respectively.
// ------------------------------------------------------------------
function centerElementInBody(centerElement, vertOffset, horzOffset) 
{
	vOffset = 0;
	hOffset = 0;
	if(arguments.length == 3)
	{
		vOffset = vertOffset;
		hOffset = horzOffset;
	}
	else if(arguments.length == 2)
	{
		vOffset = vertOffset;
	}
	if(centerElement)
	{
		var width = centerElement.offsetWidth;
		var height = centerElement.offsetHeight;
		var theBody = document.getElementsByTagName("BODY")[0];
		var scTop = parseInt(getScrollTop(),10);
		var scLeft = parseInt(theBody.scrollLeft,10);
		var fullHeight = getViewportHeight();
		var fullWidth = getViewportWidth();
		centerElement.style.top  = (scTop  + ((fullHeight - height) / 2) + vOffset) + "px";
		centerElement.style.left = (scLeft + ((fullWidth  - width)  / 2) + hOffset) + "px";
	}
}

function setBodyMaskSize(maskElement)
{
	var theBody = document.getElementsByTagName("BODY")[0];
	var maskHigh = (getViewportHeight() > theBody.scrollHeight) ? getViewportHeight() : theBody.scrollHeight;
	var maskWide = (getViewportWidth() > theBody.scrollWidth) ? getViewportWidth() : theBody.scrollWidth;
	maskElement.style.height = maskHigh + "px";
	maskElement.style.width = maskWide + "px";
}

// ------------------------------------------------------------------
// Adjust the centerElement's top and left so that
// it is centered in the targetElement.
// ------------------------------------------------------------------
function centerElementInElement(centerElement, targetElement) 
{
	var cRect = Rectangle.fromDomObject(centerElement);
	var tRect = Rectangle.fromDomObject(targetElement);
	var newL = tRect.x + ((tRect.width - cRect.width)/2);
	var newT = tRect.y + ((tRect.height - cRect.height)/2);
	centerElement.style.left = newL + "px";
	centerElement.style.top = newT + "px";
}


