// Copyright (C) 2008 Dwain Blazej

function getElementByName(form,name) {
	var eltFound;
	for (var i=0;i<form.length;i++) {
		var elt=form.elements[i];
		// debugMessage('id: '+ elt.id + '\tname: '+ elt.name + '\tvalue: '+ elt.value + '<br />');
		if (name == elt.name) {
			// debugMessage('Found '+name);
			if (typeof(eltFound) == 'undefined') {
				eltFound = elt;
			} else {
				throw('Found duplicates of \"'+name+'\" in \"'+form+'\".');
			}
		}
	}
	return eltFound;

}

// str: string.  Remove leading and trailing space from str, then return the resulting string.
function trimExtraSpaces(str) {
	// Trim leading spaces.
	while((str.indexOf(' ',0) == 0) && (str.length > 1)) {
		str = str.substring(1,str.length);
	}

	// Trim ending spaces.
	while((str.lastIndexOf(' ') == (str.length - 1) && (str.length > 1)))	{
		str = str.substring(0,(str.length - 1));
	}

	if (str == ' ') { str = ''; }
	return str;
}

/* Return:
	true: browser implements at least HTML 1.0
	false: browser does not implement

	http://www.quirksmode.org/js/support.html
	http://www.brothercake.com/Ref/in.html
	http://www.esqsoft.com/javascript-help/javascript-testing-defined-undefined-variables.htm
	http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
*/
function supportedBrowser() {
	if (typeof document.implementation == 'undefined'
		|| ! document.implementation.hasFeature('HTML', '1.0')) {
		return false;
	} else {
		return true;
	}
}


function handleError(msg,url,line) {
	if (supportedBrowser) {
		var txt;
		txt='There was an error on this page.\n\n';
		txt+='Please copy-and-paste the following message into an email to\n' + problemReportEmail + '\n\n';
		txt+='Error: ' + msg + '\n';
		if (line) { txt+='Line: ' + line + '\n'; }
		if (url) {
			txt+='URL: ' + url + '\n';
		} else {
			txt+='Reporting URL: ' + document.URL + '\n';
		}
		txt+='\nBrowser: ' + navigator.userAgent + '\n';
		txt+='\nClick "OK" to continue.\n\n';
		alert(txt);
	}
	// Tell browser not to show the built in error window.
	return true;
}

// Report non-fatal bugs.
function reportBug(msg) {
	if (supportedBrowser) {
		alert ('Web page error.\n\nPlease copy-and-paste the following message into an email to\n' + problemReportEmail + '\n\nLogic Error: ' + msg + '\nURL: ' + document.URL + '\nBrowser: ' + navigator.userAgent + '\n\nClick "OK" to continue.\n\n');
	}
}

 
function exist (a) {
	var itemType = typeof(a);
	switch (itemType) {
	case 'undefined':
		return false;
	default:
		return true;
	}
	
	// Check if the variable a undefined.
	try { var b=a;}
	catch(e){return false;}
	return true;
} 




/*
num: positive integer
return: ordinal html string of num.
*/
function numToHtmlOrdinal(num) {
	switch(num)	{
	case 1:
		return('1<sup><font size="1">st</font></sup>');
	case 2:
		return('2<sup><font size="1">nd</font></sup>');
	case 3:
		return('3<sup><font size="1">rd</font></sup>');
	default:
		return(num + '<sup><font size="1">th</font></sup>');
	}
}

// onclick="setSelected('id_string_of_radio_or_button');"
function setSelected(strId) {
	var obj = document.getElementById(strId);
	if (!obj) {
		throw('setSelected: Could not find object with ID \"' + strId + '\"');
	}
	if (obj.checked == undefined) {
		throw('setSelected: Object with ID \"' + strId + '\" has no \"checked\" method.');
	}
	obj.checked=true;
}


/* ======================================== 
http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
http://www.robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/
http://code.google.com/p/getelementsbyclassname/downloads/list

/*
	Developed by Robert Nyman, http://www.robertnyman.com
	Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/	
var getElementsByClassName = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var j=0, jl=classes.length; j<jl; j+=1){
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			}
			catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};

/* ========================================
This section of prototypes is copied from: 
http://www.hunlock.com/blogs/Mastering_Javascript_Arrays

Added prototype checks for sortNum, find, shuffle, compare
 */


function isArray(testObject) {
	return testObject && !(testObject.propertyIsEnumerable('length')) && typeof testObject === 'object' && typeof testObject.length === 'number';
}


// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.every)
{
	Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this && !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}


// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.lastIndexOf)
{
  Array.prototype.lastIndexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]);
    if (isNaN(from))
    {
      from = len - 1;
    }
    else
    {
      from = (from < 0)
           ? Math.ceil(from)
           : Math.floor(from);
      if (from < 0)
        from += len;
      else if (from >= len)
        from = len - 1;
    }

    for (; from > -1; from--)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.map)
{
  Array.prototype.map = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        res[i] = fun.call(thisp, this[i], i, this);
    }

    return res;
  };
}


// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.some)
{
  Array.prototype.some = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          fun.call(thisp, this[i], i, this))
        return true;
    }

    return false;
  };
}

/*
numerical sort
document.writeln([5,8,12,50,25,80,93].sortNum()); // outputs 5,8,12,25,50,80,93
*/
if (!Array.prototype.sortNum)
{
	Array.prototype.sortNum = function() {
		return this.sort( function (a,b) { return a-b; } );
	}
}


/*
Array.indexOf() is a nice method but this extension is a little more powerful and flexible. First it will return an array of all the indexes it found (it will return false if it doesn't find anything). Second in addition to passing the usual string or number to look for you can actually pass a regular expression, which makes this the ultimate Array prototype in my book. 
*/
if (!Array.prototype.find)
{
	Array.prototype.find = function(searchStr) {
		var returnArray = false;
		for (i=0; i<this.length; i++) {
			if (typeof(searchStr) == 'function') {
				if (searchStr.test(this[i])) {
					if (!returnArray) { returnArray = [] }
					returnArray.push(i);
				}
			} else {
				if (this[i]===searchStr) {
					if (!returnArray) { returnArray = [] }
					returnArray.push(i);
				}
			}
		}
		return returnArray;
	}
}

if (!Array.prototype.shuffle)
{
	Array.prototype.shuffle = function (){ 
		for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);
	};
}

if (!Array.prototype.compare)
{
	Array.prototype.compare = function(testArr) {
		if (this.length != testArr.length) return false;
		for (var i = 0; i < testArr.length; i++) {
			if (this[i].compare) { 
				if (!this[i].compare(testArr[i])) return false;
			}
			if (this[i] !== testArr[i]) return false;
		}
		return true;
	}
}
/* ========================================
*/
