Object.prototype.type = function(){
	/*
	Parameters:
		If no parameters are specified, this method will return a string of the name of the object determined.
		If any parameters are specified; they are passed to the constructor of the object, and the new object created is returned.
	Purpose:
		Use this on any Object to determine it's type, far more precisely than the built in JavaScript typeof operator.
		If the object type is determined to be an HTML element, the arguments passed are expected to be name=value pairs, designating attributes to be set on the new object.
		If constructor arguments are passed, and the return object can not be created; a string of the name of the object is returned instead.
	Returns:
		Either a string with the name of the object found; or a new object of the type found.
		Objects Recognized:
			object
			array
			boolean
			date
			enumerator (IE Specific)
			error
			function
			number
			regexp
			string
			*UDF Objects (returns the name of the constructor function)
		Will return null if could not determine object type.
	*/
	var value = null;
	var constructor = this.constructor;
	switch (typeof this){
		case "object":
			switch (constructor){
				case Object:
					value = (arguments.length > 0 ? new Object(arguments[0]) : "object");
					break;
				case String:
					value = (arguments.length > 0 ? new String(arguments[0]) : "string");
					break;
				case Number:
					value = (arguments.length > 0 ? new Number(arguments[0]) : "number");
					break;
				case Boolean:
					value = (arguments.length > 0 ? new Boolean(arguments[0]) : "boolean");
					break;
				case Array:
					value = (arguments.length > 0 ? new Array(arguments) : "array");
					break;
				case Date:
					value = (arguments.length > 0 ? new Date(arguments) : "date");
					break;
				case Error:
					value = (arguments.length > 0 ? new Error(arguments[0],arguments[1]) : "error");
					break;
				case RegExp:
					value = (arguments.length > 0 ? new RegExp(arguments[0],arguments[1]) : "regexp");
					break;
				default:
					var cName = $getFunctionName(constructor)
					if (cName != null){
						value = (arguments.length > 0 ? constructor.call(arguments) : cName);
					}
			}
			break;
		case "function":
			switch (constructor){
				case RegExp:
					value = (arguments.length > 0 ? new RegExp(arguments[0],arguments[1]) : "regexp");
					break;
				case Function:
					value = (arguments.length > 0 ? new Function(arguments) : "function");
					break;
			}
			break;
		default:
			value = (returnObj ? null : "undetermined");
	}
	if (value == null){
		// If after all that we didn't find what we're looking for, let's try some browser specific objects.
		try{
			if (constructor == Enumerator)value = (arguments.length > 0 ? new Enumerator(arguments[0]) : "enumerator");
		}
		catch (e){
		};
	}
	return value;
};
function $getFunctionName(f){
	/*
	Parameters:
		f (string|function) - The function or function text to get the name from.
	Purpose:
		To get the name of a function passed.
	Returns:
		A string, representing the name of the function.
	*/
	var value = null;
	var re = /^function (.+?)\(.*?\)/i;
	var result = null;
	if (typeof f){
		value = f.name; //Some browsers provide a name property on the function object, so we'll use that if we can.
		if (value != null)return value;
		f = f.toString();
	};
	result = re.exec(f);
	if (result != null)value = result[1];
	return value;
};
function $getElementsByAttribute(attribute,value,start){
   /*
	Parameters:
		attribute (variant) - Either a string which is an exact attribute or a regular expression.
			This parameter can also be an array of strings or regular expressions, for matches of more than one attribute.
		value (variant) - Either a string or a regular expression, of the value of the attribute to retrieve elements of. Default is null.
			If attribute is an array, this must be an array of equal length (or null).
		start (variant) - Either the ID of the element to start looking under or the element reference itself. Default is body.
	Purpose:
		This function returns an array of all matching elements which match the specified attributes or values.
	Returns:
		An array of elements, or a zero length array if no elements contain the specific attribute and value passed.
	*/
	var array = [];
	start = (start == null ? document.body : start);
	var recurse = function(el,attribute,value){
		if (el.nodeType == 1){
			var attr = attribute;
			if (attribute.type() == "regexp"){
				var attrs = el.attributes;
				for (var i=0; i<attrs.length; i++){
					var result = attribute.test(attrs[i].nodeName);
					if (result){
						attr = attrs[i].nodeName;
						break;
					};
				};
			}
			var condition1 = (el.getAttributeNode(attr) != null);
			var condition2 = (value == null || (condition1 && value != null && ((value.type() == "string" && el.getAttributeNode(attr).nodeValue == value) || (value.type() == "regexp" && new RegExp(value.source,(value.global ? "g" : "")+(value.ignoreCase ? "i" : "")+(value.multiline ? "m" : "")).test(el.getAttributeNode(attr).nodeValue)))));
			if (condition1 && condition2)array[array.length] = el;
		};
		for (var i=0; i<el.childNodes.length; i++)recurse(el.childNodes[i],attribute,value);
	};
	if (attribute != null){
		if ((attribute.type() == "array" && value != null && value.type() == "array" && value.length == attribute.length) || (attribute.type() == "array" && value == null) || (attribute.type() != "array")){
			if (attribute.type() == "array"){
				for (var i=0; i<attribute.length; i++)recurse(start,attribute[i],value[i]);
			}
			else recurse(start,attribute,value);
		}
		else Object.error("$getElementsByAttribute(): When passing attribute as an array, if value is also being checked; it must be an equal length array.");
	}
	else Object.error("$getElementsByAttribute(): No attribute was specified.");
	return array;
}
function dateInput(el,key){
	var code = key.code;
	var enter = 13;
	var backspace = 8;
	var tab = 9;
	var numpad_0 = 96;
	var numpad_1 = 97;
	var numpad_2 = 98;
	var numpad_3 = 99;
	var numpad_4 = 100;
	var numpad_5 = 101;
	var numpad_6 = 102;
	var numpad_7 = 103;
	var numpad_8 = 104;
	var numpad_9 = 105;
	var numpad_period = 110;
	var number_0 = 48;
	var number_1 = 49;
	var number_2 = 50;
	var number_3 = 51;
	var number_4 = 52;
	var number_5 = 53;
	var number_6 = 54;
	var number_7 = 55;
	var number_8 = 56;
	var number_9 = 57;
	var left = 37;
	var right = 39;
	var up = 38;
	var down = 40;
	var pgup = 33;
	var pgdown = 34;
	var home = 36;
	var del = 46;
	var period = 190;
	var end = 35;
	var rv = true;
   if ((code >= numpad_0 && code <= numpad_9) || (code >= number_0 && code <= number_9) || code == enter || code == backspace || code == tab || code == left || code == right || code == up || code == down || code == pgup || code == pgdown || code == home || code == del && !key.shiftKey){
      if ((code >= numpad_0 && code <= numpad_9) || (code >= number_0 && code <= number_9)){
         var len = el.value.length;
         if (len == 0 && ((code >= numpad_2 && code <= numpad_9) || (code >= number_2 && code <= number_9)))rv = false;
         if (len == 1){
            if (el.value == 0 && (code == numpad_0 || code == number_0))rv = false;
            if (el.value == 1 && ((code >= numpad_3 && code <= numpad_9) || (code >= number_3 && code <= number_9)))rv = false;
         };
         if (len == 2 || len == 3){
            if (el.value.charAt(0)+el.value.charAt(1) == 2 && ((code >= numpad_3 && code <= numpad_9) || (code >= number_3 && code <= number_9)))rv = false;
            if (el.value.charAt(0)+el.value.charAt(1) != 2 && ((code >= numpad_4 && code <= numpad_9) || (code >= number_4 && code <= number_9)))rv = false;
         };
         if (el.value.length == 2 || el.value.length == 5)el.value += "../../index.html";
      };
      if (code == backspace){
         if (el.value.length == 3 || el.value.length == 4 || el.value.length == 6 || el.value.length == 7)el.value = el.value.substring(0,el.value.length-1);
      };
      if (code == up || code == down){
         if (el.value.length == 0){
            var date = new Date();
            el.value = (date.getMonth()+1 <= 9 ? "0"+(date.getMonth()+1) : (date.getMonth()+1))+"/"+(date.getDate() <= 9 ? "0"+date.getDate() : date.getDate())+"/"+date.getFullYear();
         };
         if (el.value.length == 10){
            var date = new Date(el.value);
            if (code == up)date.setDate(date.getDate()+1);
            else date.setDate(date.getDate()-1);
            el.value = (date.getMonth()+1 <= 9 ? "0"+(date.getMonth()+1) : (date.getMonth()+1))+"/"+(date.getDate() <= 9 ? "0"+date.getDate() : date.getDate())+"/"+date.getFullYear();
         };
         rv = false;
      };
      if (code == pgup || code == pgdown){
         if (el.value.length == 0){
            var date = new Date();
            el.value = (date.getMonth()+1 <= 9 ? "0"+(date.getMonth()+1) : (date.getMonth()+1))+"/"+(date.getDate() <= 9 ? "0"+date.getDate() : date.getDate())+"/"+date.getFullYear();
         };
         if (el.value.length == 10){
            var date = new Date(el.value);
            if (code == pgup)date.setMonth(date.getMonth()+1);
            else date.setMonth(date.getMonth()-1);
            el.value = (date.getMonth()+1 <= 9 ? "0"+(date.getMonth()+1) : (date.getMonth()+1))+"/"+(date.getDate() <= 9 ? "0"+date.getDate() : date.getDate())+"/"+date.getFullYear();
         };
      };
      if (code == home){
         var date = new Date();
         el.value = (date.getMonth()+1 <= 9 ? "0"+(date.getMonth()+1) : (date.getMonth()+1))+"/"+(date.getDate() <= 9 ? "0"+date.getDate() : date.getDate())+"/"+date.getFullYear();
         rv = false;
      };
   }
   else rv = false;
	return rv;
};

function __checkKey(evt){
	var evt = (window.event != null ? window.event : evt);
	var el = (evt.currentTarget != null ? evt.currentTarget : evt.srcElement);
	if (evt.keyCode == 13){
		if (evt.preventDefault)evt.preventDefault();
		if (evt.stopPropagation)evt.stopPropagation();
		evt.returnValue = false;
		evt.cancelBubble = true;
		insertDate((el.id == "dateStart" ? true : false));
	};
};

function __init_inputtypes(e){
	e = (e == null ? window.event : e);
	Validate.inputmasks.add("date-us",dateInput);
	var inputs = $getElementsByAttribute("inputmask","date-us");
	for (var i=0; i<inputs.length; i++){
		var inputMethod = inputs[i].getAttribute("dateInputMethod");
		if (inputMethod)inputMethod = inputMethod.toLowerCase();
		else inputMethod = "normal";
		if (inputMethod == "calendar" || inputMethod == "normal"){
			Calendar.setup({inputField:inputs[i].name,button:inputs[i].name});
		}
		try {
			Calendar.setup({inputField:inputs[i].name,button:"btn"+inputs[i].name});
		}
		catch(e){
			Calendar.setup({inputField:inputs[i].name,button:inputs[i].name});
		};
		if (inputMethod == "mask" || inputMethod == "normal"){
			if (inputs[i].addEventListener)inputs[i].addEventListener("keydown",__checkKey,false);
			if (inputs[i].attachEvent)inputs[i].attachEvent("onkeydown",__checkKey);
		};
		if (inputMethod == "text"){
			var attr = inputs[i].getAttributeNode("inputmask");
			inputs[i].removeAttributeNode(attr);
		};
	};
};

if (window.addEventListener)window.addEventListener("load",__init_inputtypes,false);
if (window.attachEvent)window.attachEvent("onload",__init_inputtypes);