///////////////////////////////////////////////////////////////////////////////////////////////////
//	DLib General JavaScript functions - copyright davidviner.com 2006-2009 (except where stated)
//
//	10.11.2009	5.6.9	DJV		Added getStyle().
//
///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////
// Some useful methods/functions.
///////////////////////////////////////////////////////////////////////////////////////////////////

// From http://www.delphifaq.com/faq/f1031.shtml

if (!String.prototype.trim)
{
	String.prototype.trim = function ()
	{
    	return this.replace (/^\s*/, "").replace (/\s*$/, "");
    }
}

function isArray (object)
{
	return object != null && typeof object == "object" && 'splice' in object && 'join' in object;
}

//C////////////////////////////////////////////////////////////////////////////////////////////////
// Utility functions.
// @DLibUtilities
///////////////////////////////////////////////////////////////////////////////////////////////////

DLibUtilities = function ()
{
	var	ta = new Object;

	var _private =
	{
		///////////////////////////////////////////////////////////////////////////////////////////
		// From http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
		///////////////////////////////////////////////////////////////////////////////////////////

		filterResults : function (n_win, n_docel, n_body)
		{
			var n_result = n_win ? n_win : 0;

			if (n_docel && (!n_result || (n_result > n_docel)))
			{
				n_result = n_docel;
			}

			return (n_body && (!n_result || (n_result > n_body)) ? n_body : n_result);
		}
	}

	var _public =
	{
		//F////////////////////////////////////////////////////////////////////////////////////////
		// Find the x/Y position of an object (from: http://www.quirksmode.org/js/findpos.html).
		// This doesn't take into account scrolling - add the values from scrollOffsets.
		// @findPos	[int]	The x/y position.
		// @obj		Object	The object to check.
		///////////////////////////////////////////////////////////////////////////////////////////

		findPos : function (obj)
		{
			var	left = 0;
			var top = 0;

			if (obj.offsetParent)
			{
				left = obj.offsetLeft;
				top = obj.offsetTop;

				// WARNING: this loop will fail if it encounters a "position: relative" box

				while (obj = obj.offsetParent)
				{
					left += obj.offsetLeft;
					top += obj.offsetTop;
				}
			}

			return [left, top];
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Find the X/Y scroll positions of the browser window. From
		// http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html.
		// @scrollOffset	[int]	X/Y offset (if any).
		///////////////////////////////////////////////////////////////////////////////////////////

		scrollOffset : function ()
		{
			scX = _private.filterResults (window.pageXOffset ? window.pageXOffset : 0,
				document.documentElement ? document.documentElement.scrollLeft : 0,
				document.body ? document.body.scrollLeft : 0);

			scY = _private.filterResults (window.pageYOffset ? window.pageYOffset : 0,
				document.documentElement ? document.documentElement.scrollTop : 0,
				document.body ? document.body.scrollTop : 0);

			return [scX, scY];
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Get the current browser window size. From
		// www.howtocreate.co.uk/tutorials/javascript/browserwindow
		// @getWindowSize	[int]	Array of width/height.
		///////////////////////////////////////////////////////////////////////////////////////////

		getWindowSize : function ()
		{
			var w = 0, h = 0;

			if (typeof (window.innerWidth) == 'number')
			{
				// Standard

				w = window.innerWidth;
				h = window.innerHeight;
			}
			else
			if (document.documentElement && (document.documentElement.clientWidth ||
				document.documentElement.clientHeight))
			{
				// IE 6+ in 'standards compliant mode'

				w = document.documentElement.clientWidth;
				h = document.documentElement.clientHeight;
			}
			else
			if (document.body && (document.body.clientWidth || document.body.clientHeight))
			{
				// IE 4 compatible

				w = document.body.clientWidth;
				h = document.body.clientHeight;
			}

			return [w, h];
		},

		///////////////////////////////////////////////////////////////////////////////////////////
		// Used by SEF_TABLE entry in dbscreens.php.
		///////////////////////////////////////////////////////////////////////////////////////////

		selectMove : function (fn, md)
		{
			var selList = document.getElementById (fn + "_sel");
			var avList = document.getElementById (fn + "_av");
			var mainList = document.getElementById (fn);
			var from = avList;
			var to = selList;

			if (md == 1)
			{
				from = selList;
				to = avList;
			}

			if (from.length > 0)
			{
				var idx = from.selectedIndex;

				if (idx > -1)
				{
					var txt = from.options [idx].text;
					var val = from.options [idx].value;
					var newOpt = new Option (txt, val);
					var done = false;

					for (i = 0; i < to.length; i++)
						if (txt < to.options [i].text)
						{
							to.options.add (newOpt, i);
							done = true;
							break;
						}

					if (!done)
						to.options.add (newOpt, to.length);

					from.options [idx] = null;
				}

				var sList = "^";

				if (selList.length > 0)
				{
					for (i = 0; i < selList.length; i++)
					{
						sList += selList.options [i].value + "^";
					}
				}

				if (sList == "^") sList = "";

				mainList.value = sList;
			}
		},

		///////////////////////////////////////////////////////////////////////////////////////////
		// Fill the specified drop-down menu with the supplied array.
		///////////////////////////////////////////////////////////////////////////////////////////

		fillMenu : function (fn, data)
		{
			var menu = document.getElementById (fn);

			// Remove any existing entries

			if (menu.length > 0)
			{
				for (i = menu.length - 1; i >= 0; i--)
				{
					menu.options [i] = null;
				}
			}

			// Add in the new options

			for (i = 0; i < data.length; i++)
			{
				var newOpt = (isArray (data [i]) ? new Option (data [i][1], data [i][0]) :
					new Option (data [i], data [i]));

				menu.options.add (newOpt, i);
			}
		},

		///////////////////////////////////////////////////////////////////////////////////////////
		// Initialise the taField values.
		///////////////////////////////////////////////////////////////////////////////////////////

		initTA : function (taFlds, minRows, maxRows)
		{
			ta.flds = taFlds;
			ta.minRows = minRows;
			ta.maxRows = maxRows;
		},

		///////////////////////////////////////////////////////////////////////////////////////////
		// Handle a taField vertical size.
		///////////////////////////////////////////////////////////////////////////////////////////

		expandTA : function (fld)
		{
			for (i = 0; i < ta.flds.length; i++)
			{
				document.getElementById (ta.flds [i]).rows =
					(fld == ta.flds [i] ? ta.maxRows : ta.minRows);
			}
		},

		///////////////////////////////////////////////////////////////////////////////////////////
		// Toggle the visibility of the image change fields (SEF_IMAGE).
		///////////////////////////////////////////////////////////////////////////////////////////

		imgChgFlds : function (fld)
		{
			var f = document.getElementById ("ichg" + fld).style;
			f.display = (f.display == "none" ? "inline" : "none");
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Initialise an AJAX connection.
		// @initAjax	object	The ajax object.
		// @url			string	The URL of the ajax handler.
		// @resp		object	The function object	that will handle the ajax response (can be
		//						blank if no response required).
		///////////////////////////////////////////////////////////////////////////////////////////

		initAjax : function (url, resp)
		{
			var xmlHttp;

			xmlHttp = (window.XMLHttpRequest ? new XMLHttpRequest () :
				new ActiveXObject ("MSXML2.XMLHTTP"));

			xmlHttp.open ("GET", url, true);

			if (resp != "") xmlHttp.onreadystatechange = resp;

			xmlHttp.send (null);

			return xmlHttp;
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Return true if there is a valid response from the specified AJAX connection.
		// @checkAjax	boolean	True if valid.
		// @ajax		object	The ajax object to be checked.
		///////////////////////////////////////////////////////////////////////////////////////////

		checkAjax : function (ajax)
		{
			return (ajax != null && ajax.readyState == 4 && ajax.status == 200);
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Set the opacity level of the specified object.
		// @opacity
		// @o		object	The object to use.
		// @opac	int		The opacity level to use (0 to 100).
		///////////////////////////////////////////////////////////////////////////////////////////

		opacity : function (o, opac)
		{
			o.style.opacity = (opac / 100);
			o.style.MozOpacity = (opac / 100);
			o.style.KhtmlOpacity = (opac / 100);
			o.style.filter = "alpha(opacity=" + opac + ")";
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Return the version number given a string and a starting position (version numbers are
		// assumed to contain only digits and dots).
		// @versionNumber	string	The version number.
		// @str				string	The string to use.
		// @pos				int		The starting position.
		///////////////////////////////////////////////////////////////////////////////////////////

		versionNumber : function (str, pos)
		{
			var version = "";

			while ((str.charAt (pos) >= '0' && str.charAt (pos) <= '9') || str.charAt (pos) == '.')
			{
				version += str.charAt (pos++);
			}

			return version;
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Return information about the platform, browser and browser version.
		// @systemCheck	array	[platform, browser, version].
		///////////////////////////////////////////////////////////////////////////////////////////

		systemCheck : function ()
		{
			var	browser = '?';
			var	platform = '?';
			var ua = navigator.userAgent;

			var iWebTV = ua.indexOf ('WebTV');
			var iIE = ua.indexOf ('MSIE');
			var iOpera = ua.indexOf ('Opera');
			var iChrome = ua.indexOf ('Chrome');
			var iSafari = ua.indexOf ('Safari');
			var iMozilla = ua.indexOf ('Gecko');
			var iFirefox = ua.indexOf ('Firefox');
			var iKonqueror = ua.indexOf ('Konqueror');
			var iNetscape = ua.indexOf ('Mozilla');
			var iCamino = ua.indexOf ('Camino');

			var ver = -1;

			if (iWebTV >= 0)
			{
				browser = 'WebTV';
				ver = iWebTV + 6;
			}
			else
			if (iOpera >= 0)
			{
				browser = 'Opera';
				ver = iOpera + 6;
			}
			else
			if (iIE >= 0)
			{
				browser = 'Internet Explorer';
				ver = iIE + 5;
			}
			else
			if (iChrome >= 0)
			{
				browser = 'Chrome';
				ver = iChrome + 7;
			}
			else
			if (iCamino >= 0)
			{
				browser = 'Camino';
				ver = ua.indexOf('Camino/') + 7;
			}
			else
			if (iSafari >= 0)
			{
				browser = 'Safari';
				ver = iSafari + 7;
			}
			else
			if (iFirefox >= 0)
			{
				browser = 'Firefox';
				ver = ua.indexOf('Firefox/') + 8;
			}
			else
			if (iMozilla >= 0)
			{
				browser = 'Mozilla';
				ver = ua.indexOf('rv:') + 3;
			}
			else
			if (iKonqueror >= 0)
			{
				browser = 'Konqueror';
				ver = iKonqueror + 10;
			}
			else
			if (iNetscape >= 0)
			{
				browser = 'Netscape';
				ver = iNetscape + 8;
			}

			var version = DLibUtilities.versionNumber (ua, ver);

			if (ua.indexOf ('Win') >= 0)
			{
				platform = 'Windows';

				if (ua.indexOf ('95') >= 0) platform += " 95";
				else if (ua.indexOf ('98') >= 0) platform += " 98";
				else if (ua.indexOf ('2000') >= 0) platform += " 2000";
				else if (ua.indexOf ('NT 5.2') >= 0) platform += " XP/2003";
				else if (ua.indexOf ('NT 5.1') >= 0) platform += " XP";
				else if (ua.indexOf ('NT 5.0') >= 0) platform += " 2000";
				else if (ua.indexOf ('NT 6.0') >= 0) platform += " Vista";
				else if (ua.indexOf ('NT 6.1') >= 0) platform += " 7";
				else if (ua.indexOf ('NT') >= 0) platform += " NT";
			}

			if (ua.indexOf ('Mac') >= 0)		platform = 'Macintosh';
			if (ua.indexOf ('Mac OS X') >= 0)	platform = 'Mac OS X';
			if (ua.indexOf ('OS/2') >= 0)		platform = 'OS/2';
			if (ua.indexOf ('X11') >= 0)		platform = 'UNIX';
			if (ua.indexOf ('Linux') >= 0)		platform = 'Linux';

			var ub = ua.indexOf ('Ubuntu/');
			if (ub >= 0) platform = 'Ubuntu Linux ' + DLibUtilities.versionNumber (ua, ub + 7);

			if (browser == "Netscape" && version >= 5 && version < 7) version = 6;

			return [platform, browser, version];
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Return true if the specified value is found in the array to test. Based on the code at:
		// kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_in_array
		// @in_array	boolean		True if found.
		// @needle		mixed		The item to search for.
		// @haystack	array		Array to be tested.
		///////////////////////////////////////////////////////////////////////////////////////////

		in_array : function (needle, haystack)
		{
			var key = '';

			for (key in haystack)
			{
				if (haystack [key] === needle) return true;
			}

			return false;
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Return the specified number of non-blank spaces.
		// @spaces	string	The "nbsp" characters.
		// @qty		int		The number required.
		///////////////////////////////////////////////////////////////////////////////////////////

		spaces : function (qty)
		{
			var txt = "";

			for (i = 0; i < qty; i++)
				txt += "&nbsp;";

			return txt;
		},

		//F////////////////////////////////////////////////////////////////////////////////////////
		// Return the specified CSS style of an object (based upon code found at
		// www.quirksmode.org/dom/getstyles.html).
		// @getStyle	string	The currently assigned style.
		// @id			string	The ID of the object to interrogate.
		// @prop		string	The property to return.
		///////////////////////////////////////////////////////////////////////////////////////////

		getStyle : function (id, prop)
		{
			var obj = document.getElementById (id);

			if (obj.currentStyle) return obj.currentStyle [prop];
			return document.defaultView.getComputedStyle (obj, null).getPropertyValue (prop);
		}
	};

	return _public;
} ();

///////////////////////////////////////////////////////////////////////////////////////////////////


