/**
 * @website: subaru.com
 * @type: General purpose functions
 * @dependencies: requires jQuery 1.6.1
 * @date: 07.28.11
 * @author: Ronny Fallas
 * 
 * 
 * 0.0 Global Variables
 * 1.0 Instantiate - $(function() {}
 * 2.0 create_
 * 3.0 delete_
 * 4.0 format_
 * 5.0 get_
 * 6.0 instantiate_
 * 7.0 is_
 * 8.0 submit_
 * 9.0 update_
 * 10.0 validate_
 * 11.0 print_
 * 12.0 SMALL extensions
 * 13.0 ajax_
 * 14.0 DOM Behavior - (addbehavior_ or removebehavior_)
*/

//----------------------------------------------------------------
//0.0 Global Variables
//-----------------------------------------------------------------

// distance dropdown
var distanceFrom = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];

// min and max date allowed by the site, mainly used for datepicker components.
var minDate = new Date(1995, 1 - 1, 1);
var maxDate = new Date(2012, 1 - 1, 1);

// create months object
var months = [
	{monthNumber: "01", monthName: "January", monthAbbrev: "Jan"},
	{monthNumber: "02", monthName: "February", monthAbbrev: "Feb"},
	{monthNumber: "03", monthName: "March", monthAbbrev: "Mar"},
	{monthNumber: "04", monthName: "April", monthAbbrev: "Apr"},
	{monthNumber: "05", monthName: "May", monthAbbrev: "May"},
	{monthNumber: "06", monthName: "June", monthAbbrev: "Jun"},
	{monthNumber: "07", monthName: "July", monthAbbrev: "Jul"},
	{monthNumber: "08", monthName: "August", monthAbbrev: "Aug"},
	{monthNumber: "09", monthName: "September", monthAbbrev: "Sept"},
	{monthNumber: "10", monthName: "October", monthAbbrev: "Oct"},
	{monthNumber: "11", monthName: "November", monthAbbrev: "Nov"},
	{monthNumber: "12", monthName: "December", monthAbbrev: "Dec"},
];

// years - used for Brochures
var years = [2012,2011,2010,2009,2008,2007,2006,2005];
/**
 * Keeps 2 of the most often used ajax type, GET and POST.
 * these are used in the ajax_call function as second parameter.
 * 
 * You can use it as ajaxType.GET; or ajaxType.POST;
 */
var ajaxType = function(){}
ajaxType.GET = "GET";
ajaxType.POST = "POST";
/**
 * @description Returns the ajaxType representation of the parameter.
 * This functions has sense only at ajax_call function.
 * @param value Used to evaluate if is a valid ajaxType representation.
 * ajaxType.GET is return as default if the parameter doesn't match any ajaxType representation. 
 */
ajaxType.getType = function(value){
	for (key in ajaxType) {
		if (value == ajaxType[key]) {
			return (ajaxType[key]);
		}
	}
	return ajaxType.GET;
}
/**
 * Keeps the possibles return type supported by ajax(JQuery).
 * these are used in the ajax_call function as third parameter.
 * 
 * You can use it as ajaxDataType.XML, ajaxDataType.HTML, etc.
 */
var ajaxDataType = function(){}
ajaxDataType.XML = "xml";
ajaxDataType.HTML = "html";
ajaxDataType.SCRIPT = "script";
ajaxDataType.JSON = "json";
ajaxDataType.JSONP = "jsonp";
ajaxDataType.TEXT = "text";
/**
 * @description Returns the ajaxDataType representation of the parameter.
 * This functions has sense only at ajax_call function.
 * @param value Used to evaluate if is a valid ajaxDataType representation.
 * ajaxDataType.XML is return as default if the parameter doesn't match any ajaxDataType representation. 
 */
ajaxDataType.getType = function(value){
	for (key in ajaxDataType) {
		if (value == ajaxDataType[key]) {
			return (ajaxDataType[key]);
		}
	}
	return ajaxDataType.XML;
}
/**
 * Keeps the 2 possibles Content Type states expected for a POST request.
 * these are used in the ajax_call function as 4th parameter.
 * 
 * You can use it as ajaxContentType.MULTIPART_FORM_DATA or ajaxContentType.APP_FORM_URL_ENCODED.
 */
var ajaxContentType = function(){}
ajaxContentType.MULTIPART_FORM_DATA = "multipart/form-data";
ajaxContentType.APP_FORM_URL_ENCODED = "application/x-www-form-urlencoded";
/**
 * @description Returns the ajaxContentType representation of the parameter.
 * This functions has sense only at ajax_call function.
 * @param value Used to evaluate if the parameter value is an ajaxDataType valid representation.
 * ajaxContentType.APP_FORM_URL_ENCODED is return as default if the parameter doesn't match any. 
 */
ajaxContentType.getType = function(value){
	for (key in ajaxContentType) {
		if (value == ajaxContentType[key]) {
			return (ajaxContentType[key]);
		}
	}
	return ajaxContentType.APP_FORM_URL_ENCODED;
}


//-----------------------------------------------------------------
//2.0 create_
//-----------------------------------------------------------------
/**
 * @description create a Cookie.
 */
function create_cookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

/**
 * @description Adds an error message box to the specified element
 * @param inputId: id of the element
 * @param topMessage: Message title, "" no title, "default" = This field cannot be left blank.
 * @param mainMessage: Main or body message of the error
 */
function create_errorMessage(inputId, topMessage, mainMessage) {
	$("#error_"+inputId+", div.errorClear").remove();
	
	if(topMessage == "default"){
		topMessage = "This field cannot be left blank.";
	}
	
	$("#"+inputId).errorMessage({
		containerId: inputId,
		messageMain: mainMessage,
		messageTop: topMessage
	});
}

/**
 * @description Returns the HTML to be appended to a select element with all the US states
 * 
 * @param myState State to be selected as default option. Two-letters abbreviation
 * @param defaultText: Default text when there is no selection
 * 
 * @return HTML with the states eg. <option value="AB">state</option>
 */
function create_stateOptions(myState, defaultText) {
	if (myState === undefined) { myState = ''; }
	if (defaultText === undefined) { defaultText = "Select a State"; }
	var createStates = usStates;
	var options = "<option value=''>" + defaultText + "</option>";
	$(createStates).each(function() {
		var sAbbrev = this.stateAbbrev;
		var sName = this.stateName;
		if (sAbbrev == myState) {
			options += "<option selected='selected' value='"+sAbbrev+"'>"+sName+"</option>";
		} else {
			options += "<option value='"+sAbbrev+"'>"+sName+"</option>";
		}
	});
	return options;
} // end create_stateOptions

//-----------------------------------------------------------------------------------
//3.0 delete_
//-----------------------------------------------------------------------------------

/**
 * @description "delete" a cookie, that is, overrides its value
 */
function delete_cookie(name){
	create_cookie(name,"",-1);
}

/**
 * @description Delete an error message box from the specified element
 * @param inputId: Element which error message will be removed
 */
function delete_errorMessage(inputId) {
	$("#error_"+inputId+", div.errorClear").remove();
	$("#"+inputId).removeClass("errorFocus");
}

//-----------------------------------------------------------------------------------
//4.0 format_
//-----------------------------------------------------------------------------------
/**
 * @description Return letter capitalized concatenated with string minus it's first letter
 * 
 * @param incomingString The string to be formatted
 * 
 * @return formatted string
 */
function format_capitalize(incomingString){
	//extract the first letter of str
	var letter = incomingString.substr(0,1);
	//return letter capitalised concatonated with str minus it's first letter
	var str = incomingString.toLowerCase();
	return letter.toUpperCase() + str.substr(1);
} // end format_capitalize

/**
 * @description Return a formatted currency value 
 * @param num Value to be formatted
 * @param noCents <boolean>true</boolean> no cents, <boolean>include cents in the format</boolean>
 * @returns {String} Format $00,000.00 | $00,000
 */
function format_currency(num, noCents) {
	num = num.toString().replace(/\$|\,/g,'');
	
	if(isNaN(num)){
		num = "0";
	}
	
	var sign = (num == (num = Math.abs(num)));
	num = Math.floor(num*100+0.50000000001);
	
	var cents = num%100;
	num = Math.floor(num/100).toString();
	
	if(cents<10){
		cents = "0" + cents;
	}
	
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++){
		num = num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));
	}
	
	return (((sign)?'':'-') + '$' + num + (noCents?'':'.' + cents) );
} // end format_currency

//-----------------------------------------------------------------------------------
//5.0 get_
//-----------------------------------------------------------------------------------
/**
 * @description retrieve a Cookie, if doesn't exists returns null.
 */

function get_cookie(name){	
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

/**
 * @description TODO document me
 */
function get_modelInfo(modelYear) {
	var yearAbbrev = modelYear.substr(2);
	var models;
	$.ajax({
		async : false,
		url : pathPrefix + 'vehicles/my' + yearAbbrev + '/models.xml',
		complete : function(xhr, textStatus) {
			models = xhr;
		}
	});
	return models;
} // end get_modelInfo

/**
 * @description Returns the vertical scroll position
 * 
 * @return ScrollTop: An integer indicating the new position to set the scroll bar to.
 */
function get_pageScroll() {
	var ScrollTop = document.body.scrollTop;
	if (ScrollTop == 0) {
		if (window.pageYOffset) ScrollTop = window.pageYOffset;
		else ScrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
	}
	return ScrollTop;
}

/**
 *	@description Returns true is the current loaded page was served through a secure (SSL) protocol.
 */
function isSecure(){
   return window.location.protocol == 'https:';
}

//-----------------------------------------------------------------------------------
//10.0 validate_
//-----------------------------------------------------------------------------------
/**
 * @description If the provided input is a valid email address
 * @returns isValid: <code>true</code> if the input is a valid email address  
 */
function validate_email(inputId, inputValue) {
	var isValid = validate.isValidEmail(inputValue);
	if (isValid) {
		delete_errorMessage(inputId);
	} else {
		var topMessage;
		var mainMessage;
		if (inputValue.length == 0) {
			topMessage = "default";
			mainMessage = "Please enter your email address.";
		} else {
			topMessage = "The email you entered is not valid.";
			mainMessage = "Please enter a valid email address.";
		}		
		create_errorMessage(inputId, topMessage, mainMessage);
	}
	return isValid;
}

/**
 * @description If the provided input matches the expect format for a password field
 * 
 * @param inputId: id of the password input
 * @param inputValue: User's provided value
 */
function validate_password(inputId, inputValue) {
	var isValid = validate.isWellFormedPassword(inputValue);
	if (inputValue.length == 0) {
		create_errorMessage(inputId, "default", "Please enter your password");
	}
	else {
		if (isValid && inputValue.length > 5) {
			delete_errorMessage(inputId);
		}
		else {
			create_errorMessage(inputId, "Invalid Password!", 'Password must be at least 6 characters long and contain only letters, numbers, ".", "@", "-", or "_"');
		}
	}
	return isValid;
}

/**
 * If both passwords match
 * @param inputId
 * @param pw1
 * @param pw2
 */
function validate_passwordConfirm(inputId, pw1, pw2) {
	if (pw2 != pw1)	{
		var topMessage = "The passwords you entered do NOT match!";
		var mainMessage = "Please re-enter your password.";

		$("#error_"+inputId+", div.errorClear").remove();
		$(this).errorMessage({
			containerId: inputId,
			messageTop: topMessage,
			messageMain: mainMessage
		});
	}else if (pw2.length == 0) {
		var topMessage = "You forgot to confirm your password!";
		var mainMessage = "Please re-enter your password.";

		$("#error_"+inputId+", div.errorClear").remove();
		$(this).errorMessage({
			containerId: inputId,
			messageTop: topMessage,
			messageMain: mainMessage
		});
	}else{
		$("#error_"+inputId+", div.errorClear").remove();
		$("#"+inputId).removeClass("errorFocus");
	}
}

/**
 * @description: Trims the input if exceeds the limit
 * 
 * @param: field Textarea to be validated
 * @param: maxlimit Max characters allowed
 */
function validate_textCounter(field, maxlimit) {
    if (field.value.length > maxlimit)  {// if too long...trim it!
        field.value = field.value.substring(0, maxlimit);
    }
}

//----------------------------------------------------------------
//11.0 print_
//-----------------------------------------------------------------
/**
 * @description: Just a wrapper to the native function window.print
 */
function print_Page(){
	window.print();
}

/**
 * I had to create this function because the page /my-subaru/my-account/service-coupon.html
 * calls a service through ajax and loads the coupons and the print link is pointing
 * to one function called printCoupon().   
 */
function printCoupon(){
	window.print();
}
//-----------------------------------------------------------------------------------
//12.0 Small Extensions
//-----------------------------------------------------------------------------------

/**
 * @description: Extension to get url variables
 * Usage:
 * var allVars = $.getUrlVars();
 * var byName = $.getUrlVars('name');
 * 
 * @return Parameter value, "" if doesn't exist
 */
$.extend({
  getUrlVars: function(){
	  var vars = [], hash;
	  var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
	  for(var i = 0; i < hashes.length; i++) {
		  hash = hashes[i].split('=');
		  vars.push(hash[0]);
		  vars[hash[0]] = hash[1];
	  }
	  return vars;
  },
  getUrlVar: function(name){
	  var urlVar = $.getUrlVars()[name];
	  if(undefined == urlVar){
		  return "";
	  }
	  return urlVar;
  }
});


//----------------------------------------------------------------
//13.0 Ajax Calls
//-----------------------------------------------------------------

/**
 * @description Makes an ajax call using the parameter given.
 * You can use this function to performs an ajax call and continue doing whatever you want,
 * when the server response comes back to you the successCallback or errorCallback functions
 * will be lunched depending what happens.
 * 
 * @param url The url used to ask for information or do some action as server side.
 * @param type The method through ajax will request the information, could be GET or POST 
 * 		  	   or you can use ajaxType.GET OR ajaxType.POST.
 * 			   If none is specified, ajaxType.GET will be used.
 * @param dataType The type of data that you're expecting back from the server.
 * 				   You can use some of the ajaxDataType variables.
 * 				   If none is specified, ajaxDataType.XML will be used. 
 * @param contentType The Content Type that the server is expecting.
 * 				   You can use some of the ajaxContentType variables.
 * 				   If none is specified, ajaxContentType.APP_FORM_URL_ENCODED will be used.
 * @param data key/value pair send to the server when we use a POST request. 
 * @param successCallback Callback function invoked when the server sends a success response.
 * @param errorCallback Callback function invoked when the server sends an error response.
 */
function ajax_call(url, type, dataType, contentType, data, successCallback, errorCallback) {
	type = ajaxType.getType(type);
	dataType = ajaxDataType.getType(dataType);
	contentType = ajaxContentType.getType(contentType);
	
	if(successCallback == null || !$.isFunction(successCallback)){
		successCallback = function(){};
	}
	if(errorCallback == null || !$.isFunction(errorCallback)){
		errorCallback = function(){};
	}
	$.ajax({
		type : type,
		url : url,
		async : true,
		dataType: dataType,
		contentType:contentType,
		data: data,
		success : successCallback,
		error : errorCallback
	});
};

//----------------------------------------------------------------
//14.0 DOM Behavior 
//-----------------------------------------------------------------

function addbehavior_allowNumbers(id){
	$(id).bind('keypress', function(e){
		return ( e.which!=8 && e.which!=0 && (e.which<48 || e.which>57)) ? false : true ;
	});
}

/**
 * Alphanumeric characters plus backspace, tab, delete.
 * @param id
 */
function addbehavior_allowAlphanumeric(id){
	id.bind('keypress', function(e){
		var key = e.which;
		var allowed = (key == 8 || key == 9 || key == 46 || (key >= 48 && key <= 57) || (key >= 65 && key <= 90) || (key >= 96 && key <= 105));
		
        if (!allowed) {            
            e.preventDefault();
        }
	});
}
