// JavaScript 1.3

// global.js
// global JavaScript functions & variables

// st-out.com


//-----------------------------------------------------------------------------------------------------------------------------
//					window functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- popup ------------- //
// function		: opens a seamless popup window
// arguments	: href, [width], [height], [left], [top]
// call			: popup(myHref, [myWidth], [myHeight], [myLeft], [myTop]);
function popup(href, w, h, l, t) {
	popString = 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes';
	if(w) popString += ', width=' + w;
	if(h) popString += ', height=' + h;
	if(l) popString += ', left=' + l;
	if(t) popString += ', top=' + t;
	window.open(href, '_blank', popString);
}

// ------------- popupFixed ------------- //
// function		: opens a seamless popup window, non resizable, no scrollbars
// arguments	: href, [width], [height], [left], [top]
// call			: popupFixed(myHref, [myWidth], [myHeight], [myLeft], [myTop]);
function popupFixed(href, w, h, l, t) {
	popString = 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no';
	if(w) popString += ', width=' + w;
	if(h) popString += ', height=' + h;
	if(l) popString += ', left=' + l;
	if(t) popString += ', top=' + t;
	window.open(href, '_blank', popString);
}

// ------------- mail3 ------------- //
// function		: replicates mailto: link
// arguments	: domain, username
// call			: mail3(myDomain, myUsername);
function mail3(dom, usr) {
	document.location = "mailto:" + usr + "@" + dom;
}


//-----------------------------------------------------------------------------------------------------------------------------
//					document functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- triggerEvent ------------- //
// function		: trigger event on object (no DOM-events supported)
// arguments	: event, object
// call			: triggerEvent(myEvent, myObject);
function triggerEvent(evt, obj) {
	evt = evt.toLowerCase();
	onEvt = evt.split('');
	onEvt[0] = onEvt[0].toUpperCase();
	onEvt = 'on' + onEvt.join('');
	switch(evt) {
		case 'abort' : evtSet = 'HTMLEvents'; break;
		case 'blur' : evtSet = 'HTMLEvents'; break;
		case 'change' : evtSet = 'HTMLEvents'; break;
		case 'error' : evtSet = 'HTMLEvents'; break;
		case 'focus' : evtSet = 'HTMLEvents'; break;
		case 'load' : evtSet = 'HTMLEvents'; break;
		case 'reset' : evtSet = 'HTMLEvents'; break;
		case 'resize' : evtSet = 'HTMLEvents'; break;
		case 'scroll' : evtSet = 'HTMLEvents'; break;
		case 'select' : evtSet = 'HTMLEvents'; break;
		case 'submit' : evtSet = 'HTMLEvents'; break;
		case 'unload' : evtSet = 'HTMLEvents'; break;
		case 'click' : evtSet = 'MouseEvents'; break;
		case 'mousedown' : evtSet = 'MouseEvents'; break;
		case 'mousemove' : evtSet = 'MouseEvents'; break;
		case 'mouseout' : evtSet = 'MouseEvents'; break;
		case 'mouseover' : evtSet = 'MouseEvents'; break;
		case 'mouseup' : evtSet = 'MouseEvents'; break;
		case 'keydown' : evtSet = 'UIEevents'; break;
		case 'keypress' : evtSet = 'UIEevents'; break;
		case 'keyup' : evtSet = 'UIEevents'; break;
		default: evtSet = 'Events';
	}
	if(document.createEvent) {
		myEvent = document.createEvent(evtSet);
		myEvent.initEvent(evt, true, false);
		obj.dispatchEvent(myEvent);
	}
	else if(document.createEventObject) obj.fireEvent(onEvt);
}

// ------------- createCookie ------------- //
// function		: creates a cookie
// arguments	: cookie name, cookie value, days to expiration
// returns		: nothing
// call			: createCookie(myName,myValue,myDays);
// courtesy of	: Scott Andrew -- http://www.quirksmode.org/js/cookies.html
function createCookie(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=/";
}

// ------------- readCookie ------------- //
// function		: reads a cookie
// arguments	: cookie name
// returns		: cookie value string
// call			: readCookie(name);
// courtesy of	: Scott Andrew -- http://www.quirksmode.org/js/cookies.html
function readCookie(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 FALSE;
}

// ------------- eraseCookie ------------- //
// function		: reads a cookie
// arguments	: cookie name
// returns		: nothing
// call			: eraseCookie(name);
// courtesy of	: Scott Andrew -- http://www.quirksmode.org/js/cookies.html
function eraseCookie(name) {
	createCookie(name,"",-1);
}


//-----------------------------------------------------------------------------------------------------------------------------
//					string functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- trimSpaces ------------- //
// function		: removes spaces at start & end of string
// arguments	: string
// returns		: new string
// call			: trimspaces(myString);
function trimSpaces(str) {
	str = str.split('');
	while(str[0] == ' ') str.shift()
	while(str[str.length - 1] == ' ') str.pop();
	str = str.join('');
	return str;
}

// ------------- urlencode ------------- //
// function		: encodes string (cfr. escape(), compatible with php urlencode & -decode)
// arguments	: string
// returns		: encoded string
// call			: urlencode(myString);
function urlencode(str) {
	str = escape(str);
	str = str.replace('+', '%2B');
	str = str.replace('%20', '+');
	str = str.replace('*', '%2A');
	str = str.replace('/', '%2F');
	str = str.replace('@', '%40');
	return str;
}

// ------------- urldecode ------------- //
// function		: decodes string (cfr. unescape(), compatible with php urlencode & -decode)
// arguments	: string
// returns		: decoded string
// call			: urldecode(myString);
function urldecode(str) {
	str = str.replace('+', ' ');
	str = unescape(str);
	return str;
}

// ------------- stringContains ------------- //
// function		: checks if string contains string argument or one of the values of array argument
// arguments	: string + string or array + case sensitivity (true if sensitive)
// returns		: true if string contains string argument or one of the values in array argument; false otherwise
// call			: stringContains(myString, myArgument, caseSensitive);
function stringContains(str, arg, cas) {
	if(str != '') {
		if(typeof(arg) == 'object') {
			if(cas) for(x = 0; x < arg.length; x++) {
				if(str.indexOf(arg[x]) != -1) return true;
			}
			else for(x = 0; x < arg.length; x++) {
				if(str.toLowerCase().indexOf(arg[x].toLowerCase()) != -1) return true;
			}
		}
		else {
			if(cas && str.indexOf(arg) != -1) return true;
			else if(!cas && str.toLowerCase().indexOf(arg.toLowerCase()) != -1) return true;
		}
		return false;
	}
}

// ------------- stringIsEmail ------------- //
// function		: checks if string is a valid email-address
// arguments	: string
// returns		: true if string is a valid email-address; false otherwise
// call			: stringIsEmail(myString);
function stringIsEmail(str) {
	result = true;
	if(str != '') {
		check_1 = str.split('@');
		if(check_1.length == 2 && check_1[0] != '') {
			check_2 = check_1[1].split('.');
			if(check_2.length >= 2) {
				for(x = 0; x < check_2.length; x++) if(check_2[x] == '') result = false;
				check_3 = str.split(' ');
				if(check_3.length > 1) result = false;
			}
			else result = false;
		}
		else result = false;
	}
	return result;
}


//-----------------------------------------------------------------------------------------------------------------------------
//					file functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- getFileName ------------- //
// function		: gets the filename out of a path
// arguments	: path string
// returns		: name string
// call			: getFileName(myPath)
function getFileName(str) {
	arr = str.split('/');
	if(arr.length > 1) str = arr[arr.length - 1];
	arr = str.split('\\');
	if(arr.length > 1) str = arr[arr.length - 1];
	return str;
}

// ------------- getFileExt ------------- //
// function		: gets the extension out of a filename or a path
// arguments	: filename or path string + case (optional: 'upper', 'lower' or none)
// returns		: extension string (or false for none)
// call			: getFileExt(myPath, myCase)
function getFileExt(str, cas) {
	arr = str.split('.');
	if(arr.length > 1) {
		ext = arr[arr.length - 1];
		if(cas && cas == 'lower') return ext.toLowerCase();
		if(cas && cas == 'upper') return ext.toUpperCase();
		return ext;
	}
	return false;
}

// ------------- bytes2KB ------------- //
// function		: converts bytes to kilobytes
// arguments	: integer
// returns		: floating point (max 2 decimals)
// call			: bytes2KB(num);
function bytes2KB(num) {
	return Math.round((num / 10.24)) / 100;
}

// ------------- bytes2MB ------------- //
// function		: converts bytes to megabytes
// arguments	: integer
// returns		: floating point (max 2 decimals)
// call			: bytes2MB(num);
function bytes2MB(num) {
	return Math.round((num / 10485.76)) / 100;
}

// ------------- bytes2GB ------------- //
// function		: converts bytes to gigabytes
// arguments	: integer
// returns		: floating point (max 2 decimals)
// call			: bytes2GB(num);
function bytes2GB(num) {
	return Math.round((num / 10737418.24)) / 100;
}

// ------------- bytes2string ------------- //
// function		: converts bytes to either bytes, KB, MB or GB (what is most suitable)
// arguments	: integer
// returns		: string with floating point (max 2 decimals) and unit
// call			: bytes2string(num);
function bytes2string(num) {
	if(num < (1024 / 2)) return num + ' bytes';
	if(num < (1048576 / 2)) return bytes2KB(num) + ' KB';
	if(num < (1073741824 / 2)) return bytes2MB(num) + ' MB';
	return bytes2GB(num) + ' GB';
}


//-----------------------------------------------------------------------------------------------------------------------------
//					array & object functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- arrayContains & objectContains ------------- //
// function		: checks if array or object contains string argument or one of the values of array or object argument
// arguments	: array or object + string or array or object
// returns		: true if one of the values in array or object equals string argument or one of the values in array or object argument; false otherwise
// call			: arrayContains(myArray, myArgument); or objectContains(myObject, myArgument);
function arrayContains(arr, arg) {
	if(typeof(arg) == 'object') {
		for(x in arr) if(!arr.hasOwnProperty || arr.hasOwnProperty(x)) {
			for(y in arg) if(!arg.hasOwnProperty || arg.hasOwnProperty(y)) {
				if(arr[x] == arg[y]) return true;
			}
		}
	}
	else {
		for(x in arr) if(!arr.hasOwnProperty || arr.hasOwnProperty(x)) {
			if(arr[x] == arg) return true;
		}
	}
	return false;
}
function objectContains(obj, arg) {
	if(typeof(arg) == 'object') {
		for(x in obj) {
			for(y in arg) {
				if(obj[x] == arg[y]) return true;
			}
		}
	}
	else {
		for(x in obj) {
			if(obj[x] == arg) return true;
		}
	}
	return false;
}

// ------------- arrayRemoveKey & objectRemoveKey ------------- //
// function		: removes item from array or object
// arguments	: array or object + key of removable item
// returns		: new array or object
// call			: arrayRemoveKey(myArray, myKey); or objectRemoveKey(myObject, myKey);
function arrayRemoveKey(arr, key) {
	result = new Array();
	for(x in arr) if(!arr.hasOwnProperty || arr.hasOwnProperty(x)) {
		if(x != key) result[x] = arr[x];
	}
	return result;
}
function objectRemoveKey(obj, key) {
	result = new Object();
	for(x in obj) if(x != key) result[x] = obj[x];
	return result;
}

// ------------- arrayRemoveValue & objectRemoveValue ------------- //
// function		: removes item(s) from array or object
// arguments	: array or object + value of removable item(s)
// returns		: new array or object
// call			: arrayRemoveValue(myArray, myValue); or objectRemoveValue(myObject, myValue);
function arrayRemoveValue(arr, val) {
	result = new Array();
	for(x in arr) if(!arr.hasOwnProperty || arr.hasOwnProperty(x)) {
		if(arr[x] != val) result[x] = arr[x];
	}
	return result;
}
function objectRemoveValue(obj, val) {
	result = new Object();
	for(x in obj) if(obj[x] != val) result[x] = obj[x];
	return result;
}

// ------------- arraySortKey & objectSortKey  ------------- //
// function		: sorts array or object by index
// arguments	: array or object
// returns		: new sorted array or object
// call			: arraySortKey(myArray); or objectSortKey(myObject);
function arraySortKey(arr) {
	temp = new Array();
	result = new Array();
	delim = '__&&__';
	for(x in arr) if(!arr.hasOwnProperty || arr.hasOwnProperty(x)) temp.push(x + delim + arr[x]);
	temp = temp.sort();
	for(x in temp) if(!temp.hasOwnProperty || temp.hasOwnProperty(x)) {
		keyVal = temp[x].split(delim);
		key = keyVal[0];
		val = keyVal[1];
		result[key] = val;
	}
	return result;
}
function objectSortKey(obj) {
	temp = new Array();
	result = new Object();
	delim = '__&&__';
	for(x in obj) temp.push(x + delim + obj[x]);
	temp = temp.sort();
	for(x in temp) if(!temp.hasOwnProperty || temp.hasOwnProperty(x)) {
		keyVal = temp[x].split(delim);
		key = keyVal[0];
		val = keyVal[1];
		result[key] = val;
	}
	return result;
}

// ------------- object2string  ------------- //
// function		: converts an object into a string, keys and values delimited by one string, key-value-pairs from each other by another string
// arguments	: object, delimiter 1, delimiter 2
// returns		: resulting string
// call			: object2string(myObject, delimiter1, delimiter2);
function object2string(obj, delim1, delim2) {
	str = '';
	i = 0;
	for(x in obj) {
		if(i > 0) str += delim2;
		str += x + delim1 + obj[x];
		i++;
	}
	return str;
}

// ------------- string2object  ------------- //
// function		: converts a string into an object (reverses objectToString())
// arguments	: string, delimiter 1, delimiter 2
// returns		: original object
// call			: string2object(myString, delimiter1, delimiter2);
function string2object(str, delim1, delim2) {
	var obj = new Object();
	arr1 = str.split(delim2);
	for(i = 0; i < arr1.length; i++) {
		arr2 = arr1[i].split(delim1);
		obj[arr2[0]] = arr2[1];
	}
	return obj;
}


//-----------------------------------------------------------------------------------------------------------------------------
//					math functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- dec2hex ------------- //
// function		: converts decimal value into hexadecimal
// arguments	: decimal value
// returns		: hexadecimal value
// call			: dec2hex(myDecimal);
function dec2hex(arg) {
	result = '';
	arg = parseInt(arg);
	hexChars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
	quot = Math.floor(arg / 16);
	mod = arg % 16;
	result = hexChars[mod];
	while(quot >= 16) {
		sQuot = Math.floor(quot / 16);
		mod = quot % 16;
		result = hexChars[mod] + result;
		quot = sQuot;
	}
	result = hexChars[quot] + result;
	return result;
}

// ------------- hex2dec ------------- //
// function		: converts hexadecimal value into decimal
// arguments	: hexadecimal value
// returns		: decimal value
// call			: hex2dec(myHexadecimal);
function hex2dec(arg) {
	result = parseInt(arg,16);
	return result;
}


//-----------------------------------------------------------------------------------------------------------------------------
//					color functions
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- compColor ------------- //
// function		: converts a color to its complementary value
// arguments	: html-style color
// returns		: html-style complementary color
// call			: compColor(myColor);
function compColor(col) {
	fence = false;
	if(col.indexOf('#') > -1) {
		col = col.split('#').join('');
		fence = true;
	}
	R = hex2dec(col.substring(0, 2));
	G = hex2dec(col.substring(2, 4));
	B = hex2dec(col.substring(4, 6));
	R = dec2hex(255 - R);
	G = dec2hex(255 - G);
	B = dec2hex(255 - B);
	compCol = R + G + B;
	if(fence) compCol = '#' + compCol;
	return compCol;
}

// ------------- color2hex ------------- //
// function		: converts a color (RGB or hexadecimal) to an uppercase html-style color
// arguments	: RGB or hexadecimal color
// returns		: uppercase html-style color
// call			: color2hex(myColor);
function color2hex(col) {
	if(col.indexOf('(') > -1 || col.indexOf(',') > -1) {
		temp = col.split('(');
		if(temp.length > 1) col = temp[1];
		temp = col.split(')');
		if(temp.length > 1) col = temp[0];
		temp = col.split(',');
		R = dec2hex(temp[0]);
		G = dec2hex(temp[1]);
		B = dec2hex(temp[2]);
		col = '#' + R + G + B;
	}
	else if(col.indexOf('#') == -1) col = '#' + col;
	col = col.toUpperCase();
	return col;
}


//-----------------------------------------------------------------------------------------------------------------------------
//					misc variables
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- urlSchemes ------------- //
// function		: array of common url schemes
var urlSchemes = new Array('file://', 'ftp://', 'gopher://', 'http://', 'https://', 'mailto:', 'news://', 'nntp://', 'telnet://');

// ------------- days ------------- //
// function		: array of days of the week
var days = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');

// ------------- months ------------- //
// function		: array of months of the year
var months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');


//-----------------------------------------------------------------------------------------------------------------------------
//					navigator & client variables
//-----------------------------------------------------------------------------------------------------------------------------

// ------------- navIs?? ------------- //
// function		: checks user navigator
var navIsOpera = (navigator.userAgent.indexOf('Opera') != -1);
var navIsNetscape = (navigator.userAgent.indexOf('Netscape') != -1);
var navIsSafari = (navigator.userAgent.indexOf('Safari') != -1);
var navIsFirefox = (navigator.userAgent.indexOf('Firefox') != -1);
var navIsKonqueror = (navigator.userAgent.indexOf('Konqueror') != -1);
var navIsIexplorer = (navigator.userAgent.indexOf('MSIE') != -1 && !navIsOpera && !navIsNetscape);
var navIsMozilla = (navigator.userAgent.indexOf('Mozilla') != -1 && !navIsOpera && !navIsNetscape && !navIsSafari && !navIsIexplorer && !navIsFirefox && !navIsKonqueror);
var navIsOther = (!navIsOpera && !navIsNetscape && !navIsSafari && !navIsFirefox && !navIsKonqueror && !navIsIexplorer && !navIsMozilla);

// ------------- cltIs?? ------------- //
// function		: checks user client operating system
var cltIsWindows = (navigator.userAgent.indexOf('Windows') != -1);
var cltIsMacos = (navigator.userAgent.indexOf('Mac') != -1);
var cltIsLinux = (navigator.userAgent.indexOf('Linux') != -1);
var cltIsOther = (!cltIsWindows && !cltIsMacos && !cltIsLinux);

// ------------- mouseX & mouseY ------------- //
// function		: gets mouse X and Y position on mousedown
if (!navIsIexplorer) document.captureEvents(Event.MOUSEDOWN);
document.onmousedown = getMouseXY;
var mouseX = 0;
var mouseY = 0;
function getMouseXY(e) {
	if(navIsIexplorer) {
		mouseX = event.clientX + document.body.scrollLeft;
		mouseY = event.clientY + document.body.scrollTop;
	}
	else {
		mouseX = e.pageX;
		mouseY = e.pageY;
	}
	if(mouseX < 0) mouseX = 0;
	if(mouseY < 0) mouseY = 0;
	return true;
}