/**
 * The JavaScript main object for the KramTek Framework
 * 
 * LICENSE: This source file is owned by KramTek Computing
 * Under no circumstances may this code be used or duplicated without
 * written permission from KramTek Computing
 *
 * @author     Mark Boon <mark@kramtek.com.au>
 * @copyright  Copyright (c) 2005-2008, KramTek Computing (http://www.kramtek.com.au/)
 * @package    KramTek
 * @subpackage JavaScript
 * @version    2.00 2007-01-27 09:00
 *
 */

// Set namespace
if (typeof KramTek == "undefined") { KramTek = {}; }

KramTek = function() 
{

	// Private
	var _scriptName    = "kramtek.js";
	var _scriptUrl 	   = '';
	var _imagesUrl 	   = _scriptUrl + "images/";
	var _cssUrl 	   = _scriptUrl + "css/";
	var _majorVersion  = '2';
	var _minorVersion  = '00';
	var _releaseDate   = '27-01-2007';
	var _scriptsLoaded = ["kramtek.js"];
	var _cssLoaded 	   = [];

	return {
		
		/**
		 * Initialisation
		 */
		init : function()
		{
			_scriptUrl = this.getUrl(_scriptName);
			_imagesUrl = _scriptUrl + "images/";
			_cssUrl    = _scriptUrl + "css/";
		},
	
		/**
		 * Initialise Listeners
		 */
		initListeners : function()
		{
			KramTek.popupListeners();
			KramTek.sortableTables();
			KramTek.fixPng();
		},
	
		/**
		 * Sets the popup listener events
		 */
		popupListeners : function()
		{
			// Get the 'anchor' elements
			var anchorTags = document.getElementsByTagName('a');
		
			// anchor events
			for (var i = 0; i < anchorTags.length; i++) {
				
				switch(true) {
					
					// Show popup window
					case anchorTags[i].className.indexOf('showPopup') > -1:
						KramTek.Events.attach(anchorTags[i], "click", KramTek.showPopup, false);
					break;
	
					// Close popup window
					case anchorTags[i].className.indexOf('closePopup') > -1:
						KramTek.Events.attach(anchorTags[i], "click", KramTek.closePopup, false);
					break;
				}
			}
			return true;
		}, // End of KramTek.popupListeners();
	
		/**
		 * Sets the Sortable Table listener events
		 */
		sortableTables : function()
		{
			var tables = KramTek.getElementsByAttribute("class", "sortableTable");
			
			for (var i = 0; i < tables.length; i++) {
						
				var ths = tables[i].getElementsByTagName("th");
			
				for (var k = 0; k < ths.length; k++) {
					var newA = KramTek.newElement('a', ['href', 'title'], ['#', 'Sort by this column in descending order']);
					for (var m = 0; m < ths[k].childNodes.length; m++) { newA.appendChild(ths[k].childNodes[m]); }
					ths[k].appendChild(newA);
					KramTek.Events.attach(newA, "click", KramTek.sortColumn, false);
				}
			}
			return true;
		}, // End of KramTek.sortableTables();
	
		// Detecting the load event
		addLoadListener : function(fn)
		{
			if (typeof window.addEventListener != 'undefined') {
	
				window.addEventListener('load', fn, false);
	
			} else if (typeof document.addEventListener != 'undefined') {
	
				document.addEventListener('load', fn, false);
	
			} else if (typeof window.attachEvent != 'undefined') {
	
				window.attachEvent('onload', fn);
	
			} else {
	
				var oldfn = window.onload;
				window.onload = (typeof window.onload != 'function') ? fn : window.onload = function() { oldfn(); fn(); };
			}
		},
	
		// Dynamically loads JavaScript files for the KramTek Framework
		include : function(script, cb, defer)
		{
			var url = _scriptUrl + script;
			var callback = cb;
			
			// Only need to load the script once
			var num = _scriptsLoaded.length;
			for (var i = 0; i < num; i++) { if (_scriptsLoaded[i] == script) { return; } }
			
			_scriptsLoaded[num] = script;
			var scriptTag = document.createElement("script");
				scriptTag.setAttribute("src", url);
				scriptTag.setAttribute("type", "text/javascript");
				
			if (defer) { scriptTag.setAttribute("defer", "defer"); }
	
			document.getElementsByTagName("head")[0].appendChild(scriptTag);
			
			if (cb) {
				scriptTag.onreadystatechange = function () { if (this.readyState == 'loaded' || this.readyState == 'complete') { callback(); } }
				scriptTag.onload = callback;
			}
		},
	
		// Dynamically loads CSS files for the KramTek Framework
		includeCSS : function(css)
		{
			var url = _cssUrl + css;
			
			// Only need to load the CSS once
			var num = _cssLoaded.length;
			for (var i = 0; i < num; i++) { if (_cssLoaded[i] == css) { return; } }
			
			_cssLoaded[num] = css;
			var linkTag = document.createElement("link");
				linkTag.setAttribute("href", url);
				linkTag.setAttribute("type", "text/css");
				linkTag.setAttribute("rel", "stylesheet");
				
			document.getElementsByTagName("head")[0].appendChild(linkTag);
		},
	
		// Returns the URL or the supplied script name
		getUrl : function(scriptName)
		{
			var scriptTags = document.getElementsByTagName("script");
			for (var i = 0; i < scriptTags.length; i++) {
				var src = scriptTags[i].getAttribute('src');
				if (src != null && src.indexOf(scriptName) > -1) {
					return src.replace(/\\/g,'/').replace(/\/[^\/]*\/?$/, '') + "/";
					break;
				}
			}
			return false;
		},
	
		/**
		 * Function to handle the popup windows
		 * @param object The event listening object
		 * @return boolean false to cancel default action
		 */
		showPopup : function(event)
		{
			if (typeof event == "undefined") { event = window.event; }
		
			var target = KramTek.Events.getTarget(event);
			while (target.nodeName.toLowerCase() != "a") { target = target.parentNode; }
	
			var classValues = KramTek.getClass(target.className, 'showPopup');
	
			var width  = (typeof classValues[1] == 'undefined') ? 640 : classValues[1];
			var height = (typeof classValues[2] == 'undefined') ? 480 : classValues[2];
			var url    = target.getAttribute('href');
	
			KramTek.makePopup(url, width, height);
		
			// Stop event and default action
			KramTek.Events.stopEvent(event, true);
		
			//  For browsers not supporting W3C DOM
			return false;
		},
	
		/**
		 * Method to make a new popup
		 */
		makePopup : function(url, width, height, overflow)
		{
			if (isNaN(width) || width < 1) { width = 640; }
			if (isNaN(height) || height < 1) { height = 480; }
	
			if (overflow == '' || !/^(scroll|resize|both)$/.test(overflow)) { overflow = 'both'; }
	
			// Center popup window
			var left = Math.floor((screen.availWidth - width) / 2);
			var top = Math.floor((screen.availHeight - height) / 2);
	
			var win = window.open(url, '', 'width=' + width + ',height=' + height + ",left=" + left + ", top=" + top
								  + ',scrollbars=' + (/^(scroll|both)$/.test(overflow) ? 'yes' : 'no')
								  + ',resizable=' + (/^(resize|both)$/.test(overflow) ? 'yes' : 'no')
								  + ',status=yes,toolbar=no,menubar=no,location=no');
			return win;
		},
	
		closePopup : function(event)
		{
			if (typeof event == "undefined") { event = window.event; }
		
			var target = KramTek.Events.getTarget(event);
			while (target.nodeName.toLowerCase() != "a") { target = target.parentNode; }
	
			if (window.opener) { window.close(); }
			
			// Stop event and default action
			KramTek.Events.stopEvent(event, true);
		
			//  For browsers not supporting W3C DOM
			return false;
		},
	
		popupForm : function(formObj, formInputs, formButtons, formHidden)
		{
			var pageDimensions = KramTek.getPageDimensions();
			var viewportSize = KramTek.getViewportSize();
	
			if (viewportSize[1] > pageDimensions[1]) { pageDimensions[1] = viewportSize[1]; }
	
			var bodyElement = document.getElementsByTagName("body")[0];
			KramTek.createDropSheet();
	
			try {
	
				// Reminder - IE not happy with something.class
				var dialog = KramTek.newElement('div', ['id', 'class'], [formObj.id, formObj['class']]);
					dialog.style.visibility = "hidden";
					dialog.style.position = "absolute";
	
				var h1 = KramTek.newElement('h1', ['text'], [formObj.title]);
					dialog.appendChild(h1);
	
				var form = KramTek.newElement('form', formObj.attributes, formObj.attribValues);
	
				if (formObj.validation) {
					var div  = KramTek.newElement('div', ['class', 'text'], ['requiredInfo textRight', '* Required information ']);
					form.appendChild(div);
				}
	
				var para = []; var label = []; var span = []; var button = []; var hidden = []; var formElement = [];
	
				for (var i=0; i < formInputs.length; i++) {
	
					para[i] = KramTek.newElement('p', ['class'], ['noPadding']);
	
					if (typeof formInputs[i].validation == 'undefined') {
						label[i] = KramTek.newElement('label', ['class', 'htmlFor', 'text'], [formInputs[i].label[0], formInputs[i].label[1], formInputs[i].label[2]]);
					} else {
						label[i] = KramTek.newElement('label', ['class', 'htmlFor'], [formInputs[i].label[0], formInputs[i].label[1]]);
						span[i] = KramTek.newElement('span', ['class', 'text'], ['alert', '*']);
						label[i].appendChild(document.createTextNode(formInputs[i].label[2]));
						label[i].appendChild(span[i]);
					}
	
					para[i].appendChild(label[i]);
	
					switch (formInputs[i].type) {
					
						case "radio":
								
							var radioText = [];	
							var radioOption = [];	
							for (var j=0;j < formInputs[i].radioOptions.length; j++) {
								
								var textLabel = formInputs[i].radioOptions[j][0];
								var textValue = formInputs[i].radioOptions[j][1];
								radioText[j] = document.createTextNode(textLabel);
								para[i].appendChild(radioText[j]);
								radioOption[j] = KramTek.newElement('input', ['name', 'type', 'value'], [formInputs[i].name, 'radio', textValue]);
								para[i].appendChild(radioOption[j]);
							}
	
							break;
							
						case "select":
						
							break;
							
						default:
							
							formElement[i] = KramTek.newElement(formInputs[i].type, formInputs[i].attributes, formInputs[i].attribValues);
							para[i].appendChild(formElement[i]);
					}
	
					form.appendChild(para[i]);
				}
	
				// Buttons
				if (formButtons.length > 0) {
					var paraActions = KramTek.newElement('p', ['class', 'class'], ['noPadding', 'textRight']);
					for (var i=0; i < formButtons.length; i++) {
	
						button[i] = KramTek.newElement('input', formButtons[i].attributes, formButtons[i].attribValues);
						if (typeof formButtons[i].events != 'undefined') {
							KramTek.Events.attach(button[i], formButtons[i].events[0], formButtons[i].events[1], formButtons[i].events[2]);
						}
						paraActions.appendChild(button[i]);
					}
					form.appendChild(paraActions);
				}
	
				// Hidden Fields
				if (formHidden.length > 0) {
					for (var i=0; i < formHidden.length; i++) {
						hidden[i] = KramTek.newElement('input', formHidden[i].attributes, formHidden[i].attribValues);
						form.appendChild(hidden[i]);
					}
				}
	
				dialog.appendChild(form);
				bodyElement.appendChild(dialog);
	
				var scrollingPosition = KramTek.getScrollingPosition();
	
				dialog.style.left = scrollingPosition[0] + parseInt(viewportSize[0] / 2) - parseInt(dialog.offsetWidth / 2) + "px";
				dialog.style.top = scrollingPosition[1] + parseInt(viewportSize[1] / 2) - parseInt(dialog.offsetHeight / 2) + "px";
				dialog.style.visibility = "visible";
	
				formElement[0].focus();
	
			} catch(error) {
	
				KramTek.notify(error, 1);
				KramTek.removeDropSheet();
				return false;
			}
		}, // End of KramTek.popupForm();
	
		printWindow : function(event)
		{
			if (typeof event == "undefined") { event = window.event; }
	
			var target = KramTek.Events.getTarget(event);
			while (target.nodeName.toLowerCase() != "a" && target.nodeName.toLowerCase() != "input") { target = target.parentNode; }
	
			window.print();
	
			// Stop event and default action
			KramTek.Events.stopEvent(event, true);
	
			//  For browsers not supporting W3C DOM
			return false;
		},
	
		browser : function()
		{
			var agent = navigator.userAgent.toLowerCase();
	
			// Konqueror
			if (typeof navigator.vendor != "undefined" && navigator.vendor == "KDE" && typeof window.sidebar != "undefined") {
	
				return "kde";
	
			// Opera
			} else if (typeof window.opera != "undefined") {
	
				var version = parseFloat(agent.replace(/.*opera[\/ ]([^ $]+).*/, "$1"));
				if (version >= 7) { return "opera7"; } else if (version >= 5) { return "opera5"; }
	
				return false;
	
			// Windows
			} else if (typeof document.all != "undefined") {
	
				if (typeof document.getElementById != "undefined") {
	
					var browser = agent.replace(/.*ms(ie[\/ ][^ $]+).*/, "$1").replace(/ /, "");
	
					if (typeof document.uniqueID != "undefined") {
						return (browser.indexOf("5.5") != -1) ? browser.replace(/(.*5\.5).*/, "$1") : browser.replace(/(.*)\..*/, "$1");
					} else {
						return "ie5mac";
					}
				}
				return false;
	
			} else if (typeof document.getElementById != "undefined") {
	
				// Safari
				if (navigator.vendor.indexOf("Apple Computer, Inc.") != -1) {
	
					if (typeof window.XMLHttpRequest != "undefined") { return "safari1.2"; }
					return "safari1";
	
				// Mozilla		
				} else if (agent.indexOf("gecko") != -1) { return "mozilla"; }
			}
			return false;
		},
	
		// Removes a class value
		removeClass : function(target, classValue)
		{
			var removedClass = target.className.split(" ");
			for (var i=0; i < removedClass.length; i++) { if (removedClass[i].indexOf(classValue) > -1) { removedClass[i] = ""; } }
			target.className = removedClass.join(" ");
			return true;
		},
	
		// Adds a class value
		addClass : function(target, classValue)
		{
			if (target.className.indexOf(classValue) == -1) {
				if (target.className == "") { target.className = classValue; } else { target.className += " " + classValue; }
			}
			return true;
		},
	
		// Helper function to return the class values for the selected string, -1 if not found
		getClass : function(inputStr, valueStr)
		{
			// Split multiple classes, if any
			var classArray = inputStr.split(' ');
			for (var i=0; i < classArray.length; i++) {
				if (classArray[i].indexOf(valueStr) > -1) { 
					var classValues = classArray[i].split('_');
					// Return the array or string
					return (classValues.length > 1) ? classValues : classArray[i];
				}
			}
			return -1;
		},
	
		// returns an array of all elements in document for supplied 
		// attribute value, eg getElementsByAttribute('class', 'myClass');
		getElementsByAttribute : function(attribute, attributeValue)
		{
			var elementArray = new Array();
			var matchedArray = new Array();
			// May need to change to indexOf if value contains other characters
			var pattern = new RegExp("(^| )" + attributeValue + "( |$)");
	
			elementArray = (document.all) ? document.all : document.getElementsByTagName("*");
	
			for (var i = 0; i < elementArray.length; i++) {
	
				switch(attribute) {
	
					case "class":
	
						if (pattern.test(elementArray[i].className)) { matchedArray[matchedArray.length] = elementArray[i]; }
						break;
	
					case "for":
	
						if (elementArray[i].getAttribute("htmlFor") || elementArray[i].getAttribute("for")) {
							if (elementArray[i].htmlFor == attributeValue) { matchedArray[matchedArray.length] = elementArray[i]; }
						}
						break;
	
					default:
	
						if (elementArray[i].getAttribute(attribute) == attributeValue) { matchedArray[matchedArray.length] = elementArray[i]; }
				}
			}
			return matchedArray;
		},
	
		// Removes supplied chars from start and end of string.
		// Usually used to strip spaces
		trim : function(str, chars)
		{
			return KramTek.ltrim(KramTek.rtrim(str, chars), chars);
		},
	
		// Removes supplied chars from start of string.
		ltrim : function(str, chars)
		{
			chars = chars || "\\s";
			return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
		},
	
		// Removes supplied chars from end of string.
		rtrim : function(str, chars)
		{
			chars = chars || "\\s";
			return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
		},
	
		// Returns the actual viewpoint size of window
		getViewportSize : function()
		{
			var size = [0, 0];
	
			if (typeof window.innerWidth != 'undefined') {
	
				size = [window.innerWidth, window.innerHeight];
	
			} else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined'
						&& document.documentElement.clientWidth != 0) {
	
				size = [document.documentElement.clientWidth, document.documentElement.clientHeight];
	
			} else {
	
				size = [document.getElementsByTagName('body')[0].clientWidth, document.getElementsByTagName('body')[0].clientHeight];
			}
	
			return size;
		},
	
		// Returns the current page dimensions
		getPageDimensions : function()
		{
			var body = document.getElementsByTagName("body")[0];
			var bodyOffsetWidth = 0;
			var bodyOffsetHeight = 0;
			var bodyScrollWidth = 0;
			var bodyScrollHeight = 0;
			var pageDimensions = [0, 0];
	
			if (typeof document.documentElement != "undefined" && typeof document.documentElement.scrollWidth != "undefined") {
				pageDimensions[0] = document.documentElement.scrollWidth;
				pageDimensions[1] = document.documentElement.scrollHeight;
			}
	
			bodyOffsetWidth = body.offsetWidth;
			bodyOffsetHeight = body.offsetHeight;
			bodyScrollWidth = body.scrollWidth;
			bodyScrollHeight = body.scrollHeight;
	
			if (bodyOffsetWidth > pageDimensions[0]) { pageDimensions[0] = bodyOffsetWidth; }
			if (bodyOffsetHeight > pageDimensions[1]) { pageDimensions[1] = bodyOffsetHeight; }
			if (bodyScrollWidth > pageDimensions[0]) { pageDimensions[0] = bodyScrollWidth; }
			if (bodyScrollHeight > pageDimensions[1]) { pageDimensions[1] = bodyScrollHeight; }
	
			return pageDimensions;
		},
	
		// Returns the current scrolling position
		getScrollingPosition : function()
		{
			var position = [0, 0];
	
			// If the window.pageYOffset property is supported
			if (typeof window.pageYOffset != 'undefined') { position = [window.pageXOffset, window.pageYOffset]; }
	
			// If the documentElement.scrollTop property is supported and the value is greater than zero
			if (typeof document.documentElement.scrollTop != 'undefined' && document.documentElement.scrollTop > 0) {
				position = [document.documentElement.scrollLeft, document.documentElement.scrollTop];
					// If the body.scrollTop property is supported
			} else if (typeof document.body.scrollTop != 'undefined') { 
						position = [document.body.scrollLeft, document.body.scrollTop];
			}
			//return the array
			return position;
		},
	
		// Function to create a Drop Sheet
		createDropSheet : function()
		{
			var bodyElement = document.getElementsByTagName("body")[0];
			var pageDimensions = KramTek.getPageDimensions();
			var viewportSize = KramTek.getViewportSize();
	
			if (viewportSize[1] > pageDimensions[1]) { pageDimensions[1] = viewportSize[1]; }
	
			var dropSheet = document.createElement("div");
	
			dropSheet.setAttribute("id", "dropSheet");
			dropSheet.style.position = "absolute";
			dropSheet.style.left = "0";
			dropSheet.style.top = "0";
			dropSheet.style.width = pageDimensions[0] + "px";
			dropSheet.style.height = pageDimensions[1] + "px";
			bodyElement.appendChild(dropSheet);
		},
	
		// Function to remove a DropSheet
		removeDropSheet : function()
		{
			var dropSheet = document.getElementById("dropSheet");
			if (typeof dropSheet != 'undefined') { dropSheet.parentNode.removeChild(dropSheet); }
		},
	
		// Removes the dropsheet from main page 
		closeDialog : function(dialog)
		{
			KramTek.removeDropSheet();
			dialog.parentNode.removeChild(dialog);
			return true;
		},
	
		// Creates a dialog box
		createDialog : function(event)
		{
			var title = "";
			var msg = "";
			var action = "";
			var actionClass = "dialogAction";
			var pageDimensions = KramTek.getPageDimensions();
			var viewportSize = KramTek.getViewportSize();
	
			if (viewportSize[1] > pageDimensions[1]) { pageDimensions[1] = viewportSize[1]; }
	
			if (typeof event == "undefined") { event = window.event; }
	
			var target = KramTek.Events.getTarget(event);
	
			while (target.nodeName.toLowerCase() != "a") { target = target.parentNode; }
	
			// An array should be returned, the 2nd element is the callback function
			var classValues = KramTek.getClass(target.className, 'popupDialog');
	
			if (classValues[1]) {
				var funcRef = window[classValues[1]];
				// Double check the returned value is a function
				if (typeof funcRef == 'function') { 
					var actionParams = funcRef();
					title = actionParams[0];
					msg   = actionParams[1];
					if (actionParams[2]) { action = actionParams[2]; }
				}
			} else {
				title = "Confirmation Message";
				msg   = "Do you wish to continue with the requested action?";
			}
	
			var bodyElement = document.getElementsByTagName("body")[0];
			KramTek.createDropSheet();
	
			try {
	
				var dialog = document.createElement("div");
					dialog.className = "customDialog";
					dialog.style.visibility = "hidden";
					dialog.style.position = "absolute";
	
				var dialogTitle = document.createElement("h1");
					dialogTitle.appendChild(document.createTextNode(title));
					dialog.appendChild(dialogTitle);
	
				var dialogMessage = document.createElement("p");
					dialogMessage.appendChild(document.createTextNode(msg));
					dialog.appendChild(dialogMessage);
	
				var dialogForm = document.createElement("form");
					dialogForm.setAttribute("name", "frmDialog");
					dialogForm.setAttribute("action", action);
					dialogForm.setAttribute("method", "post");
					dialog.appendChild(dialogForm);
	
				var dialogButton1 = document.createElement("input");
					dialogButton1.setAttribute("type", "button");
					dialogButton1.setAttribute("value", "Yes");
					KramTek.Events.attach(dialogButton1, "click", KramTek.dialogClick, false);
					dialogForm.appendChild(dialogButton1);
	
				var dialogButton3 = document.createElement("input");
					dialogButton3.setAttribute("type", "button");
					dialogButton3.setAttribute("value", "Cancel");
					KramTek.Events.attach(dialogButton3, "click", KramTek.dialogClick, false);
					dialogForm.appendChild(dialogButton3);
	
				bodyElement.appendChild(dialog);
	
				var scrollingPosition = KramTek.getScrollingPosition();
	
				dialog.style.left = scrollingPosition[0] + parseInt(viewportSize[0] / 2) - parseInt(dialog.offsetWidth / 2) + "px";
				dialog.style.top = scrollingPosition[1] + parseInt(viewportSize[1] / 2) - parseInt(dialog.offsetHeight / 2) + "px";
				dialog.style.visibility = "visible";
	
				dialogButton1.focus();
	
			} catch(error) {
	
				KramTek.notify(error, 1);
				KramTek.removeDropSheet();
				return false;
			}
	
			// Stop event
			KramTek.Events.stopEvent(event);
	
			KramTek.Events.stopDefaultAction(event);
			
			// For browsers not supporting W3C DOM, return false to cancel default action
			return false;
		},
	
		// Action to take when a custom dialog button has been clicked
		dialogClick : function(event)
		{
			if (typeof event == "undefined") { event = window.event; }
			var target = KramTek.Events.getTarget(event);
			while (target.nodeName.toLowerCase() != "input") { target = target.parentNode; }
			var value = target.getAttribute("value");
	
			// Stop event
			KramTek.Events.stop(event);
	
			// A cancelled action or just an acknowledgement box
			if (value == "Cancel" || value == "Ok") {
				var dialog = target;
				while (dialog.className != "customDialog" && dialog.className != "popupForm") { dialog = dialog.parentNode; }
				KramTek.closeDialog(dialog);
			} else {
				document.frmDialog.submit();
			}
	
			KramTek.Events.stopDefaultAction(event);
	
			// For browsers not supporting W3C DOM, return false to cancel default action
			return false;
		},
	
		// A wrapper function for creating elements
		newElement : function(type, attribs, attribValues)
		{
			var element = document.createElement(type);
	
			if (attribs) {
				for (var i=0; i < attribs.length; i++) {
	
					var value = attribValues[i];
					var attribute = attribs[i];
	
					switch(attribs[i]) {
	
						case 'class':
							KramTek.addClass(element, value);
							break;
	
						case 'text':
							element.appendChild(document.createTextNode(value));
							break;
	
						default:
							element.setAttribute(attribute, value);
					}
				}
			}
	
			return element;
		}, // End of KramTek.newElement();
	
		sortColumn : function(event)
		{
			if (typeof event == "undefined") { event = window.event; }
	
			var targetA = KramTek.Events.getTarget(event);
			while (targetA.nodeName.toLowerCase() != "a") { targetA = targetA.parentNode; }
	
			var targetTh = targetA.parentNode;
			var targetTr = targetTh.parentNode;
			var targetTrChildren = targetTr.getElementsByTagName("th");
			var targetTable = targetTr.parentNode.parentNode;
			var targetTbody = targetTable.getElementsByTagName("tbody")[0];
			var targetTrs = targetTbody.getElementsByTagName("tr");
			var targetColumn = 0;
	
			for (var i = 0; i < targetTrChildren.length; i++) {
	
				targetTrChildren[i].className = targetTrChildren[i].className.replace(/(^| )sortedDescending( |$)/, "$1");
				targetTrChildren[i].className = targetTrChildren[i].className.replace(/(^| )sortedAscending( |$)/, "$1");
	
				if (targetTrChildren[i] == targetTh) {
					targetColumn = i;
	
					if (targetTrChildren[i].sortOrder == "descending" && targetTrChildren[i].clicked) {
						targetTrChildren[i].sortOrder = "ascending";
						targetTrChildren[i].className += " sortedAscending";
						targetA.setAttribute("title", "Sort by this column in descending order");
					} else {
						if (targetTrChildren[i].sortOrder == "ascending" && !targetTrChildren[i].clicked) {
							targetTrChildren[i].className += " sortedAscending";
						} else {
							targetTrChildren[i].sortOrder = "descending";
							targetTrChildren[i].className += " sortedDescending";
							targetA.setAttribute("title", "Sort by this column in ascending order");
						}
					}
	
					targetTrChildren[i].clicked = true;
				} else {
					targetTrChildren[i].clicked = false;
	
					if (targetTrChildren[i].sortOrder == "ascending") {
						targetTrChildren[i].firstChild.setAttribute("title", "Sort by this column in ascending order");
					} else {
						targetTrChildren[i].firstChild.setAttribute("title", "Sort by this column in descending order");
					}
				}
			}
	
			var newTbody = targetTbody.cloneNode(false);
	
			for (var i = 0; i < targetTrs.length; i++) {
				var newTrs = newTbody.childNodes;
				var targetValue = KramTek.getInternalText(targetTrs[i].getElementsByTagName("td")[targetColumn]);
	
				for (var j = 0; j < newTrs.length; j++) {
					var newValue = KramTek.getInternalText(newTrs[j].getElementsByTagName("td")[targetColumn]);
	
					if (targetValue == parseInt(targetValue, 10) && newValue == parseInt(newValue, 10)) {
						targetValue = parseInt(targetValue, 10);
						newValue = parseInt(newValue, 10);
					} else if (targetValue == parseFloat(targetValue) && newValue == parseFloat(newValue)) {
						targetValue = parseFloat(targetValue, 10);
						newValue = parseFloat(newValue, 10);
					}
	
					if (targetTrChildren[targetColumn].sortOrder == "descending") {
						if (targetValue >= newValue) { break; }
					} else {
						if (targetValue <= newValue) { break; }
					}
				}
	
				if (j >= newTrs.length) {
					newTbody.appendChild(targetTrs[i].cloneNode(true));
				} else {
					newTbody.insertBefore(targetTrs[i].cloneNode(true), newTrs[j]);
				}
			}
	
			targetTable.replaceChild(newTbody, targetTbody);
	
			// Stop event and default action
			KramTek.Events.stopEvent(event, true);
		
			//  For browsers not supporting W3C DOM
			return false;
		},
	
		getInternalText : function(target)
		{
			var elementChildren = target.childNodes;
			var internalText = "";
			
			for (var i = 0; i < elementChildren.length; i++) {
				if (elementChildren[i].nodeType == 3) {
					if (!/^\s*$/.test(elementChildren[i].nodeValue)) { internalText += elementChildren[i].nodeValue; }
				} else {
					internalText += KramTek.getInternalText(elementChildren[i]);
				}
			}
			return internalText;
		}, // End of KramTek.getInternalText();
	
		// Preloads specified images
		// eg. KramTek.preloadImages( 'image01.gif', 'image02.gif' );
		preloadImages : function()
		{ 
			var args = KramTek.preloadImages.arguments;
			document.imageArray = new Array(args.length);
		
			for(var i=0; i<args.length; i++) {
				document.imageArray[i] = new Image;
				document.imageArray[i].src = args[i];
			}
		}, // End of KramTek.preloadImages();
	
		// Pads supplied value with leading chars
		padLeft : function(value, chars, numChars)
		{ 
			var padded = "";
			var converted = "";
			var convert = value.toString();
			
			if (convert.length >= numChars) {
				converted = convert;
			} else {
				for (var i=0; i < numChars - convert.length; i++) { padded += chars; }
				converted = padded + convert;
			}
	
			return converted;
		
		}, // End of KramTek.padLeft();
	
		// Pads supplied value with trailing chars
		padRight : function(value, chars, numChars)
		{ 
			var padded = "";
			var converted = "";
			var convert = value.toString();
			
			if (convert.length >= numChars) {
				converted = convert;
			} else {
				for (var i=0; i < numChars - convert.length; i++) { padded += chars; }
				converted = convert + padded;
			}
	
			return converted;
		
		}, // End of KramTek.padRight();
		
		// Function used to 'fix' png images in IE6
		fixPng : function()
		{
			var browser = KramTek.browser();
			var ie6 = (browser.substring(0, 2) == 'ie' && browser.substring(2) == '6') ? true : false;
			if (!ie6) { return; }
	
			var imgTags = document.getElementsByTagName('img');
	
			for (var i=0; i < imgTags.length; i++) {
	
				var img = imgTags[i];
				var src = img.src.toUpperCase();
	
				if (src.substring(src.length - 3, src.length) == "PNG") {
	
					var imgTitle = (img.title) ? img.title : img.alt;
					var spanElement = KramTek.newElement('span', ['id', 'title', 'class'], [img.id, imgTitle, img.className]);
						// Styles
						spanElement.style.width = img.offsetWidth + "px";
						spanElement.style.height = img.offsetHeight + "px";
						spanElement.style.display = "inline-block";
						spanElement.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.src + "', sizingMethod='crop')";
						if (img.parentNode.href) { spanElement.style.cursor = "hand"; }
						img.replaceNode(spanElement);
					i = i - 1;
				}
			}
		
		}, // End of KramTek.fixPng();
	
		// Removes all children from supplied Parent Node
		removeChildren : function(parent) {
			while(parent.hasChildNodes()) { parent.removeChild(parent.childNodes[0]) }
		}, // End of KramTek.removeChildren();
		
		// Displays a notification message to user or diagnostics
		notify : function(message, debug)
		{
			var title = "System Message";
			var pageDimensions = KramTek.getPageDimensions();
			var viewportSize = KramTek.getViewportSize();
	
			var defaultMsg = "Sorry, there has been a problem processing your request. ";
				defaultMsg += "If the problem persists, please contact us. ";
				defaultMsg += "Support have been notfied. ";
			
			displayMsg = (debug == 0) ? defaultMsg : message;
	
			if (viewportSize[1] > pageDimensions[1]) { pageDimensions[1] = viewportSize[1]; }
			
			var bodyElement = document.getElementsByTagName("body")[0];
			KramTek.createDropSheet();
		
			try {
				
				var dialogForm = KramTek.newElement('form', ['name', 'action', 'method'], ['frmDialog', '', 'post']);
	
				var dialog = KramTek.newElement('div', ['class'], ['dialogBox']);
					dialog.style.visibility = "hidden";
					dialog.style.position = "absolute";
			
				var headerBox = KramTek.newElement('div', ['class'], ['dialogBox_head']);
				var dialogTitle = KramTek.newElement('h2', ['text'], [title]);
					headerBox.appendChild(dialogTitle);
					dialog.appendChild(headerBox);
	
				var contentBox = KramTek.newElement('div', ['class'], ['dialogBox_body']);
				var dialogMessage = KramTek.newElement('p', ['text'], [displayMsg]);
					contentBox.appendChild(dialogMessage);
					dialog.appendChild(contentBox);
			
				var dialogButton1 = KramTek.newElement('input', ['type', 'value'], ['button', 'Ok']);
					KramTek.Events.attach(dialogButton1, "click", KramTek.dialogClick, false);
					contentBox.appendChild(dialogButton1);
				
				dialogForm.appendChild(dialog);
				bodyElement.appendChild(dialog);
				
				var scrollingPosition = KramTek.getScrollingPosition();
				
				dialog.style.left = scrollingPosition[0] + parseInt(viewportSize[0] / 2) - parseInt(dialog.offsetWidth / 2) + "px";
				dialog.style.top = scrollingPosition[1] + parseInt(viewportSize[1] / 2) - parseInt(dialog.offsetHeight / 2) + "px";
				dialog.style.visibility = "visible";
				
				dialogButton1.focus();
		
			} catch(error) {
		
				alert(error);
				KramTek.removeDropSheet();
				return false;
			}
	
		}, // End of KramTek.notify();
	
		// Used to decode objects
		debugObject : function(object)
		{
			if (typeof object == "undefined" || typeof object == null) { alert('Object Undefined'); return; }
	
			var win = window.open('', win, 'width=320,height=240');
				win.document.open();
				win.document.write('<ul>');
			
			for (var i in object) { win.document.write('<li>' + i + " = " + object[i] + '</li>'); }
			
			win.document.write('</ul>');
			win.document.close();
		},
	
		// Used for debugging
		debugElement : function(element)
		{
			if (typeof element == "undefined" || typeof element == null) { alert(element + ' Undefined'); }
	
			var win = window.open('', win, 'width=320,height=240');
				win.document.open();
				win.document.write('<ul>');
	
			for (var i=0; i < element.attributes.length; i++) {
				win.document.write('<li>' + element.attributes[i].nodeName + " = " + element.attributes[i].nodeValue + '</li>');
			}
			
			win.document.write('</ul>');
			win.document.close();
		} // End of KramTek.debugElement();
	};
}();
KramTek.init();
KramTek.include('kramtek_events.js');
KramTek.includeCSS('js_styles.css');