/***********************************************

	Basic Javascript library that adds extended
	functionality to some standard objects used
	in javascript and an html document.

***********************************************/

// addEvent	and	removeEvent
// cross-browser event handling	for	IE5+,  NS6 and Mozilla
// By Scott	Andrew
function addEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
	obj.addEventListener(evType, fn, useCapture);
	return true;
  }	else if	(obj.attachEvent){
	var	r =	obj.attachEvent("on"+evType, fn);
	return r;
  }	else {
	alert("Handler could not be	attached");
	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 {
	alert("Handler could not be	removed");
	return false;
  }
}


function getObject(objectId)	{
	var	element	= false;

	// cross-browser function to get an	object given its id
	if(document.getElementById && document.getElementById(objectId)) {
		// W3C DOM
		element	= document.getElementById(objectId);
	} 
	else if	(document.all && document.all(objectId)) {
		// MSIE	4 DOM
		element	= document.all(objectId);
	} 
	else if	(document.layers &&	document.layers[objectId]) {
		// NN 4	DOM.. note:	this won't find	nested layers
		element	= document.layers[objectId];
	} 

	return element;
} 



/********
ARRAYS
********/


/* 	
	since IE in all of its flavors does not fully support the JS array implementation
 	we are forced to expand the Array object by adding new methods.
*/

// here we add the PUSH method to the Array object

// first make sure any existing push methods are destroyed so we know
// we are always working with the same method regardless of browser
// viewing the page.

/* COMMENTED OUT FOR JQUERY COMPATIBILITY ISSUE */

//if(Array.prototype.push){
//	Array.prototype.push = null;
//}

if(!Array.prototype.push) {
	function ArrayPush(value){
		// simply add the element to the end of the array changing the arrays
		// length by +1
		this[this.length] = value;
	}
	// set the Arrays push method equal to our ArrayPush function
	Array.prototype.push = ArrayPush;
}	

// here we add the POP method to the Array object.


// first make sure any existing pop methods are destroyed so we know
// we are always working with the same method regardless of browser
// viewing the page.
if(Array.prototype.pop){
	Array.prototype.pop = null;
}

if(!Array.prototype.pop){
	// pop by default, without an index provided, removes the last element in the array
	// changing the arrays size by -1.  However, this verison of pop has been extended
	// so that an index can be provided and then the element at the given index will
	// be popped instead of the last element.  This alteration also alters the arrays
	// size by -1.
	function ArrayPop(index)	
		{
			// if the array is empty do nothing.
			if(this.length == 0) return false;
			// no index is provided get the value of the last index
			// in the array.
			if(index == null) index = this.length - 1;
		
			//get the value of the element at the requested index.
			var elem = this[index];
		
			// loop over the array starting at the index point and going
			// till the last element in the array and change the value of
			// the current element to the value of the next element - thus
			// left shifting the array from the deletion point onward.
			for (var i = index; i < this.length - 1; i++) this[i] = this[i+1];
	 
	 		// set the final elements value = NULL thus destroying that element
			this[this.length - 1] = null;
			// change the length of the array to its old length - 1.
			this.length--;   
			// return the value that was removed from the array.
			return elem;
		}
	// set the arrays pop method equal to our defined ArrayPop function.
	Array.prototype.pop = ArrayPop;
}

// here we add the SPLICE method to the Array object.


// first make sure any existing splice methods are destroyed so we know
// we are always working with the same method regardless of browser
// viewing the page.
/* COMMENTED OUT FOR JQUERY COMPATIBILITY ISSUE */
/*
if(Array.prototype.splice)
    Array.prototype.splice = null;
*/

if(!Array.prototype.splice) {

    function ArraySplice(index,count){

		// we use the slice method which is supported
		// across browsers to get the chunk of the array
		// we want to remove.
        removeArray = this.slice(index,index+count);
        endArray = this.slice(index+count);

		// we alter the length by setting it equal to the index
        this.length = index;

        for(var i=2;i<arguments.length;i++){
            this[this.length] = arguments[i];
        }

        for(var i=0;i<endArray.length;i++){
            this[this.length] = endArray[i];
        }

        return removeArray;
    }

	// set the arrays slice method equal to our defined ArraySlice function.
    Array.prototype.splice = ArraySplice;
}




/********
STRINGS
********/
// like Trim( ) in vbscript. removes trailing and 
// leading whitespace from a string
String.prototype.trim = function() {
  return this.replace(/^\s*|\s*$/g, "")
}



String.prototype.stripAlpha = function(b) {
	  return this.replace(/\a/g,'')
}
String.prototype.stripNonAlpha = function(b) {
	  return this.replace(/\A/g,'')
}
String.prototype.stripDecimal = function(b) {
	  return this.replace(/\d/g,'')
}
String.prototype.stripNonDecimal = function(b) {
	  return this.replace(/\D/g,'')
}
String.prototype.stripAlphaNumeric = function() {
	  return this.replace(/\w/g,'')
}
String.prototype.stripNonAlphaNumeric = function() {
	  return this.replace(/\W/g,'')
}



/********
CHECK BOXES
********/
function getCheckedCount(obj) {
	var vCount=0;
	
	if (obj) {
		if (obj.length) {
			for (var vI=0; vI<pCtrl.length; vI++) {
				if (obj[vI].checked)
					vCount++;
			}		
		}
		else {
			if (obj.checked) 
				vCount=1;
		}
	}
	
	return vCount;
}





/********
SELECT BOXES
********/



/* 
	functional equivilants as you cant extend the HTMLSelectElement in IE
*/
// removes all options from the select box
function clearSelect(obj){
	while (obj.length > 0) {
		obj.remove(0);
	}
}

// changes the selection to a specified position
function pickSelect(obj,position){
	if(position > obj.length-1) position = obj.length-1;

	obj.selectedIndex = position;
}


// changes the selection to a specific id
function pickSelectByID(obj,id){
	var idx = 0;
	for (idx=0;idx<obj.length;idx++){
		if(obj.options[idx].value == id){
			pickSelect(obj,idx);
			break;
		}
	}
}

// changes the selection to a specific text value
function pickSelectByText(obj,textValue){
	var idx = 0;
	for (idx=0;idx<obj.length;idx++){
		if(obj.options[idx].text == textValue){
			pickSelect(obj,idx);
			break;
		}
	}
}


function getSelectCount(obj) {
	/* gets the number of elements selected in a multi-select dropdown */

	var	vCount=0;
	
	if (obj) {
		if (obj.length) {
			for	(var vI=0; vI<obj.length;	vI++) {
				if (obj[vI].selected)
					vCount++;
			}		
		}
		else {
			if (obj.selected) 
				vCount=1;
		}
	}
	
	return vCount;
}




// gets the text value from a specific position
function getSelectText(obj,position){
	if(!position){
		position = obj.selectedIndex;
	}
	
	return obj.options[position].text.trim();
}

function getSelectTextByID(obj,id){
	var idx = 0;
	var val = "";
	for (idx=0;idx<obj.length;idx++){
		if(obj.options[idx].value == id){
			val= obj.options[idx].text.trim();
			break;
		}
	}
	return val;
}


function getSelectAttribute(obj,attr){
	return	obj.options[obj.selectedIndex].getAttribute(attr);	
}

// clears a select box and optionaly inserts a first object
function initSelect(obj,id,textValue){
	clearSelect(obj);
	if(textValue){
		obj.options[0] = new Option(textValue,id);
	}
}


function insertSelect(obj,id,textValue,attr,attrvalue,position){
	/*
		obj - the select box
		id - the option "value" attribute
		textValue = the text displayed in the option
		OPTIONAL position - where to put the new item (only works in nonIE browsers).
	*/
	var newOpt = new Option(textValue,id);

	if(attr){
		newOpt.setAttribute(attr,attrvalue);
	}

	var oldOpt = null;
	
	if(!isNaN(position) && position < obj.length-1 && position >= 0) {
		oldOpt = obj.options[position];
	} 
		try{ // standards compliant
			obj.add(newOpt,oldOpt);
		} catch(err){
			// ie hack (ie can only append)
			obj.add(newOpt);
		}
}

function selectDropValueByPosition(obj,position){
	obj.options[position] = null;
}

function selectSort(obj) {
	// BUBBLE SORT
	// create an array based on the dropdown
	var		arrayTemp = new Array();
	for(var ddcount=0;ddcount<obj.length;ddcount++){
		var		element = new Array();
		element[0]=obj[ddcount].value;
		element[1]=obj[ddcount].text;
		arrayTemp[ddcount]=element;
	}

	var length = arrayTemp.length;

	for (var oldP=0; oldP<(length-1); oldP++){
        for (var newP=oldP+1; newP<length; newP++){
				oldText = arrayTemp[oldP][1];
				newText = arrayTemp[newP][1];
				
            if (newText < oldText) {
                var dummy = arrayTemp[oldP];
                arrayTemp[oldP] = arrayTemp[newP];
                arrayTemp[newP] = dummy;
            }
		}
	}

	clearSelect(obj);
	for(aryCount=0;aryCount<arrayTemp.length;aryCount++){
		insertSelect(obj,arrayTemp[aryCount][0],arrayTemp[aryCount][1]);
	}

}

/********
DATE
********/

// Extensions to the Date class:
// var myDate = new Date();
// myDate.getMonthName(); -> "February"
// myDate.getHumanDateString(); -> "February 29, 2000"
// myDate.getHumanTimeString(); -> "4:00 pm"


// returns the name of the month
Date.prototype.getMonthName = function() {
	return ["January","February","March","April","May","June","July","August",
			"September","October","November","December"][this.getMonth()]
}

// returns the number of the month
Date.prototype.getMonthNumber = function() {
	return ["1","2","3","4","5","6","7","8",
			"9","10","11","12"][this.getMonth()]
}

// returns a nicely formatted date string
Date.prototype.getHumanDateString = function() {
return this.getMonthName() + " " + this.getDate() + ", " + this.getFullYear()
}

Date.prototype.getDateString = function() {
return this.getMonthNumber() + "/" + this.getDate() + "/" + this.getFullYear()
}

// returns a nicely formatted time string
Date.prototype.getHumanTimeString = function() {
	var h = this.getHours()
	var m = this.getMinutes()
	var t = h >= 12 ? "pm" : "am"

	if (h == 0) h = 24
	if (h > 12) h -= 12
	h = String(h)
	m = String(m)
	if (m.length == 1) m = "0" + m

	return h + ":"
}

Date.prototype.toFormattedString = function (f)
{
    var nm = this.getMonthName();
    var nd = this.getDayName();
    f = f.replace(/yyyy/g, this.getFullYear());
    f = f.replace(/yy/g, String(this.getFullYear()).substr(2,2));
    f = f.replace(/MMM/g, nm.substr(0,3).toUpperCase());
    f = f.replace(/Mmm/g, nm.substr(0,3));
    f = f.replace(/MM\*/g, nm.toUpperCase());
    f = f.replace(/Mm\*/g, nm);
    f = f.replace(/mm/g, String(this.getMonth()+1).padLeft('0',2));
    f = f.replace(/DDD/g, nd.substr(0,3).toUpperCase());
    f = f.replace(/Ddd/g, nd.substr(0,3));
    f = f.replace(/DD\*/g, nd.toUpperCase());
    f = f.replace(/Dd\*/g, nd);
    f = f.replace(/dd/g, String(this.getDate()).padLeft('0',2));
    f = f.replace(/d\*/g, this.getDate());
    return f;
};

Date.prototype.getMonthName = function ()
{
    switch(this.getMonth())
    {
    	case 0: return 'January';
        case 1: return 'February';
        case 2: return 'March';
        case 3: return 'April';
        case 4: return 'May';
        case 5: return 'June';
        case 6: return 'July';
        case 7: return 'August';
        case 8: return 'September';
        case 9: return 'October';
        case 10: return 'November';
        case 11: return 'December';
    }
};

Date.prototype.getDayName = function ()
{
    switch(this.getDay())
    {
        case 0: return 'Sunday';
        case 1: return 'Monday';
        case 2: return 'Tuesday';
        case 3: return 'Wednesday';
        case 4: return 'Thursday';
        case 5: return 'Friday';
        case 6: return 'Saturday';
    }
};

String.prototype.padLeft = function (value, size) 
{
    var x = this;
    while (x.length < size) {x = value + x;}
    return x;
};
