
/**
 * General Javascript functions library.
 *
 * Put third party functions at the bottom. Docblock all home-grown functions.
 *
 * @package	Glide-Website
 * @author	SBF
 * @copyright	2011 Glide Utilities Ltd., all rights reserved
 */

/**
 * Resize main content pane to fit content (useful if content dynamically changes).
 *
 * This function is run automatically on page load but can be run subsequent times.
 *
 * @return void
 */
function resizeContentPane() {
	if ($("#content").height() > $("#main").height()) {
		$("#main").css("height", $("#content").height());
	}
}


/**
 * Apply jQuery placeholders to input fields where the browser does not support
 * the placeholder attribute natively.
 *
 * Note that this will NOT work properly on text fields that are hidden at the
 * time of running this function. Such fields must have the placeholder() jQuery
 * function run separately on each of them and only AFTER they have been
 * displayed (unhidden). Do not run this function automatically on page load if
 * it contains any hidden text or textarea fields.
 *
 * @return void
 */
function applyPlaceholders() {
	if (!Modernizr.input.placeholder) {
		$('.placeholder').placeholder();
	}
}

/**
 * E-mail address validation AJAX function.
 *
 * @param number		- e-mail address to check
 *
 * @return boolean		- true if valid, otherwise false
 */
function verifyEmailAddress(email) {

	var json;

	$.ajax({
		type:	"POST",
		data:	"email="+email,
		url:	"/ajax/verify_email/",
		async:	false,
		success: function(response) {
			json = eval('('+response+')');
		}
	});

	return(json["valid"]);

}

/**
 * Telephone number validation AJAX function.
 *
 * @param number		- telephone number to check
 *
 * @return boolean		- true if valid, otherwise false
 */
function verifyTelephoneNumber(number) {

	var json;

	$.ajax({
		type:	"POST",
		data:	"telephone="+number,
		url:	"/ajax/verify_telephone/",
		async:	false,
		success: function(response) {
			json = eval('('+response+')');
		}
	});

	return(json["valid"]);

}

/**
 * Verify recaptcha input.
 *
 * @return boolean
 */
function verify_recaptcha() {

	recaptcha_challenge_field = $('#recaptcha_challenge_field').val();
	recaptcha_response_field = $('#recaptcha_response_field').val();

	r = null;
	$.ajax({
		type:	"POST",
		data:	"recaptcha_response_field="+recaptcha_response_field+"&recaptcha_challenge_field="+recaptcha_challenge_field,
		url:	"/ajax/verify_recaptcha/",
		async:	false,
		success: function(response) {
			json = eval('('+response+')');
			if (json["valid"] == true) {
				r = true;
			} else {
				r = json;
			}
		}
	});

	return r;

}

/**
 * Generate options for DataTables "display x records" menus.
 *
 * @para, string label		- record label (houses, tenants, whatevers)
 * @param integer totalrows	- maximum number of records
 *
 * @return string		- string of <option> tags
 */
function dataTablesDisplayOptions(label,totalrows) {

	menuoptions = "";
	numbers = new Array();

	// low numbers
	if (10 <= totalrows) numbers.push(10);
	if (25 <= totalrows) numbers.push(25);
	if (50 <= totalrows) numbers.push(25);

	// hundreds
	if (totalrows >= 100) {
		for (i=100; i<1000; i=i+100) {
			if (i <= totalrows) {
				numbers.push(i);
			}
		}
	}

	// thousands
	if (totalrows >= 1000) {
		for (i=1000; i<10000; i=i+1000) {
			if (i <= totalrows) {
				numbers.push(i);
			}
		}
	}

	// tens of thousands
	if (totalrows >= 10000) {
		for (i=10000; i<100000; i=i+10000) {
			if (i <= totalrows) {
				numbers.push(i);
			}
		}
	}

	// hundreds of thousands
	if (totalrows >= 100000) {
		for (i=100000; i<1000000; i=i+100000) {
			if (i <= totalrows) {
				numbers.push(i);
			}
		}
	}

	// assemble string
	for (var i in numbers) {
		menuoptions = menuoptions + "<option value=\""+numbers[i]+"\">"+numbers[i]+"</option>";
	}

	// add "all" option
	menuoptions = menuoptions + "<option value=\""+totalrows+"\">"+totalrows+" (all)</option>";

	// return options menu
	return "Display <select>"+menuoptions+"</select> "+label;

}

/**
 * Flash the server action acknowledgement panel.
 *
 * @param string message	- message to display (keep it short)
 *
 * @return void
 */
function serverOK(message) {

	// set message
	$('#server_ok').html(message);

	// reposition on page
	$('#server_ok').css("top", "150px");
	$('#server_ok').css("left", (($(window).width() - $('#server_ok').outerWidth()) / 2) + $(window).scrollLeft() + "px")

	// show briefly
	$('#server_ok').fadeIn("fast","swing").delay(500).fadeOut("slow","swing");

}

/**
 * Functions written by third parties follow. These functions may not follow our
 * coding standards. All due credits have been retained within the comments.
 */

function formatJSON(val) {

	// Format JSON string into something more human readable
	// http://ketanjetty.com/coldfusion/javascript/format-json/

	var retval = '';
	var str = val;
	var pos = 0;
	var strLen = str.length;
	var indentStr = '&nbsp;&nbsp;&nbsp;&nbsp;';
	var newLine = '<br />';
	var char = '';

	for (var i=0; i<strLen; i++) {

		char = str.substring(i,i+1);

		if (char == '}' || char == ']') {

			retval = retval + newLine;
			pos = pos - 1;

			for (var j=0; j<pos; j++) {
				retval = retval + indentStr;
			}

		}

		retval = retval + char;

		if (char == '{' || char == '[' || char == ',') {

			retval = retval + newLine;

			if (char == '{' || char == '[') {
				pos = pos + 1;
			}

			for (var k=0; k<pos; k++) {
				retval = retval + indentStr;
			}

		}

	}

	return retval;

}

function base64_decode (data) {

	// http://kevin.vanzonneveld.net
	// +   original by: Tyler Akins (http://rumkin.com)
	// +   improved by: Thunder.m
	// +      input by: Aman Gupta
	// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +   bugfixed by: Onno Marsman
	// +   bugfixed by: Pellentesque Malesuada
	// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +      input by: Brett Zamir (http://brett-zamir.me)
	// +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// -    depends on: utf8_decode
	// *     example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
	// *     returns 1: 'Kevin van Zonneveld'
	// mozilla has this native
	// - but breaks in 2.0.0.12!
	//if (typeof this.window['btoa'] == 'function') {
	//    return btoa(data);
	//}

	var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
	var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
	ac = 0,
	dec = "",
	tmp_arr = [];

	if (!data) {
		return data;
	}

	data += '';

	do { // unpack four hexets into three octets using index points in b64
		h1 = b64.indexOf(data.charAt(i++));
		h2 = b64.indexOf(data.charAt(i++));
		h3 = b64.indexOf(data.charAt(i++));
		h4 = b64.indexOf(data.charAt(i++));

		bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

		o1 = bits >> 16 & 0xff;
		o2 = bits >> 8 & 0xff;
		o3 = bits & 0xff;

		if (h3 == 64) {
			tmp_arr[ac++] = String.fromCharCode(o1);
		} else if (h4 == 64) {
			tmp_arr[ac++] = String.fromCharCode(o1, o2);
		} else {
			tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
		}
	} while (i < data.length);

	dec = tmp_arr.join('');
	dec = this.utf8_decode(dec);

	return dec;

}

function utf8_decode (str_data) {

	// http://kevin.vanzonneveld.net
	// +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
	// +      input by: Aman Gupta
	// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +   improved by: Norman "zEh" Fuchs
	// +   bugfixed by: hitwork
	// +   bugfixed by: Onno Marsman
	// +      input by: Brett Zamir (http://brett-zamir.me)
	// +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// *     example 1: utf8_decode('Kevin van Zonneveld');
	// *     returns 1: 'Kevin van Zonneveld'

	var tmp_arr = [],
	i = 0,
	ac = 0,
	c1 = 0,
	c2 = 0,
	c3 = 0;

	str_data += '';

	while (i < str_data.length) {
		c1 = str_data.charCodeAt(i);
		if (c1 < 128) {
			tmp_arr[ac++] = String.fromCharCode(c1);
			i++;
		} else if (c1 > 191 && c1 < 224) {
			c2 = str_data.charCodeAt(i + 1);
			tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
			i += 2;
		} else {
			c2 = str_data.charCodeAt(i + 1);
			c3 = str_data.charCodeAt(i + 2);
			tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
		}
	}

	return tmp_arr.join('');

}

function base64Encode(text){
	if (/([^\u0000-\u00ff])/.test(text)) throw new Error("Can't base64 encode non-ASCII characters.");
	var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", i = 0, cur, prev, byteNum,result=[];
	while(i < text.length){
		cur = text.charCodeAt(i);
		byteNum = i % 3;
		switch(byteNum){
			case 0: //first byte
				result.push(digits.charAt(cur >> 2));
				break;
			case 1: //second byte
				result.push(digits.charAt((prev & 3) << 4 | (cur >> 4)));
				break;
			case 2: //third byte
				result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)));
				result.push(digits.charAt(cur & 0x3f));
				break;
		}
		prev = cur;
		i++;
	}
	if (byteNum == 0){
		result.push(digits.charAt((prev & 3) << 4));
		result.push("==");
	} else if (byteNum == 1){
		result.push(digits.charAt((prev & 0x0f) << 2));
		result.push("=");
	}
	return result.join("");
}

function bcheck() {
	var BrowserDetect = {
		init: function () {
			this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
			this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
			this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
		searchString: function (data) {
			for (var i=0;i<data.length;i++)	{
				var dataString = data[i].string;
				var dataProp = data[i].prop;
				this.versionSearchString = data[i].versionSearch || data[i].identity;
				if (dataString) {
					if (dataString.indexOf(data[i].subString) != -1)
						return data[i].identity;
	}
				else if (dataProp)
					return data[i].identity;
			}
		},
		searchVersion: function (dataString) {
			var index = dataString.indexOf(this.versionSearchString);
			if (index == -1) return;
			return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
		dataBrowser: [
	{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
	},
	{
			string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
	},
	{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
	},
	{
			prop: window.opera,
			identity: "Opera",
			versionSearch: "Version"
	},
	{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
	},
	{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
	},
	{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
	},
	{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
	},
	{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
	},
	{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
	},
	{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
	},
	{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
	}
		],
		dataOS : [
	{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
	},
	{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
	},
	{
			string: navigator.userAgent,
			subString: "iPhone",
			identity: "iPhone/iPod"
	},
	{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
	}
		]

	};
	BrowserDetect.init();

	if ((BrowserDetect.browser == 'Explorer' && (BrowserDetect.version == '6' || BrowserDetect.version == '7' || BrowserDetect.version == '8')) || BrowserDetect.browser == 'Opera') {
		return false;
	}
	return true;
}

