/*****************************************
 * 
 * Summary: Core Application JavaScript Module 
 * 
 * Description: Handles all the core methods and properties for the application
 * 
 * Created: 2nd March 2009
 * 
 * Developer: Marc Donaldson
 * 
 *****************************************/


var core = function() {};

core = { 			
	
	expandDiv : function(inputElement) {		
		
		layoutObj = document.getElementById(inputElement+'_layer');
		hideObj = document.getElementById('hide_'+inputElement);
		showObj = document.getElementById('show_'+inputElement);
		
		if (layoutObj.className=='hide') {
			showObj.className = 'hide';
			hideObj.className = 'show';
			layoutObj.className = 'show';
		} else { 
			layoutObj.className = 'hide' ;
			showObj.className = 'show';
			hideObj.className = 'hide';
		}
		
	},
		
	/************** Checks to see if the string passed in is a numerical string */ 
	/******************************************************************************/
	
	isHex : function(inputString) {
		var hexRe = /^[0-9a-fA-F]+$/i; 
		return(hexRe.test(inputString));
	},
	
	isNumeric : function(inputString) {
		var numberRe = /^[0-9]+$/i;
		return(numberRe.test(inputString));
	},
	
	convertToFriendly : function(inputString) {
		inputString = inputString.replace(new RegExp( "/[^0-9a-zA-Z \- ]/", "gi" ),'');		
		inputString = inputString.replace(/#/g,'');
		inputString = inputString.replace(/\'/g,'-');
		inputString = inputString.replace(/ /g,'-');
		inputString = inputString.replace(/--/g,'-');
		
		return(inputString.toLowerCase());
	},
	
	/************** Checks to see if the string passed in is a telephone number */ 
	/******************************************************************************/
		
	isTelephone : function(inputString) {
		return(this.isTelephoneLocal(inputString,"English (UK)"));
	},
	
	/************** Checks to see if the string passed in is a telephone number */ 
	/******************************************************************************/
		
	isFriendlyUrl : function(inputString) {	
		var friendlyRe = /^[0-9a-zA-Z-_]+$/i;
		return(friendlyRe.test(inputString));
	},
	
	/************** Checks to see if the string passed in is a telephone number */ 
	/******************************************************************************/
		
	isTelephoneLocal : function(inputString,inputCountry) {	
		var telephoneRe = /^[0-9 ]+$/i;
		switch(inputCountry) {		
			case "English (UK)":
			default:
				
				break;		
		}
		return(telephoneRe.test(inputString));
	},
	
	/************** Checks to see if the string passed in is an ip address */
	/******************************************************************************/
	
	isIP : function(inputString) {
		var ipRe = /^(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)+$/i;		
		return(ipRe.test(inputString));		
	},
	
	/************** Checks to see if the string passed in is an web address */
	/******************************************************************************/
	
	isWebAddress : function(inputString) {
		var webRe = /^\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+$/i		
		return(webRe.test(inputString));		
	},
	
	/************** Checks to see if the string passed in is an email address */ 
	/******************************************************************************/
	
	isEmail : function(inputString) {
		var emailRe = /^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(info|name|mobi))$/i;
		return(emailRe.test(inputString));		
	},
	
	/************** Checks to see if the string passed in is a decimal string */ 
	/*******************************************************************************/
	 
	isDecimal : function(inputString) {
		
		var notNumberPatternRe = /[^0-9.-]/i;
        var twoDotPatternRe = /[0-9]*[.][0-9]*[.][0-9]*/i;
        var twoMinusPatternRe = /[0-9]*[-][0-9]*[-][0-9]*/i;
        var numberPatternRe = /^(([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$)|(([-]|[0-9])[0-9]*$)/i;
      
        return(!notNumberPatternRe.test(inputString) &&
                !twoDotPatternRe.test(inputString) &&
                !twoMinusPatternRe.test(inputString) && 
                numberPatternRe.test(inputString));
		
	},
	
	/************** Checks to see if the string passed in is a date string and converts to date object */  
	/***************************************************************************************************/
	 
	convertToDate : function(inputString) {			
		
		var shortMonthNames = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Nov","Dec"];
		var longMonthNames = ["January","February","March","April","May","June","July","August","September","November","December"];
		
		/* 1st Jan 2009 or 1st January 2009 */		
		var fullNormalDate = /((\b2?(1st|2nd|3rd|[4-9]th)|(2|3)0th|31st|1\dth\b) (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Jul(y)?|Jun(e)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|(Nov|Dec)(ember)?) ([0-9]{4}))/i;
		
		/* Jan 1st 2009 or January 1st 2009  */
		var fullMonthDate = /(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Jul(y)?|Jun(e)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|(Nov|Dec)(ember)?) ((\b(2|3)?(1st|2nd|3rd|[4-9]th)|(2|3)0th|1\dth\b) ([0-9]{4}))/i;				
		
		/* Jan 1 2009 or January 1 2009  or 1 Jan 2009 or 1 January 2009 */
		var fullDateWithoutSuffix = /((\b2?([1-9]|0[1-9])|(2|3)0|31|1\d\b) (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Jul(y)?|Jun(e)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|(Nov|Dec)(ember)?) ([0-9]{4}))/i;				
		var fullMonthDateWithoutSuffix = /(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Jul(y)?|Jun(e)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|(Nov|Dec)(ember)?) ((\b2?([1-9])|(2|3)0|31|1\d\b) ([0-9]{4}))/i;
		
		/* 01/01/2009 or 01-01-2009 */
		var standardDateRe = /^(([1-9]|0[1-9]|[12][0-9]|3[01])[- \/.]([1-9]|0[1-9]|1[012])[- \/.]([0-9]{4}))+$/i;
				
		var daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];		
		
		var dayPos = 0;
		var monthPos = 0;
		var yearPos = 0;
		var dateType = 0;
		var dateMatches = null;
		
		if (fullNormalDate.test(inputString)) {			
			dateMatches = fullNormalDate.exec(inputString);
			dateType = 1;
			dayPos = 2;
			monthPos = 5;
			yearPos = 18;
		}		
		else if (fullMonthDate.test(inputString)) {			
			dateMatches = fullMonthDate.exec(inputString);
			dateType = 2;
			dayPos = 15;
			monthPos = 1;
			yearPos = 19;
		}		
		else if (standardDateRe.test(inputString)) {			
			dateMatches = standardDateRe.exec(inputString);
			dateType = 3;
			dayPos = 2;
			monthPos = 3;
			yearPos = 4;
		} else if (fullDateWithoutSuffix.test(inputString)) {
			dateMatches = fullDateWithoutSuffix.exec(inputString);
			dateType = 2;
			dayPos = 2;
			monthPos = 5;
			yearPos = 18;
		} else if (fullMonthDateWithoutSuffix.test(inputString)) {
			dateMatches = fullMonthDateWithoutSuffix.exec(inputString);
			dateType = 1;
			dayPos = 15;
			monthPos = 1;
			yearPos = 18;
		} else {
			return(null);
		}
		
	    if (dateMatches!=null) {	    	
	    	var numCheckRe = /\D/g;
	    		    		    	
	    	var yearDate = Number(dateMatches[yearPos]);
	    	var monthDate = dateMatches[monthPos];
	    	var dayDate = Number(dateMatches[dayPos].replace(numCheckRe,''));
	    	   		
	    	if (yearDate%4==0) { daysInMonth[1] = 29; }
	    	
	    	if (dateType<3) { 
	    		switch(monthDate.toLowerCase().substring(0,3))
	    		{
	    			case "jan": monthDate = 1; break;
	    			case "feb": monthDate = 2; break;
	    			case "mar": monthDate = 3; break;
	    			case "apr": monthDate = 4; break;
	    			case "may": monthDate = 5; break;
	    			case "jun": monthDate = 6; break;
	    			case "jul": monthDate = 7; break;
	    			case "aug": monthDate = 8; break;
	    			case "sep": monthDate = 9; break;
	    			case "oct": monthDate = 10; break;
	    			case "nov": monthDate = 11; break;
	    			case "dec": monthDate = 12; break;
	    		}
	    	}
	    	
	    	if (Number(monthDate)>=1) { monthDate = Number(monthDate)-1; }
	    	
	    	var maxDays = daysInMonth[monthDate];
	    	
	    	if (Number(dayDate) > Number(maxDays)) { return(null); }
	    	
	    	var dateTest = new Date(yearDate,monthDate,dayDate);
	    	
	    	if (!isNaN(dateTest)) {
	    		
	    		actualDateMonth = dateTest.getMonth();
	    		
    			if (actualDateMonth==monthDate) { return(dateTest); }
	    	}	    	
	    	
	    	return(null);
	    }
		
	    return(null);
		
	},
	
	/************** Checks to see if the string passed in is a date string */  
	/******************************************************************************/
	 
	isDate : function(inputString) {			
		
		if (this.convertToDate(inputString)!=null) {
			return(true);
		}
		return(false);
	},
	
	/************** Checks to see if the string passed in is an ip address */
	/******************************************************************************/
	
	focusField : function(inputFieldName) {
	
		if (document.getElementById(inputFieldName)) {
			document.getElementById(inputFieldName).focus();
		}
	},
	
	
	 
	/************** Validates a form element to data type assigned */  
	/******************************************************************************/
	
	validateFormField : function(inputDataType,inputElement) {
		return(this.validateField(inputDataType,inputElement,false));
	},
	
	/************** Validates to see if both elements passed in match  */  
	/******************************************************************************/
	
	validateConfirmField : function(inputDataType,inputElementConfirm,inputElement,inputState) {
		
		var fieldState = false;
		var elementToConfirm = document.getElementById(inputElementConfirm);
		
		if (!this.validateField(inputDataType,inputElement,inputState) || 
			!this.validateField(inputDataType,elementToConfirm,inputState)) {
			
			return(false);			
		}		
		
		if (elementToConfirm.value == inputElement.value) { fieldState=true; }

		if (elementToConfirm.value == inputElement.value && 
			inputElement.value == '' && inputState == false) { return(fieldState); }
		
		if (fieldState) {
			//inputElement.className='ok';
		} else {
			//inputElement.className='error';
		}
		
		
		return(fieldState);
	},	
	
	/************** Validates a form element to data type assigned */  
	/******************************************************************************/
	
	validateField : function(inputDataType,inputElement,inputRequired,inputFunc) {
		
		try { 
			var fieldState = false;
			if (inputElement!=null && inputElement.value.length>0) {
				switch(inputDataType.toLowerCase()) {
					case "percentage": 
							if (this.isDecimal(inputElement.value)) {
								fieldState = true;
							}			
							if (Number(inputElement.value)>100) {
								fieldState = false;
							}
						break;
					case "hex":
						if (this.isHex(inputElement.value)) {
							fieldState = true;
						}
						break;
					case "friendlyurl":
						if (this.isFriendlyUrl(inputElement.value)) {
							fieldState = true;
						}
						break;
					case "telephone":
						if (this.isTelephone(inputElement.value)) {
							fieldState = true;
						}
						break;
					case "currency":
						if (this.isDecimal(inputElement.value)) {
							fieldState=true;
						}
						break;
					case "numeric":				
						if(this.isNumeric(inputElement.value)) {
						    fieldState=true;
						} 
						break;
					case "date":
						if(this.isDate(inputElement.value)) {
							fieldState=true;
						}
						break;
					case "url":
					case "web":
					case "web_address":
						if (this.isWebAddress(inputElement.value)) {
							fieldState=true;
						}
						break;
					case "ip":
					case "ip_address":
						if (this.isIP(inputElement.value)) {
							fieldState=true;
						}
						break;
					case "email_address":
					case "email":
						if (this.isEmail(inputElement.value)) {
							fieldState=true;
						}
						break;
					default:
						fieldState = true;
						break;
				}
			} else {
				fieldState = true;
			}
					
			if (inputElement!=null && inputElement.value.length<1 && inputRequired) {
				fieldState = false;
			}
			
			if (inputFunc!=null) {
				fieldState = inputFunc;
			}
			
			if (inputElement!=null && inputElement.value.length<1 && !inputRequired) {
				//inputElement.className='';
				return(true);
			}
					
			return(fieldState);
		} catch(e) {
			alert(e);
		}
		return(true);
	},
	
	
	/************** Sets the validation state of a HTML element */  
	/******************************************************************************/
	
	setFieldState : function(inputElement,inputState) {
		if (inputState) {
			//inputElement.className='ok';
		} else {
			//inputElement.className='error';
		}
	},
	
	/************** Enumerates through all FORM elements stored in array and validates to see */    
	/************** if the format corresponds to data type assigned */  
	/******************************************************************************/
	
	validateForm : function(inputValidator) {
		
		//TODO: Add code to either parse an XML object or JavaScript defined array 
		
	},			

	showOverlay : function(inputElement,inputWidth,inputHeight) {
		
		if (document.getElementById('page_overlay_hidden') &&
			document.getElementById('page_overlay') &&
			document.getElementById('page_overlay_content')) {
			
			document.getElementById('page_overlay_hidden').className="show overlay_hidden";
			document.getElementById('page_overlay').className="show overlay";
			document.getElementById('page_overlay_content').className="show bg_white overlay_content";
			
			document.getElementById('page_overlay').style.top = ((get_viewport_size()[1]-(inputHeight+20))/2)+'px';
			document.getElementById('page_overlay').style.left = ((get_viewport_size()[0]-(inputWidth+20))/2)+'px';
			document.getElementById('page_overlay').style.width = (inputWidth+20)+'px';
			document.getElementById('page_overlay').style.height = (inputHeight+20)+'px';
			
			document.getElementById('page_overlay_content').style.top = ((get_viewport_size()[1]-inputHeight)/2)+'px';
			document.getElementById('page_overlay_content').style.left = ((get_viewport_size()[0]-inputWidth)/2)+'px';
			document.getElementById('page_overlay_content').style.width = inputWidth+'px';
			document.getElementById('page_overlay_content').style.height = inputHeight+'px';
			
			document.getElementById('page_overlay_hidden').onclick = function() {
				document.getElementById('page_overlay').className="hide overlay";
				document.getElementById('page_overlay_content').className="hide overlay_content";
				document.getElementById('page_overlay_hidden').className="hide overlay_hidden";															
			}
			
			if (document.getElementById(inputElement))
			{
				document.getElementById('page_overlay_content').innerHTML =  document.getElementById(inputElement).innerHTML;
			}
		}
		
	},
	
	hideOverlay : function() {
		
		if (document.getElementById('page_overlay_hidden') &&
			document.getElementById('page_overlay') &&
			document.getElementById('page_overlay_content')) {
			
			document.getElementById('page_overlay_hidden').className="hide overlay_hidden";
			document.getElementById('page_overlay').className="hide overlay";
			document.getElementById('page_overlay_content').className="hide overlay_content";
			
			
		}	
	},
	
	hideError : function(elem,parentElem,timerStatus) {

		if (typeof timerStatus == 'undefined') {
			var t = setTimeout(function() { 
				var errorID = elem.id+'_status_tooltip';		

				var errorP = document.getElementById(errorID);
				$(errorP).fadeOut('slow', function() {
					if (document.getElementById(errorID)) { parentElem.removeChild(document.getElementById(errorID)); }
	    		});
	
			},5000);
		} else {
			var errorID = elem.id+'_status_tooltip';				
			if (document.getElementById(errorID)) { parentElem.removeChild(document.getElementById(errorID)); }
		}
	},
	
	showError : function(elem,errorMessage,pos,parentElem) {
		if (jQuery) {
			
			if (typeof parentElem == 'undefined') { parentElem = document.body; }
			if (typeof elem == 'String') { elem = document.getElementById(elem); }	
			if (typeof parentElem == 'String') { parentElem = document.getElementById(parentElem); }	
			
			var parentPos = $(parentElem).offset();
			var elemPos = $(elem).offset();
				elemPos.top = elemPos.top - parentPos.top;
				elemPos.left = elemPos.left - parentPos.left;	 	
				
			var elemWidth = $(elem).outerWidth();
			var elemHeight = $(elem).outerHeight();
			var prevError = document.getElementById(elem.id+'_status_tooltip');
			
			if (prevError) { parentElem.removeChild(prevError); }
			
			var errorP = document.createElement("p");
			var errorPArrow = document.createElement("span");	
				errorPArrow.className = pos;
				
				errorP.className="errorTooltip";
				errorP.style.zIndex = 210000;
				errorP.style.display = 'none';
				errorP.style.visibility = 'visible';		
				errorP.id = elem.id+'_status_tooltip';
				errorP.appendChild(document.createTextNode(errorMessage));		
		
				errorP.appendChild(errorPArrow);	
		
				parentElem.appendChild(errorP);		
			
			var elemErrorWidth = $(errorP).width();
			var elemErrorHeight = $(errorP).height();	
				
			var xPos = (elemWidth-elemErrorWidth)/2;
			if (elemWidth<elemErrorWidth) { xPos = (elemErrorWidth-elemWidth)/2; }
		
			var yPos = (elemHeight-elemErrorHeight)/2; 
			if (elemHeight<elemErrorHeight) { yPos = (elemErrorHeight-elemHeight)/2; }		
			
			switch(pos) {
				case 'right':
					errorP.style.left = (elemPos.left+elemWidth)+'px';
					errorP.style.top = (elemPos.top-yPos)+'px';	
				break;
				default:
					errorP.style.left = (elemPos.left+xPos)+'px';					
					errorP.style.top = (elemPos.top+elemHeight)+'px';	
				break;
			}
			
			$(errorP).fadeIn('slow', function() {
	        	core.hideError(elem,parentElem);
    		});
			
			return(true);
		
		} 
		return(true);
	}

	
}


