/*
Copyright (C)  TicketGang 2007-2010. All rigths Reserved.
*/
function TGisMSIE() {
	if (navigator.userAgent.toLowerCase().indexOf('msie')>=0) 
		return true;
	else 
		return false;
}
function TGToggleDisplay(target) {
	var targetObj = document.getElementById(target);
	if (targetObj == null) {
		alert('TGToggleDisplay: target[' + target + '] should be defined!');
		return;
	}
	if (targetObj.style.display != 'none') {
		targetObj.style.display = 'none';
	} else {
		targetObj.style.display = '';	
	}
}
function TGForceOnchange(obj) {
	if (document.createEvent) {	// FF, Opera, etc.
		var evt = document.createEvent('HTMLEvents');
		evt.initEvent('change', true, true);
		obj.dispatchEvent(evt);
	} else {	// IE
		obj.fireEvent('onclick');	// onchange doesn't seem to work on select box!!!
	}
}
function TGSRFormOrderingChange(selObj) {
	var ordering = selObj.options[selObj.selectedIndex].value;
	TGLoadContent('FormResponse', 'action.php?name=EventRowList&op=updord&ordering=' + ordering);
}
function TGExtOrgSaleVERowClickCallBack(obj) {
	var selId = obj.getAttribute('id');
	TGLoadContent('visitorEventTable', 'action.php?name=ExtSaleOrg&op=new&evt=' + selId);	
}
function TGReloadPage() {
	window.location.reload(false);
}
function TGObjMOverAction(obj) {
	clearTimeout(obj.outTimerId);
	obj.inTimerId = setTimeout(function(){TGShowEventDetail(obj)}, 500);
	obj.onmouseout = function(){TGObjMOutAction(obj)};
}
function TGShowEventDetail(obj) {
	var imgObjs = obj.getElementsByTagName('img');
	TGObjResize(imgObjs[0], null, '164', 0, 10);
	var divObjs = obj.getElementsByTagName('div');
	for (var i = 0; i < divObjs.length; i++) {
		var divObj = divObjs[i];
		if (divObj.id == 'calendar') divObj.style.display = 'block';
	}
}
function TGObjMOutAction(obj) {
	clearTimeout(obj.inTimerId);
	obj.outTimerId = setTimeout(function(){TGHideEventDetail(obj)}, 200);
}
function TGHideEventDetail(obj) {
	var imgObjs = obj.getElementsByTagName('img');
	TGObjResize(imgObjs[0], '80', null, 0, 10);
	var divObjs = obj.getElementsByTagName('div');
	for (var i = 0; i < divObjs.length; i++) {
		var divObj = divObjs[i];
		if (divObj.id == 'calendar') divObj.style.display = 'none';
	}
}
function TGObjResize(obj, width, height, speed, step) {
	var curWidth = obj.offsetWidth;
	var curHeight = obj.offsetHeight;
	var scaleFactor = 0;
	if (width) {
		scaleFactor = width / curWidth;
	} else if (height) {
		scaleFactor = height / curHeight;
	}	
	var newWidth = Math.round(curWidth * scaleFactor)
	var newHeight =  Math.round(curHeight * scaleFactor);
	if (speed == 0) {
		obj.style.width = newWidth + 'px';
		obj.style.height = newHeight + 'px';
		return;
	}
	//obj.intTimerId = setInterval(function(){TGObjSizeStep(obj, size, step)}, speed); 
}
function TGObjSizeStep(obj, size, step) {
	var reqSize = parseInt(size.slice(0, -2)); // Remove 'px'
	var curSize = parseInt(obj.style.width.slice(0, -2)); // Remove 'px'
	if (curSize < reqSize) {
		curSize = curSize + step; 
		obj.style.width = curSize + 'px';
		return;
	} 
	if (curSize > reqSize) {
		curSize = curSize - step; 
		obj.style.width = curSize + 'px';
		return;
	} 
	clearInterval(obj.intTimerId);
}
function TGShowHelpAction(helpShowId, helpContentId, redrawId) {
	var contentObj = document.getElementById(helpContentId);
	if (contentObj == null) {
		alert('helpContentId should be defined!');
	}
	contentObj.style.display = 'block';
	var helpShowObj = document.getElementById(helpShowId);
	if (helpShowObj == null) {
		alert('helpShowId should be defined!');
	}
	helpShowObj.style.display = 'none';
	TGIERedraw(redrawId);	
}
function TGHideHelpAction(helpShowId, helpContentId, redrawId) {
	var contentObj = document.getElementById(helpContentId);
	if (contentObj == null) {
		alert('helpContentId should be defined!');
	}
	contentObj.style.display = 'none';
	var helpShowObj = document.getElementById(helpShowId);
	if (helpShowObj == null) {
		alert('helpShowId should be defined!');
	}
	helpShowObj.style.display = 'block';
	TGIERedraw(redrawId);
}
function TGIERedraw(redrawId) {
	// Force redraw to circumvent an IE refresh bug ...
	if (!TGisMSIE()) return;
	if (redrawId == null) return;
	var redrawObj = document.getElementById(redrawId);
	if (redrawObj == null) return;
	redrawObj.style.display = 'none';
	redrawObj.style.display = 'block';	// Different table behaviour on IE and Firefox !
}
// ---------------------------------------------------------------------------------------------------------------

function displayQCalendar(m,y) {
	TGLoadContent('quickCalender', 'calendar.php?m=' + m + '&y=' + y);
}

// Browser pageWidth and pageHeight (C)  copyright Stephen Chapman.
function pageWidth() {return window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ?       document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;} 
function pageHeight() {return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;} 

TG = function() {
}
TG.prototype = {
	OrganizerLogin : function() {
		TGLoadContent('contentDiv','action.php?name=OrganizerContent');
		TGLoadContent('logoutContent','logout.php');	
	}
	,
	VisitorLogin : function() {
		TGLoadContent('contentDiv','visitorContent.php');
		TGLoadContent('logoutContent','logout.php');	
	}
}
// ----------------------------------------------------------------------------------------------------------------------
function TGFormFocus(formId) {
	var formObj = document.getElementById(formId);
	if (!formObj) return;
	var inpObj = formObj.getElementsByTagName('INPUT')[0];
	if (!inpObj) return;
	inpObj.focus();
}
// ----------------------------------------------------------------------------------------------------------------------
function TGTabbedUI(ulId) {
	var ulObj = document.getElementById(ulId);
	if (!ulObj) return;
	var liObj = ulObj.getElementsByTagName('LI')[0];
	if (!liObj) return;
	TGTabLoad(liObj);
}
// ----------------------------------------------------------------------------------------------------------------------
function TGModuleLoad(selObj) {
	var menuObj = selObj.parentNode;
	var menuItems = menuObj.childNodes;
	for (var i = 0; i < menuItems.length; i++) {
		var curItem = menuItems[i];
		curItem.className = 'TGModuleMenuItem';
		tgIconI = curItem.getAttribute('tg_icon_i');
		curItem.style.backgroundImage = 'url(' + tgIconI + ')';
	}
	selObj.className = 'TGModuleMenuItemSel';
	var tgUri = selObj.getAttribute('tg_uri');
	if (!tgUri) return;	
	var tgIconA = selObj.getAttribute('tg_icon_a');
	selObj.style.backgroundImage = 'url(' + tgIconA + ')';
	TGLoadContent('TGModuleContent', tgUri);
}
// ----------------------------------------------------------------------------------------------------------------------
function TGTabLoad(liObj) {
	var ulObj = liObj.parentNode;
	var lis = ulObj.childNodes;
	for (var i = 0; i < lis.length; i++) {
		var curLi = lis[i];
		curLi.className = '';
		var cDivName = curLi.getAttribute('tg_div');
		var cDiv = document.getElementById(cDivName);
		cDiv.style.display = 'none';
	}
	liObj.className = 'current';
	var tgDiv = liObj.getAttribute('tg_div');
	if (!tgDiv) return;
	var tgUri = liObj.getAttribute('tg_uri');
	if (!tgUri) return;	
	TGLoadContent(tgDiv, tgUri);
	cDiv = document.getElementById(tgDiv);
	cDiv.style.display = 'block';	
}
// ----------------------------------------------------------------------------------------------------------------------
function TGSortTable(colHeader) {
	var trNode = colHeader.parentNode;
	var theadNode = trNode.parentNode;
	var tableNode = theadNode.parentNode;
	var tableDivId = tableNode.id + '_div';
	
	var paramString = 'id=' + tableNode.id;
	paramString += '&si=' + colHeader.getAttribute('si');
	var newSortOrder = '';
	if (colHeader.getAttribute('so') == 'ASC')
		newSortOrder = 'DESC';
	else
		newSortOrder = 'ASC';
	paramString += '&so=' + newSortOrder;
	TGLoadContent(tableDivId, 'table.php?' + paramString);
}
function TGSortTable2(colHeader) {
	var trNode = colHeader.parentNode;
	var theadNode = trNode.parentNode;
	var tableNode = theadNode.parentNode;
	var tableDivId = tableNode.id + '_div';
	
	var paramString = 'id=' + tableNode.id;
	paramString += '&si=' + colHeader.getAttribute('si');
	var newSortOrder = '';
	if (colHeader.getAttribute('so') == 'ASC')
		newSortOrder = 'DESC';
	else
		newSortOrder = 'ASC';
	paramString += '&so=' + newSortOrder;
	TGLoadContent(tableDivId, 'tableView.php?' + paramString);
}
// ----------------------------------------------------------------------------------------------------------------------
function TGTable(tblId) {
	var tableObj = document.getElementById(tblId);
	var tableContainer = tableObj.parentNode;
	if (TGisMSIE()) {
		tableContainer.style.overflowY = 'scroll';
		tableContainer.style.overflowX = 'hidden';
		var tHead = tableObj.getElementsByTagName('THEAD')[0];
		var row = tHead.getElementsByTagName('TR')[0];
		row.style.position = 'relative';
	} else {
		tableContainer.style.overflow = 'hidden';
		var tBody = tableObj.getElementsByTagName('TBODY')[0];
		tBody.style.overflowY = 'scroll';
		tBody.style.overflowX = 'hidden';
		tBody.style.height = tableContainer.clientHeight - 100 + 'px';
	}
}
// ----------------------------------------------------------------------------------------------------------------------
TGDynamicContent = function() {
	var ajaxLoader;
}
TGDynamicContent.prototype = {
	load : function(divId, url) {
		if (!this.ajaxLoader) {
			this.ajaxLoader = document.getElementById('ajax_loader');
		}
		this.ajaxLoader.style.display = 'block';	// Show Ajax loader image
		var sackObj = new sack();
		sackObj.requestFile = url;
		sackObj.onCompletion = function(){_TGShowContent(sackObj, divId, url)};
		sackObj.onError = function(){_TGShowError(sackObj, divId, url)};
		sackObj.runAJAX();	
	}
}
function TGOrganizerLogin() {
	TGLoadContent('contentDiv','organizerContent.php');
	TGLoadContent('logoutContent','logout.php');
}
function TGVisitorLogin() {
	TGLoadContent('contentDiv','visitorContent.php');
	TGLoadContent('logoutContent','logout.php');
}
function TGEventFilter() {
	var paramString = TGEventFilterParams();
	if (paramString.length <= 0) return;
	TGLoadContent('visitorEventTable', 'action.php?name=VisitorEvents' + paramString);
}
function TGEventFilterAll() {
	TGLoadContent('visitorEventTable', 'action.php?name=VisitorEvents');
}
function TGEventFilterExt() {
	var paramString = TGEventFilterParams();
	if (paramString.length <= 0) return;
	TGLoadContent('visitorEventTable', 'action.php?name=ExtSaleOrg&op=filter' + paramString);
}
function TGEventFilterAllExt() {
	TGLoadContent('visitorEventTable', 'action.php?name=ExtSaleOrg&op=filter');
}
function TGEventFilterParams() {
	var eventType = ''; var region = ''; var period = ''; var organizer = ''; var artist = ''; var date = '';
	var eventTypeFilter = document.getElementById('visitor_event_type');
	if (eventTypeFilter) eventType = eventTypeFilter.options[eventTypeFilter.selectedIndex].value;
	var regionFilter = document.getElementById('visitor_region');
	if (regionFilter) region = regionFilter.options[regionFilter.selectedIndex].value;
	var periodFilter = document.getElementById('visitor_period');
	if (periodFilter) period = periodFilter.options[periodFilter.selectedIndex].value;
	var organizerFilter = document.getElementById('visitor_organizer');
	if (organizerFilter) organizer = organizerFilter.options[organizerFilter.selectedIndex].value;
	var artistFilter = document.getElementById('visitor_artist');
	if (artistFilter) artist = artistFilter.options[artistFilter.selectedIndex].value;
	var eventDateFilter = document.getElementById('visitor_evt_date');
	if (eventDateFilter) date = eventDateFilter.options[eventDateFilter.selectedIndex].value;
	var paramString = '';
	if (eventType.length > 0) paramString = '&eventType=' + eventType;
	if (region.length > 0) paramString = paramString + '&region=' + region;
	if (period.length > 0) paramString = paramString + '&period=' + period;
	if (organizer.length > 0) paramString = paramString + '&organizer=' + organizer;
	if (artist.length > 0) paramString = paramString + '&artist=' + encodeURIComponent(artist);
	if (date.length > 0) paramString = paramString + '&date=' + date;
	return paramString;
}
function TGAccountSelected(selObj, dstId) {
	var selAccount = selObj.options[selObj.selectedIndex].value;
	if (selAccount.length <=0) return;
	TGLoadContent(dstId, 'action.php?name=EventAccountAction&op=show&key=' + selAccount);	
}
function TGSectionMap(selObj, dstId) {
	var selSection = selObj.options[selObj.selectedIndex].value;
	if (selSection.length <=0) return;
	TGLoadContent(dstId, 'sectionMap.php?key=' + selSection);
}
function TGEventGetSubTypes(selObj, dstId) {
	var eventType = selObj.options[selObj.selectedIndex].value;
	if (eventType.length <=0) return;
	var dstElm = document.getElementById(dstId);
	if (dstElm == null) {
		alert('EventSubType select id should be defined!');
	}
	dstElm.options.length = 0;		// Remove all options ...
	var sackObj = new sack();
	sackObj.requestFile = 'eventSubTypes.php?type=' + eventType;
	sackObj.onCompletion = function(){_TGEventSetSubTypes(sackObj, dstId)};
	sackObj.runAJAX();
}
function _TGEventSetSubTypes(sackObj, dstId) {
	var selObj = document.getElementById(dstId);
	if (selObj == null) {
		alert('EventSubType select id should be defined!');
	}
	selObj.options.length = 0;
	selObj.options[selObj.options.length] = new Option('Kies', '');
	eval(sackObj.response);
	selObj.selectedIndex = 0;
	// Force onChange event ... setting or toggling index, or focus  doesn't seem to create one :(
	if (document.createEvent) {	// FF, Opera, etc.
		var evt = document.createEvent('HTMLEvents');
		evt.initEvent('change', true, true);
		selObj.dispatchEvent(evt);
	} else {	// IE
		selObj.fireEvent('onclick');	// onchange doesn't seem to work on select box!!!
	}
}
function TGEventGetTariffs(selObj, dstId) {
	var section = selObj.options[selObj.selectedIndex].value;
	if (section.length <=0) return;
	var sackObj = new sack();
	sackObj.requestFile = 'eventTariffs.php?section=' + section;
	sackObj.onCompletion = function(){_TGEventTariffs(sackObj, dstId)};
	sackObj.runAJAX();
}
function _TGEventTariffs(sackObj, dstId) {
	var selObj = document.getElementById(dstId);
	if (selObj == null) {
		alert('EventTariff select id should be defined!');
	}
	selObj.options.length = 0;
	selObj.options[selObj.options.length] = new Option('Kies', '');
	eval(sackObj.response);
}
function TGLoadContent(divId, url) {
	var ajaxLoader = document.getElementById('ajax_loader');
	if (ajaxLoader) ajaxLoader.style.display = 'block';
	var sackObj = new sack();
	sackObj.requestFile = url;
	sackObj.onCompletion = function(){_TGShowContent(sackObj, divId, url)};
	sackObj.onError = function(){_TGShowError(sackObj, divId, url)};
	sackObj.runAJAX();
}
function _TGShowContent(sackObj, divId, url) {
	var ajaxLoader = document.getElementById('ajax_loader');
	if (ajaxLoader) ajaxLoader.style.display = 'none';
	var elm = document.getElementById(divId);
	elm.innerHTML = sackObj.response;
	var fChild = elm.firstChild;
	if (fChild != null) {
		if (fChild.nodeType == 3) {
			if (_TGisEmptyText(fChild.data)) { // Get rid of empty text node because this creates unwanted empty lines in IE!
				fChild.parentNode.removeChild(fChild);
			}
		}
	}
	_TGScript(elm);
}
function _TGisEmptyText(text) {
	if (!text) return true;
	for (var i=0; i < text.length; i++){
		if ( text.charCodeAt(i) == 65279) continue;
		return false;
	}
	return true;
}
function _TGScript(obj) {
	var scriptTags = obj.getElementsByTagName('script');
	var jsCode = '';
	for (var no=0; no < scriptTags.length; no++){
		jsCode = jsCode + scriptTags[no].innerHTML;			
	}
	if (!jsCode) return;
	//alert('executing script: ' + jsCode);
	try {
		if (window.execScript){        	
			window.execScript(jsCode)
		}else if(window.jQuery && jQuery.browser.safari){ // safari detection in jQuery
			window.setTimeout(jsCode, 0);
		}else{        	
			window.setTimeout(jsCode, 0);
		} 
	} catch(e){		
	}
}
function _TGShowError(sack, divId, url) {
	alert(sack.responseStatus[2]);
}
function TGMenuSel(menuId, itemId) {
	var menuObj = document.getElementById(menuId);
	var links = menuObj.getElementsByTagName('a');
	for (var i=0; i < links.length; i++) {
		if (links[i].getAttribute('id') == itemId) {
			links[i].className = 'TGMenuItemSelected';
		} else {
			links[i].className = 'TGMenuItem';
		}
	}
}
function TGList2Action(idOfTable, contentDiv, name, op) {
	var selId = getSelectedRow(idOfTable);
	if (selId != null) {
		TGLoadContent(contentDiv, 'action.php' + '?name=' + name + '&op=' + op + '&key=' + selId);
	} else {
		TGLoadContent(contentDiv, 'action.php' + '?name=' + name + '&op=' + op);
	}
}
function TGList2Bc(idOfTable) {
	var selId = getSelectedRow(idOfTable);
	if (selId == null) return;
	window.location.href = 'action.php?name=BarcodeFile&key=' + selId;
}
function TGListAction(idOfTable, contentDiv, uri, action) {
	var selId = getSelectedRow(idOfTable);
	if (selId != null) {
		TGLoadContent(contentDiv, uri + '?action=' + action + '&key=' + selId);
	} else {
		TGLoadContent(contentDiv, uri + '?action=' + action);
	}
}
function TGEventReserve(obj) {
	var roomMapDiv = document.getElementById('roomMap');
	if (!roomMapDiv) {					// Simple room, seats can't be chosen!
		TGEventSaleList('reserve');
		return;
	}
	var selectedSeats = document.getElementsByName('TGselectedSeat');
	if (selectedSeats.length <= 0) {	// No seats selected => standard reservation action
		TGEventSaleList('reserve');
		return;	
	}
	var requestedSeats = '';
	for (var i = 0; i < selectedSeats.length; i++) {
		var curSeat = selectedSeats[i];
		var seat = curSeat.getAttribute('seat');
		requestedSeats += seat + ';';
	}
	TGLoadContent('TGModuleContent', 'action.php' + '?name=' + 'SelSeatReserve' + '&op=new' + '&key=' + requestedSeats);
}
function TGSeatSelect(obj) {
	var oldClass = obj.getAttribute('oldClass');
	if (!oldClass) {
		oldClass = obj.className;
		obj.setAttribute('oldClass', oldClass);
	}
	if (obj.className != 'seatSelected') {
		obj.className = 'seatSelected';
		obj.setAttribute('name', 'TGselectedSeat');		
	} else {
		obj.className = oldClass;
		obj.setAttribute('name', 'TGseat');
	}
}
function TGRowSelect(obj) {
	var selId = obj.getAttribute('id');
	var tbody = obj.parentNode;
	var rows = tbody.childNodes;
	for ( var i = 0; i < rows.length; i++) {
		var curRow = rows[i];
		if  (curRow.getAttribute('tg_selected') == 'true') {
			curRow.className = curRow.getAttribute('tg_old_class');
			curRow.setAttribute('tg_selected', 'false');
		}
	}
	obj.setAttribute('tg_selected', 'true');
	obj.setAttribute('tg_old_class', obj.className);
	obj.className = 'TGTableRowSelected';
	return selId;
}
function buyRowClickCallBack(obj) {
	selId = TGRowSelect(obj);
	TGLoadContent('visitorEventTable', 'submit.php?name=EventSaleAction&op=show&key=' + selId);
}
function saleRowClickCallBack(obj) {
	selId = TGRowSelect(obj);
	TGLoadContent('roomMap', 'submit.php?name=RoomMapAction&op=show&key=' + selId);
}
function eventRowClickCallBack(obj) {
	selId = TGRowSelect(obj);
	TGLoadContent('eventDetail', 'eventDetail.php?key=' + selId);
}
function rowClickCallBack(obj) {
	var tbody = obj.parentNode;
	var rows = tbody.childNodes;
	for ( var i = 0; i < rows.length; i++) {
		var curRow = rows[i];
		curRow.className = '';
		curRow.setAttribute('tg_selected', 'false');
	}
	obj.setAttribute('tg_selected', 'true');
	obj.className = 'tableRowSelected';
}
function getSelectedRow(idOfTable) {
		var tableObj = document.getElementById(idOfTable);
		var tBody = tableObj.getElementsByTagName('TBODY')[0];
		for (var i = 0; i < tBody.rows.length; i++){
			var row = tBody.rows[i];
			if (row.getAttribute('tg_selected') == 'true') {
				var selId = row.getAttribute('id');
				return selId;
			}
		}
		return null;
}
function getCity(id, zipCode) {
	var request = './cities.php?zip_code=' + zipCode;
	TGLoadContent(id, request);
}
function loadUrl(obj, url) {
	obj.style.backgroundColor = '#FFB100';
	obj.style.color = '#FFFFFF';
}
function foldSibling(sObj) {
	if (sObj.nextSibling.nodeType == 3) {
		tObj = sObj.nextSibling.nextSibling; 	// FF, Opera
	} else {
		tObj = sObj.nextSibling; 				// IE
	}
	if (tObj.style.display != 'block') {
		if (sObj.className == 'faqT') sObj.style.backgroundImage = "url('./images/tg-fold-16.png')";
		tObj.style.display = 'block';
	} else {
		if (sObj.className == 'faqT') sObj.style.backgroundImage = "url('./images/tg-expand-16.png')";
		tObj.style.display = 'none';
	}
}
function objEnter(obj) {	// Simulate hover: IE6 only understands hover  on <a> tags !
	if (obj.className == 'menu') {
		obj.style.borderColor = '#C4C4C4';
	} else if (obj.className == 'faqQ') {
		obj.style.cursor = 'pointer';
	}
}
function objLeave(obj) {	// Simulate hover: IE6 only understands hover  on <a> tags !
	if (obj.className == 'menu') {
		obj.style.borderColor = '#FFFFFF';
	} else if (obj.className == 'faqQ') {
		obj.style.cursor = 'default';
	}
}
/* Simple AJAX Code-Kit (SACK) v1.6.1   ©2005 Gregory Wild-Smith  www.twilightuniverse.com  Software licenced under a modified X11 licence,    see documentation or authors website for more details */

function sack(file) {
	this.xmlhttp = null;

	this.resetData = function() {
		this.method = "POST";
  		this.queryStringSeparator = "?";
		this.argumentSeparator = "&";
		this.URLString = "";
		this.encodeURIString = true;
  		this.execute = false;
  		this.element = null;
		this.elementObj = null;
		this.requestFile = file;
		this.vars = new Object();
		this.responseStatus = new Array(2);
  	};

	this.resetFunctions = function() {
  		this.onLoading = function() { };
  		this.onLoaded = function() { };
  		this.onInteractive = function() { };
  		this.onCompletion = function() { };
  		this.onError = function() { };
		this.onFail = function() { };
	};

	this.reset = function() {
		this.resetFunctions();
		this.resetData();
	};

	this.createAJAX = function() {
		try {
			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e1) {
			try {
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e2) {
				this.xmlhttp = null;
			}
		}

		if (! this.xmlhttp) {
			if (typeof XMLHttpRequest != "undefined") {
				this.xmlhttp = new XMLHttpRequest();
			} else {
				this.failed = true;
			}
		}
	};

	this.setVar = function(name, value){
		this.vars[name] = Array(value, false);
	};

	this.encVar = function(name, value, returnvars) {
		if (true == returnvars) {
			return Array(encodeURIComponent(name), encodeURIComponent(value));
		} else {
			this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value), true);
		}
	}

	this.processURLString = function(string, encode) {
		encoded = encodeURIComponent(this.argumentSeparator);
		regexp = new RegExp(this.argumentSeparator + "|" + encoded);
		varArray = string.split(regexp);
		for (i = 0; i < varArray.length; i++){
			urlVars = varArray[i].split("=");
			if (true == encode){
				this.encVar(urlVars[0], urlVars[1]);
			} else {
				this.setVar(urlVars[0], urlVars[1]);
			}
		}
	}

	this.createURLString = function(urlstring) {
		if (this.encodeURIString && this.URLString.length) {
			this.processURLString(this.URLString, true);
		}

		if (urlstring) {
			if (this.URLString.length) {
				this.URLString += this.argumentSeparator + urlstring;
			} else {
				this.URLString = urlstring;
			}
		}

		// prevents caching of URLString
		this.setVar("rndval", new Date().getTime());

		urlstringtemp = new Array();
		for (key in this.vars) {
			if (false == this.vars[key][1] && true == this.encodeURIString) {
				encoded = this.encVar(key, this.vars[key][0], true);
				delete this.vars[key];
				this.vars[encoded[0]] = Array(encoded[1], true);
				key = encoded[0];
			}

			urlstringtemp[urlstringtemp.length] = key + "=" + this.vars[key][0];
		}
		if (urlstring){
			this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator);
		} else {
			this.URLString += urlstringtemp.join(this.argumentSeparator);
		}
	}

	this.runResponse = function() {
		eval(this.response);
	}

	this.runAJAX = function(urlstring) {
		if (this.failed) {
			this.onFail();
		} else {
			this.createURLString(urlstring);
			if (this.element) {
				this.elementObj = document.getElementById(this.element);
			}
			if (this.xmlhttp) {
				var self = this;
				if (this.method == "GET") {
					totalurlstring = this.requestFile + this.queryStringSeparator + this.URLString;
					this.xmlhttp.open(this.method, totalurlstring, true);
				} else {
					this.xmlhttp.open(this.method, this.requestFile, true);
					try {
						this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
					} catch (e) { }
				}

				this.xmlhttp.onreadystatechange = function() {
					switch (self.xmlhttp.readyState) {
						case 1:
							self.onLoading();
							break;
						case 2:
							self.onLoaded();
							break;
						case 3:
							self.onInteractive();
							break;
						case 4:
							self.response = self.xmlhttp.responseText;
							self.responseXML = self.xmlhttp.responseXML;
							self.responseStatus[0] = self.xmlhttp.status;
							self.responseStatus[1] = self.xmlhttp.statusText;

							if (self.execute) {
								self.runResponse();
							}

							if (self.elementObj) {
								elemNodeName = self.elementObj.nodeName;
								elemNodeName = elemNodeName.toLowerCase();
								if (elemNodeName == "input"
								|| elemNodeName == "select"
								|| elemNodeName == "option"
								|| elemNodeName == "textarea") {
									self.elementObj.value = self.response;
								} else {
									self.elementObj.innerHTML = self.response;
								}
							}
							if (self.responseStatus[0] == "200") {
								self.onCompletion();
							} else {
								self.onError();
							}
							/* These lines were added by Alf Magne Kalleland ref. info on the sack home page. It prevents memory leakage in IE */
							self.URLString = "";
							delete self.xmlhttp['onreadystatechange'];
							self.xmlhttp=null;
							self.responseStatus=null;
							self.response=null;
							self.responseXML=null;
							
							break;
					}
				};

				this.xmlhttp.send(this.URLString);
			}
		}
	};

	this.reset();
	this.createAJAX();
}

/* Author: Denis Howlett <feedback@isocra.com> WWW: http://www.isocra.com/  */

/** Keep hold of the current table being dragged */
var currenttable = null;

/** Capture the onmousemove so that we can see if a row from the current
 *  table if any is being dragged.
 * @param ev the event (for Firefox and Safari, otherwise we use window.event for IE)
 */
document.onmousemove = function(ev){
    if (currenttable && currenttable.dragObject) {
        ev   = ev || window.event;
        var mousePos = currenttable.mouseCoords(ev);
        var y = mousePos.y - currenttable.mouseOffset.y;
        if (y != currenttable.oldY) {
            // work out if we're going up or down...
            var movingDown = y > currenttable.oldY;
            // update the old value
            currenttable.oldY = y;
            // update the style to show we're dragging
            currenttable.dragObject.style.cursor = "move";
            // If we're over a row then move the dragged row to there so that the user sees the
            // effect dynamically
            var currentRow = currenttable.findDropTargetRow(y);
            if (currentRow) {
                if (movingDown && currenttable.dragObject != currentRow) {
                    currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow.nextSibling);
                } else if (! movingDown && currenttable.dragObject != currentRow) {
                    currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow);
                }
            }
        }

        return false;
    }
}
// Similarly for the mouseup
document.onmouseup   = function(ev){
    if (currenttable && currenttable.dragObject) {
        var droppedRow = currenttable.dragObject;
        // If we have a dragObject, then we need to release it,
        // The row will already have been moved to the right place so we just reset stuff
        //@WCU droppedRow.style.backgroundColor = 'transparent';
        currenttable.dragObject   = null;
        // And then call the onDrop method in case anyone wants to do any post processing
        currenttable.onDrop(currenttable.table, droppedRow);
        currenttable = null; // let go of the table too
    }
}
/** get the source element from an event in a way that works for IE and Firefox and Safari
 * @param evt the source event for Firefox (but not IE--IE uses window.event) */
function getEventSource(evt) {
    if (window.event) {
        evt = window.event; // For IE
        return evt.srcElement;
    } else {
        return evt.target; // For Firefox
    }
}
/**
 * Encapsulate table Drag and Drop in a class. We'll have this as a Singleton
 * so we don't get scoping problems.
 */
function TableDnD() {
    /** Keep hold of the current drag object if any */
    this.dragObject = null;
    /** The current mouse offset */
    this.mouseOffset = null;
    /** The current table */
    this.table = null;
    /** Remember the old value of Y so that we don't do too much processing */
    this.oldY = 0;

    /** Initialise the drag and drop by capturing mouse move events */
    this.init = function(table) {
        this.table = table;
        var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
        for (var i=0; i<rows.length; i++) {
			// John Tarr: added to ignore rows that I've added the NoDnD attribute to (Category and Header rows)
			var nodrag = rows[i].getAttribute("NoDrag")
			if (nodrag == null || nodrag == "undefined") { //There is no NoDnD attribute on rows I want to drag
				this.makeDraggable(rows[i]);
			}
        }
    }
    /** This function is called when you drop a row, so redefine it in your code
        to do whatever you want, for example use Ajax to update the server */
    this.onDrop = function(table, droppedRow) {
        // Do nothing for now
    }
	/** Get the position of an element by going up the DOM tree and adding up all the offsets */
    this.getPosition = function(e){
        var left = 0;
        var top  = 0;
		/** Safari fix -- thanks to Luis Chato for this! */
		if (e.offsetHeight == 0) {
			/** Safari 2 doesn't correctly grab the offsetTop of a table row
			    this is detailed here:
			    http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
			    the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
			    note that firefox will return a text node as a first child, so designing a more thorough
			    solution may need to take that into account, for now this seems to work in firefox, safari, ie */
			e = e.firstChild; // a table cell
		}

        while (e.offsetParent){
            left += e.offsetLeft;
            top  += e.offsetTop;
            e     = e.offsetParent;
        }

        left += e.offsetLeft;
        top  += e.offsetTop;

        return {x:left, y:top};
    }
	/** Get the mouse coordinates from the event (allowing for browser differences) */
    this.mouseCoords = function(ev){
        if(ev.pageX || ev.pageY){
            return {x:ev.pageX, y:ev.pageY};
        }
        return {
            x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
            y:ev.clientY + document.body.scrollTop  - document.body.clientTop
        };
    }
	/** Given a target element and a mouse event, get the mouse offset from that element.
		To do this we need the element's position and the mouse position */
    this.getMouseOffset = function(target, ev){
        ev = ev || window.event;

        var docPos    = this.getPosition(target);
        var mousePos  = this.mouseCoords(ev);
        return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
    }
	/** Take an item and add an onmousedown method so that we can make it draggable */
    this.makeDraggable = function(item) {
        if(!item) return;
        var self = this; // Keep the context of the TableDnd inside the function
        item.onmousedown = function(ev) {
            // Need to check to see if we are an input or not, if we are an input, then
            // return true to allow normal processing
            var target = getEventSource(ev);
            if (target.tagName == 'INPUT' || target.tagName == 'SELECT') return true;
            currenttable = self;
            self.dragObject  = this;
            self.mouseOffset = self.getMouseOffset(this, ev);
            return false;
        }
        //@WCU item.style.cursor = "move";
    }
    /** We're only worried about the y position really, because we can only move rows up and down */
    this.findDropTargetRow = function(y) {
        var rows = this.table.tBodies[0].rows;
		for (var i=0; i<rows.length; i++) {
			var row = rows[i];
			// John Tarr added to ignore rows that I've added the NoDnD attribute to (Header rows)
			var nodrop = row.getAttribute("NoDrop");
			if (nodrop == null || nodrop == "undefined") {  //There is no NoDnD attribute on rows I want to drag
				var rowY    = this.getPosition(row).y;
				var rowHeight = parseInt(row.offsetHeight)/2;
				if (row.offsetHeight == 0) {
					rowY = this.getPosition(row.firstChild).y;
					rowHeight = parseInt(row.firstChild.offsetHeight)/2;
				}
				// Because we always have to insert before, we need to offset the height a bit
				if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
					// that's the row we're over
					return row;
				}
			}
		}
		return null;
	}
}
/*[FILE_START:dhtmlSuite-common.js] */
/************************************************************************************************************
	@fileoverview
	DHTML Suite for Applications.
	Copyright (C) 2006  Alf Magne Kalleland(post@dhtmlgoodies.com)<br>
	<br>
	This library is free software; you can redistribute it and/or<br>
	modify it under the terms of the GNU Lesser General Public<br>
	License as published by the Free Software Foundation; either<br>
	version 2.1 of the License, or (at your option) any later version.<br>
	<br>
	This library is distributed in the hope that it will be useful,<br>
	but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br>
	Lesser General Public License for more details.<br>
	<br>
	You should have received a copy of the GNU Lesser General Public<br>
	License along with this library; if not, write to the Free Software<br>
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA<br>
	<br>
	<br>
	www.dhtmlgoodies.com<br> 
	Alf Magne Kalleland<br>

************************************************************************************************************/

// Creating a trim method
if(!String.trim)String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };
var DHTMLSuite_funcs = new Object();
if(!window.DHTML_SUITE_THEME)var DHTML_SUITE_THEME = 'blue';
if(!window.DHTML_SUITE_THEME_FOLDER)var DHTML_SUITE_THEME_FOLDER = './themes/';
if(!window.DHTML_SUITE_JS_FOLDER)var DHTML_SUITE_JS_FOLDER = './js/separateFiles/';

/************************************************************************************************************
*
* Global variables
*
************************************************************************************************************/

// {{{ DHTMLSuite.createStandardObjects()
/**
 * Create objects used by all scripts
 *
 * @public
 */

var DHTMLSuite = new Object();

var standardObjectsCreated = false;	// The classes below will check this variable, if it is false, default help objects will be created
DHTMLSuite.eventEls = new Array();	// Array of elements that has been assigned to an event handler.

var widgetDep = new Object();
// Widget dependencies
widgetDep['formValidator'] = ['dhtmlSuite-formUtil.js'];	// Form validator widget
widgetDep['paneSplitter'] = ['dhtmlSuite-paneSplitter.js','dhtmlSuite-paneSplitterModel.js','dhtmlSuite-dynamicContent.js','ajax.js'];
widgetDep['menuBar'] = ['dhtmlSuite-menuBar.js','dhtmlSuite-menuItem.js','dhtmlSuite-menuModel.js'];
widgetDep['windowWidget'] = ['dhtmlSuite-windowWidget.js','dhtmlSuite-resize.js','dhtmlSuite-dragDropSimple.js','ajax.js','dhtmlSuite-dynamicContent.js'];
widgetDep['colorWidget'] = ['dhtmlSuite-colorWidgets.js','dhtmlSuite-colorUtil.js'];
widgetDep['colorSlider'] = ['dhtmlSuite-colorWidgets.js','dhtmlSuite-colorUtil.js','dhtmlSuite-slider.js'];
widgetDep['colorPalette'] = ['dhtmlSuite-colorWidgets.js','dhtmlSuite-colorUtil.js'];
widgetDep['calendar'] = ['dhtmlSuite-calendar.js','dhtmlSuite-dragDropSimple.js'];
widgetDep['dragDropTree'] = ['dhtmlSuite-dragDropTree.js'];
widgetDep['slider'] = ['dhtmlSuite-slider.js'];
widgetDep['dragDrop'] = ['dhtmlSuite-dragDrop.js'];
widgetDep['imageEnlarger'] = ['dhtmlSuite-imageEnlarger.js','dhtmlSuite-dragDropSimple.js'];
widgetDep['imageSelection'] = ['dhtmlSuite-imageSelection.js'];
widgetDep['floatingGallery'] = ['dhtmlSuite-floatingGallery.js','dhtmlSuite-mediaModel.js'];
widgetDep['contextMenu'] = ['dhtmlSuite-contextMenu.js','dhtmlSuite-menuBar.js','dhtmlSuite-menuItem.js','dhtmlSuite-menuModel.js'];
widgetDep['dynamicContent'] = ['dhtmlSuite-dynamicContent.js','ajax.js'];
widgetDep['textEdit'] = ['dhtmlSuite-textEdit.js','dhtmlSuite-textEditModel.js','dhtmlSuite-listModel.js'];
widgetDep['listModel'] = ['dhtmlSuite-listModel.js'];
widgetDep['resize'] = ['dhtmlSuite-resize.js'];
widgetDep['dragDropSimple'] = ['dhtmlSuite-dragDropSimple.js'];
widgetDep['dynamicTooltip'] = ['dhtmlSuite-dynamicTooltip.js','dhtmlSuite-dynamicContent.js','ajax.js'];
widgetDep['modalMessage'] = ['dhtmlSuite-modalMessage.js','dhtmlSuite-dynamicContent.js','ajax.js'];
widgetDep['progressBar'] = ['dhtmlSuite-progressBar.js'];
widgetDep['tabView'] = ['dhtmlSuite-tabView.js','dhtmlSuite-dynamicContent.js','ajax.js'];
widgetDep['infoPanel'] = ['dhtmlSuite-infoPanel.js','dhtmlSuite-dynamicContent.js','ajax.js'];
widgetDep['form'] = ['dhtmlSuite-formUtil.js','dhtmlSuite-dynamicContent.js','ajax.js'];

var depCache = new Object();

DHTMLSuite.include = function(widget)
{
	if(!widgetDep[widget]){
		alert('Cannot find the files for widget ' + widget + '. Please verify that the name is correct');
		return;
	}
	var files = widgetDep[widget];
	for(var no=0;no<files.length;no++){
		if(!depCache[files[no]]){
		    document.write('<' + 'script');
		    document.write(' language="javascript"');
		    document.write(' type="text/javascript"');
		    document.write(' src="' + DHTML_SUITE_JS_FOLDER + files[no] + '">');
		    document.write('</' + 'script' + '>');
		    depCache[files[no]] = true;
		}
	}
}

DHTMLSuite.discardElement = function(element) { 
	element = DHTMLSuite.commonObj.getEl(element);
    var gBin = document.getElementById('IELeakGBin'); 
    if (!gBin) { 
        gBin = document.createElement('DIV'); 
        gBin.id = 'IELeakGBin'; 
        gBin.style.display = 'none'; 
        document.body.appendChild(gBin); 
    } 
    // move the element to the garbage bin 
    gBin.appendChild(element); 
    gBin.innerHTML = ''; 
} 


DHTMLSuite.createStandardObjects = function()
{
	DHTMLSuite.clientInfoObj = new DHTMLSuite.clientInfo();	// Create browser info object
	DHTMLSuite.clientInfoObj.init();	
	if(!DHTMLSuite.configObj){	// If this object isn't allready created, create it.
		DHTMLSuite.configObj = new DHTMLSuite.config();	// Create configuration object.
		DHTMLSuite.configObj.init();
	}
	DHTMLSuite.commonObj = new DHTMLSuite.common();	// Create configuration object.
	DHTMLSuite.variableStorage = new DHTMLSuite.globalVariableStorage();;	// Create configuration object.
	DHTMLSuite.commonObj.init();
	DHTMLSuite.domQueryObj = new DHTMLSuite.domQuery();

	
	DHTMLSuite.commonObj.addEvent(window,'unload',function(){ DHTMLSuite.commonObj.__clearMemoryGarbage(); });
	
	standardObjectsCreated = true;	
}

    


/************************************************************************************************************
*	Configuration class used by most of the scripts
*
*	Created:			August, 19th, 2006
* 	Update log:
*
************************************************************************************************************/


/**
* @constructor
* @class Store global variables/configurations used by the classes below. Example: If you want to  
*		 change the path to the images used by the scripts, change it here. An object of this   
*		 class will always be available to the other classes. The name of this object is 
*		"DHTMLSuite.configObj".	<br><br>
*			
*		If you want to create an object of this class manually, remember to name it "DHTMLSuite.configObj"
*		This object should then be created before any other objects. This is nescessary if you want
*		the other objects to use the values you have put into the object. <br>
* @version				1.0
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/
DHTMLSuite.config = function()
{
	var imagePath;	// Path to images used by the classes. 
	var cssPath;	// Path to CSS files used by the DHTML suite.	

	var defaultCssPath;
	var defaultImagePath;
}


DHTMLSuite.config.prototype = {
	// {{{ init()
	/**
	 * 	Initializes the config object - the config class is used to store global properties used by almost all widgets
	 *
	 * @public
	 */
	init : function()
	{
		this.imagePath = DHTML_SUITE_THEME_FOLDER + DHTML_SUITE_THEME + '/images/';	// Path to images		
		this.cssPath = DHTML_SUITE_THEME_FOLDER + DHTML_SUITE_THEME + '/css/';	// Path to images	
		
		this.defaultCssPath = this.cssPath;
		this.defaultImagePath = this.imagePath;
			
	}	
	// }}}
	,
	// {{{ setCssPath()
    /**
     * This method will save a new CSS path, i.e. where the css files of the dhtml suite are located(the folder).
     *	This method is rarely used. Default value is the variable DHTML_SUITE_THEME_FOLDER + DHTML_SUITE_THEME + '/css',
     *	which means that the css path is set dynamically based on which theme you choose.
     *
     * @param string newCssPath = New path to css files(folder - remember to have a slash(/) at the end)
     * @public
     */
    	
	setCssPath : function(newCssPath)
	{
		this.cssPath = newCssPath;
	}
	// }}}
	,
	// {{{ resetCssPath()
    /**
     * @deprecated
     * Resets css path back to default value which is ../css_dhtmlsuite/
     * This method is deprecated.
     *
     * @public
     */    	
	resetCssPath : function()
	{
		this.cssPath = this.defaultCssPath;
	}
	// }}}
	,
	// {{{ resetImagePath()
    /**
     * @deprecated
     *
     * Resets css path back to default path which is DHTML_SUITE_THEME_FOLDER + DHTML_SUITE_THEME + '/css'
     * This method is deprecated. 
     * @public
     */    	
	resetImagePath : function()
	{
		this.imagePath = this.defaultImagePath;
	}
	// }}}
	,
	// {{{ setImagePath()
    /**
     * This method will save a new image file path, i.e. where the image files used by the dhtml suite ar located
     *
     * @param string newImagePath = New path to image files (remember to have a slash(/) at the end)
     * @public
     */
	setImagePath : function(newImagePath)
	{
		this.imagePath = newImagePath;
	}
	// }}}
}



DHTMLSuite.globalVariableStorage = function()
{
	var menuBar_highlightedItems;	// Array of highlighted menu bar items
	this.menuBar_highlightedItems = new Array();
	
	var arrayDSObjects;	// Array of objects of class menuItem.
	var arrayOfDhtmlSuiteObjects;
	this.arrayDSObjects = new Array();
	this.arrayOfDhtmlSuiteObjects = this.arrayDSObjects;
	var ajaxObjects;
	this.ajaxObjects = new Array();
}

DHTMLSuite.globalVariableStorage.prototype = {
	
}


/************************************************************************************************************
*	A class with general methods used by most of the scripts
*
*	Created:			August, 19th, 2006
*	Purpose of class:	A class containing common method used by one or more of the gui classes below, 
* 						example: loadCSS. 
*						An object("DHTMLSuite.commonObj") of this  class will always be available to the other classes. 
* 	Update log:
*
************************************************************************************************************/


/**
* @constructor
* @class A class containing common method used by one or more of the gui classes below, example: loadCSS. An object("DHTMLSuite.commonObj") of this  class will always be available to the other classes. 
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.common = function()
{
	var loadedCSSFiles;	// Array of loaded CSS files. Prevent same CSS file from being loaded twice.
	var cssCacheStatus;	// Css cache status
	var eventEls;
	var isOkToSelect;	// Boolean variable indicating if it's ok to make text selections
	
	this.okToSelect = true;
	this.cssCacheStatus = true;	// Caching of css files = on(Default)
	this.eventEls = new Array();	
}

DHTMLSuite.common.prototype = {
	
	// {{{ init()
    /**
     * This method initializes the DHTMLSuite_common object.
     *	This class contains a lot of useful methods used by most widgets.
     *
     * @public
     */    	
	init : function()
	{
		this.loadedCSSFiles = new Array();
	}	
	// }}}
	,
	// {{{ loadCSS()
    /**
     * This method loads a CSS file(Cascading Style Sheet) dynamically - i.e. an alternative to <link> tag in the document.
     *
     * @param string cssFile = Name of css file. It will be loaded from the path specified in the DHTMLSuite.common object
     * @param Boolean prefixConfigPath = Use config path as prefix.
     * @public
     */	
	loadCSS : function(cssFile,prefixConfigPath)
	{
		if(!prefixConfigPath && prefixConfigPath!==false)prefixConfigPath=true;
		if(!this.loadedCSSFiles[cssFile]){
			this.loadedCSSFiles[cssFile] = true;
			var lt = document.createElement('LINK');
			if(!this.cssCacheStatus){
				if(cssFile.indexOf('?')>=0)cssFile = cssFile + '&'; else cssFile = cssFile + '?';
				cssFile = cssFile + 'rand='+ Math.random();	// To prevent caching
			}
			if(prefixConfigPath){
				lt.href = DHTMLSuite.configObj.cssPath + cssFile;
			}else{
				lt.href = cssFile;
			}
			lt.rel = 'stylesheet';
			lt.media = 'screen';
			lt.type = 'text/css';
			document.getElementsByTagName('HEAD')[0].appendChild(lt);				
		}
	}		
	// }}}
	,
	// {{{ __setTextSelOk()
    /**
     * Is it ok to make text selections ?
     *
     * @param Boolean okToSelect 
     * @private
     */		
	__setTextSelOk : function(okToSelect){
		this.okToSelect = okToSelect;
	}
	// }}}
	,
	// {{{ __setTextSelOk()
    /**
     * Returns true if it's ok to make text selections, false otherwise.
     *
     * @return Boolean okToSelect 
     * @private
     */		
	__isTextSelOk : function()
	{
		return this.okToSelect;
	}
	// }}}	
	,	
	// {{{ setCssCacheStatus()
    /**
     * Specify if css files should be cached or not. 
     *
     *	@param Boolean cssCacheStatus = true = cache on, false = cache off
     *
     * @public
     */	
	setCssCacheStatus : function(cssCacheStatus)
	{		
	  this.cssCacheStatus = cssCacheStatus;
	}
	// }}}	
	,
	// {{{ getEl()
    /**
     * Return a reference to an object
     *
     * @param Object elRef = Id, name or direct reference to element
     * @return Object HTMLElement - direct reference to element
     * @public
     */		
	getEl : function(elRef)
	{
		if(typeof elRef=='string'){
			if(document.getElementById(elRef))return document.getElementById(elRef);
			if(document.forms[elRef])return document.forms[elRef];
			if(document[elRef])return document[elRef];
			if(window[elRef])return window[elRef];
		}
		return elRef;	// Return original ref.
		
	}
	// }}}
	,
	// {{{ isArray()
    /**
     * Return true if element is an array
     *
     * @param Object el = Reference to HTML element
     * @public
     */		
	isArray : function(el)
	{
		if(el.constructor.toString().indexOf("Array") != -1)return true;
		return false;
	}
	// }}}
	,
	// {{{ getStyle()
    /**
     * Return specific style attribute for an element
     *
     * @param Object el = Reference to HTML element
     * @param String property = Css property
     * @public
     */		
	getStyle : function(el,property)
	{		
		el = this.getEl(el);
	    if (document.defaultView && document.defaultView.getComputedStyle) {
            var retVal = null;	            
            var comp = document.defaultView.getComputedStyle(el, '');
            if (comp){
                retVal = comp[property];
            }	            
            return el.style[property] || retVal;
	    }
		if (document.documentElement.currentStyle && DHTMLSuite.clientInfoObj.isMSIE){	
	        var retVal = null;
	        if(el.currentStyle)value = el.currentStyle[property];
	        return (el.style[property] || retVal);                    		
		}
		return el.style[property];				
	}
	// }}}
	,
	// {{{ getLeftPos()
    /**
     * This method will return the left coordinate(pixel) of an HTML element
     *
     * @param Object el = Reference to HTML element
     * @public
     */	
	getLeftPos : function(el)
	{	 
		/*
		if(el.getBoundingClientRect){ // IE
			var box = el.getBoundingClientRect();	
			return (box.left/1 + Math.max(document.body.scrollLeft,document.documentElement.scrollLeft));
		}
		*/
		if(document.getBoxObjectFor){
			if(el.tagName!='INPUT' && el.tagName!='SELECT' && el.tagName!='TEXTAREA')return document.getBoxObjectFor(el).x
		}		 
		var returnValue = el.offsetLeft;
		while((el = el.offsetParent) != null){
			if(el.tagName!='HTML'){
				returnValue += el.offsetLeft;
				if(document.all)returnValue+=el.clientLeft;
			}
		}
		return returnValue;
	}
	// }}}
	,
	// {{{ getTopPos()
    /**
     * This method will return the top coordinate(pixel) of an HTML element/tag
     *
     * @param Object el = Reference to HTML element
     * @public
     */	
	getTopPos : function(el)
	{	
		/*
		if(el.getBoundingClientRect){	// IE
			var box = el.getBoundingClientRect();	
			return (box.top/1 + Math.max(document.body.scrollTop,document.documentElement.scrollTop));
		}
		*/	
		if(document.getBoxObjectFor){
			if(el.tagName!='INPUT' && el.tagName!='SELECT' && el.tagName!='TEXTAREA')return document.getBoxObjectFor(el).y
		}
		
		var returnValue = el.offsetTop;
		while((el = el.offsetParent) != null){
			if(el.tagName!='HTML'){
				returnValue += (el.offsetTop - el.scrollTop);
				if(document.all)returnValue+=el.clientTop;
			}
		} 
		return returnValue;
	}
	// }}}
	,	
	// {{{ getCookie()
    /**
     *
     * 	These cookie functions are downloaded from 
	 * 	http://www.mach5.com/support/analyzer/manual/html/General/CookiesJavaScript.htm
	 *
     *  This function returns the value of a cookie
     *
     * @param String name = Name of cookie
     * @param Object inputObj = Reference to HTML element
     * @public
     */	
	getCookie : function(name) { 
	   var start = document.cookie.indexOf(name+"="); 
	   var len = start+name.length+1; 
	   if ((!start) && (name != document.cookie.substring(0,name.length))) return null; 
	   if (start == -1) return null; 
	   var end = document.cookie.indexOf(";",len); 
	   if (end == -1) end = document.cookie.length; 
	   return unescape(document.cookie.substring(len,end)); 
	} 	
	// }}}
	,	
	// {{{ setCookie()
    /**
     *
     * 	These cookie functions are downloaded from 
	 * 	http://www.mach5.com/support/analyzer/manual/html/General/CookiesJavaScript.htm
	 *
     *  This function creates a cookie. (This method has been slighhtly modified)
     *
     * @param String name = Name of cookie
     * @param String value = Value of cookie
     * @param Int expires = Timestamp - days
     * @param String path = Path for cookie (Usually left empty)
     * @param String domain = Cookie domain
     * @param Boolean secure = Secure cookie(SSL)
     * 
     * @public
     */	
	setCookie : function(name,value,expires,path,domain,secure) { 
		expires = expires * 60*60*24*1000;
		var today = new Date();
		var expires_date = new Date( today.getTime() + (expires) );
	    var cookieString = name + "=" +escape(value) + 
	       ( (expires) ? ";expires=" + expires_date.toGMTString() : "") + 
	       ( (path) ? ";path=" + path : "") + 
	       ( (domain) ? ";domain=" + domain : "") + 
	       ( (secure) ? ";secure" : ""); 
	    document.cookie = cookieString; 
	}
	// }}}
	,
	// {{{ deleteCookie()
    /**
	 *
     *  This function deletes a cookie. (This method has been slighhtly modified)
     *
     * @param String name = Name of cookie
     * @param String path = Path for cookie (Usually left empty)
     * @param String domain = Cookie domain
     * 
     * @public
     */	
	deleteCookie : function( name, path, domain ) 
	{
		if ( this.getCookie( name ) ) document.cookie = name + "=" +
		( ( path ) ? ";path=" + path : "") +
		( ( domain ) ? ";domain=" + domain : "" ) +
		";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	}
	// }}}
	,
	// {{{ cancelEvent()
    /**
     *
     *  This function only returns false. It is used to cancel selections and drag
     *
     * 
     * @public
     */	
    	
	cancelEvent : function()
	{
		return false;
	}
	// }}}	
	,
	// {{{ addEvent()
    /**
     *
     *  This function adds an event listener to an element on the page.
     *
     *	@param Object whichObject = Reference to HTML element(Which object to assigne the event)
     *	@param String eventType = Which type of event, example "mousemove" or "mouseup" (NOT "onmousemove")
     *	@param functionName = Name of function to execute. 
     * 
     * @public
     */	
	addEvent : function( obj, type, fn,suffix ) {
		if(!suffix)suffix = '';
		if ( obj.attachEvent ) {
			if ( typeof DHTMLSuite_funcs[type+fn+suffix] != 'function') {
				DHTMLSuite_funcs[type+fn+suffix] = function() {
					fn.apply(window.event.srcElement);
				};
				obj.attachEvent('on'+type, DHTMLSuite_funcs[type+fn+suffix] );
			}
			obj = null;
		} else {
			obj.addEventListener( type, fn, false );
		}
		this.__addEventEl(obj);
	}	

	// }}}	
	,	
	// {{{ removeEvent()
    /**
     *
     *  This function removes an event listener from an element on the page.
     *
     *	@param Object whichObject = Reference to HTML element(Which object to assigne the event)
     *	@param String eventType = Which type of event, example "mousemove" or "mouseup"
     *	@param functionName = Name of function to execute. 
     * 
     * @public
     */		
	removeEvent : function(obj,type,fn,suffix)
	{ 
		if ( obj.detachEvent ) {
		obj.detachEvent( 'on'+type, DHTMLSuite_funcs[type+fn+suffix] );
			DHTMLSuite_funcs[type+fn+suffix] = null;
			obj = null;
		} else {
			obj.removeEventListener( type, fn, false );
		}
	} 
	// }}}
	,
	// {{{ __clearMemoryGarbage()
    /**
     *
     *  This function is used for Internet Explorer in order to clear memory when the page unloads.
     *
     * 
     * @private
     */	
    __clearMemoryGarbage : function()
    {
   		/* Example of event which causes memory leakage in IE 
   		DHTMLSuite.commonObj.addEvent(expandRef,"click",function(){ window.refToMyMenuBar[index].__changeMenuBarState(this); })
   		We got a circular reference.
   		*/
    	if(!DHTMLSuite.clientInfoObj.isMSIE)return;
   	
    	for(var no=0;no<DHTMLSuite.eventEls.length;no++){
    		try{
    			var el = DHTMLSuite.eventEls[no];
	    		el.onclick = null;
	    		el.onmousedown = null;
	    		el.onmousemove = null;
	    		el.onmouseout = null;
	    		el.onmouseover = null;
	    		el.onmouseup = null;
	    		el.onfocus = null;
	    		el.onblur = null;
	    		el.onkeydown = null;
	    		el.onkeypress = null;
	    		el.onkeyup = null;
	    		el.onselectstart = null;
	    		el.ondragstart = null;
	    		el.oncontextmenu = null;
	    		el.onscroll = null;   
	    		el = null; 		
    		}catch(e){
    		}
    	}    	
    	
    	for(var no in DHTMLSuite.variableStorage.arrayDSObjects){
    		DHTMLSuite.variableStorage.arrayDSObjects[no] = null;    			
    	}
    	
    	window.onbeforeunload = null;
    	window.onunload = null;
    	DHTMLSuite = null;
    }		
    // }}}
    ,
	// {{{ __addEventEl()
    /**
     *
     *  Add element to garbage collection array. The script will loop through this array and remove event handlers onload in ie.
     *
     * 
     * @private
     */	    
    __addEventEl : function(el)
    {
    	DHTMLSuite.eventEls[DHTMLSuite.eventEls.length] = el;    
    }
    // }}}
    ,
	// {{{ getSrcElement()
    /**
     *
     *  Returns a reference to the HTML element which triggered an event.
     *	@param Event e = Event object
     *
     * 
     * @public
     */	       
    getSrcElement : function(e)
    {
    	var el;
		if (e.target) el = e.target;
			else if (e.srcElement) el = e.srcElement;
			if (el.nodeType == 3) // defeat Safari bug
				el = el.parentNode;
		return el;	
    }	
    // }}}
    ,
	// {{{ getKeyFromEvent()
    /**
     *
     *  Returns key from event object
     *	@param Event e = Event object
     * 
     * @public
     */	     
    getKeyFromEvent : function(e)
    {
		var code = this.getKeyCode(e);   	
    	return String.fromCharCode(code);
    }
    // }}}
    ,
	// {{{ getKeyCode()
    /**
     *
     *  Returns key code from event
     *	@param Event e = Event object
     * 
     * @public
     */	     
    getKeyCode : function(e)
    {
    	if (e.keyCode) code = e.keyCode; else if (e.which) code = e.which;  
    	return code;
    }
    // }}}	
    ,
	// {{{ isObjectClicked()
    /**
     *
     *  Returns true if an object is clicked, false otherwise. This method will also return true if you clicked on a sub element
     *	@param Object obj = Reference to HTML element
     *	@param Event e = Event object
     *
     * 
     * @public
     */	      
	isObjectClicked : function(obj,e)
	{
		var src = this.getSrcElement(e);
		var string = src.tagName + '(' + src.className + ')';
		if(src==obj)return true;
		while(src.parentNode && src.tagName.toLowerCase()!='html'){
			src = src.parentNode;
			string = string + ',' + src.tagName + '(' + src.className + ')';
			if(src==obj)return true;			
		}		
		return false;		
	}
	// }}}
	,
	// {{{ getObjectByClassName()
    /**
     *
     *  Walks up the DOM tree and returns first found object with a given class name
     *
     *	@param Event e = Event object
     *	@param String className = CSS - Class name
     *
     * 
     * @public
     */	 	
	getObjectByClassName : function(e,className)
	{
		var src = this.getSrcElement(e);
		if(src.className==className)return src;
		while(src && src.tagName.toLowerCase()!='html'){
			src = src.parentNode;	
			if(src.className==className)return src;
		}
		return false;
	}
	//}}}
	,
	// {{{ getObjectByAttribute()
    /**
     *
     *  Walks up the DOM tree and returns first found object with a given attribute set
     *
     *	@param Event e = Event object
     *	@param String attribute = Custom attribute
     *
     * 
     * @public
     */	 	
	getObjectByAttribute : function(e,attribute)
	{
		var src = this.getSrcElement(e);
		var att = src.getAttribute(attribute);
		if(!att)att = src[attribute];
		if(att)return src;
		while(src && src.tagName.toLowerCase()!='html'){
			src = src.parentNode;	
			var att = src.getAttribute('attribute');
			if(!att)att = src[attribute];		
			if(att)return src;
		}
		return false;
	}
	//}}}
	,
	// {{{ getUniqueId()
    /**
     *
     *  Returns a unique numeric id
     *
     *
     * 
     * @public
     */		
	getUniqueId : function()
	{
		var no = Math.random() + '';
		no = no.replace('.','');		
		var no2 = Math.random() + '';
		no2 = no2.replace('.','');		
		return no + no2;		
	}
	// }}}
	,
	// {{{ getAssociativeArrayFromString()
    /**
     *
     *  Returns an associative array from a comma delimited string
     *  @param String propertyString - commaseparated string(example: "id:myid,title:My title,contentUrl:includes/tab.inc")
     *
     *	@return Associative array of keys + property value(example: key: id, value : myId)
     * @public
     */		
	getAssociativeArrayFromString : function(propertyString)
	{
		if(!propertyString)return;
		var retArray = new Array();
		var items = propertyString.split(/,/g);
		for(var no=0;no<items.length;no++){
			var tokens = items[no].split(/:/);	
			retArray[tokens[0]] = tokens[1];			
		}	
		return retArray;	
	}
	// }}}
	,
	// {{{ correctPng()
    /**
     *
     *  Correct png for old IE browsers
     *  @param Object el - Id or direct reference to image
     *
     * @public
     */	
	correctPng : function(el)
	{
		el = DHTMLSuite.commonObj.getEl(el);	
		var img = el;
		var width = img.width;
		var height = img.height;
		var html = '<span style="display:inline-block;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + img.src + '\',sizingMethod=\'scale\');width:' + width + ';height:' + height + '"></span>';
		img.outerHTML = html;	
					
	}
	,	
	// {{{ __evaluateJs()
    /**
     * Evaluate Javascript in the inserted content
     *
     * @private
     */	
	__evaluateJs : function(obj)
	{
		obj = this.getEl(obj);
		var scriptTags = obj.getElementsByTagName('SCRIPT');
		var string = '';
		var jsCode = '';
		for(var no=0;no<scriptTags.length;no++){	
			if(scriptTags[no].src){
		        var head = document.getElementsByTagName("head")[0];
		        var scriptObj = document.createElement("script");
		
		        scriptObj.setAttribute("type", "text/javascript");
		        scriptObj.setAttribute("src", scriptTags[no].src);  	
			}else{
				if(DHTMLSuite.clientInfoObj.isOpera){
					jsCode = jsCode + scriptTags[no].text + '\n';
				}
				else
					jsCode = jsCode + scriptTags[no].innerHTML;	
			}			
		}
		if(jsCode)this.__installScript(jsCode);
	}
	// }}}
	,
	// {{{ __installScript()
    /**
     *  "Installs" the content of a <script> tag.
     *
     * @private        
     */		
	__installScript : function ( script )
	{		
		try{
		    if (!script)
		        return;		
	        if (window.execScript){        	
	        	window.execScript(script)
	        }else if(window.jQuery && jQuery.browser.safari){ // safari detection in jQuery
	            window.setTimeout(script,0);
	        }else{        	
	            window.setTimeout( script, 0 );
	        } 
		}catch(e){
			
		}
	}	
	// }}}
	,
	// {{{ __evaluateCss()
    /**
     *  Evaluates css
     *
     * @private        
     */	
	__evaluateCss : function(obj)
	{
		obj = this.getEl(obj);
		var cssTags = obj.getElementsByTagName('STYLE');
		var head = document.getElementsByTagName('HEAD')[0];
		for(var no=0;no<cssTags.length;no++){
			head.appendChild(cssTags[no]);
		}	
	}	
}

/************************************************************************************************************
*	Client info class
*
*	Created:			August, 18th, 2006
* 	Update log:
*
************************************************************************************************************/

/**
* @constructor
* @class Purpose of class: Provide browser information to the classes below. Instead of checking for
*		 browser versions and browser types in the classes below, they should check this
*		 easily by referncing properties in the class below. An object("DHTMLSuite.clientInfoObj") of this 
*		 class will always be accessible to the other classes. * @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/


DHTMLSuite.clientInfo = function()
{
	var browser;			// Complete user agent information
	
	var isOpera;			// Is the browser "Opera"
	var isMSIE;				// Is the browser "Internet Explorer"
	var isOldMSIE;			// Is this browser and older version of Internet Explorer ( by older, we refer to version 6.0 or lower)	
	var isFirefox;			// Is the browser "Firefox"
	var navigatorVersion;	// Browser version
	var isOldMSIE;
}
	
DHTMLSuite.clientInfo.prototype = {
	
	// {{{ init()
    /**
     *  This method initializes the clientInfo object. This is done automatically when you create a widget object.
     *
     * @public
     */	    	
	init : function()
	{
		this.browser = navigator.userAgent;	
		this.isOpera = (this.browser.toLowerCase().indexOf('opera')>=0)?true:false;
		this.isFirefox = (this.browser.toLowerCase().indexOf('firefox')>=0)?true:false;
		this.isMSIE = (this.browser.toLowerCase().indexOf('msie')>=0)?true:false;
		this.isOldMSIE = (this.browser.toLowerCase().match(/msie\s[0-6]/gi))?true:false;
		this.isSafari = (this.browser.toLowerCase().indexOf('safari')>=0)?true:false;
		this.navigatorVersion = navigator.appVersion.replace(/.*?MSIE\s(\d\.\d).*/g,'$1')/1;
		this.isOldMSIE = (this.isMSIE&&this.navigatorVersion<7)?true:false;
	}	
	// }}}		
	,
	// {{{ getBrowserWidth()
    /**
     *
	 *
     *  This method returns the width of the browser window(i.e. inner width)
     *
     * 
     * @public
     */		
	getBrowserWidth : function()
	{
		if(self.innerWidth)return self.innerWidth;
		return document.documentElement.offsetWidth;		
	}
	// }}}
	,
	// {{{ getBrowserHeight()
    /**
     *
	 *
     *  This method returns the height of the browser window(i.e. inner height)
     *
     * 
     * @public
     */		
	getBrowserHeight : function()
	{
		if(self.innerHeight)return self.innerHeight;
		return document.documentElement.offsetHeight;
	}
}



/************************************************************************************************************
*	DOM query class 
*
*	Created:			August, 31th, 2006
*
* 	Update log:
*
************************************************************************************************************/

/**
* @constructor
* @class Purpose of class:	Gives you a set of methods for querying elements on a webpage. When an object
*		 of this class has been created, the method will also be available via the document object.
*		 Example: var elements = document.getElementsByClassName('myClass');
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.domQuery = function()
{
	// Make methods of this class a member of the document object. 
	document.getElementsByClassName = this.getElementsByClassName;
	document.getElementsByAttribute = this.getElementsByAttribute;
}



	
DHTMLSuite.domQuery.prototype = {
}

/*[FILE_START:dhtmlSuite-dragDropTree.js] */
/************************************************************************************************************
*	Drag and drop folder tree
*
*	Created:					August, 23rd, 2006
*	
*	Demos of this class:		demo-drag-drop-folder-tree.html				
*			
* 	Update log:
*
************************************************************************************************************/
	
var JSTreeObj;
var treeUlCounter = 0;
var nodeId = 1;
	
/**
* @constructor
* @class Purpose of class:	Transforms an UL,LI list into a folder tree with drag and drop capabilities(See <a target="_blank" href="../../demos/demo-drag-drop-folder-tree.html">demo</A>).
* @version				1.0
* @version 1.0
* 
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/


DHTMLSuite.JSDragDropTree = function()
{
	var idOfTree;
	var folderImage;
	var plusImage;
	var minusImage;
	var maximumDepth;
	var dragNode_source;
	var dragNode_parent;
	var dragNode_sourceNextSib;
	var dragNode_noSiblings;
	
	var dragNode_destination;
	var floatingContainer;
	var dragDropTimer;
	var dropTargetIndicator;
	var insertAsSub;
	var indicator_offsetX;
	var indicator_offsetX_sub;
	var indicator_offsetY;
	var messageMaximumDepthReached;
	var ajaxObjects;
	var layoutCSS;
	var cookieName;
	
	/* Initial variable values */
	this.folderImage = 'DHTMLSuite_folder.gif';
	this.plusImage = 'DHTMLSuite_plus.gif';
	this.minusImage = 'DHTMLSuite_minus.gif';
	this.maximumDepth = 6;		
	this.layoutCSS = 'drag-drop-folder-tree.css';
	
	this.floatingContainer = document.createElement('UL');
	this.floatingContainer.style.position = 'absolute';
	this.floatingContainer.style.display='none';
	this.floatingContainer.id = 'floatingContainer';
	this.insertAsSub = false;
	document.body.appendChild(this.floatingContainer);
	this.dragDropTimer = -1;
	this.dragNode_noSiblings = false;
	this.cookieName = 'DHTMLSuite_expandedNodes';
	
	if(document.all){
		this.indicator_offsetX = 1;	// Offset position of small black lines indicating where nodes would be dropped.
		this.indicator_offsetX_sub = 1;
		this.indicator_offsetY = 13;
	}else{
		this.indicator_offsetX = 1;	// Offset position of small black lines indicating where nodes would be dropped.
		this.indicator_offsetX_sub = 3;
		this.indicator_offsetY = 5;			
	}
	if(navigator.userAgent.indexOf('Opera')>=0){
		this.indicator_offsetX = 2;	// Offset position of small black lines indicating where nodes would be dropped.
		this.indicator_offsetX_sub = 3;
		this.indicator_offsetY = -7;				
	}

	this.messageMaximumDepthReached = ''; // Use '' if you don't want to display a message 
	this.ajaxObjects = new Array();
	
	try{
		if(!standardObjectsCreated)DHTMLSuite.createStandardObjects();	// This line starts all the init methods  
	}catch(e){
		alert('You need to include the dhtmlSuite-common.js file');
	}
	var objectIndex;
	
	this.objectIndex = DHTMLSuite.variableStorage.arrayDSObjects.length;
	DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex] = this;

}


/* DHTMLSuite.JSDragDropTree class */
DHTMLSuite.JSDragDropTree.prototype = {
	// {{{ init()
    /**
     * Initializes the script
     *
     * @public
     */	    	
	init : function()
	{		
		var ind = this.objectIndex;		
		DHTMLSuite.commonObj.loadCSS(this.layoutCSS);
		JSTreeObj = this;
		this.__createDropIndicator();		
		if(!document.documentElement.onselectstart)document.documentElement.onselectstart = function() { return DHTMLSuite.commonObj.__isTextSelOk(); };		
		document.documentElement.ondragstart = document.documentElement.ondragstart = function() { return false; };
		DHTMLSuite.commonObj.__addEventEl(document.documentElement);
		var nodeId = 0;
		var DHTMLSuite_tree = document.getElementById(this.idOfTree);
		var menuItems = DHTMLSuite_tree.getElementsByTagName('LI');	// Get an array of all menu items
		for(var no=0;no<menuItems.length;no++){
			// No children var set ?
			var noChildren = false;
			var tmpVar = menuItems[no].getAttribute('noChildren');
			if(!tmpVar)tmpVar = menuItems[no].noChildren;
			if(tmpVar=='true')noChildren=true;
			// No drag var set ?
			var noDrag = false;
			var tmpVar = menuItems[no].getAttribute('noDrag');
			if(!tmpVar)tmpVar = menuItems[no].noDrag;
			if(tmpVar=='true')noDrag=true;					 
			nodeId++;
			var subItems = menuItems[no].getElementsByTagName('UL');
			var img = document.createElement('IMG');
			img.src = DHTMLSuite.configObj.imagePath + 'drag-drop-tree/' + this.plusImage;
			img.onclick = function(e) { DHTMLSuite.variableStorage.arrayDSObjects[ind].showHideNode(e); };
			DHTMLSuite.commonObj.__addEventEl(img);
			if(subItems.length==0)img.style.visibility='hidden';else{
				subItems[0].id = 'tree_ul_' + treeUlCounter;
				treeUlCounter++;
			}
			var aTag = menuItems[no].getElementsByTagName('A')[0];

			if(!noDrag)aTag.onmousedown = this.__initializeDragProcess;
			if(!noChildren){
				aTag.onmousemove = function(e){ DHTMLSuite.variableStorage.arrayDSObjects[ind].__moveDragableNodes(e,'text'); }
				DHTMLSuite.commonObj.__addEventEl(aTag);
				
			}
			DHTMLSuite.commonObj.__addEventEl(aTag);
			menuItems[no].insertBefore(img,aTag);
			var folderImg = document.createElement('IMG');
			if(!noDrag)folderImg.onmousedown = this.__initializeDragProcess;
			if(!noChildren){
				folderImg.onmousemove = function(e) { DHTMLSuite.variableStorage.arrayDSObjects[ind].__moveDragableNodes(e,'folder'); };
				DHTMLSuite.commonObj.__addEventEl(folderImg);
			}
			if(menuItems[no].className){
				folderImg.src = DHTMLSuite.configObj.imagePath + 'drag-drop-tree/' + menuItems[no].className;
			}else{
				folderImg.src = DHTMLSuite.configObj.imagePath + 'drag-drop-tree/' + this.folderImage;
			}
			DHTMLSuite.commonObj.__addEventEl(folderImg);
			menuItems[no].insertBefore(folderImg,aTag);
		}	
		initExpandedNodes = DHTMLSuite.commonObj.getCookie(this.cookieName);
		if(initExpandedNodes){
			var nodes = initExpandedNodes.split(',');
			for(var no=0;no<nodes.length;no++){
				if(nodes[no])this.showHideNode(false,nodes[no]);	
			}			
		}		
		DHTMLSuite.commonObj.addEvent(document.documentElement,"mousemove",DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex].__moveDragableNodes);
		DHTMLSuite.commonObj.addEvent(document.documentElement,"mouseup",DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex].__dropDragableNodes);

	}	
	// }}}
	,
	// {{{ setCookieName()
    /**
     * set new CSS file
     *
     * @param String cookieName - Name of cookie (storing expanded nodes ) default value : DHTMLSuite_expandedNodes
     *
     * @public
     */		
	setCookieName : function(cookieName)
	{
		this.cookieName = cookieName;
	}
	// }}}		
	,
	// {{{ setLayoutCss()
    /**
     * set new CSS file
     *
     * @param String cssFileName - name of new css file(example: drag-drop.css). Has to be set before init is called. 
     *
     * @public
     */	
	setLayoutCss : function(cssFileName)
	{
		this.layoutCSS = cssFileName;	
	}	
	// }}}	
	,
	// {{{ setFolderImage()
    /**
     * set new folder image file
     *
     * @param String newFolderImage - name of folder image(example: folder.gif). Has to be set before init is called. 
     *
     * @public
     */		
	setFolderImage : function(newFolderImage)
	{
		this.folderImage = newFolderImage;
	}
	// }}}	
	,
	// {{{ setPlusImage()
    /**
     * set new CSS file
     *
     * @param String newPlusImage - name of new [+] image(example: plus.gif). Has to be set before init is called. 
     *
     * @public
     */		
	setPlusImage : function(newPlusImage)
	{
		this.plusImage = newPlusImage;
	}
	// }}}	
	,
	// {{{ setMinusImage()
    /**
     * set new plus imagee
     *
     * @param String newMinusImage - name of new [-] image(example: minus.gif). Has to be set before init is called. 
     *
     * @public
     */		
	setMinusImage : function(newMinusImage)
	{
		this.minusImage = newMinusImage;
	}
	// }}}	
	,
	// {{{ setMaximumDepth()
    /**
     * set maximum depth of tree. 
     *
     * @param Int maxDepth - new maximum depth of tree. 
     *
     * @public
     */		
	setMaximumDepth : function(maxDepth)
	{
		this.maximumDepth = maxDepth;	
	}
	// }}}
	,
	// {{{ setMessageMaximumDepthReached()
    /**
     * Set maximum depth reached error message
     *
     * @param String newMessage - Specify message to show when max depth is reached, i.e. error message
     *
     * @public
     */		
	setMessageMaximumDepthReached : function(newMessage)
	{
		this.messageMaximumDepthReached = newMessage;
	}
	// }}}	
	,	
	// {{{ setTreeId()
    /**
     * set ID of tree root element
     *
     * @param String idOfTree - Id of UL tag which is root element of the tree. 
     *
     * @public
     */			
	setTreeId : function(idOfTree)
	{
		this.idOfTree = idOfTree;			
	}
	// }}}		
	,
	// {{{ expandAll()
    /**
     * Expand all tree nodes
     *
     *
     * @public
     */		
	expandAll : function()
	{
		var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI');
		for(var no=0;no<menuItems.length;no++){
			var subItems = menuItems[no].getElementsByTagName('UL');
			if(subItems.length>0 && subItems[0].style.display!='block'){
				this.showHideNode(false,menuItems[no].id);
			}			
		}
	}
	// }}}		
	,
	// {{{ collapseAll()
    /**
     * Collapse all tree nodes
     *
     *
     * @public
     */		
	collapseAll : function()
	{
		var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI');
		for(var no=0;no<menuItems.length;no++){
			var subItems = menuItems[no].getElementsByTagName('UL');
			if(subItems.length>0 && subItems[0].style.display=='block'){
				this.showHideNode(false,menuItems[no].id);
			}			
		}		
	}	
	// }}}	
	,
	// {{{ showHideNode()
    /**
     * Expand a specific node
     *
     * @param boolean e - If you call this method manually, set this argument to false(It's not used)
     * @param string inputId - Id of node to expand/collapse
     *
     * @public
     */	
	showHideNode : function(e,inputId)
	{
		if(inputId){
			if(!document.getElementById(inputId))return;
			thisNode = document.getElementById(inputId).getElementsByTagName('IMG')[0]; 
		}else {
			if(document.all)e = event;	
			var srcEl = DHTMLSuite.commonObj.getSrcElement(e);
			thisNode = srcEl;
			if(srcEl.tagName=='A')thisNode = srcEl.parentNode.getElementsByTagName('IMG')[0];			
		}
		if(thisNode.style.visibility=='hidden')return;		
		var parentNode = thisNode.parentNode;
		inputId = parentNode.id.replace(/[^0-9]/g,'');
		if(thisNode.src.indexOf(this.plusImage)>=0){
			thisNode.src = thisNode.src.replace(this.plusImage,this.minusImage);
			var ul = parentNode.getElementsByTagName('UL')[0];
			ul.style.display='block';
			if(!initExpandedNodes)initExpandedNodes = ',';
			if(initExpandedNodes.indexOf(',' + inputId + ',')<0) initExpandedNodes = initExpandedNodes + inputId + ',';
		}else{
			thisNode.src = thisNode.src.replace(this.minusImage,this.plusImage);
			parentNode.getElementsByTagName('UL')[0].style.display='none';
			initExpandedNodes = initExpandedNodes.replace(',' + inputId,'');
		}	
		DHTMLSuite.commonObj.setCookie(this.cookieName,initExpandedNodes,500);			
		return false;						
	}
	// }}}	
	,
	// {{{ getSaveString()
    /**
     * Return save string 
     * 
     * @param Object initObj - Only for private use inside the method
     * @param String saveString - Only for private use inside the method - you should call this method without arguments.
     *
     * @return String saveString - A string with the format id-parentId,id-parentId,id-parentId
     * @type String
     * @public
     */		
	getSaveString : function(initObj,saveString)
	{		
		if(!saveString)var saveString = '';
		if(!initObj){
			initObj = document.getElementById(this.idOfTree);

		}
		var lis = initObj.getElementsByTagName('LI');

		if(lis.length>0){
			var li = lis[0];
			while(li){
				if(li.id){
					if(saveString.length>0)saveString = saveString + ',';
					saveString = saveString + li.id.replace(/[^0-9]/gi,'');
					saveString = saveString + '-';
					if(li.parentNode.id!=this.idOfTree)saveString = saveString + li.parentNode.parentNode.id.replace(/[^0-9]/gi,''); else saveString = saveString + '0';
					
					var ul = li.getElementsByTagName('UL');
					if(ul.length>0){
						saveString = this.getSaveString(ul[0],saveString);	
					}	
				}			
				li = li.nextSibling;
			}
		}		
		if(initObj.id == this.idOfTree){
			return saveString;						
		}
		return saveString;
	}
	// }}}	
	,	
	// {{{ __initializeDragProcess()
    /**
     * Init a drag process
     *
     * @param event e = Event object
     * @private
     */		
	__initializeDragProcess : function(e)
	{
		if(document.all)e = event;	
		
		var subs = JSTreeObj.floatingContainer.getElementsByTagName('LI');
		if(subs.length>0){
			if(JSTreeObj.dragNode_sourceNextSib){
				JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib);
			}else{
				JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source);
			}					
		}
		
		JSTreeObj.dragNode_source = this.parentNode;
		JSTreeObj.dragNode_parent = this.parentNode.parentNode;
		JSTreeObj.dragNode_sourceNextSib = false;

		
		if(JSTreeObj.dragNode_source.nextSibling)JSTreeObj.dragNode_sourceNextSib = JSTreeObj.dragNode_source.nextSibling;
		JSTreeObj.dragNode_destination = false;
		JSTreeObj.dragDropTimer = 0;
		DHTMLSuite.commonObj.__setTextSelOk(false);
		JSTreeObj.__waitBeforeDragProcessStarts();
		return false;
	}
	// }}}	
	,
	// {{{ __waitBeforeDragProcessStarts()
    /**
     * A small delay before drag is started
     *
     * @private
     */		
	__waitBeforeDragProcessStarts : function()
	{	
		if(this.dragDropTimer>=0 && this.dragDropTimer<10){
			this.dragDropTimer = this.dragDropTimer + 1;
			setTimeout('JSTreeObj.__waitBeforeDragProcessStarts()',20);
			return;
		}
		if(this.dragDropTimer==10)
		{
			JSTreeObj.floatingContainer.style.display='block';
			JSTreeObj.floatingContainer.appendChild(JSTreeObj.dragNode_source);	
		}
	}
	// }}}	
	,
	// {{{ __moveDragableNodes()
    /**
     * Move dragable nodes
     * @param event e - Event object
     *
     * @private
     */		
	__moveDragableNodes : function(e,tagType)
	{
		if(JSTreeObj.dragDropTimer<10)return;
		if(document.all)e = event;
		dragDrop_x = e.clientX/1 + 5 + document.body.scrollLeft;
		dragDrop_y = e.clientY/1 + 5 + document.documentElement.scrollTop;	
				
		JSTreeObj.floatingContainer.style.left = dragDrop_x + 'px';
		JSTreeObj.floatingContainer.style.top = dragDrop_y + 'px';
		
		var thisObj = DHTMLSuite.commonObj.getSrcElement(e);
		var thisObjOrig = DHTMLSuite.commonObj.getSrcElement(e);
		if(thisObj.tagName=='A' || thisObj.tagName=='IMG')thisObj = thisObj.parentNode;

		JSTreeObj.dragNode_noSiblings = false;
		var tmpVar = thisObj.getAttribute('noSiblings');
		if(!tmpVar)tmpVar = thisObj.noSiblings;
		if(tmpVar=='true')JSTreeObj.dragNode_noSiblings=true;
				
		if(thisObj && tagType)
		{
			JSTreeObj.dragNode_destination = thisObj;
			var img = thisObj.getElementsByTagName('IMG')[1];
			var tmpObj= JSTreeObj.dropTargetIndicator;
			tmpObj.style.display='block';
			
			var eventSourceObj = thisObjOrig;
			if(JSTreeObj.dragNode_noSiblings && eventSourceObj.tagName=='IMG')eventSourceObj = eventSourceObj.nextSibling;
			
			var tmpImg = tmpObj.getElementsByTagName('IMG')[0];
			if(thisObjOrig.tagName=='A' || JSTreeObj.dragNode_noSiblings){
				tmpImg.src = tmpImg.src.replace('ind1','ind2');	
				JSTreeObj.insertAsSub = true;
				tmpObj.style.left = (DHTMLSuite.commonObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX_sub) + 'px';
			}else{
				
				tmpImg.src = tmpImg.src.replace('ind2','ind1');
				JSTreeObj.insertAsSub = false;
				tmpObj.style.left = (DHTMLSuite.commonObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX) + 'px';
			}
			
			
			tmpObj.style.top = (DHTMLSuite.commonObj.getTopPos(thisObj) + JSTreeObj.indicator_offsetY) + 'px';
		}
		
		return false;
		
	}
	// }}}	
	,
	// {{{ __dropDragableNodes()
    /**
     * Drag process ended - drop nodes
     *
     * @private
     */		
	__dropDragableNodes:function()
	{
		if(JSTreeObj.dragDropTimer<10){				
			JSTreeObj.dragDropTimer = -1;
			DHTMLSuite.commonObj.__setTextSelOk(true);
			return;
		}
		var showMessage = false;
		if(JSTreeObj.dragNode_destination){	// Check depth
			var countUp = JSTreeObj.__getDepthOfABranchInTheTree(JSTreeObj.dragNode_destination,'up');
			var countDown = JSTreeObj.__getDepthOfABranchInTheTree(JSTreeObj.dragNode_source,'down');
			var countLevels = countUp/1 + countDown/1 + (JSTreeObj.insertAsSub?1:0);		
			
			if(countLevels>JSTreeObj.maximumDepth){
				JSTreeObj.dragNode_destination = false;
				showMessage = true; 	// Used later down in this function
			}
		}
		
		
		if(JSTreeObj.dragNode_destination){			
			if(JSTreeObj.insertAsSub){
				var uls = JSTreeObj.dragNode_destination.getElementsByTagName('UL');
				if(uls.length>0){
					ul = uls[0];
					ul.style.display='block';
					
					var lis = ul.getElementsByTagName('LI');

					if(lis.length>0){	// Sub elements exists - drop dragable node before the first one
						ul.insertBefore(JSTreeObj.dragNode_source,lis[0]);	
					}else {	// No sub exists - use the appendChild method - This line should not be executed unless there's something wrong in the HTML, i.e empty <ul>
						ul.appendChild(JSTreeObj.dragNode_source);	
					}
				}else{
					var ul = document.createElement('UL');
					ul.style.display='block';
					JSTreeObj.dragNode_destination.appendChild(ul);
					ul.appendChild(JSTreeObj.dragNode_source);
				}
				var img = JSTreeObj.dragNode_destination.getElementsByTagName('IMG')[0];					
				img.style.visibility='visible';
				img.src = img.src.replace(JSTreeObj.plusImage,JSTreeObj.minusImage);					
				
				
			}else{
				if(JSTreeObj.dragNode_destination.nextSibling){
					var nextSib = JSTreeObj.dragNode_destination.nextSibling;
					nextSib.parentNode.insertBefore(JSTreeObj.dragNode_source,nextSib);
				}else{
					JSTreeObj.dragNode_destination.parentNode.appendChild(JSTreeObj.dragNode_source);
				}
			}	
			/* Clear parent object */
			var tmpObj = JSTreeObj.dragNode_parent;
			var lis = tmpObj.getElementsByTagName('LI');
			if(lis.length==0){
				var img = tmpObj.parentNode.getElementsByTagName('IMG')[0];
				img.style.visibility='hidden';	// Hide [+],[-] icon
				DHTMLSuite.discardElement(tmpObj);		
			}			
		}else{
			// Putting the item back to it's original location
			
			if(JSTreeObj.dragNode_sourceNextSib){
				JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib);
			}else{
				JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source);
			}			
				
		}
		JSTreeObj.dropTargetIndicator.style.display='none';		
		JSTreeObj.dragDropTimer = -1;	
		DHTMLSuite.commonObj.__setTextSelOk(true);
		if(showMessage && JSTreeObj.messageMaximumDepthReached)alert(JSTreeObj.messageMaximumDepthReached);
	}
	// }}}	
	,
	// {{{ __createDropIndicator()
    /**
     * Create small black lines indicating where items will be dropped
     *
     * @private
     */		
	__createDropIndicator : function()
	{
		this.dropTargetIndicator = document.createElement('DIV');
		this.dropTargetIndicator.style.zIndex = 240000;
		this.dropTargetIndicator.style.position = 'absolute';
		this.dropTargetIndicator.style.display='none';			
		var img = document.createElement('IMG');
		img.src = DHTMLSuite.configObj.imagePath + 'drag-drop-tree/' + 'dragDrop_ind1.gif';
		img.id = 'dragDropIndicatorImage';
		this.dropTargetIndicator.appendChild(img);
		document.body.appendChild(this.dropTargetIndicator);		
	}
	// }}}	
	,
	// {{{ __getDepthOfABranchInTheTree()
    /**
     * Count depth of a branch
     *
     * @private
     */		
	__getDepthOfABranchInTheTree : function(obj,direction,stopAtObject){
		var countLevels = 0;
		if(direction=='up'){
			while(obj.parentNode && obj.parentNode!=stopAtObject){
				obj = obj.parentNode;
				if(obj.tagName=='UL')countLevels = countLevels/1 +1;
			}		
			return countLevels;
		}	
		
		if(direction=='down'){ 
			var subObjects = obj.getElementsByTagName('LI');
			for(var no=0;no<subObjects.length;no++){
				countLevels = Math.max(countLevels,JSTreeObj.__getDepthOfABranchInTheTree(subObjects[no],"up",obj));
			}
			return countLevels;
		}	
	}	
}
	
/*[FILE_START:dhtmlSuite-ajaxUtil.js] */	
/************************************************************************************************************
*	Ajax dynamic content script
*
*	Created:					August, 23rd, 2006
*
*			
* 	Update log:
*
************************************************************************************************************/

/**
* @constructor
* @class The purpose of this class is to load content of external files into HTML elements on your page(<a href="../../demos/demo-dynamic-content-1.html" target="_blank">demo</a>).
* @version				1.0
* @version 1.0
* 
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.ajaxUtil = function()
{
	var ajaxObjects;
	this.ajaxObjects = new Array();	
	try{
		if(!standardObjectsCreated)DHTMLSuite.createStandardObjects();	// This line starts all the init methods
	}catch(e){
		alert('You need to include the dhtmlSuite-common.js file');
	}
	var objectIndex;	
	this.objectIndex = DHTMLSuite.variableStorage.arrayDSObjects.length;
	DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex] = this;
		
}

DHTMLSuite.ajaxUtil.prototype = {	
	// {{{ sendRequest()
    /**
     * Sends an ajax request to the server
     *
     * @param String url = Path on the server
     * @param String paramString - Parameters,  Example: "varA=2&varB=3";
     * @param String functionNameOnComplete = Function to execute on complete, example: "myFunction". The ajax object will be sent to this function and you can get the response from the "reponse" attribute.
     *					NB! This ajax object will be cleared automatically by the script after a 3 second delay.
     * 
     * @public
     */		
	sendRequest : function(url,paramString,functionNameOnComplete)
	{
		var ind = this.objectIndex;
		var ajaxIndex = this.ajaxObjects.length;
		try{
			this.ajaxObjects[ajaxIndex] = new sack();
		}catch(e){
			alert('Could not create ajax object. Please make sure that ajax.js is included');
		}
		if(paramString){			
			var params = this.__getArrayByParamString(paramString);	
			for(var no=0;no<params.length;no++){
				this.ajaxObjects[ajaxIndex].setVar(params[no].key,params[no].value);				
			}		
		}
		this.ajaxObjects[ajaxIndex].requestFile = url;	// Specifying which file to get
		this.ajaxObjects[ajaxIndex].onCompletion = function(){ DHTMLSuite.variableStorage.arrayDSObjects[ind].__onComplete(ajaxIndex,functionNameOnComplete); };	// Specify function that will be executed after file has been found
		this.ajaxObjects[ajaxIndex].onError = function(){ DHTMLSuite.variableStorage.arrayDSObjects[ind].__onError(ajaxIndex,url); };	// Specify function that will be executed after file has been found
		this.ajaxObjects[ajaxIndex].runAJAX();		// Execute AJAX function	
	}
	// }}}
	,
	// {{{ __getArrayByParamString()
    /**
     * Sends an ajax request to the server
     *
     * @param String paramString - Parameters,  Example: "varA=2&varB=3";
     * @return Array of key+value
     * 
     * @private
     */		
	__getArrayByParamString : function(paramString)
	{
		var retArray = new Array();
		var items = paramString.split(/&/g);
		for(var no=0;no<items.length;no++){
			var tokens = items[no].split(/=/);
			var index = retArray.length;
			retArray[index] = { key:tokens[0],value:tokens[1] }
		}
		return retArray;
	}
	// }}}
	,
	// {{{ __onError()
    /**
     * On error event
     *
     * @param Integer ajaxIndex - Index of ajax object
     * @return String url - failing url
     * 
     * @private
     */	
	__onError : function(ajaxIndex,url)
	{
		alert('Could not send Ajax request to ' + url);
	}
	// }}}
	,
	// {{{ __onComplete()
    /**
     * On complete event
     *
     * @param Integer ajaxIndex - Index of ajax object
     * @return String functionNameOnComplete - function to execute
     * 
     * @private
     */	
	__onComplete : function(ajaxIndex,functionNameOnComplete)
	{
		var ind = this.objectIndex;	
		if(functionNameOnComplete){			
			eval(functionNameOnComplete+'(DHTMLSuite.variableStorage.arrayDSObjects[' + ind + '].ajaxObjects[' + ajaxIndex + '])');
		}	
		
		setTimeout('DHTMLSuite.variableStorage.arrayDSObjects[' + ind + '].__deleteAjaxObject(' + ajaxIndex + ')',3000);
	}
	// }}}
	,
	// {{{ __deleteAjaxObject()
    /**
     * Remove ajax object from memory
     *
     * @param Integer ajaxIndex - Index of ajax object
     * 
     * @private
     */
	__deleteAjaxObject : function(ajaxIndex)
	{
		this.ajaxObjects[ajaxIndex] = false;	
	}
}
// Creating global variable of this class
DHTMLSuite.ajax = new DHTMLSuite.ajaxUtil();

/*[FILE_START:dhtmlSuite-dynamicContent.js] */	
/************************************************************************************************************
*	Ajax dynamic content script
*
*	Created:					August, 23rd, 2006
*
*			
* 	Update log:
*
************************************************************************************************************/
/**
* @constructor
* @class The purpose of this class is to load content of external files into HTML elements on your page(<a href="../../demos/demo-dynamic-content-1.html" target="_blank">demo</a>).<br>
*		 The pane splitter, window widget and the ajax tooltip script are also using this class to put external content into HTML elements.
* @version				1.0
* @version 1.0
* 
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.dynamicContent = function()
{
	var enableCache;	// Cache enabled.
	var jsCache;
	var ajaxObjects;
	var waitMessage;
	
	this.enableCache = true;
	this.jsCache = new Object();
	this.ajaxObjects = new Array();
	this.waitMessage = 'Loading content - please wait...';
	this.waitImage = 'dynamic-content/ajax-loader-darkblue.gif';
	try{
		if(!standardObjectsCreated)DHTMLSuite.createStandardObjects();	// This line starts all the init methods
	}catch(e){
		alert('You need to include the dhtmlSuite-common.js file');
	}
	var objectIndex;
	
	this.objectIndex = DHTMLSuite.variableStorage.arrayDSObjects.length;
	DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex] = this;
		
}

DHTMLSuite.dynamicContent.prototype = {

	// {{{ loadContent()
    /**
     * Load content from external files into an element on your web page.
     *
     * @param String divId = Id of HTML element
     * @param String url = Path to content on the server(Local content only)
     * @param String functionToCallOnLoaded = Function to call when ajax is finished. This string will be evaulated, example of string: "fixContent()" (with the quotes).
     * 
     * @public
     */	
	loadContent : function(divId,url,functionToCallOnLoaded)
	{
		
		var ind = this.objectIndex;
		if(this.enableCache && this.jsCache[url]){
			document.getElementById(divId).innerHTML = this.jsCache[url];
			DHTMLSuite.commonObj.__evaluateJs(divId);
			DHTMLSuite.commonObj.__evaluateCss(divId);	
			if(functionToCallOnLoaded)eval(functionToCallOnLoaded);	
			return;
		}
		var ajaxIndex = 0;
		
		/* Generating please wait message */
		var waitMessageToShow = '';
		if(this.waitImage){	// Wait image exists ?
			waitMessageToShow = waitMessageToShow + '<div style="text-align:center;padding:10px"><img src="' + DHTMLSuite.configObj.imagePath + this.waitImage + '" border="0" alt=""></div>';
		}
		if(this.waitMessage){	// Wait message exists ?
			waitMessageToShow = waitMessageToShow + '<div style="text-align:center">' + this.waitMessage + '</div>';
		}		
		try{
			if(waitMessageToShow.length>0)document.getElementById(divId).innerHTML=waitMessageToShow; 
		}catch(e){			
		}		
		waitMessageToShow = false;
		var ajaxIndex = this.ajaxObjects.length;		
		
		try{
			this.ajaxObjects[ajaxIndex] = new sack();
		}catch(e){
			alert('Could not create ajax object. Please make sure that ajax.js is included');
		}
	
		
		
		if(url.indexOf('?')>=0){	// Get variables in the url
			this.ajaxObjects[ajaxIndex].method='GET';	// Change method to get
			var string = url.substring(url.indexOf('?'));	// Extract get variables
			url = url.replace(string,'');
			string = string.replace('?','');
			var items = string.split(/&/g);
			for(var no=0;no<items.length;no++){
				var tokens = items[no].split('=');
				if(tokens.length==2){
					this.ajaxObjects[ajaxIndex].setVar(tokens[0],tokens[1]);
				}	
			}	
			url = url.replace(string,'');
		}	

		
		
			
		this.ajaxObjects[ajaxIndex].requestFile = url;	// Specifying which file to get
		this.ajaxObjects[ajaxIndex].onCompletion = function(){ DHTMLSuite.variableStorage.arrayDSObjects[ind].__ajax_showContent(divId,ajaxIndex,url,functionToCallOnLoaded); };	// Specify function that will be executed after file has been found
		this.ajaxObjects[ajaxIndex].onError = function(){ DHTMLSuite.variableStorage.arrayDSObjects[ind].__ajax_displayError(divId,ajaxIndex,url,functionToCallOnLoaded); };	// Specify function that will be executed after file has been found
		this.ajaxObjects[ajaxIndex].runAJAX();		// Execute AJAX function	
	}
	// }}}		
	,
	// {{{ setWaitMessage()
    /**
     * Specify which message to show when Ajax is busy.
     *
     * @param String newWaitMessage = New wait message (Default = "Loading content - please wait") - use false if you don't want any wait message
     * 
     * @public
     */		
	setWaitMessage : function(newWaitMessage)
	{
		this.waitMessage = newWaitMessage;		
	}
	// }}}
	,
	// {{{ setWaitImage()
    /**
     * Specify an image to show when Ajax is busy working.
     *
     * @param String newWaitImage = New wait image ( default = ajax-loader-blue.gif - it is by default located inside the image_dhtmlsuite folder. - If you like a new image, try to generate one at http://www.ajaxload.info/
     * 
     * @public
     */		
	setWaitImage : function(newWaitImage)
	{
		this.waitImage = newWaitImage;
	}
	// }}}
	,
	// {{{ setCache()
    /**
     * Cancel selection when drag is in process
     *
     * @param Boolean enableCache = true if you want to enable cache, false otherwise(default is true). You can also send HTMl code in here, example an &lt;img> tag.
     * 
     * @public
     */		
	setCache : function(enableCache)
	{
		this.enableCache = enableCache;		
	}
	// }}}
	,
	// {{{ __ajax_showContent()
    /**
     * Evaluate Javascript in the inserted content
     *
     * @private
     */		
	__ajax_showContent :function(divId,ajaxIndex,url,functionToCallOnLoaded)
	{
		document.getElementById(divId).innerHTML = '';
		document.getElementById(divId).innerHTML = this.ajaxObjects[ajaxIndex].response;
		if(this.enableCache){	// Cache is enabled
			this.jsCache[url] = document.getElementById(divId).innerHTML + '';	// Put content into cache
		}	
		DHTMLSuite.commonObj.__evaluateJs(divId);	// Call private method which evaluates JS content
		DHTMLSuite.commonObj.__evaluateCss(divId);	// Call private method which evaluates JS content
		if(functionToCallOnLoaded)eval(functionToCallOnLoaded);
		this.ajaxObjects[ajaxIndex] = null;	// Clear sack object
		return false;
	}
	// }}}
	,
	// {{{ __ajax_displayError()
    /**
     * Display error message when the request failed.
     *
     * @private
     */		
	__ajax_displayError : function(divId,ajaxIndex,url,functionToCallOnLoaded)
	{
		document.getElementById(divId).innerHTML = '<h2>Message from DHTMLSuite.dynamicContent</h2><p>The ajax request for ' + url + ' failed</p>';		
	}
	// }}}		
}

/*[FILE_START:dhtmlSuite-formUtil.js] */
/************************************************************************************************************
*	Form utility classes
*
*	Created:						February, 22nd, 2007
*	Last updated:					March, 13th, 2007
*	@class Purpose of class:		Form utility classes
*			
*	Css files used by this script:	form-validator.css
*
*	Demos of this class:			demo-form-validator.html
*
* 	Update log:
*
************************************************************************************************************/

/**
* @constructor
* @class Form validator
* Demo: <a href="../../demos/demo-form-validator.html" target="_blank">demo-form-validator.html</a>		
*
* @param Object - propArray - Associative array of properties. Possible keys:<br>
*	formRef - Reference to form<br>
*	indicateWithCss - Indicate error by adding a red or green border around elements. (default = false)
*	keyValidation - Validate as you type. This applies to numeric and letteric characters (default = false)
*	callbackOnFormValid - Name of function to execute when the form is valid
*	callbackOnFormInvalid - Name of function to execute when the form is invalid
*	indicateWithBars - Indicate valid and invalid form elements by a red or green bar at the left of the elements. (default = false)
*	
* @version				1.0
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/
DHTMLSuite.formValidator = function(propArray)
{
	var formRef;
	var indicateWithCss;
	var indicateWithBars;
	
	var keyValidation;
	var objectIndex;
	var layoutCSS;
	
	var callbackOnFormValid;
	var callbackOnFormInvalid;
	
	var formElements;
	var masks;	
	var radios;
	var indicationImages;
	var indicationBars;
	var equalToEls;
 	var formUtil;
 	
 
	this.equalToEls= new Object();
	this.equalToEls.from = new Object();
	this.equalToEls.to = new Object();
	
	this.formUtil = new DHTMLSuite.formUtil();
	
	this.masks = new Object();	
	this.indicationImages = new Array();
	this.indicationBars = new Array();
	
	var domainString = '(com|org|net|mil|edu|info|mobi|travel|a[cdfgilmnoqrstuwxz]|b[abdefghijmnorstwyz]|c[acdfghiklmnoruvxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[adefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnrwyz]|l[abcikrstuvy]|m[acdghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eouw]|s[abcdeghiklmnrtvyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[etu]|z[amw])';
	
	this.masks.email = new RegExp("^[A-Z0-9._%-]+@[A-Z0-9.-]+\\." + domainString + "$","gi");
	this.masks.numeric = /^[0-9]+$/gi;	// Numeric
	this.masks.letter = /^[A-Zæøå]+$/gi;	// letteric
	this.masks.domain = new RegExp("^(https?\:\/\/)?[a-zA-Z0-9]+([a-zA-Z0-9\-\.]+)?\\." + domainString + "$","gi");
	
	this.layoutCSS = 'form-validator.css';
	this.indicateWithCss = false;
	this.indicateWithBars = false;
	this.keyValidation = false;
	this.formElements = new Object();
	this.radios = new Object();	// Array of radio button objects
	try{
		if(!standardObjectsCreated)DHTMLSuite.createStandardObjects();	// This line starts all the init methods
	}catch(e){
		alert('You need to include the dhtmlSuite-common.js file');
	}
		
	this.objectIndex = DHTMLSuite.variableStorage.arrayDSObjects.length;
	DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex] = this;	
	
	if(propArray)this.__setInitProps(propArray);
	this.__init();
}
DHTMLSuite.formValidator.prototype = 
{
	// {{{ addMask()
    /**
     *	Add regexp mask
     * 	
     *	@param String maskName - Name of mask, i.e. the value you use in the flag attribute of your form elements.
     *	@param String mask - Example: [0-9]
     *	@param String regexpFlags - Regexp flags, example "gi"
     *
     * @public
     */		
	addMask : function(maskName,regexpPattern,regexpFlags)
	{
		try{
			this.masks[maskName] = new RegExp(regexpPattern,regexpFlags);
		}catch(e){
			alert('Could not create regexp mask of ' + regexpPattern +',flags: ' + regexpFlags);
		}		
	}
	// }}}
	,	
	// {{{ __setInitProps()
    /**
     *	Add regexp mask
     * 	
     *	@param Array props - Array of properties
     *
     * @private
     */	
	__setInitProps : function(props)
	{
		if(props.formRef){
			var obj = DHTMLSuite.commonObj.getEl(props.formRef);
			this.formRef = obj;
		}
		if(props.indicateWithCss || props.indicateWithCss===false)this.indicateWithCss = props.indicateWithCss;
		if(props.keyValidation)this.keyValidation = props.keyValidation;
		if(props.callbackOnFormValid)this.callbackOnFormValid = props.callbackOnFormValid;
		if(props.callbackOnFormInvalid)this.callbackOnFormInvalid = props.callbackOnFormInvalid;
		if(props.indicateWithBars || props.indicateWithBars===false)this.indicateWithBars = props.indicateWithBars;
		if(this.indicateWithCss)this.indicateWithBars = false;
	}
	// }}}
	,	
	// {{{ __init()
    /**
     *	Initializes the widget
     *
     * @private
     */	
	__init : function()
	{
		if(this.formRef){
			var ind = this.objectIndex;
			this.__initiallyParseAForm();	
			this.formRef.onreset = function(){ setTimeout("DHTMLSuite.variableStorage.arrayDSObjects["+ ind +"].__validateAllFields()",50); };
			DHTMLSuite.commonObj.__addEventEl(this.formRef);
			DHTMLSuite.commonObj.addEvent(window,'resize',function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__positionIndImages(); });			
		}
		DHTMLSuite.commonObj.loadCSS(this.layoutCSS);
	}
	// }}}
	,
	// {{{ __validateAllFields()
    /**
     *	This method is called by events, example when someone resets the form.
     *
     * @private
     */		
	__validateAllFields : function()
	{
		for(var prop in this.formElements){
			this.__validateInput(this.formElements[prop].el);			
		}		
	}
	// }}}
	,
	// {{{ __addRadiosToArray()
    /**
     *	This method add radios and checkboxes with the same name to the radios array
  	 * 	@param HTMLElement el - Reference to a radio button
     *
     * @private
     */		
	__addRadiosToArray : function(el)
	{
		if(!this.radios[el.name]){	// Radio with this name or id has not been added to the array
			this.radios[el.name] = new Array();
			for(var no=0;no<this.formRef.elements.length;no++){
				var formEl = this.formRef.elements[no];
				if(formEl.name==el.name)this.radios[el.name][this.radios[el.name].length] = formEl;
			}
		}		
	}
	// }}}
	,
	// {{{ __initiallyParseAForm()
    /**
     *	Initially parse a form.
     *
     * @private
     */		
	__initiallyParseAForm : function()
	{
		var ind = this.objectIndex;
		var formRef = this.formRef;
		var vElements = new Array();	// Array of elements to parse	
		var inputs = formRef.getElementsByTagName('INPUT');
		for(var no=0;no<inputs.length;no++){	/* Looping through inputs */
			if(!this.__hasValidationAttr(inputs[no]))continue;
			if(inputs[no].type.toLowerCase()=='text' || inputs[no].type.toLowerCase()=='checkbox' || inputs[no].type.toLowerCase()=='radio' || inputs[no].type.toLowerCase()=='password'){
				vElements[vElements.length] = inputs[no];				
			}	
			if(inputs[no].type.toLowerCase()=='radio'){
				this.__addRadiosToArray(inputs[no]);	
			}	
			if(inputs[no].type.toLowerCase()=='checkbox'){
				this.__addRadiosToArray(inputs[no]);	
			}
			
				
		}
		var ta = formRef.getElementsByTagName('TEXTAREA');
		for(var no=0;no<ta.length;no++){	/* Looping through inputs */
			if(!this.__hasValidationAttr(ta[no]))continue;
			vElements[vElements.length] = ta[no];
		}		
		var sel = formRef.getElementsByTagName('SELECT');
		for(var no=0;no<sel.length;no++){	/* Looping through inputs */
			if(!this.__hasValidationAttr(sel[no]))continue;
			vElements[vElements.length] = sel[no];
		}
		for(var no=0;no<vElements.length;no++){
			var elType=vElements[no].tagName.toLowerCase();
			if(elType=='input')elType = vElements[no].type.toLowerCase();
			if(!elType)elType='text';
			
			if(this.indicateWithCss){			
				if(elType=='select')this.__addParentToSelect(vElements[no]);				
				if(elType=='textarea')vElements[no].className = vElements[no].className + ' DHTMLSuite_validInput';
				if(vElements[no].tagName.toLowerCase()=='input' && elType=='text')vElements[no].className = vElements[no].className + ' DHTMLSuite_validInput';
				if(vElements[no].tagName.toLowerCase()=='input' && elType=='checkbox')vElements[no].className = vElements[no].className + ' DHTMLSuite_validInput';
			}
			if(document.getElementById('_' + vElements[no].name)){				
				if(!this.indicationImages[vElements[no].name]){
					this.indicationImages[vElements[no].name] = document.createElement('DIV');				
					var el = this.indicationImages[vElements[no].name];
					document.getElementById('_' + vElements[no].name).appendChild(el);
					el.className = 'DHTMLSuite_validationImage DHTMLSuite_invalidInputImage';
					//@WCU el.style.height = document.getElementById('_' + vElements[no].name).clientHeight + 'px';
				}
			}
			if(this.indicateWithBars){
				if(!this.indicationBars[vElements[no].name] && elType!='radio' && elType!='checkbox'){					
					this.indicationBars[vElements[no].name] = document.createElement('DIV');				
					var el = this.indicationBars[vElements[no].name];					
					var parent = vElements[no].parentNode;
					parent.insertBefore(el,vElements[no].parentNode.firstChild);
					if(DHTMLSuite.clientInfoObj.isMSIE){	// Firefox doesn't support absolute positioned elements inside relative positioned td tags.
						el.style.left = '0px';
						el.style.top = '0px';
						if(DHTMLSuite.commonObj.getStyle(parent,'position')!='absolute')parent.style.position = 'relative';
					}
					el.innerHTML = '<span></span>';
					el.className = 'DHTMLSuite_validationBar DHTMLSuite_validationBarValid';
					el.style.position='absolute';					
				}			
			}
			
			if(!vElements[no].id)vElements[no].id=DHTMLSuite.commonObj.getUniqueId();
			vElements[no].setAttribute('elementIndex',no);
			this.formElements[vElements[no].name] = new Array();
			this.formElements[vElements[no].name].el = vElements[no].id;
			this.formElements[vElements[no].name].result = false;
			this.__setRegExpPattern(vElements[no]);			
			this.__validateInput(vElements[no]);
			this.__addEvent(vElements[no]);			
		}				
		setTimeout('DHTMLSuite.variableStorage.arrayDSObjects[' + this.objectIndex + '].__positionIndImages()',50);
	}
	// }}}
	,
	// {{{ __positionIndImages()
    /**
     *	Assign regexp pattern as special attribute of the HTML element.
     *
     * @private
     */	
	__positionIndImages : function()
	{	
		for(var prop in this.indicationBars){
			try{
				var el = this.indicationBars[prop]; 
				var formEl = DHTMLSuite.commonObj.getEl(this.formElements[prop].el);
				var left = (formEl.offsetLeft - el.offsetWidth);
				el.style.marginLeft = left + 'px';	
				el.style.marginTop = '0px';
				if(DHTMLSuite.clientInfoObj.isMSIE)el.style.marginTop = (DHTMLSuite.commonObj.getTopPos(formEl) - DHTMLSuite.commonObj.getTopPos(formEl.parentNode)) + 'px';	
				el.style.height = formEl.offsetHeight + 'px';	
			}catch(e){
				
			}		
		}
		
	}
	// }}}
	,
	// {{{ __setRegExpPattern()
    /**
     *	Assign regexp pattern as special attribute of the HTML element.
     *
     * @private
     */	
	__setRegExpPattern : function(formEl)
	{
		var pat = formEl.getAttribute('regexpPattern');
		if(pat){
			if(pat.indexOf('/')==-1){
				pat = '/' + pat + '/';
				formEl.setAttribute('regexpPattern',pat);
			}
			return;	// Regexp pattern already exists
		}
		var req = formEl.getAttribute('required');
		if(req || req===''){
			pat = '/./';	// Require single character	
		}
		var minLength = formEl.getAttribute('minLength');
		if(minLength){
			var pat = '/';
			for(var no=0;no<minLength;no++)pat = pat + '.';
			pat = pat + '/'	
		}
		var sp = formEl.getAttribute('simplePattern');
		
		var freemask = formEl.getAttribute('freemask');
		if(freemask){			
			var cs = formEl.getAttribute('caseInsensitive');
			cs = cs + '';	
	
			freemask = freemask.replace(/([^NSs])/g,'\\$1');
			freemask = freemask.replace(/N/gi,'[0-9]');
			freemask = freemask.replace(/s/g,'[a-z]');
			freemask = freemask.replace(/S/g,'[A-Z]');
			freemask = '/^' + freemask + '$/';
			if(cs || cs==='')freemask = freemask + 'i';
			pat = freemask;			
		}
		var mask = formEl.getAttribute('mask');
		if(mask){
			try{
				pat = mask;
			}catch(e){
			}			
		}
		formEl.setAttribute('regexpPattern',pat);
		formEl.setAttribute('regexpFlag',pat);
		
		var equalTo = formEl.getAttribute('equalTo');
		if(equalTo){
			try{
				this.equalToEls.from[formEl.name] = DHTMLSuite.commonObj.getEl(equalTo);	
				this.equalToEls.to[equalTo] = formEl;
				// Avoid circular references		
				this.equalToEls.from[equalTo] = false;		
				this.equalToEls.to[formEl.name] = false;				
			}catch(e){
			}
		}
	}
	// }}}
	,
	// {{{ __addEvent()
    /**
     *	Add event to a form element.
     *	@param Object formEl - referenc eto form element.
     *
     * @private
     */	
	__addEvent : function(formEl)
	{
		var ind = this.objectIndex;
		var id = formEl.id;
		DHTMLSuite.commonObj.addEvent(formEl,'change',function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateInput(id); });		
		// formEl.onchange = function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateInput(id); };
		formEl.onpaste = function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateInput(id); };
		formEl.onblur = function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateInput(id); };
		formEl.onkeyup = function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateInput(id); };
		formEl.onclick = function() { DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateInput(id); };
		if(this.keyValidation){
			formEl.onkeypress = function(e) { return DHTMLSuite.variableStorage.arrayDSObjects[ind].__validateKey(e,id); };
			formEl.onpaste = function() { setTimeout('DHTMLSuite.variableStorage.arrayDSObjects[' + ind + '].__validatePaste("' + id + '")',2) };
		}
		DHTMLSuite.commonObj.__addEventEl(formEl);
	}
	// }}}
	,
	// {{{ __validatePaste()
    /**
     *	Validate pasted data and remove non-valid characters from the input
     *	@param String elRef - Id of form element
     *
     * @private
     */	
	__validatePaste : function(elRef)
	{
		var src = DHTMLSuite.commonObj.getEl(elRef);
		var pat = src.getAttribute('regexpPattern');
		if(pat == 'letter')src.value = src.value.replace(/[^a-z]/gi,'');
		if(pat == 'numeric')src.value = src.value.replace(/[^0-9]/g,'');
		if(pat=='letter' || pat=='numeric')this.__validateInput(elRef);
	}
	// }}}
	,
	// {{{ __validateKey()
    /**
     *	Validate key stroke
     *	@param Event e - Event object - used to find key code
     *	@param String elRef - Id of form element
     *
     * @private
     */	
	__validateKey : function(e,elRef)
	{
		if(document.all)e = event;	
		if(e.ctrlKey || e.altKey)return true;	
		var src = DHTMLSuite.commonObj.getSrcElement(e);
		var pat = src.getAttribute('regexpPattern');	
		var code = DHTMLSuite.commonObj.getKeyCode(e);
		var key = DHTMLSuite.commonObj.getKeyFromEvent(e);		
		if(code<48 && code!=32)return true;		
		if(key=='\t')return true;// Tabulator
		if(pat == 'letter'){
			if(code==192 || code==222 || code==221)return true;	// Scandinavian characters
			if(!key.match(/[a-z]/gi))return false;
		}
		if(pat == 'numeric' && !key.match(/[0-9]/g))return false;
		return true;	// Not yet implemented
	}
	// }}}
	,
	// {{{ __hasValidationAttr()
    /**
     *	Should this form element be validated - look for attributes
     *
     * @private
     */	
	__hasValidationAttr : function(el)
	{
		var req = el.getAttribute('required');
		if(req || req==='')return true;
		var mask = el.getAttribute('mask');
		if(mask)return true;
		var mask = el.getAttribute('freemask');
		if(mask)return true;
		var regexp = el.getAttribute('regexpPattern');
		if(regexp)return true;
		var equalTo = el.getAttribute('equalTo');
		if(equalTo)return true;
		return false;	
	}
	// }}}
	,
	// {{{ __addParentToSelect()
    /**
     *	Create parent div for select boxes.
     *
     * @private
     */		
	__addParentToSelect : function(selectRef)
	{
		var div = document.createElement('DIV');
		selectRef.parentNode.insertBefore(div,selectRef);
		div.appendChild(selectRef);
		div.className = 'DHTMLSuite_validInput';
		div.style.cssText = 'display:inline-block;';
		div.style.width = selectRef.offsetWidth + 'px';
	}
	// }}}
	,
	// {{{ __validateInput()
    /**
     *	Validate input
     *	@param Object inputRef - Reference to form element
     *
     * @private
     */	
	__validateInput : function(inputRef)
	{
		
		inputRef = DHTMLSuite.commonObj.getEl(inputRef);
		var index = inputRef.name;
		
		if(this.__isInputValid(inputRef)){
			this.formElements[index].result = true;
			this.__toggleInput(inputRef,'valid');
		}else{
			this.formElements[index].result = false;
			this.__toggleInput(inputRef,'invalid');
		}
		
		this.__validateForm();
	}
	// }}}
	,
	// {{{ __isInputValid()
    /**
     *	Validate input
     *	@param Object inputRef - reference to form element
     *
     * @private
     */	
	__isInputValid : function(inputRef,circular)
	{
		if (inputRef.disabled) return true;	//@WCU
		
		var required = inputRef.getAttribute('required');
		var elType = 'select';
		if((inputRef.tagName.toLowerCase()=='input' && (inputRef.type.toLowerCase()=='text' || inputRef.type.toLowerCase()=='password')) || inputRef.tagName.toLowerCase()=='textarea')elType = 'text';
		if(inputRef.tagName.toLowerCase()=='input' && inputRef.type.toLowerCase()=='checkbox')elType = 'checkbox';
		if(inputRef.tagName.toLowerCase()=='input' && inputRef.type.toLowerCase()=='radio')elType = 'radio';
		
		// equalTo attribute set?
		if(this.equalToEls.from[inputRef.name]){	
			var equal = this.formUtil.areEqual(inputRef,this.equalToEls.from[inputRef.name]);
			if(!equal)return false;			
		}
		// equalTo attribute set?
		if(this.equalToEls.to[inputRef.name]){	
			this.__validateInput(this.equalToEls.to[inputRef.name]);			
		}
			
		if(elType=='text'){
			if((!required && required!='') && inputRef.value.length==0)return true;
			var pat = inputRef.getAttribute('regexpPattern');
			if(pat.indexOf('/')==-1)pat = this.masks[pat];else pat = eval(pat);
			if(inputRef.value.trim().match(pat)){
				var matches = inputRef.value.trim().match(pat);
				var minLength = inputRef.getAttribute('minLength');
				if(minLength)if(inputRef.value.trim().length<minLength)return false;
				return true; 
			}else return false;
		}
		if(elType=='select'){
			var multiple = inputRef.getAttribute('multiple');
			if(multiple || multiple===''){
				if(required || required===''){
					for(var no=0;no<inputRef.options.length;no++){
						if(inputRef.options[no].selected && inputRef.options[no].value)return true;
					}
					return false;					
				}
			}else{
				if(required || required==='' && !inputRef.options[inputRef.selectedIndex].value)return false;	
			}		
		}

		if(elType=='radio' || elType=='checkbox'){
			var name = inputRef.name;
			var elChecked = false;
			for(var no=0;no<this.radios[name].length;no++){
				if(this.radios[name][no].checked)elChecked = true;	
			}
			if(!elChecked)return false;
		}
		return true;
	}
	// }}}
	,
	// {{{ __toggleInput()
    /**
     *	Toggle input, i.e. style it depending on if it's valid or not.
     *	@param Object inputRef - reference to form element
     *	@param String style - "valid" or "invalid"
     *
     * @private
     */	
	__toggleInput : function(inputRef,style)
	{
		var el = inputRef;
		
		if(this.indicationImages[el.name]){			
			var obj= this.indicationImages[el.name];
			obj.className = obj.className.replace(' DHTMLSuite_invalidInputImage','');
			obj.className = obj.className.replace(' DHTMLSuite_validInputImage','');
			if(style=='valid'){
				obj.className = obj.className + ' DHTMLSuite_validInputImage';
			}else{
				obj.className = obj.className + ' DHTMLSuite_invalidInputImage';
			}
		}
		if(this.indicateWithBars){
			var obj = this.indicationBars[el.name];
			if(!obj)return;
			obj.className = obj.className.replace(' DHTMLSuite_validationBarValid','');
			obj.className = obj.className.replace(' DHTMLSuite_validationBarInvalid','');
			if(style=='valid'){
				obj.className = obj.className + ' DHTMLSuite_validationBarValid';
			}else{
				obj.className = obj.className + ' DHTMLSuite_validationBarInvalid';
			}						
		}
		
		if(this.indicateWithCss){
			if(el.tagName.toLowerCase()=='select')el = el.parentNode;
			if(el.className.indexOf('DHTMLSuite_')==-1)return;
			el.className = el.className.replace(' DHTMLSuite_invalidInput','');
			el.className = el.className.replace(' DHTMLSuite_validInput','');
						
			if(style=='valid'){
				el.className = el.className + ' DHTMLSuite_validInput';				
			}else{			
				el.className = el.className + ' DHTMLSuite_invalidInput';	
			}
		}
	}
	// }}}
	,
	// {{{ isFormValid()
    /**
     *	Returns true if the form is valid, false otherwise
     *
     * @public
     */	
	isFormValid : function()
	{
		for(var no in this.formElements){
			if(!this.formElements[no].result){				
				return false;
			}
		}		
		return true;		
	}
	// }}}
	,
	// {{{ __validateForm()
    /**
     *	Validate form
     *
     * @private
     */		
	__validateForm : function()
	{
		if(this.isFormValid()){
			this.__handleCallback('formValid');
		}else{ 
			this.__handleCallback('formInvalid');
		}
	}
	// }}}
	,
	// {{{ __handleCallback()
    /**
     *	Execute call back functions.
     *
     * @private
     */	
	__handleCallback : function(action)
	{
		var callbackString = '';
		switch(action){
			case "formValid":
				if(this.callbackOnFormValid)callbackString = this.callbackOnFormValid;
				break;
			case "formInvalid":
				if(this.callbackOnFormInvalid)callbackString = this.callbackOnFormInvalid;
				break;			
		}			
		if(callbackString){
			callbackString = callbackString + '(this.formElements)';
			eval(callbackString);
		}	
	}
}


/************************************************************************************************************
*	Form submission class
*
*	Created:						March, 6th, 2007
*	@class Purpose of class:		Ajax form submission class
*			
*	Css files used by this script:	
*
*	Demos of this class:			demo-form-validator.html
*
* 	Update log:
*
************************************************************************************************************/


/**
* @constructor
* @class Form submission
* Demo: <a href="../../demos/demo-form-validator.html" target="_blank">demo-form-validator.html</a>		
*
* @param Object - formRef - Reference to form
* @version				1.0
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.formUtil = function()
{
	
	
	
}
	
DHTMLSuite.formUtil.prototype = 
{
	// {{{ getFamily
    /**
     *	Return an array of elements with the same name
     *	@param Object el - Reference to form element
     *	@param Object formRef - Reference to form
     *
     * @public
     */		
	getFamily : function(el,formRef)
	{
		var els = formRef.elements;
		var retArray = new Array();
		for(var no=0;no<els.length;no++){
			if(els[no].name == el.name)retArray[retArray.length] = els[no];
		}
		return retArray;		
	}
	// }}}
	,
	// {{{ hasFileInputs()
    /**
     *	Does the form has file inputs?
     *	@param Object formRef - Reference to form
     *
     * @public
     */		
	hasFileInputs : function(formRef)
	{
		var els = formRef.elements;
		for(var no=0;no<els.length;no++){
			if(els[no].tagName.toLowerCase()=='input' && els[no].type.toLowerCase()=='file')return true;	
		}
		return false;
	}
	// }}}
	,	
	// {{{ getValuesAsArray()
    /**
     *	Return value of form as associative array
     *	@param Object formRef - Reference to form
     *
     * @public
     */		
	getValuesAsArray : function(formRef)
	{
		var retArray = new Object();
		formRef = DHTMLSuite.commonObj.getEl(formRef);
		var els = formRef.elements;
		for(var no=0;no<els.length;no++){
			if(els[no].disabled)continue;
			var tag = els[no].tagName.toLowerCase();
			switch(tag){
				case "input": 
					var type = els[no].type.toLowerCase();
					if(!type)type='text';
					switch(type){
						case "text":
						case "image":
						case "hidden":
						case "password":
							retArray[els[no].name] = els[no].value;
							break;
						case "checkbox":
							var boxes = this.getFamily(els[no],formRef);
							if(boxes.length>1){
								retArray[els[no].name] = new Array();
								for(var no2=0;no2<boxes.length;no2++){
									if(boxes[no2].checked){
										var index = retArray[els[no].name].length;
										retArray[els[no].name][index] = boxes[no2].value;
									}
								}								
							}else{
								if(els[no].checked)retArray[els[no].name] = els[no].value;
							}
							break;	
						case "radio":
							if(els[no].checked)retArray[els[no].name] = els[no].value;
							break;		
						
					}	
					break;	
				case "select":
					var string = '';			
					var mult = els[no].getAttribute('multiple');
					if(mult || mult===''){
						retArray[els[no].name] = new Array();
						for(var no2=0;no2<els[no].options.length;no2++){
							var index = retArray[els[no].name].length;
							if(els[no].options[no2].selected)retArray[els[no].name][index] = els[no].options[no2].value;	
						}
					}else{
						retArray[els[no].name] = els[no].options[els[no].selectedIndex].value;
					}
					break;	
				case "textarea":
					retArray[els[no].name] = els[no].value;
					break;					
			}			
		}
		return retArray;		
	}
	// }}}
	,	
	// {{{ getValue()
    /**
     *	Return value of form element
     *	@param Object formEl - Reference to form element
     *
     * @public
     */
	getValue : function(formEl)
	{
		switch(formEl.tagName.toLowerCase()){
			case "input":
			case "textarea": return formEl.value;
			case "select": return formEl.options[formEl.selectedIndex].value;			
		}
		
	}
	// }}}
	,	
	// {{{ areEqual()
    /**
     *	Check if two form elements have the same value
     *	@param Object input1 - Reference to form element
     *	@param Object input2 - Reference to form element
     *
     * @public
     */	
	areEqual : function(input1,input2)
	{
		input1 = DHTMLSuite.commonObj.getEl(input1);
		input2 = DHTMLSuite.commonObj.getEl(input2);	
		if(this.getValue(input1)==this.getValue(input2))return true;
		return false;		
	}	
}
	
/************************************************************************************************************
*	Form submission class
*
*	Created:						March, 6th, 2007
*	@class Purpose of class:		Ajax form submission class
*			
*	Css files used by this script:	form.css
*
*	Demos of this class:			demo-form-validator.html
*
* 	Update log:
*
************************************************************************************************************/


/**
* @constructor
* @class Form submission
* Demo: <a href="../../demos/demo-form-validator.html" target="_blank">demo-form-validator.html</a>		
*
* @param Associative array of properties, possible keys: <br>
*	formRef - Reference to form<br>
*	method - How to send the form, "GET" or "POST", default is "POST"
*	reponseEl - Where to display response from ajax
*	action - Where to send form data
*	responseFile - Alternative response file. This will be loaded dynamically once the script receives response from the file specified in "action".
*		
* @version				1.0
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.form = function(propArray)
{
	var formRef;
	var method;
	var responseEl;
	var action;
	var responseFile;
	
	var formUtil;
	var objectIndex;
	var sackObj;
	var coverDiv;
	var layoutCSS;
	var iframeName;
	
	this.method = 'POST';
	this.sackObj = new Array();
	this.formUtil = new DHTMLSuite.formUtil();
	this.layoutCSS = 'form.css';
	
	
	try{
		if(!standardObjectsCreated)DHTMLSuite.createStandardObjects();	// This line starts all the init methods
	}catch(e){
		alert('You need to include the dhtmlSuite-common.js file');
	}
		
	this.objectIndex = DHTMLSuite.variableStorage.arrayDSObjects.length;
	DHTMLSuite.variableStorage.arrayDSObjects[this.objectIndex] = this;	
		
	DHTMLSuite.commonObj.loadCSS(this.layoutCSS);
	
	if(propArray)this.__setInitProperties(propArray);
	
}
DHTMLSuite.form.prototype = 
{
	// {{{ submit()
    /**
     *	Submits the form
     *
     * @public
     */		
	submit : function()
	{
		this.__createCoverDiv();
		var index = this.sackObj.length;
		if(this.formUtil.hasFileInputs(this.formRef)){
			this.__createIframe();
			this.formRef.submit();
			
		}else{
			this.__createSackObject(index);			
			this.__populateSack(index);			
			this.sackObj[index].runAJAX();
		}
		this.__positionCoverDiv();
		return false;
	}
	// }}}
	,
	__createIframe : function()
	{
		if(this.iframeName)return;
		var ind = this.objectIndex;
		var div = document.createElement('DIV');
		document.body.appendChild(div);
		this.iframeName = 'DHTMLSuiteForm' + DHTMLSuite.commonObj.getUniqueId();
		div.innerHTML = '<iframe style="visibility:hidden;width:5px;height:5px" id="' + this.iframeName + '" name="' + this.iframeName + '" onload="parent.DHTMLSuite.variableStorage.arrayDSObjects[' + ind + '].__getIframeResponse()"></iframe>'; 
		this.formRef.method = this.method;
		this.formRef.action = this.action;
		this.formRef.target = this.iframeName;	
		if(!this.formRef.enctype)this.formRef.enctype = 'multipart/form-data';
			
	}
	// }}}
	,
	// {{{ __getIframeResponse()
    /**
     *	Form has been submitted to iframe - move content from iframe
     *
     * @private
     */	
	__getIframeResponse : function()
	{
		if(this.responseEl){		
			if(this.responseFile){
				if(!this.responseEl.id)this.responseEl.id = 'DHTMLSuite_formResponse' + DHTMLSuite.getUniqueId();
				var dynContent = new DHTMLSuite.dynamicContent();
				dynContent.loadContent(this.responseEl.id,this.responseFile);				
			}else{			
				this.responseEl.innerHTML = self.frames[this.iframeName].document.body.innerHTML;	
				DHTMLSuite.commonObj.__evaluateJs(this.responseEl);
				DHTMLSuite.commonObj.__evaluateCss(this.responseEl);	
			}						
		}	
		this.coverDiv.style.display='none';
		this.__handleCallback('onComplete');
	}
	// }}}
	,
	// {{{ __positionCoverDiv()
    /**
     *	Position cover div
     *
     * @private
     */	
	__positionCoverDiv : function()
	{
		if(!this.responseEl)return;
		try{
			var st = this.coverDiv.style;
			st.left = DHTMLSuite.commonObj.getLeftPos(this.responseEl) + 'px';	
			st.top = DHTMLSuite.commonObj.getTopPos(this.responseEl) + 'px';	
			st.width = this.responseEl.offsetWidth + 'px';	
			st.height = this.responseEl.offsetHeight + 'px';	
			st.display='block';
		}catch(e){
		}
	}
	// }}}
	,
	// {{{ __createCoverDiv()
    /**
     *	Submits the form
     *
     * @private
     */		
	__createCoverDiv : function()
	{	
		if(this.coverDiv)return;
		this.coverDiv = document.createElement('DIV');
		var el = this.coverDiv;
		el.style.overflow='hidden';
		el.style.zIndex = 1000;
		el.style.position = 'absolute';

		document.body.appendChild(el);
		
		var innerDiv = document.createElement('DIV');
		innerDiv.style.width='105%';
		innerDiv.style.height='105%';
		innerDiv.className = 'DHTMLSuite_formCoverDiv';
		innerDiv.style.opacity = '0.2';
		innerDiv.style.filter = 'alpha(opacity=20)';		
		el.appendChild(innerDiv);
		
		var ajaxLoad = document.createElement('DIV');
		ajaxLoad.className = 'DHTMLSuite_formCoverDiv_ajaxLoader';
		el.appendChild(ajaxLoad);		
	}
	// }}}
	,
	// {{{ __createSackObject()
    /**
     *	Create new sack object
     *
     * @private
     */		
	__createSackObject : function(ajaxIndex)
	{		
		var ind = this.objectIndex;
		this.sackObj[ajaxIndex] = new sack();
		this.sackObj[ajaxIndex].requestFile = this.action;	
		this.sackObj[ajaxIndex].method = this.method;		
		this.sackObj[ajaxIndex].onCompletion = function(){ DHTMLSuite.variableStorage.arrayDSObjects[ind].__getResponse(ajaxIndex); }
	}
	,
	__getResponse : function(ajaxIndex)
	{
		if(this.responseEl){			
			if(this.responseFile){
				if(!this.responseEl.id)this.responseEl.id = 'DHTMLSuite_formResponse' + DHTMLSuite.getUniqueId();
				var dynContent = new DHTMLSuite.dynamicContent();
				dynContent.loadContent(this.responseEl.id,this.responseFile);				
			}else{			
				this.responseEl.innerHTML = this.sackObj[ajaxIndex].response;
				var fChild = this.responseEl.firstChild;
				if (fChild != null) {
					if (fChild.nodeType == 3) {
						if (_TGisEmptyText(fChild.data)) { // Get rid of empty text node because this creates unwanted empty lines in IE!
							fChild.parentNode.removeChild(fChild);
						}
					}
				}
				DHTMLSuite.commonObj.__evaluateJs(this.responseEl);
				DHTMLSuite.commonObj.__evaluateCss(this.responseEl);	
			}				
		}		
		this.coverDiv.style.display='none';
		this.sackObj[ajaxIndex] = null;
		this.__handleCallback('onComplete');
	}
	// }}}
	,
	// {{{ __populateSack()
    /**
     *	Populate sack object with form data
     *	@param ajaxIndex - index of current sack object
     *
     * @private
     */	
	__populateSack : function(ajaxIndex)
	{
		var els = this.formUtil.getValuesAsArray(this.formRef);		
		for(var prop in els){
			if(DHTMLSuite.commonObj.isArray(els[prop])){
				for(var no=0;no<els[prop].length;no++){
					var name = prop + '[' + no + ']';
					if(prop.indexOf('[')>=0){ // The name of the form field is already indicating an array
						name = prop.replace('[','[' + no);	
					}
					this.sackObj[ajaxIndex].setVar(name,els[prop][no]);	
				}
			}else{
				this.sackObj[ajaxIndex].setVar(prop,els[prop]);			
			}			
		}		
	}
	// }}}
	,
	// {{{ __setInitProperties()
    /**
     *	Fill object with data sent to the constructor
     *	@param Array props - Associative Array("Object") of properties
     *
     * @private
     */		
	__setInitProperties : function(props)
	{
		if(props.formRef)this.formRef = DHTMLSuite.commonObj.getEl(props.formRef);
		if(props.method)this.method = props.method;
		if(props.responseEl)this.responseEl = DHTMLSuite.commonObj.getEl(props.responseEl);
		if(props.action)this.action = props.action;
		if(props.responseFile)this.responseFile = props.responseFile;
		if(props.callbackOnComplete)this.callbackOnComplete = props.callbackOnComplete;
		if(!this.action)this.action = this.formRef.action;
		if(!this.method)this.method = this.formRef.method;
	}	
	// }}}
	,
	// {{{ __handleCallback()
    /**
     *	Execute callback
     *	@param String action - Which callback action
     *
     * @private
     */	
	__handleCallback : function(action)
	{
		var callbackString = '';
		switch(action){
			case "onComplete":
				callbackString = this.callbackOnComplete;
				break;	
			
			
		}	
		if(callbackString){
			if(callbackString.indexOf('(')==-1)callbackString = callbackString + '("' + this.formRef.name + '")';
			eval(callbackString);
		}
		
	}
}

