/**
 * javascript_common.js
 *
 * Javascript file
 * @description	Commonly used functions
 * @copyright 	2007 Kaaterskil Management, LLC
 * @version		070628
 * @package		includes.modules.javascript
 */
 
/*------------------------------------------------------------
ACTION FUNCTIONS
------------------------------------------------------------*/
/**
 * Confirms a delete record request.
 * @param v		The type of record to be deleted.
 */
function confirm_delete(v){
	var msg = 'Are you sure you want to delete this ' + v + '?';
	if(confirm(msg)){
		return true;
	}
	return false;
}
/**
 * Confirms a copy record request.
 * @param v		The type of record to be copied.
 */
function confirm_copy(v){
	var msg = 'Are you sure you want to copy this ' + v + '?';
	if(confirm(msg)){
		return true;
	}
	return false;
}

/**
 * Privilege alert
 */
function privilege_alert(){
	msg = 'That option is not available for this user.';
	alert(msg);
}

/**
 * Redirect
 */
function redirect(url){
	if(url != '' && url != 0){
		window.location.href = url;
	}
}
 
/*------------------------------------------------------------
DOM FUNCTIONS
------------------------------------------------------------*/
/**
 * Gets element from DOM tree
 * @param e		The html element id
 */
function find_DOM(e){
	if(document.getElementById){
		var r = document.getElementById(e);
	}else if(document.all){
		var r = document.all[e];
	}else if(document.layers){
		var r = document.layers[e];
	}
	return r;
}
 
/**
 * Returns an element's coordinates.
 * @param e		The html element's DOM id
 */
function get_coords(e){
	var r = {x:0, y:0}
	while(e){
		r.x += e.offsetLeft;
		r.y += e.offsetTop;
		e = e.offsetParent;
	}
	return r;
}

/**
 * Set element x/y coordinates
 * @param e			The html element
 * @params x, y		coordinate values
 */
function set_coords(e, x, y){
	var r = {x:0, y:0};
	if(e.offsetParent){
		r = get_coords(e.offsetParent);
	}
	e.style.left = (x - r.x) + 'px';
	e.style.top = (y - r.y) + 'px';
}
 
/**
 * Returns a tab's DOM tree.
 */
function get_tab(){
	var r = new Object();
	r.value = 'tab_1';
	var a = window.location.search.split(/[\?&]/);
	for(var i = 0; i < a.length; i++){
		var p = a[i].match(/^t\=(tab_[0-9])$/);
		if(p){
			r.value = p[1];
			break;
		}
	}
	r.dom = find_DOM(r.value + 'a');
	return r;
}

/**
 * Positions the footer element at the bottom of a window if
 * the html content does not extend that far. Positions the
 * footer below the content if it extends further.
 * @param id		The html id if the footer element.
 */
function set_footer(id){
	var sh	= 0;
	//Compute window size. Most browsers support
	//window.innerHeight. IE supports the others.
	var sh1	= window.innerHeight ? window.innerHeight : 0;
	var sh2	= document.documentElement ? document.documentElement.clientHeight : 0;
	var sh3	= document.body ? document.body.clientHeight : 0;
	
	//set to the highest number
	sh = sh1 > 0 ? sh1 : 0;
	sh = sh2 > sh ? sh2 : sh;
	sh = sh3 > sh ? sh3 : sh;
	
	//get bottom of footer
	var e = find_DOM(id);
	if(e){
		var obj = get_coords(e);
		var h	= e.offsetHeight;
		var eb = obj.y + h;
		
		//compare dimensions
		if(sh > eb){
			e.style.position = 'absolute';
			e.style.top = (sh - h) + 'px';
		}
	}
}

/*------------------------------------------------------------
WINDOW FUNCTIONS
------------------------------------------------------------*/
/**
 * Opens new browser window for scrollable pages.
 * @param r		The reference name for the window object.
 * @param url	The url to be displayed in the new window.
 * @param w		The width of the new window.
 * @param h		The height of the new window.
 */
function open_popup(r, url, w, h){
	var x = (screen.availWidth - w) / 2;
	var y = (screen.availHeight - h) / 2;
	r = window.open(url, r, 'toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=no,width=' + w + ',height=' + h + ',left=' + x + ',top=' + y);
}

/**
 * Opens new browser window for non-scrollable pages
 * such as images.
 * @param r		The reference name for the window object.
 * @param url	The url to be displayed in the new window.
 * @param w		The width of the new window.
 * @param h		The height of the new window.
 */
function open_image_popup(r, url, w, h){
	var x = (screen.availWidth - w) / 2;
	var y = (screen.availHeight - h) / 2;
	r = window.open(url, r, 'toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=no,resizable=no,width=' + w + ',height=' + h + ',left=' + x + ',top=' + y);
}

/**
 * Opens new browser window for context-sensitive
 * help. For compliant browsers, the info window
 * will open either left or right of the main window
 * depending on available room. For non-compliant
 * browsers, such as IE, the window opens in the
 * center of the screen.
 * @param url	The url to be displayed in the new window.
 * @param a		The html anchor id.
 */
function open_info(url, a){
	var w = screen.availWidth;
	var h = screen.availHeight;
	var x = 0;
	var y = (h / 2) - 200;
	if(window.screenX){
		var px = window.screenX;
		if(px < 305){
			if(window.outerWidth){
				var pw = px + window.outerWidth;
				if(w - pw > 305){
					x = pw;
				}
			}else{
				x = (w / 2) - 150;
			}
		}else{
			x = px - 305;
		}
	}else{
		x = 100;
	}
	var info = window.open(url + '#' + a, 'info', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=300,height=400,left=' + x + ',top=' + y);
	return false;
}

/**
 * Closes pop-up windows.
 */
function close_window(){
	window.close();
}

/*------------------------------------------------------------
TEXT FORMATTING FUNCTIONS
------------------------------------------------------------*/
/**
 * Returns a number as a currency decimal.
 * @param obj	The html form element
 */
function dollar_format(obj){
	var r = '0.00';
	var v = obj.value;
	var t = v.match(/[^0-9\.\-]/);
	if(!t){
		var a = v.split('.');
		if(a.length == 1){
			r = a[0] + '.00';
		}else{
			if(a[1].length > 2){
				a[1] = a[1].substr(0, 2) + '.' + a[1].substr(2);
				a[1] = Math.round(a[1]);
			}else if(a[1].length == 1){
				a[1] = a[1] + '0';
			}
			r = a[0] + '.' + a[1];
		}
	}
	obj.value = r;
	return;
}

/**
 * Returns a value in XXX-XXX-XXXX telephone format.
 * @param obj	The html form element
 */
function telephone_format(obj){
	var r = '';
	var v = obj.value;
	var p = /^\(?([2-9]\d{2})\)?(?:\-?|\s?)([2-9]\d{2})(?:\-?|\s?)(\d{4})$/;
	var t = v.match(p);
	if(t){
		if(t.length == 4){
			r = t[1] + '-' + t[2] + '-' + t[3];
		}else{
			r = t[1] + '-' + t[2];
		}
	}
	obj.value = r;
	return;
}

/**
 * Returns an uppercase value.
 * @param obj	The html form element
 */
function uppercase(obj){
	if(obj.value){
		obj.value.toUpperCase();
	}
	return;
}

/*------------------------------------------------------------
FORM VALIDATION
------------------------------------------------------------*/
/**
 * Performs RegExp pattern matching.
 * @param ty	The type of pattern to match.
 * @param obj	The html form element.
 */
function validate_string(ty, obj){
	var s = obj.value;
	if(ty != '' && s != ''){
		var p = set_regexp_pattern(ty);
		var msg = set_validation_error_message(ty);
		var t = s.match(p);
		if(!t){
			alert(msg);
			obj.value = '';
			return false;
		}else{
			return true;
		}
	}
}

/**
 * Retruns a RegExp matching pattern.
 * @param ty	The type of pattern to match
 */
function set_regexp_pattern(ty){
	var p_html_text	= /^[a-zA-Z0-9_#\-\+\='"\.\!\:\s,<>\/\(\)]+$/;
	var p_text		= /^[a-zA-Z0-9_#\-\+'"\.\!\:\s,\/\?\(\)]+$/;
	var p_int		= /^[\d\-]+$/;
	var p_float		= /^[0-9\-]+(\.[0-9]*)?$/;
	var p_dollar	= /^[0-9\-]+(\.[0-9]{0,2})?$/;
	var p_keyword	= /[a-zA-Z0-9_\-'\s]+/;
	var p_state		= /^[a-zA-Z]{2}$/;
	var p_ZIP_Code	= /^\d{5}-\d{4}|\d{5}|[A-Z]\d[A-Z] \d[A-Z]\d$/;
	var p_telephone	= /^\(?([2-9][0-9][0-9])\)?(?:[\-\.\s])?([2-9][0-9][0-9])(?:[\-\.\s])?([0-9]{4})$/;
	var p_email		= /([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,6})/;
	var p_year		= /^([1][9][0-9][0-9]|[2][0][0-9][0-9])$/;
	var p_ip		= /^(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))$/;
	var p_url		= /^((http|https)\:\/\/)?(([a-zA-Z0-9_\-]{2,}\.)+[a-zA-Z]{2,})(\:[a-zA-Z0-9]+)?([a-zA-Z0-9_\-\.\?\+\/\\&;%\$#\=~]*)?$/;
	
	var a = new Array();
	a[0]	= ['html_text', p_html_text];
	a[1]	= ['text', p_text];
	a[2]	= ['int', p_int];
	a[3]	= ['float', p_float];
	a[4]	= ['dollar', p_dollar];
	a[5]	= ['keyword', p_keyword];
	a[6]	= ['state', p_state];
	a[7]	= ['ZIP_Code', p_ZIP_Code];
	a[8]	= ['telephone', p_telephone];
	a[9]	= ['email', p_email];
	a[10]	= ['year', p_year];
	a[11]	= ['ip', p_ip];
	a[12]	= ['url', p_url];
	
	var r = '';
	for(var i = 0; i < a.length; i++){
		if(a[i][0] == ty){
			r = a[i][1];
			break;
		}
	}
	return r;
}

/**
 * Returns error text for a failed RegExp match.
 * @param ty	The type of pattern to match
 */
function set_validation_error_message(ty){
	var a = new Array();
	a[0]	= ['text',		'Please use only letters, dashes, periods, commas or whitespace.'];
	a[1]	= ['int',		'Please enter a valid integer.'];
	a[2]	= ['float',		'Please enter a valid decimal number.'];
	a[3]	= ['keyword',	'Please enter a query using standard characters.'];
	a[4]	= ['state',		'Please enter a two-character state abbreviation.'];
	a[5]	= ['ZIP_Code',	'Please enter a valid ZIP Code in XXXXX-XXXX format.'];
	a[6]	= ['telephone', 'Please enter a valid telephone number in XXX-XXX-XXXX format.'];
	a[7]	= ['email',		'Please enter a valid email address.'];
	a[8]	= ['year',		'Please enter a 4-digit year between 1900 and 2100.'];
	a[9]	= ['ip',		'Please enter valid IP address in XXX.XXX.XXX.XXX format.'];
	a[10]	= ['url',		'Please enter valid URL.'];
	
	if(ty.match(/[Tt]ext/)){
		ty = 'text';
	}
	if(ty.match(/int/)){
		ty = 'int';
	}
	
	var r = 'Hold up!';
	for(var i = 0; i < a.length; i++){
		if(a[i][0] == ty){
			r = a[i][1];
			break;
		}
	}
	return r;
}

/**
 * Validates a time string.
 * @param obj	The html form element.
 */
function validate_time(obj){
	if(obj.value != ''){
		var meridian;
		var str = obj.value;
		var long_pattern = /^([0-9]|[1][0-9]|[2][0-3])\:?([0-5][0-9])\x20?([AM|PM|am|pm]{2,2})?$/;
		var short_pattern = /^([0-9]|[1][0-9]|[2][0-3])\x20?([AM|PM|am|pm]{2,2})?$/;
		var msg = 'Please enter a valid time in one of the following four formats: a) hh, b) hh am|pm, c) hh:mm, or d) hh:mm am|pm.';
		
		//match to long pattern
		var time_array = str.match(long_pattern);
		if(time_array != null){
			if(time_array[3] != null){
				meridian = time_array[3];
				if((meridian == 'PM' || meridian == 'pm') && time_array[1] < 12){
					time_array[1] = parseInt(time_array[1]) + 12;
				}
			}
			var v = (parseInt(time_array[1]) * 60 * 60) + (parseInt(time_array[2]) * 60);
		}else{
			//match to short pattern
			time_array = str.match(short_pattern);
			if(time_array != null){
				if(time_array[2] != null){
					meridian = time_array[2];
					//time_array[2] = '00';
					if((meridian == 'PM' || meridian == 'pm') && time_array[1] < 12){
						time_array[1] = parseInt(time_array[1]) + 12;
					}
				}
				var v = parseInt(time_array[1]) * 60 * 60;
			}else{
				obj.value = '';
				alert(msg);
				return false;
			}
		}
		if(v < (60 * 60 * 24)){
			//obj.value = time_array[1] + ':' + time_array[2];
			return true;
		}
		obj.value = '';
		alert(msg);
	}
	return false;
}

/**
 * Validates a date string.
 * @param obj	The html form element.
 */
function validate_date(obj){
	if(obj.value != ''){
		var str = obj.value;
		var min_year = 1900;
		var max_year = 2100;
		var month_days_array = new Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
		var parser_array = new Array('-', ' ', '/', '.');
		var parser_type = -1;
		var msg = 'Please enter a valid date in mm/dd/YY or mm/dd/YYYY format.';
		
		//get date parser
		for(i = 0; i < parser_array.length; i++){
			var pos = str.indexOf(parser_array[i]);
			if(pos > 0){
				parser_type = i;
				break;
			}
		}
		//split date components
		if(parser_type != -1){
			var date_array = str.split(parser_array[parser_type]);
			if(date_array.length != 3){
				obj.value = '';
				alert(msg);
				return false;
			}
		}else{
			obj.value = '';
			alert(msg);
			return false;
		}
		//test year
		var year = (date_array[2].length == 2 
					? 2000 + parseInt(date_array[2]) 
					: parseInt(date_array[2]));
		if(year < min_year || year > max_year){
			obj.value = '';
			alert(msg);
			return false;
		}
		//test month
		var month = parseInt(date_array[0]);
		if(month < 1 || month > 12){
			obj.value = '';
			alert(msg);
			return false;
		}
		//test day
		var day = parseInt(date_array[1]);
		var feb_days = get_february_days(year);
		if((day < 1) || (day > month_days_array[month - 1]) 
				|| (month == 2 && day > feb_days)){
			obj.value = '';
			alert(msg);
			return false;
		}
		//reformat date
		var r = month + '/' + day + '/' + year;
		obj.value = r;
	}
	return;
}
function get_february_days(year){
	var r = 28;
	if(year % 100 == 0){
		if(year % 400 == 0){
			r = 29;
		}
	}else if(year % 4 == 0){
		r = 29;
	}
	return r;
}

/**
 * Basic form validation
 * @param f		The html form name.
 */
function validate_form(f){
	var empty = '';
	var error = '';
	var not_set = '';
	var msg = '';
	for(i = 0; i < f.length; i++){
		var e = f.elements[i];
		if(e.type == 'text' || e.type == 'textarea'){
			if((e.value == '' || e.value == null) && e.required == true){
				empty +="\n" + ' - ' + e.name;
			}
			if(e.value != '' && e.pattern != ''){
				var t = validate_string(e.pattern, e);
				if(!t){
					error += "\n" + ' - ' + e.name;
				}
			}
		}
		if((e.type == 'select-one' || e.type == 'select-multiple') && e.required == true){
			if(e.options[e.selectedIndex].value == 0){
				not_set += "\n" + ' - ' + e.name;
			}
		}
		if(e.type == 'hidden' && e.required == true){
			if(e.value == 0 || e.value == '0' || e.value == '' || e.value == null){
				not_set += "\n" + ' - ' + e.name;
			}
		}
	}
	if(empty != '' || error != '' || not_set != ''){
		msg = 'Hold up! The form has errors:';
		if(empty != ''){
			msg += "\n\n" + 'The following required fields are empty:' + empty;
		}
		if(not_set != ''){
			msg += "\n\n" + 'The following items have not been set:' + not_set;
		}
		if(error != ''){
			msg += "\n\n" + 'The following fields have invalid values:' + error;
		}
		alert(msg);
		return false;
	}
	return true;
}

/**
 * Test for saved record
 * @param param		The GET param
 */
function test_record_id(param){
	var s = window.location.search;
	if(s.indexOf('&' + param + '=0') != -1){
		var msg = 'Please enter some data and save the record.';
		var f = document.forms[0];
		for(var i = 0; i < f.length; i++){
			var e = f.elements[i];
			if(((e.type == 'text' || e.type == 'textarea') 
				 && (e.value != '' && e.value != '0.00')) 
			   || ((e.type == 'select-one' || e.type == 'select-multiple') 
					&& e.options[e.selectedIndex] > 0)){
				msg = 'Please save the record.';
				break;
			}
		}
		alert(msg);
		return false;
	}
	return true;
}

/**
 * Performs basic validataion for an activity end date
 * based on the start date value.
 * @param $obj		The start_date form element
 */
function test_end_date(obj){
	var str = obj.name;
	str = str.replace(/_start_/, '_end_');
	
	var f = document.forms[0];
	if(obj.value != ''){
		var d_start	= new Date(obj.value);
		
		for(var i = 0; i < f.length; i++){
			var e = f.elements[i];
			if(e.name.indexOf(str) != -1 && e.value != ''){
				var d_end = new Date(e.value);
				if(d_end.getTime() < d_start.getTime()){
					e.value = obj.value;
				}
				break;
			}
		}//end for
	}else{
		//find and unset the end_date field
		for(i = 0; i < f.length; i++){
			var e = f.elements[i];
			if(e.name.indexOf(str) != -1 && e.value != ''){
				e.value = '';
				break;
			}
		}
	}
}

/**
 * Performs basic validataion for an activity start date
 * based on the end date value.
 * @param $obj		The end_date form element
 */
function test_start_date(obj){
	var f = document.forms[0];
	if(obj.value != ''){
		var d_end = new Date(obj.value);
		
		var str = obj.name;
		str = str.replace(/_end_/, '_start_');
		for(var i = 0; i < f.length; i++){
			var e = f.elements[i];
			if(e.name.indexOf(str) != -1){
				if(e.value != ''){
					var d_start = new Date(e.value);
					if(d_start.getTime() > d_end.getTime()){
						e.value = obj.value;
					}
				}else{
					e.value = obj.value;
				}
			}
		}//end for
	}
}

