SC = {
	Sandbox: {},
	Util: {
		toInt: function (s) {
			var v = parseInt(s, 10); 
			return v;
		},
		isInt: function (s) {
			// Check that current character is number.
			if (((s < "0") || (s > "9"))) {
				return false;
			}
			else {
				return true;
			}
		},
		areInt: function (s) {
			var v;
			s = s.toString()
			for(var i = 0; i < s.length; i++) {   
				var c = s.charAt(i);
				if(this.isInt(c)) {
					v = true;
				}
				else {
					v = false;
					break;
				}
		    }
		    // All characters are numbers.
		    return v;
		},
		makeInt: function (s) {
			var i;
			var v = '';
		    s = s.toString()
			for (i = 0; i < s.length; i++) {   
				var c = s.charAt(i);
				if(this.isInt(c)) {
					v += c;
				}
			}
			return v;
		},
		isWhitespace: function (c) {
			if (c != " ") {
				return true;
			}
			else {
				return false;
			}
		},
		removeWhitespace: function (s) {
			var i;
		    var v = "";
		    // Search through a string's characters one by one.
		    // If character is not a whitespace, append to returnString.
		    for (i = 0; i < s.length; i++) {   
		        // Check that current character isn't whitespace.
		        var c = s.charAt(i);
				if(this.isWhitespace(c)) {
					v += c;
				}
		    }
		    return v;
		},
		checkDate: function (date1, date2, comp) {
			date1 = this.prepDate(date1);
			if(!date1) return false;
			date2 = this.prepDate(date2) ? this.prepDate(date2) : new Date();
			comp = (comp !== undefined) ? comp : '>';

			if(comp == '=' || comp == '==') {
				if(date1 == date2) return true;
			}
			else if(comp == '<') {
				if(date1 < date2) return true;
			}
			else if(comp == '!=') {
				if(date1 != date2) return true;
			}
			else { //default to greater than
				if(date1 > date2) return true;
			}
			return false;
		},
		prepDate: function (date) {
			var i;
			var arrNumDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
			if(!date) {
				return false;
			}
			else {
				var arr = date.split('/')
				for(i = 0; i < arr.length; i++) {
					arr[i] = parseInt(arr[i]);
				}
				date = new Date();

				if(arr.length == 1) {
					arr[2] = arr[0];
					arr[0] = 11;
					arr[1] = arrNumDays[arr[0]];
				}
				else if(arr.length == 2) {
					arr[2] = arr[1];
					arr[0] = arr[0] - 1;
					arr[1] = arrNumDays[arr[0]];
				}
				else if(arr.length == 3) {
					arr[0] = arr[0] - 1;
				}
				else {
					return false;
				}
				date.setFullYear(arr[2], arr[0], arr[1]);
				return date;
			}

		},
		setCss: function (element, params) {
			for(p in params) {
				$(element).css(p, params[p]);
			}
		},
		getWindowYOffset: function () {
			if(typeof( window.pageYOffset ) == 'number' ) {
				return window.pageYOffset;
			}
			else if( document.documentElement && ( document.documentElement.scrollTop) ) {
		    	//IE 6+ in 'standards compliant mode'
		  		return document.documentElement.scrollTop
			} 
			else if( document.body && ( document.body.scrollTop) ) {
		    	//IE 4 compatible
				return document.body.scrollTop;
			}

		},
		isVowell: function (s) {
			var arr = ['A', 'a', 'E', 'e', 'I', 'i', 'O', 'o', 'U', 'u']
			for(var i = 0; i < arr.length; i++) {
				if(s == arr[i]) {
					return true;
				}
			}
			return false;
		},		
		getPrefix: function (s) {
			s = s.charAt(0);
			if(this.isVowell(s)) {
				return 'an';
			}
			return 'a';
		},
		popUp: function () {
			
		},
		TextFitter: {
			fit: function (element, maxHeight, minFont) {
				this.fitHeight(element, maxHeight, minFont);
				this.fitWidth(element, maxHeight);				
			},
			fitHeight: function (element, maxHeight, minFont) {
				var minFont = (minFont != undefined) ? minFont : 6;
				minFont = SC.Util.areInt(minFont) ? minFont : 6;
				var height = $(element).attr('clientHeight');
				if(height > maxHeight) {
					var fontSize = $(element).css('font-size');
					fontSize = SC.Util.makeInt(fontSize);
					fontSize--;
					$(element).css('font-size', fontSize);
					height = $(element).attr('clientHeight');
					if(fontSize > minFont) {
						if(height > maxHeight) {
							return this.fitHeight(element, maxHeight, minFont);
						}
					}	
				}
				else {
					var space = maxHeight - height;
					if((space % 2) !== 0) {
						space++;
					}
					var margin = space / 2;
					height = maxHeight - margin;
					$(element).css('margin-top', margin);			
				}
			},
			fitWidth: function (element, maxHeight, padding) {
				var height = $(element).height();
				var width = $(element).width();
				var space = 10;
				if(height > maxHeight) {
					width = width - (-space);
					$(element).width(width + 'px');
				}
				else {
					width = width - space;
					$(element).width(width + 'px');
					return this.fitWidth(element, maxHeight);
				}
			}
		}
	},
	Forms: {
		Validate: {
			expDate: function (id) {
				var fieldValue = $("#Expiration_Date").val();

				if(!fieldValue) { //check for value
					return this.addError(id, 'value');
				}
				else if(!SC.Util.checkDate(fieldValue)) {
					return this.addError(id, 'exp');
				}
				else {
					return false;
				}
			},
			creditCardNumber: function (id) {
				var field;

				$("#" + id).val(SC.Util.makeInt($("#" + id).val()));

				var fieldValue = $("#" + id).val();

				if(!fieldValue) { //check for value
					return this.addError(id, 'value');
				}
				else if(!this.checkMinLength(fieldValue, 15)) { //check min length
					return this.addError(id, 'min');					
				}
				else if(!this.checkMaxLength(fieldValue, 17)) { //check max length
					return this.addError(id, 'max');
				}
				else {
					var valid = "0123456789"  // Valid digits in a credit card number
					var len = fieldValue.length;  // The length of the submitted cc number
					var iCCN = parseInt(fieldValue);  // integer of fieldValue
					var sCCN = fieldValue.toString();  // string of fieldValue
					sCCN = sCCN.replace (/^\s+|\s+$/g,'');  // strip spaces
					var iTotal = 0;  // integer total set at zero
					var bNum = true;  // by default assume it is a number
					var v = false;  // by default assume it is NOT a valid cc
					var temp;  // temp variable for parsing string
					var calc;  // used for calculation of each digit

					// Determine if the fieldValue is in fact all numbers
					for(var j=0; j<len; j++) {
						temp = "" + sCCN.substring(j, j+1);
						if (valid.indexOf(temp) == "-1"){v = false;}
					}

					// Determine if it is the proper length 
					if((len == 0)&&(v)) {  
						// nothing, field is blank AND passed above # check
						v = false;					
					}
					else {  
						// fieldValue is a number and the proper length - let's see if it is a valid card number
					  	if(len >= 15) {
							// 15 or 16 for Amex or V/MC
						    for(var i=len;i>0;i--) {
								// LOOP throught the digits of the card
								calc = parseInt(iCCN) % 10;  // right most digit
								calc = parseInt(calc);  // assure it is an integer
								iTotal += calc;  // running total of the card number as we loop - Do Nothing to first digit
								i--;  // decrement the count - move to the next digit in the card
								iCCN = iCCN / 10;                               // subtracts right most digit from fieldValue
								calc = parseInt(iCCN) % 10 ;    // NEXT right most digit
								calc = calc *2;                                 // multiply the digit by two
								// Instead of some screwy method of converting 16 to a string and then parsing 1 and 6 and then adding them to make 7,
								// I use a simple switch statement to change the value of calc2 to 7 if 16 is the multiple.
								switch(calc) {
								  	case 10: calc = 1; break;       //5*2=10 & 1+0 = 1
									case 12: calc = 3; break;       //6*2=12 & 1+2 = 3
									case 14: calc = 5; break;       //7*2=14 & 1+4 = 5
									case 16: calc = 7; break;       //8*2=16 & 1+6 = 7
									case 18: calc = 9; break;       //9*2=18 & 1+8 = 9
									default: calc = calc;           //4*2= 8 &   8 = 8  -same for all lower numbers
								}     
						    	iCCN = iCCN / 10;  // subtracts right most digit from ccNum
						    	iTotal += calc;  // running total of the card number as we loop
						  	}
							// END OF LOOP
					  		if ((iTotal%10)==0) {
								// check to see if the sum Mod 10 is zero
					    		v = true;  // This IS (or could be) a valid credit card number.
					  		}
							else {
					    		v = false;  // This could NOT be a valid credit card number
					    	}
						}
					}
					if(v) {
						return false;
					}
					else {
						return this.addError(id, 'The Credit Card Number is Invalid');
					}
				}			

				 // return v; // Return the results

			},
			phone: function (id) {
				var field;
				var fieldValue = $("#" + id).val();

				if(fieldValue.charAt(0) == '+') {
					id = id.replace(/\+/g, "011");
				}

				$("#" + id).val(SC.Util.makeInt($("#" + id).val()));

				var fieldValue = $("#" + id).val();

				if(!fieldValue) { //check for value
					field = this.addError(id, 'value');
				}
				else if(!this.checkMinLength(fieldValue, 10)) { //check min length
					field = this.addError(id, 'min');					
				}
				else if(!this.checkMaxLength(fieldValue, 25)) { //check max length
					field = this.addError(id, 'max');
				}
				else if(fieldValue.charAt(0) == '0') { //international phone
					return false;
				}
				else if(fieldValue.length == 11) { // local number must start with 1
					if(fieldValue.charAt(0) == '1') {
						return false;
					}
					else {
						field = this.addError(id, 'This is Not a Valid Phone Number');
					}
				}
				else { // local number must NOT start with 1
					if(fieldValue.charAt(0) == '1') {
						field = this.addError(id, 'This is Not a Valid Phone Number');
					}
					else if(!this.checkMaxLength(fieldValue, 10)) { //check max length
						field = this.addError(id, 'max');
					}
					else {
						return false;
					}
				}
				return field;						
			},
			email: function (id) {
				var field;
				var fieldValue = $("#" + id).val();
				if(!fieldValue) { //check for value 
					return this.addError(id, 'value');
				}
				else if(!this.checkMinLength(fieldValue, 3)) { //check min length 
					return this.addError(id, 'min');					
				}
				else if(!this.checkMaxLength(fieldValue, 99)) { //check max length
					return this.addError(id, 'max');
				}
				else {
					var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
					if(!filter.test(fieldValue)) {
						return this.addError(id, 'The Email Address You Entered is Invalid');
					}
					else {
						return false;
					}
				}
			},
			postalCode: function (id) {
				$("#" + id).val(SC.Util.makeInt($("#" + id).val()));
				var fieldValue = $("#" + id).val();

				if(!fieldValue) { //check for value
					field = this.addError(id, 'value');
				}
				else if(!this.checkMinLength(fieldValue, 5)) { //check min length
					field = this.addError(id, 'min');					
				}
				else if(!this.checkMaxLength(fieldValue, 10)) { //check max length
					field = this.addError(id, 'max');
				}
				else {
					return false;
				}
				return field;
			},
			password: function (id) {
				var field;
				var fieldValue = $("#" + id).val();
				if(!fieldValue) { //check for value
					return this.addError(id, 'value');
				}
				else if(!this.checkMinLength(fieldValue, 3)) { //check min length
					return this.addError(id, 'min');					
				}
				else if(!this.checkMaxLength(fieldValue, 99)) { //check max length
					return this.addError(id, 'max');
				}
				else {
					return false;
				}
			},
			passwordConfirm: function (id) {
				var password = $("#Password").val();
				var passwordConfirm = $("#Confirm_Password").val();
				if(password !== passwordConfirm) {
					return this.addError(id, 'match');
				}
				else {
					return false;
				}
			},
			textField: function (id) {
				var fieldValue = $("#" + id).val();
				if(!fieldValue) { //check for value
					return this.addError(id, 'value');
				}
				else if(!this.checkMinLength(fieldValue, 3)) { //check min length
					return this.addError(id, 'min');					
				}
				else if(!this.checkMaxLength(fieldValue, 99)) { //check max length
					return this.addError(id, 'max');
				}
				else {
					return false;
				}
			},
			textArea: function (id) {
				var fieldValue = $("#" + id).val();
				if(!fieldValue) { //check for value
					return this.addError(id, 'value');
				}
				else {
					return false;
				}
			},
			select: function (id) {
				var fieldValue = $("#" + id).val();
				if(!fieldValue) { //check for value
					return SC.Forms.Validate.addError(id, 'select');
				}
				else {
					return false;
				}
			},
			fields: function () {
				var v;
				var i = 0;
				var arr = [];
				$(".failed-validation").each(function () {
					$(this).removeClass("failed-validation");
				});
				$(".required").each(function () {
					if($(this).hasClass('generic')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.textField(id);
						if(v) {
							arr[i] = v;
							i++;
						}
					}
					else if($(this).hasClass('phone')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.phone(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('password')) {
						id = 'Password'; // $(this).attr('id');
						v = SC.Forms.Validate.password(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('passwordConfirm')) {
						id = 'Confirm_Password'; // $(this).attr('id');
						v = SC.Forms.Validate.passwordConfirm(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('zip')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.postalCode(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('select')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.select(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('credit_card_number')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.creditCardNumber(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('email')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.email(id);
						if(v) {
							arr[i] = v;
							i++;							
						}
					}
					else if($(this).hasClass('textarea')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.textArea(id);
						if(v) {
							arr[i] = v;
							i++;
						}
					}
					else if($(this).hasClass('exp-date')) {
						id = $(this).attr('id');
						v = SC.Forms.Validate.expDate(id);
						if(v) {
							arr[i] = v;
							i++;
						}
					}
				});
				if(arr.length > 0) {
					this.showErrors(arr)
					return false;
				}
				else {
					return true;
				}
			},
			checkMinLength: function (s, l) {
				if(s.length < l) {
					return false;
				}
				else {
					return true;
				}
			},
			checkMaxLength: function (s, l) {
				if(s.length > l) {
					return false;
				}
				else {
					return true;
				}

			},
			addError: function (id, type) {
				field = {
					id: null,
					error: null
				};
				$('#' + id + '_Label').addClass("failed-validation");
				var re = /_/g;
				field.id = id.replace(re, " ");
				if(type == 'value') {
					field.error = "This Field is Required";
				}
				else if(type == 'min') {
					field.error = "Your Input is Too Short";
				}
				else if(type == 'max') {
					field.error = "Your Input is Too Long";
				}
				else if(type == 'match') {
					field.error = "The Passwords Entered Do Not Match";
				}
				else if(type == 'select') {
					field.error = "Please Select an Option";
				}
				else if(type == 'exp') {
					field.error = "This Date has Expired";
				}
				else {
					field.error = type;
				}
				return field;
			},
			showErrors: function (arr) {
				if(arr) {
					if(arr.length == 1) {
						var errors = '<div class="error-box">There was an error when processing your request.<ul>';
					}
					else {
						var errors = '<div class="error-box">There were errors when processing your request.<ul>';
					}
					for(i = 0; i < arr.length; i++) {
						errors += '<li><b>' + $(arr[i]).attr('id') + '</b> - ' + $(arr[i]).attr('error') + '</li>';
					}
					errors += '</ul></div>';
				}
				$("#form-errors").html(errors);

				var targetOffset = $("#form-errors").offset().top;
				$('html,body').animate({scrollTop: targetOffset - 12}, 500);
			},
			isValid: function () {
				return this.fields();
			},
			console: function () {
				// document.write('stuff');
				document.write(this.isValid());
				return false;
			}
		}
	}
};
