// ./_js/common.js

// ----------------------
// general


// javascript equivalent to php's in_array
function inArray(needle, haystack) {
	var length = haystack.length;
	for(var i = 0; i < length; i++) {
	  if(haystack[i] == needle) return true;
	}
	
	return false;
}

function logToConsole(msg) {
	try {
		console.log(msg);
	} catch(err) {
	}
}

// -- determines if a value is between two other values. option: strict [must be below or above but not equal to]
function isBetween(value, value_min, value_max, can_match_exactly) {
	if(strict) {
		return (value > value_min && value < value_max);
	} else {
		return (value >= value_min && value <= value_max);
	}
}

// -- determines whether a variable is defined
function variableDefined(name) {
	return typeof this[name] !== 'undefined';
}

// -- determines whether a variable is an array
function isArray(input) {
	return typeof(input)=='object'&&(input instanceof Array);
}

// -- determines if a variable is an object
function isObject(mixed_var) {
	if(mixed_var instanceof Array) {
		return false;
	} else {
		return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
	}
}


// - browser functions

// -- refreshes target window. optional clause to do so only if the name matches.
function refreshWindow(target, name) {
	if(!target) target = 'window';
	try{
		if(name) {
		// --- target's name must match
			if(eval(target+'.name') != name) return;
		} 
		eval(target+'.location.reload();');
	} catch(err) {	
	}
}

// -- checks whether our page is loaded in a frame
function inFrame() {
	return (window.location != window.parent.location);
}

// -- for generate_link (admin tools)
function linkWindow(URL) {
	smallWindow(URL, 'generate_link', 700, 500);
}

// -- for protected_images (admin tools)
function protectedImagesWindow(URL) {
	smallWindow(URL, 'protected_images', 700, 500);
}

// -- new window
function smallWindow(URL, id, width, height) {
	eval("page_"+id+" = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width='+width+',height='+height);");
	
	try {
		if (window.focus) {eval("page_"+id).focus()}
	} catch(err) {
	}
}

function minimizeWindow() {
	window.innerWidth = 100;
	window.innerHeight = 100;
	window.screenX = screen.width;
	window.screenY = screen.height;
	alwaysLowered = true;
}

function maximizeWindow() {
	window.innerWidth = screen.width;
	window.innerHeight = screen.height;
	window.screenX = 0;
	window.screenY = 0;
	alwaysLowered = false;
}

function goToURL(url, target, properties) {
	
	if(!properties) properties = new Object();
	
	switch(target) {
		default:
			window.location = url;
		break;
		case '_blank':
			window.open(url, properties.name);
		break;
	}
}



// ----------------------
// form-related


// confirmation
function confirmAction(strMessage, strURL) {
	var agree=confirm(strMessage);
	if (agree) {
		window.location = strURL;
	}
	else {
		return false;
	}
}


// -- object to store user's choices / values for form elements that may be reset based on other selections
var stored_values = new Object();

function assignStoredValue(target, property, set_value) {
	var target_id = '';

	if(!property) property = 'val';

	if(isObject(target)) {
		if(!set_value) {		
			switch(property) {
				default:
					set_value = $(target).attr(property);
				break;
				case 'val':
					set_value = $(target).val();
				break;				
			}
		}
		
		target_id = $(target).attr("id");
	} else {
		target_id = target;
	}
	
	if(!target_id || !property) return;

	if(!stored_values[target_id]) stored_values[target_id] = new Object();
	stored_values[target_id][property] = set_value;
}



// check and submit form from outside of the form itself.
// -- check and submit form from outside of the form itself.
function checkAndSubmitForm(form_name, properties) { 
	var t_form = $("form[name=form_"+form_name+"]");
	if(!properties) properties = new Object();
	
	// --- validate the form
	if(checkForm(t_form)) {		
		// ---- validation passed
		
		if(properties.action == 'redirect' && properties.url) {
			$("input#r").val(properties.url);
			$("input#next_action_override").val(1);
		}
	
		/* 2010-07-20 - from testing in IE8 and FF, checkForm is called again (via onSubmit) when submitting the form
		that's not *so* bad since it will only throw the errors once per submit, but it is more efficient to clean up the onSubmit */
		t_form.removeAttr('onSubmit'); 
	
		$("textarea.ta_ckeditor").each(function(i){
		// ----- update all ckeditor instances
			CKEDITOR.instances[$("textarea.ta_ckeditor")[i].id].updateElement();
		});	
		t_form.submit();
	}
	
	return false;	
}


// makes a field disabeld / readonly or enabled / writeable
function setFieldState(obj_field, state_name, off) {		
	var field_name = $(obj_field).attr('name'); // traverse by object name, so that we can toggle arrayed items like radios and checkboxes
	
	$("input[name="+field_name+"], select[name="+field_name+"]").each(function(){
	// traverse by name, to allow for arrayed checkboxes and radios
		if(off) {
		// disable / readonly
			$(this).attr(state_name, state_name);
			$(this).addClass('disabled');
		} else {
		// enable / writeable
			$(this).removeAttr(state_name);
			$(this).removeClass('disabled');						
		}
	});
	
	// now handle the labels (again, traverse by name)
	if(off) {
		setLabelsErrored(obj_field, false); // remove errored state
		$('label[name=label_'+field_name+']').addClass('cursor_default');
	} else {
		$('label[name=label_'+field_name+']').removeClass('cursor_default');	
	}
}


// sets  labels as errored / not errored
function setLabelsErrored(obj_field, is_errored) {
	var field_name = $(obj_field).attr('name'); // traverse by object name, so that we can toggle arrayed items like radios and checkboxes
	$('label[name=label_'+field_name+'] span').attr('class', (is_errored) ? 'errored' : '');	
}


// set labels as errored
function setLabelsErrored(fieldName, isErrored) {
	try {
		var relevantLabels = document.getElementsByName('label_'+fieldName);		
		for(var i = 0; i < relevantLabels.length; i++) {
			relevantLabels[i].getElementsByTagName('span')[0].className = (isErrored) ? 'errored' : '';	
		}	
	} catch(err) {
	}
}


// resets "blur check"
var blurCheck_passed = true;
function resetBlurCheck() {
	blurCheck_passed = true;
}


// Search through string's characters one by one. If character is not a whitespace, append to returnString.
function trim(s) {
	var i;
	var returnString = "";	
	for (i = 0; i < s.length; i++) {
		// Check that current character isn't whitespace.
		var c = s.charAt(i);
		if (c != " ") returnString += c;
	}
	return returnString;
}


// Search through string's characters one by one. If character is not in bag, append to returnString.
function stripCharsInBag(s, bag) {
	var i;
	var returnString = "";	
	for (i = 0; i < s.length; i++) {
		// Check that current character isn't whitespace.
		var c = s.charAt(i);
		if (bag.indexOf(c) == -1) returnString += c;
	}
	return returnString;
}


// ----------------------
//  mandatory field validation

function validateObjText(objText) {
	try {
		return (objText.value.length > 0);
	} catch(err) {
	}
	return true;
}


function validateObjSelect(objSelectBox) {
	return (objSelectBox[objSelectBox.selectedIndex].value != '');
}


function validateObjCheckbox(objCheckbox) { // works for radios, too
	try {
		var thisCheckGroup = document.getElementsByName(objCheckbox.name); 
		for (i = 0; i < thisCheckGroup.length; i++) {
			if (thisCheckGroup[i].checked) {
				return true;
			}
		}
	} catch(err) {
	}
	
	return false;
}


function missedObjectMandatory(obj, failed_string){
	var has_value = true; // assume true
	
	try {
		switch(obj.type) {
			case 'text':
			case 'text_input':
			case 'text_area':
			case 'textarea':
			case 'password':
				has_value = validateObjText(obj);
			break;
			case 'checkbox':
			case 'radio':
				has_value = validateObjCheckbox(obj);
			break;
			case 'select':
			case 'select-one':
			case 'select-multiple':
				has_value = validateObjSelect(obj);
			break;
		}
		
		if(!has_value) {
			return (failed_string) ? failed_string : true;			
		}
	} catch (err) {
	}

	return false;	
}


function blurCheckObjMandatory(obj, failed_string) {
	try {
		if(blurCheck_passed) {			
			if(missedObjectMandatory(obj, '')) {
				setLabelsErrored(obj.name, true);			
				alert(failed_string);
				blurCheck_passed = false;
			} else {
				setLabelsErrored(obj.name, false);
			}
		}
	} catch (err) {
	}
}



// ----------------------
// format validation

function validateEmail(string) {
	var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,6})$/;
	return (reg.test(string));
}


function validateInteger(string) {
	if(isNaN(string)) string = 0;
	return (string > 0);
}


function validateNumber(string) {
	return (!isNaN(string));
}



/* phone number validation */
function validatePhoneNumber(strPhone){
	var phoneNumberDelimiters = "()-. extnsio#"; // non-digit characters which are allowed in phone numbers (accepts any chars in the word extension)
	var validWorldPhoneChars = phoneNumberDelimiters + "+"; // characters which are allowed in international phone numbers -  a leading + is OK
	var minDigitsInIPhoneNumber = 10; // Minimum no of digits in an international phone no.

	var bracket=3;
	strPhone = trim(strPhone);
	if(strPhone.indexOf("+") > 1) return false; // only allow + as the first character
	if(strPhone.indexOf("-") != -1)bracket=bracket+1; // offset the bracket by 1 if - exists
	var openingBracketPos = strPhone.indexOf("("); // get position of opening bracket
 	var closingBracketPos = strPhone.indexOf(")"); // get position of closing bracket
	if(openingBracketPos != -1 && openingBracketPos > bracket)return false; // don't allow ( after the allocated bracet range
	if(openingBracketPos != -1 && closingBracketPos != openingBracketPos + 4) return false; // closing bracket must be 4 characters after opening bracket
	if(openingBracketPos == -1 && closingBracketPos !=- 1) return false; // can't have a closing bracket without an opening backet
	s=stripCharsInBag(strPhone,validWorldPhoneChars); // trim allowed chars
	return (validateNumber(s) && s.length >= minDigitsInIPhoneNumber); // check only numbers exist, and ensure minimum numbers is met
}


function validateFormat(format, data) {
	switch(format) {
		case 'email':
		case 'email_address':
			return validateEmail(data);
		break;
		case 'int':
			return validateInteger(data);
		break;
		case 'number':
			return validateNumber(data);	
		break;
		case 'phone':
		case 'phone_number':
			return validatePhoneNumber(data);	
		break;
	}
	
	return true;
}

function invalidObjectFormat(obj, format, failed_string){
	var is_valid = true; // assume true
	var value;
	
	try {		
		switch(obj.type) {
			case 'text':
			case 'text_input':
			case 'textarea':
				value = obj.value;
			break;
			case 'select':
			case 'select-one':
			case 'select-multiple':
				value = obj[obj.selectedIndex].value;
			break;
		}

		if(!validateFormat(format, value)) {
			return (failed_string) ? failed_string : 'true';
		}
	} catch (err) {
	}
	
	return false;	
}

function blurCheckObjFormat(obj, format, failed_string) {
	try {
		if(blurCheck_passed) {
			if(invalidObjectFormat(obj, format, '')) {
				setLabelsErrored(obj.name, true);
				alert(failed_string);
				blurCheck_passed = false;
			} else {
				setLabelsErrored(obj.name, false);
			}
		}
	} catch (err) {
	}
}
