// Setup namespaces and libraries
(function($) {
	$.namespace = function()
	{
		var 	args = arguments, 
				obj = null,
				nspace = null,
				i, 
				j;

		for (i = 0;  i < args.length; i++)
		{
			nspace = ("" + args[i]).split(".");
			obj = window;
	
			// namespace is added to 'window', so if it is included, it is ignored
			for (j = (nspace[0] == "window") ? 1 : 0; j < nspace.length; j++)
			{
				obj[nspace[j]] = obj[nspace[j]] || {};
				obj = obj[nspace[j]];
			}
		}

		return obj;
	};


	$.namespace("site.utils.format");
	$.namespace("site.utils.is");


	site.utils = 
	{
		dialog: function(id, options)
		{
			options = options || {};
			options.error = options.error || false;

			var	dialog = $("#" + id),
				exists = true;

			if (dialog.length == 0)
			{
				dialog = $("<div id=\"" + id + "\"></div>").appendTo("body");
				exists = false;
			}
			else
			{
				if (dialog[0].title.length > 0 && (options.title == undefined || options.title.length == 0))
				{
					options.title = dialog[0].title;
				}
			}

			if ("message" in options)
			{
				dialog.html(options.message);

				delete options.message;
			}

			if (options.error)
			{
				options.title = options.title || "";
				options.title = "<span class=\"ui-icon ui-icon-alert\" style=\"float: left; margin-right: 3px;\"> </span> " + options.title;
				options.modal = options.modal || true;
			}

			dialog.dialog(options);
			dialog.dialog("option", options);

			if (options.error && !dialog.siblings("div.ui-dialog-titlebar").hasClass("ui-state-error"))
			{
				dialog.siblings("div.ui-dialog-titlebar").addClass("ui-state-error");
			}

			return dialog;
		},


		getFieldValue: function(field, isChecked)
		{
			var fieldValue = "";
			var fieldValueArray = [];


			if (isChecked == undefined || isChecked == null)
			{
				isChecked = false;	
			}


			// Checkbox or Radio group passed in
			if (field.nodeName == undefined && field.length != undefined)
			{
				for (var i = 0; i < field.length; i++)
				{
					if (field[i].checked)
					{
						fieldValueArray.push(field[i].value);
					}
				}

				fieldValue = fieldValueArray.join(",");
			}


			// Indiviual field passed in
			else
			{
				var fieldType = field.nodeName.toLowerCase();


				if (fieldType == "input")
				{
					if (field.type == "checkbox" || field.type == "radio")
					{
						if (isChecked && field.checked || !isChecked)
						{
							fieldValue = field.value;
						}
					}
					else if (field.type == "text" || field.type == "hidden" || field.type == "password")
					{
						fieldValue = field.value;
					}
				}
				else if (fieldType == "select" && field.length > 0)
				{
					fieldValue = field[field.selectedIndex].value;
				}
				else if (fieldType == "textarea")
				{
					fieldValue = field.value;
				}
			}


			return fieldValue;
		},


		getFormValues: function(form)
		{
			var formStructure = {};
			var formElements = form.elements;

			for (var i = 0; i < formElements.length; i++)
			{
				if (formStructure[formElements[i].name] == undefined && !formElements[i].disabled)
				{
					formStructure[formElements[i].name] = this.getFieldValue(form[formElements[i].name], true);
				}
			}

			return formStructure;
		},


		insert: function(value, insertValue, position)
		{
			return value.substr(0, position) + insertValue + value.substr(position);
		},


		later: function(when, scope, fn, data, periodic) 
		{
			when = when || 0; 
			scope = scope || {};

			var method = fn, 
				d = data, 
				f, 
				r;

			if (typeof fn === "string") 
			{
				method = scope[fn];
			}

			if (!method) {
				throw new TypeError("method undefined");
			}

			if (d && !$.isArray(d)) 
			{
				d = [data];
			}

			f = function() { method.apply(scope, d || []); };
			r = (periodic) ? setInterval(f, when) : setTimeout(f, when);

			return {
				interval: periodic,
				cancel: function() 
				{
					if (this.interval) 
					{
						clearInterval(r);
					} 
					else 
					{
						clearTimeout(r);
					}
				}
			};
		},


		left: function(value, count)
		{
			return value.substr(0, count);
		},


		randomNumber: function(minValue, maxValue, decimals)
		{
			var number = minValue + (Math.random() * (maxValue - minValue));

			return typeof floatVal == "undefined" ? Math.round(number) : number.toFixed(decimals);
		},


		right: function(value, count)
		{
			return value.substr((String(value).length - count), count);
		},


		toBoolean: function(value)
		{
			var stringValue = String(value).toLowerCase();

			switch(stringValue)
			{
				case "true": case "yes": case "1": return true;
				case "false": case "no": case "0": return false;
				default: return Boolean(stringValue);
			}
		},


		trim: function(value)
		{
			return value.replace(/^\s*/, "").replace(/\s*$/, "");
		}
	};


	site.utils.format = 
	{
		currency: function(currencyValue)
		{
			currencyValue = String(currencyValue).replace(/[^0-9\.]/g,"");

			if (site.utils.is.number(String(currencyValue)))
			{
				if (site.utils.is.integer(String(currencyValue)) && String(currencyValue).length > 0)
				{
					currencyValue = currencyValue + ".00";
				}
				else if (site.utils.is.integer(String(currencyValue)) && String(currencyValue).length == 0)
				{
					currencyValue = currencyValue + "0.00";
				}
				
				else if (String(currencyValue).length - String(currencyValue).lastIndexOf(".") - 1 == 0)
				{
					currencyValue = currencyValue + "00";
				}
				else if (String(currencyValue).length - String(currencyValue).lastIndexOf(".") - 1 == 1)
				{
					currencyValue = currencyValue + "0";
				}
				
				else if (String(currencyValue).length - String(currencyValue).lastIndexOf(".") - 1 > 2)
				{
					var cutoff = String(currencyValue).length - String(currencyValue).lastIndexOf(".") - 1 - 2;
					
					currencyValue = String(currencyValue).substr(0,String(currencyValue).length - cutoff);
				}
			}

			return currencyValue;
		},


		phoneUS: function(value, removeCountryCode)
		{
			var countryCode = "";

			if (removeCountryCode == undefined)
			{
				removeCountryCode = true;
			}

			value = value.replace(/\D/g, "");

			if (removeCountryCode && Number(site.utils.left(value, 1)) == 1)
			{
				value = site.utils.right(value, value.length - 1);
			}
			else if (!removeCountryCode && Number(site.utils.left(value, 1)) == 1)
			{
				value = site.utils.right(value, value.length - 1);
				countryCode = "1-";
			}


			if (value.length == 7)
			{
				value = site.utils.insert(value, "-", 3);
			}
			else if (value.length >= 10)
			{
				if (value.length > 10)
				{
					value = site.utils.insert(value, " x", 10);
				}


				value = site.utils.insert(value, "-", 6);
				value = site.utils.insert(value, "-", 3);
				
				
				if (countryCode.length > 0)
				{
					value = countryCode + value;	
				}
			}


			return value;
		},


		titleCase: function(value, minWordLength)
		{
			if (minWordLength == undefined)
			{
				minWordLength = 3;	
			}


			// Clean up string
			value = site.utils.trim(value).replace(/\s/, " ");

			while (value.search(/  /) > -1)
			{
				value = value.replace(/  /, " ");	
			}


			// Loop through the words in the string
			var word = "";
			var wordArray = value.split(" ");
			var hyphenWord = "";
			var hyphenWordArray = [];
			var titleCasedString = "";


			for (var i = 0; i < wordArray.length; i++)
			{
				word = wordArray[i];


				// Minimum length is 1
				if (minWordLength == 1 && word.length == 1)
				{
					word = word.toUpperCase();	
				}


				// Word must meet minimum length requirement (except JR and SR)
				// Word can only be Letters and Hyphens
				else if (
							(word.length >= minWordLength && word.search(/[^a-zA-Z\-]/) == -1) ||
							word.toLowerCase() == "jr" ||
							word.toLowerCase() == "sr"
						)
				{
					word = site.utils.left(word, 1).toUpperCase() + site.utils.right(word, word.length - 1).toLowerCase();

					// Check for word with Hyphen
					if (word.search(/-/) > -1)
					{
						hyphenWord = "";
						hyphenWordArray = word.split("-");

						for (var j = 0; j < hyphenWordArray.length; j++)
						{
							// Append a hyphen before each word, after the 1st word has been added
							if (hyphenWord.length > 0)
							{
								hyphenWord += "-";
							}


							// If the word is long enough, title case it
							if (hyphenWordArray[j].length > 1)
							{
								hyphenWord += site.utils.left(hyphenWordArray[j], 1).toUpperCase() + site.utils.right(hyphenWordArray[j], hyphenWordArray[j].length - 1).toLowerCase();
							}
							else
							{
								hyphenWord += hyphenWordArray[j];	
							}
						}

						word = hyphenWord;
					}
				}


				if (titleCasedString.length > 0)
				{
					titleCasedString += " ";	
				}

				titleCasedString += word;
			}

			return titleCasedString;
		},


		titleCaseName: function(value, minWordLength)
		{
			var name = value.replace(/[^0-9a-zA-Z\s-]/g, "");

			name = this.titleCase(name, minWordLength);


			var wordArray = name.split(" ");


			// Roman Numeral is upper cased, if it is the last word
			if (wordArray.length > 1 && site.utils.is.romanNumeral(wordArray[wordArray.length - 1]))
			{
				wordArray[wordArray.length - 1] = wordArray[wordArray.length - 1].toUpperCase();
			}

			name = wordArray.join(" ");

			return name;
		}
	};


	site.utils.is = 
	{
		array: function(obj)
		{
			if (obj == undefined || obj == null || obj.constructor.toString().indexOf("Array") == -1)
			{
				return false;
			}
			
			return true;
		},


		boolean: function(value)
		{
			var stringValue = String(value).toLowerCase();

			switch(stringValue)
			{
				case "true": case "yes": case "1": return true;
				case "false": case "no": case "0": return true;
			}

			return false;
		},


		creditcard: function(value)
		{
			//trim whitespace before we validate
			value = site.utils.trim(value);


			if (value.length == 0)
			{
				return false;
			}


			var white_space = " -";
			var creditcard_string = "";
			var check_char;


			for (var i = 0; i < value.length; i++)
			{
				check_char = white_space.indexOf(value.charAt(i));
				
				if (check_char < 0)
				{
					creditcard_string += value.substring(i, (i + 1));
				}
			}


			if (creditcard_string.length < 13 || creditcard_string.length > 19)
			{
				return false;
			}


			if (creditcard_string.charAt(0) == "+")
			{
				return false;
			}


			if (!this.integer(creditcard_string))
			{
				return false;
			}


			var doubledigit = creditcard_string.length % 2 == 1 ? false : true;
			var checkdigit = 0;
			var tempdigit;


			for (var i = 0; i < creditcard_string.length; i++)
			{
				tempdigit = eval(creditcard_string.charAt(i));

				if (doubledigit)
				{
					tempdigit *= 2;
					checkdigit += (tempdigit % 10);

					if ((tempdigit / 10) >= 1.0)
					{
						checkdigit++;
					}
		
					doubledigit = false;
				}
				else
				{
					checkdigit += tempdigit;
					doubledigit = true;
				}
			}	

			return (checkdigit % 10) == 0 ? true : false;
		},


		date: function(value)
		{
			// Returns true if value is a date format
			// otherwise returns false

			// Determine if the splitting character is: 
			// "/" - mm/dd/yyyy  -or-
			// "." - mm.dd.yyyy  -or-
			// "-" - mm-dd-yyyy
			var isplit = value.indexOf('/');
			var splitchr = "/";

			if (isplit == -1)
			{
				isplit = value.indexOf('.');
				splitchr = ".";
			}

			if (isplit == -1)
			{
				isplit = value.indexOf('-');
				splitchr = "-";
			}

			if (isplit == -1 || isplit == value.length)
			{
				return false;
			}

			var element1 = value.substring(0, isplit);


			// check for yyyy-mm-dd format
			if (element1.length == 4)
			{
				var sYear = value.substring(0, isplit);
				isplit = value.indexOf(splitchr, isplit + 1);

				if (isplit == -1 || (isplit + 1 ) == value.length)
				{
					return false;
				}

				var sMonth = value.substring((sYear.length + 1), isplit);
				var sDay = value.substring(isplit + 1);
			
			} 
			else
			{
				var sMonth = value.substring(0, isplit);
				isplit = value.indexOf(splitchr, isplit + 1);

				if (isplit == -1 || (isplit + 1 ) == value.length)
				{
					return false;
				}

				var sDay = value.substring((sMonth.length + 1), isplit);
				var sYear = value.substring(isplit + 1);
			}


			// check month
			if (!this.integer(sMonth) || !this.inRange(sMonth, 1, 12))
			{
				return false;
			}


			// check year
			else if (!this.integer(sYear) || (sYear.length != 1 && sYear.length != 2 && sYear.length != 4) || !this.inRange(sYear, 0, 9999))
			{
				return false;	
			}


			// check day
			else if (!this.integer(sDay) || !this.day(sYear, sMonth, sDay))
			{
				return false;	
			}


			else
			{
				return true;	
			}
		},


		day: function(year, month, day)
		{
			var maxDay = 31;

			if (month == 4 || month == 6 || month == 9 || month == 11)
			{
				maxDay = 30;
			}
			else if (month == 2)
			{
				if (year % 4 > 0)
				{
					maxDay = 28;
				}
				else if (year % 100 == 0 && year % 400 > 0)
				{
					maxDay = 28;
				}
				else
				{
					maxDay = 29;
				}
			}

			return this.inRange(day, 1, maxDay);
		},


		// must have commas but doesn't need $
		dollarFormat: function(dollar_value)
		{
			var regex = /^\${0,1}(([1-9]{1}\d{0,2}){1}(\,\d{3}){0,}|0){0,1}\.\d{2}$/;
			return regex.test(dollar_value);
		},


		email: function(value)
		{
			return this.validRegex(site.utils.trim(value), /^[a-zA-Z_0-9-]+(\.[a-zA-Z_0-9-]+)*@([a-zA-Z_0-9-]+\.)+[a-zA-Z]{2,7}$/);
		},


		inNumberRange: function(value, min_value, max_value)
		{
			if (!this.number(value) || !this.number(value) || !this.number(value))
			{
				return false;	
			}

			value = Number(value);
			min_value = Number(min_value);
			max_value = Number(max_value);

			if (min_value != null)
			{
				if (value < min_value)
				{
					return false;
				}
			}
		
			if (max_value != null)
			{
				if (value > max_value)
				{
					return false;
				}
			}
		
			return true;
		},


		inRange: function(value, min_value, max_value)
		{
			return this.inNumberRange(value, min_value, max_value);
		},


		integer: function(value)
		{
			value = String(value);

			if (value.length == 0)
			{
				return true;
			}

			var decimal_format = ".";
			var check_char = value.indexOf(decimal_format);

			if (check_char == -1)
			{
				return this.number(value);
			}
			else
			{
				return false;
			}
		},


		// Ex. (9/2010)
		monthDate: function(value)
		{
			var monthPattern = /^[0-9]{1,2}\/[0-9]{4}$/;

			if (this.validRegex(value, monthPattern))
			{
				var dateArray = value.split("/");
				dateArray.splice(1, 0, "1");

				value = dateArray.join("/");
			}

			return this.date(value);
		},


		number: function(value)
		{
			if (value.length == 0)
			{
				return false;
			}


			var start_format = " .+-0123456789";
			var number_format = " .0123456789";
			var check_char;
			var decimal = false;
			var trailing_blank = false;
			var digits = false;


			check_char = start_format.indexOf(value.charAt(0));


			if (check_char == 1)
			{
				decimal = true;
			}
			else if (check_char < 1)
			{
				return false;
			}


			for (var i = 1; i < value.length; i++)
			{
				check_char = number_format.indexOf(value.charAt(i));

				if (check_char < 0)
				{
					return false;
				}
				else if (check_char == 1)
				{
					if (decimal)
					{
						return false;
					}
					else
					{
						decimal = true;
					}
				}
				else if (check_char == 0)
				{
					if (decimal || digits)
					{
						trailing_blank = true;
					}
				}
				else if (trailing_blank)
				{
					return false;
				}
				else
				{
					digits = true;
				}
			}	
		
			return true;
		},


		/**
		 * validate that the value is formatted as a telephone correctly
		 * This pattern matches any US Telephone Number.
		 * This regular expression excludes the first number, after the area code,from being 0 or 1;
		 * it also allows an extension to be added where it does not have to be prefixed by 'x'.
		 *
		 * Matches: 
		 * 617.219.2000 
		 * 219-2000
		 * (617)283-3599 x234
		 * 1(222)333-4444
		 * 1 (222) 333-4444
		 * 222-333-4444
		 * 1-222-333-4444
		 * Non-Matches: 
		 * 44-1344-458606
		 * +44-1344-458606
		 * +34-91-397-6611
		 * 7-095-940-2000
		 * +7-095-940-2000
		 * +49-(0)-889-748-5516
		*/
		phoneUS: function(value)
		{
			return this.validRegex(site.utils.trim(value), /^(((1))?[ ,\-,\.]?([\\(]?([1-9][0-9]{2})[\\)]?))?[ ,\-,\.]?([^0-1]){1}([0-9]){2}[ ,\-,\.]?([0-9]){4}(( )((x){0,1}([0-9]){1,5}){0,1})?$/);
		},


		romanNumeral: function(value)
		{
			var romanNumeralPattern = /^M?M?M?(CM|CD|D?C?C?C?)(XC|XL|L?X?X?X?)(IX|IV|V?I?I?I?)$/;

			value = value.toUpperCase();

			return this.validRegex(value, romanNumeralPattern);
		},


		ssn: function(value)
		{
			return this.validRegex(site.utils.trim(value), /^[0-9]{3}(-)[0-9]{2}(-)[0-9]{4}$/);
		},


		time: function(value)
		{
			value = value.replace(/^\s+/,'').replace(/\s+$/,'');

			// replace the {t'..'} format around the timestamp if it exists
			value.replace(/{t \'/, '').replace(/'}/, '');

			return this.validRegex(value, /^(([0-1]?[0-9]|[2][1-4]):([0-5]?[0-9])(:[0-5]?[0-9])?).?([AP]M|[AP]m|[ap]m|[ap]M)?$/);
		},


		url: function(value)
		{
			var regexPattern = "^((http|https|ftp|file)\:\/\/([a-zA-Z0-0]*:[a-zA-Z0-0]*(@))?";
			regexPattern += "[a-zA-Z0-9-\.]+(\.[a-zA-Z]{2,3})?(:[a-zA-Z0-9]*)?\/?";
			regexPattern += "([a-zA-Z0-9-\._\?\,\'\/\+&amp;%\$#\=~])*)";
			regexPattern += "|((mailto)\:[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,7})|((news)\:[a-zA-Z0-9\.]*)$";
			regexPattern = new RegExp(regexPattern);

			return this.validRegex(site.utils.trim(value.toLowerCase()), regexPattern);
		},


		uuid: function(value)
		{
			return this.validRegex(site.utils.trim(value), /[A-Fa-f0-9]{8,8}-[A-Fa-f0-9]{4,4}-[A-Fa-f0-9]{4,4}-[A-Fa-f0-9]{16,16}/);
		},


		validRegex: function(value, regexPattern)
		{
			return regexPattern.test(value);
		},


		zipcode: function(value)
		{
			return this.validRegex(site.utils.trim(value), /^([0-9]){5,5}$|(([0-9]){5,5}(-| ){1}([0-9]){4,4}$)/);
		}
	};
})(jQuery);


// Perform page load actions
jQuery(
	function()
	{
		$("button.ui").hover(
			function() 
			{
				$(this).addClass("ui-state-hover");
			}, 
			function() 
			{
				$(this).removeClass("ui-state-hover");
			}
		);


		$("#errorDialog").each(
			function(index, el)
			{
				var dialogOptions =
				{
					autoOpen: true,
					draggable: true,
					error: true,
					height: 200,
					maxHeight: 400,
					maxWidth: 700,
					minHeight: 100,
					minWidth: 150,
					modal: true,
					resizable: true,
					width: 500
				};

				site.utils.dialog(this.id, dialogOptions);
			}
		);


		$("#confirmDialog").each(
			function(index, el)
			{
				var dialogOptions =
				{
					autoOpen: true,
					draggable: true,
					height: 200,
					maxHeight: 400,
					maxWidth: 700,
					minHeight: 100,
					minWidth: 150,
					modal: true,
					resizable: true,
					width: 500
				};

				el.title = "<span class=\"ui-icon ui-icon-notice\" style=\"float: left; margin-right: 3px;\"> </span> " + el.title;

				site.utils.dialog(this.id, dialogOptions);
				$("#" + this.id).siblings("div.ui-dialog-titlebar").addClass("ui-state-highlight");
				$("#" + this.id).siblings("div.ui-dialog-titlebar").addClass("ui-state-confirm");
			}
		);
	}
);
