
// Creating a trim method
if(!String.trim)String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

if(!window.DHTML_SUITE_THEME)var DHTML_SUITE_THEME = 'blue';
if(!window.DHTML_SUITE_THEME_FOLDER)var DHTML_SUITE_THEME_FOLDER = '../themes/';


/************************************************************************************************************
*
* 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.eventElements = new Array();	// Array of elements that has been assigned to an event handler.

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).
     *
     * @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()
    /**
     * Resets css path back to default value which is ../css_dhtmlsuite/
     *
     * @public
     */    	
	resetCssPath : function()
	{
		this.cssPath = this.defaultCssPath;
	}
	// }}}
	,
	// {{{ resetImagePath()
    /**
     * Resets css path back to default path which is ../images_dhtmlsuite/
     *
     * @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 arrayOfDhtmlSuiteObjects;	// Array of objects of class menuItem.
	this.arrayOfDhtmlSuiteObjects = new Array();
	
	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 eventElements;
	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.eventElements = 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 cssFileName = 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(cssFileName,prefixConfigPath)
	{
		if(!prefixConfigPath && prefixConfigPath!==false)prefixConfigPath=true;
		if(!this.loadedCSSFiles[cssFileName]){
			this.loadedCSSFiles[cssFileName] = true;
			var linkTag = document.createElement('LINK');
			if(!this.cssCacheStatus){
				if(cssFileName.indexOf('?')>=0)cssFileName = cssFileName + '&'; else cssFileName = cssFileName + '?';
				cssFileName = cssFileName + 'rand='+ Math.random();	// To prevent caching
			}
			if(prefixConfigPath){
				linkTag.href = DHTMLSuite.configObj.cssPath + cssFileName;
			}else{
				linkTag.href = cssFileName;
			}
			linkTag.rel = 'stylesheet';
			linkTag.media = 'screen';
			linkTag.type = 'text/css';
			document.getElementsByTagName('HEAD')[0].appendChild(linkTag);	
			
		}
	}		
	// }}}
	,
	// {{{ getTopPos()
    /**
     * This method will return the top coordinate(pixel) of an HTML element/tag
     *
     * @param Object inputObj = Reference to HTML element
     * @public
     */	
	getTopPos : function(inputObj)
	{		
	  var returnValue = inputObj.offsetTop;
	  while((inputObj = inputObj.offsetParent) != null){
	  	if(inputObj.tagName!='HTML'){
	  		returnValue += (inputObj.offsetTop - inputObj.scrollTop);
	  		if(document.all)returnValue+=inputObj.clientTop;
	  	}
	  } 
	  return returnValue;
	}
	// }}}
	,
	// {{{ __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;
	}
	// }}}	
	,
	// {{{ getLeftPos()
    /**
     * This method will return the left coordinate(pixel) of an HTML element
     *
     * @param Object inputObj = Reference to HTML element
     * @public
     */	
	getLeftPos : function(inputObj)
	{	  
	  var html = '';	
	  var returnValue = inputObj.offsetLeft;
	  while((inputObj = inputObj.offsetParent) != null){
	  	if(inputObj.tagName!='HTML'){
	  		returnValue += inputObj.offsetLeft;
	  		if(document.all)returnValue+=inputObj.clientLeft;
	  	}
	  }
	  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(whichObject,eventType,functionName,suffix)
	{ 
	  if(!suffix)suffix = '';
	  if(whichObject.attachEvent){ 
	    whichObject['e'+eventType+functionName+suffix] = functionName; 
	    whichObject[eventType+functionName+suffix] = function(){whichObject['e'+eventType+functionName+suffix]( window.event );} 
	    whichObject.attachEvent( 'on'+eventType, whichObject[eventType+functionName+suffix] ); 
	  } else 
	    whichObject.addEventListener(eventType,functionName,false); 	    
	  this.__addEventElement(whichObject);
	} 
	// }}}	
	,	
	// {{{ 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(whichObject,eventType,functionName)
	{ 
	  if(whichObject.detachEvent){ 
	    whichObject.detachEvent('on'+eventType, whichObject[eventType+functionName]); 
	    whichObject[eventType+functionName] = null; 
	  } else 
	    whichObject.removeEventListener(eventType,functionName,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 in DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects){
    		DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[no] = false;    			
    	}

    	for(var no=0;no<DHTMLSuite.eventElements.length;no++){
    		DHTMLSuite.eventElements[no].onclick = null;
    		DHTMLSuite.eventElements[no].onmousedown = null;
    		DHTMLSuite.eventElements[no].onmousemove = null;
    		DHTMLSuite.eventElements[no].onmouseout = null;
    		DHTMLSuite.eventElements[no].onmouseover = null;
    		DHTMLSuite.eventElements[no].onmouseup = null;
    		DHTMLSuite.eventElements[no].onfocus = null;
    		DHTMLSuite.eventElements[no].onblur = null;
    		DHTMLSuite.eventElements[no].onkeydown = null;
    		DHTMLSuite.eventElements[no].onkeypress = null;
    		DHTMLSuite.eventElements[no].onkeyup = null;
    		DHTMLSuite.eventElements[no].onselectstart = null;
    		DHTMLSuite.eventElements[no].ondragstart = null;
    		DHTMLSuite.eventElements[no].oncontextmenu = null;
    		DHTMLSuite.eventElements[no].onscroll = null;
    		
    	}
    	window.onunload = null;
    	DHTMLSuite = null;

    }		
    // }}}
    ,
	// {{{ __addEventElement()
    /**
     *
     *  Add element to garbage collection array. The script will loop through this array and remove event handlers onload in ie.
     *
     * 
     * @private
     */	    
    __addEventElement : function(el)
    {
    	DHTMLSuite.eventElements[DHTMLSuite.eventElements.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;	
    }	
    // }}}	
    ,
	// {{{ 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 elementReference - Id or direct reference to image
     *
     * @public
     */	
	correctPng : function(elementReference)
	{
		if(typeof elementReference == 'string'){
			elementReference = document.getElementById(elementReference);
		}		
		var img = elementReference;
		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;	
					
	}
}

/************************************************************************************************************
*	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 [0-6]/gi))?true:false;
		this.isSafari = (this.browser.toLowerCase().indexOf('safari')>=0)?true:false;
		this.navigatorVersion = navigator.appVersion.replace(/.*?MSIE (\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 = {
	
	// {{{ getElementsByClassName()
    /**
     *	This method will return an array of all elements of a specific class.
     *
	 *	@param String className = Class to search for
	 *	@param Object inputObj = Optional - Which element to search from(i.e. search only in sub elements of this one) if ommited, search all.
     *	@return Array objects = An array of references to HTML elements on the page. 
     *  @type Array
     *
     * @public
     */	
    	
	getElementsByClassName : function(className,inputObj)
	{
		var returnArray = new Array();
		if(inputObj)
			var allElements = inputObj.getElementsByTagName('*');
		else
			var allElements = document.getElementsByTagName('*');
		for(var no=0;no<allElements.length;no++){
			if(allElements[no].className==className)returnArray[returnArray.length] = allElements[no];	
		}
		return returnArray;
	}	
	// }}}		
	,
	// {{{ getElementsByAttribute()
    /**
     *	This method will return an array of all elements where a specific attribute is set.
     *
	 *	@param String attribute = Attribute to search for
	 *	@param String attributeValue = Optional - only search for elements where the attribute is set to this value
	 *	@param Object inputObj = Optional - Which element to search from(i.e. search only in sub elements of this one) if ommited, search all.
	 *
     *	@return Array objects = An array of references to HTML elements on the page. 
     *	@type Array
     * 
     * @public
     */	    	
	getElementsByAttribute : function(attribute,attributeValue,inputObj)
	{
		var returnArray = new Array();
		if(inputObj)
			var allElements = inputObj.getElementsByTagName('*');
		else
			var allElements = document.getElementsByTagName('*');
		for(var no=0;no<allElements.length;no++){
			var att = allElements[no].getAttribute(attribute);
			if(!attributeValue){
				if(att)returnArray[returnArray.length] = allElements[no];
			}
			else
				if(att==attributeValue)returnArray[returnArray.length] = allElements[no];
		}
		return returnArray;
	}	
	// }}}			

}


/*[FILE_START:dhtmlSuite-tableWidget.js] */
/************************************************************************************************************
*	Table widget page handler class
*
*	Created:			December, 15th, 2006
*	Purpose of class:	Displays paginating below a server sorted table
*
*	CSS used:			
*
* 	Update log:
*
************************************************************************************************************/

/**
* @constructor
* @class Purpose of class:	Make HTML tables sortable<br><br>
*/
DHTMLSuite.tableWidgetPageHandler = function()
{
	var tableRef;					// Reference to object of class DHTMLSuite.tableWidget
	var targetRef;					// Where to insert the pagination.
	
	var txtPrevious;				// Label - "Previous"
	var txtNext;					// Label - "Next"
	var txtFirst;					// Label - "First"
	var txtLast;					// Label - "last"
	
	var txtResultPrefix;			// Prefix : result - default = "Result: "
	var txtResultTo;				// Text label Result: 1 "to" 10 of 51 - default value = "to"
	var txtResultOf;				// Text label Result: 1 to 10 "of" 51 - default value = "of"
	
	var totalNumberOfRows;			// Total number of rows in dataset
	var rowsPerPage;				// Number of rows per page.
	
	var layoutCSS;					// Name of CSS file for the table widget.
	var activePageNumber;			// Active page number
	var mainDivElement;				// Reference to main div for the page handler
	var resultDivElement;			// Reference to div element which is parent for the result
	var pageListDivElement;			// Reference to div element which is parent to pages [1],[2],[3]...[Next]
	
	var objectIndex;				// Index of this widget in the arrayOfDhtmlSuiteObjects array
	
	var linkPagePrefix;				// Text in front of each page link
	var linkPageSuffix;				// Text behind each page link
	
	var maximumNumberOfPageLinks;	// Maximum number of page links.
	var callbackOnAfterNavigate;	// Callback function - executed when someone navigates to a different page
	this.txtPrevious = 'Previous';	// Default label
	this.txtNext = 'Next';			// Default label
	this.txtResultPrefix = 'Result: ';			// Default label
	this.txtResultTo = 'to';			// Default label
	this.txtResultOf = 'of';			// Default label
	this.txtFirst = 'First';
	this.txtLast = 'Last';
	
	this.tableRef = false;
	this.targetRef = false;
	this.totalNumberOfRows = false;
	this.activePageNumber = 1;
	this.layoutCSS = 'table-widget-page-handler.css';
	
	this.linkPagePrefix = '';
	this.linkPageSuffix = '';
	this.maximumNumberOfPageLinks = false;
	this.callbackOnAfterNavigate = false;
	
	
	this.objectIndex = DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[this.objectIndex] = this;
		
	
}

DHTMLSuite.tableWidgetPageHandler.prototype = {
	// {{{ setTableRef()
    /**
     *	Connect to a tableWidget object.
     *
	 *	@param Object tableRef = An object of class DHTMLSuite.tableWidget. It makes it possible for the tableWidget and this object to communicate.
     * 
     * @public
     */		
	setTableRef : function(tableRef)
	{
		this.tableRef = tableRef;
		this.tableRef.setPageHandler(this);
	}	
	// }}}
	,
	// {{{ setTargetId()
    /**
     *	Where do you want to insert the navigation links for the table
     *
	 *	@param String idOfHTMLElement = Id of HTML Element on your page.
     * 
     * @public
     */		
	setTargetId : function(idOfHTMLElement)
	{
		if(!document.getElementById(idOfHTMLElement)){
			alert('ERROR IN tableWidgetPageHandler.setTargetId:\nElement with id ' + idOfHTMLElement + ' does not exists');
			return;
		}
		this.targetRef = document.getElementById(idOfHTMLElement);		
	}
	// }}}
	,
	// {{{ setTxtPrevious()
    /**
     *	Set text label (previous page link)
     *
	 *	@param String newText = Text previous page link
     * 
     * @public
     */		
	setTxtPrevious : function(newText)
	{
		this.txtPrevious = newText;
	}
	// }}}
	,
	// {{{ setLinkPagePrefix()
    /**
     *	Set text/characters in front of each page link, example "[" to get page number in brackets
     *
	 *	@param String linkPagePrefix = Character(s) in front of page links
     * 
     * @public
     */		
	setLinkPagePrefix : function(linkPagePrefix)
	{
		this.linkPagePrefix = linkPagePrefix;
	}
	// }}}
	,
	// {{{ setLinkPageSuffix()
    /**
     *	Set text/characters in front of each page link, example "[" to get page number in brackets
     *
	 *	@param String linkPageSuffix = Character(s) in front of page links
     * 
     * @public
     */		
	setLinkPageSuffix : function(linkPageSuffix)
	{
		this.linkPageSuffix = linkPageSuffix;
	}
	
	// }}}
	,
	// {{{ setTxtNext()
    /**
     *	Set text label (next page link)
     *
	 *	@param String newText = Text next page link
     * 
     * @public
     */		
	setTxtNext : function(newText)
	{
		this.txtNext = newText;
	}
	// }}}
	,
	// {{{ setTxtResultOf()
    /**
     *	Set text label ("of" - result)
     *
	 *	@param String txtResultOf = Result of search, the "of" label ( Result: 1 to 10 "of" 51 )
     * 
     * @public
     */		
	setTxtResultOf : function(txtResultOf)
	{
		this.txtResultOf = txtResultOf;
	}
	// }}}
	,
	// {{{ setTxtResultTo()
    /**
     *	Set text label ("to" - result)
     *
	 *	@param String txtResultTo = Result of search, the "to" label ( Result: 1 "to" 10 of 51 )
     * 
     * @public
     */		
	setTxtResultTo : function(txtResultTo)
	{
		this.txtResultTo = txtResultTo;
	}
	// }}}
	,
	// {{{ setTxtResultPrefix()
    /**
     *	Set text label (prefix - result)
     *
	 *	@param String txtResultPrefix = Text next page link
     * 
     * @public
     */		
	setTxtResultPrefix : function(txtResultPrefix)
	{
		this.txtResultPrefix = txtResultPrefix;
	}
	// }}}
	,
	// {{{ setTxtFirstPage()
    /**
     *	Set text label ("Last" page)
     *
	 *	@param String txtFirst = Label of link to "First" page ( default = "First" ) .This option is only used when you are limiting the number of pages shown.
     * 
     * @public
     */		
	setTxtFirstPage : function(txtFirst)
	{
		this.txtFirst = txtFirst;
	}
	// }}}
	,
	// {{{ setTxtLastPage()
    /**
     *	Set text label ("First" page)
     *
	 *	@param String txtLast = Label of link to "Last" page ( default = "Last" ) .This option is only used when you are limiting the number of pages shown.
     * 
     * @public
     */		
	setTxtLastPage : function(txtLast)
	{
		this.txtLast = txtLast;
	}
	// }}}
	,
	// {{{ setTotalNumberOfRows()
    /**
     *	Specify total number of rows in the entire dataset
     *
	 *	@param Integer totalNumberOfRows = Total number of rows in the entire dataset.
     * 
     * @public
     */		
	setTotalNumberOfRows : function(totalNumberOfRows)
	{
		this.totalNumberOfRows = totalNumberOfRows;
	}
	// }}}
	,
	// {{{ setCallbackOnAfterNavigate()
    /**
     * Specify call back function to execute after page navigatoin
     *
     * @param String callbackOnAfterNavigate - name of javascript function.
     *
     * @public
     */		
	setCallbackOnAfterNavigate : function(callbackOnAfterNavigate)
	{
		this.callbackOnAfterNavigate = callbackOnAfterNavigate;
	}
	// }}}
	,
	// {{{ 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(layoutCSS)
	{
		this.layoutCSS = layoutCSS;
	}
	// }}}
	,
	// {{{ setMaximumNumberOfPageLinks()
    /**
     * Set maximum number of page links displayed below the table, i.e. if you have 50 pages, you can limit number of page links to 10 by sending 10 to this method.
     *
     * @param Integer maximumNumberOfPageLinks - (0 or false means = no limitation)
     *
     * @public
     */		
	setMaximumNumberOfPageLinks : function(maximumNumberOfPageLinks)
	{
		this.maximumNumberOfPageLinks = maximumNumberOfPageLinks;
	}
	// }}}
	,
	// {{{ init()
    /**
     * Initializes the script widget. Set methods should be called before your call this method.
     *
     *
     * @public
     */		
	init : function()
	{
		this.rowsPerPage = this.tableRef.getServersideSortNumberOfRows();
		DHTMLSuite.commonObj.loadCSS(this.layoutCSS);
		this.__createMainDivElements();
		this.setHTMLOfResultList();
		this.__createPageLinks();
	}
	// }}}
	,
	// {{{ __createMainDivElements()
    /**
     * Create main div elements for the page handler
     *
     *
     * @private
     */		
	__createMainDivElements : function()
	{
		if(!this.targetRef){
			alert('Error creating table widget page handler. Remember to specify targetRef');
			return;
		}
		this.mainDivElement = document.createElement('DIV');
		this.mainDivElement.className = 'DHTMLSuite_tableWidgetPageHandler_mainDiv';
		this.targetRef.appendChild(this.mainDivElement);		
		
		this.resultDivElement = document.createElement('DIV');
		this.resultDivElement.className = 'DHTMLSuite_tableWidgetPageHandler_result';
		this.mainDivElement.appendChild(this.resultDivElement);
		
		this.pageListDivElement = document.createElement('DIV');
		this.pageListDivElement.className = 'DHTMLSuite_tableWidgetPageHandler_pageList';
		this.mainDivElement.appendChild(this.pageListDivElement);
	}
	
	,
	// {{{ setHTMLOfResultList()
    /**
     *
     * 	Create result list div
     *	
	 *
     * 
     * @public
     */  	
	setHTMLOfResultList : function()
	{
		this.resultDivElement.innerHTML = '';		
		var html = this.txtResultPrefix + (((this.activePageNumber-1) * this.rowsPerPage) + 1) + ' ' + this.txtResultTo + ' ' + Math.min(this.totalNumberOfRows,(this.activePageNumber * this.rowsPerPage)) + ' ' + this.txtResultOf + ' ' + this.totalNumberOfRows;
		this.resultDivElement.innerHTML = html;
	}
	// }}}
	,
	// {{{ __createPageLinks()
    /**
     *
     * 	Create page links
     *	
	 *
     * 
     * @private
     */  	
	__createPageLinks : function()
	{
		var ind = this.objectIndex;
		
		this.pageListDivElement.innerHTML = '';	// Clearing the div element if it allready got content.

		var numberOfPages = Math.ceil(this.totalNumberOfRows/this.rowsPerPage);
		
		/* link to first page */
		if(this.maximumNumberOfPageLinks && this.maximumNumberOfPageLinks<numberOfPages){
			var span = document.createElement('SPAN');
			span.innerHTML = this.linkPagePrefix;
			this.pageListDivElement.appendChild(span);	
			span.className = 'DHTMLSuite_pageHandler_firstLink';
						
			var firstLink = document.createElement('A');	// "first" link
			firstLink.innerHTML = this.txtFirst;
			firstLink.href = '#';
			firstLink.id = 'pageLink_1';
			firstLink.onclick = function(e){ return DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__navigate(e); }
			span.appendChild(firstLink);
			DHTMLSuite.commonObj.__addEventElement(firstLink);				
		}					
		
		
		var span = document.createElement('SPAN');
		span.innerHTML = this.linkPagePrefix;
		this.pageListDivElement.appendChild(span);	
		span.className = 'DHTMLSuite_pageHandler_previousLink';
				
		var previousLink = document.createElement('A');	// "Previous" link
		previousLink.innerHTML = this.txtPrevious;
		previousLink.href = '#';
		previousLink.id = 'previous';
		previousLink.onclick = function(e){ return DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__navigate(e); }
		span.appendChild(previousLink);
		DHTMLSuite.commonObj.__addEventElement(previousLink);
		if(this.activePageNumber==1)previousLink.className = 'previousLinkDisabled'; else previousLink.className = 'previousLink';
		
		
		
		var startNumberToShow = 1;
		var endNumberToShow = numberOfPages;
		if(this.maximumNumberOfPageLinks && this.maximumNumberOfPageLinks<numberOfPages){
			startNumberToShow = Math.max(1,Math.round(this.activePageNumber - this.maximumNumberOfPageLinks/2));
			endNumberToShow = Math.min(numberOfPages,startNumberToShow + this.maximumNumberOfPageLinks - 1);	
			
			if(endNumberToShow-startNumberToShow < this.maximumNumberOfPageLinks){
				startNumberToShow = Math.max(1,endNumberToShow - this.maximumNumberOfPageLinks + 1);
			}
					
		}
		
		
		for(var no=startNumberToShow;no<=endNumberToShow;no++){
			
			var span = document.createElement('SPAN');
			span.innerHTML = this.linkPagePrefix;
			this.pageListDivElement.appendChild(span);	
			
			
			var pageLink = document.createElement('A');
			if(no==this.activePageNumber)pageLink.className='DHTMLSuite_tableWidgetPageHandler_activePage'; else pageLink.className = 'DHTMLSuite_tableWidgetPageHandler_inactivePage';
			pageLink.innerHTML = no;
			pageLink.href= '#';
			pageLink.id = 'pageLink_' + no;
			pageLink.onclick = function(e){ return DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__navigate(e); }
			DHTMLSuite.commonObj.__addEventElement(pageLink);
			this.pageListDivElement.appendChild(pageLink);		
			
			var span = document.createElement('SPAN');
			span.innerHTML = this.linkPageSuffix;
			this.pageListDivElement.appendChild(span);	
							
		}
		
		var span = document.createElement('SPAN');
		span.innerHTML = this.linkPagePrefix;
		this.pageListDivElement.appendChild(span);	
		span.className = 'DHTMLSuite_pageHandler_nextLink';
					
		var nextLink = document.createElement('A');	// "Next" link
		nextLink.innerHTML = this.txtNext;
		nextLink.id = 'next';
		nextLink.href = '#';
		nextLink.onclick = function(e){ return DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__navigate(e); }
		DHTMLSuite.commonObj.__addEventElement(nextLink);
		span.appendChild(nextLink);
		if(this.activePageNumber==numberOfPages)nextLink.className = 'nextLinkDisabled'; else nextLink.className = 'nextLink';
		
		/* link to Last page */
		if(this.maximumNumberOfPageLinks && this.maximumNumberOfPageLinks<numberOfPages){
			var span = document.createElement('SPAN');
			span.innerHTML = this.linkPagePrefix;
			this.pageListDivElement.appendChild(span);	
			span.className = 'DHTMLSuite_pageHandler_lastLink';
			
			var lastLink = document.createElement('A');	// "Last" link
			lastLink.innerHTML = this.txtLast;
			lastLink.href = '#';
			lastLink.id = 'pageLink_' + (numberOfPages);
			lastLink.onclick = function(e){ return DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__navigate(e); }
			span.appendChild(lastLink);
			DHTMLSuite.commonObj.__addEventElement(lastLink);				
		}
				
		
	}
	// }}}
	,
	// {{{ __navigate()
    /**
     *
     * 	Navigate - click on "next" or "previous" link or click on a page
     *	
     *	@param Event e	= Reference to event object. used to get a reference to the element triggering this action.
	 *
     * 
     * @private
     */  	
	__navigate : function(e)
	{
		if(document.all)e = event;
		var src = DHTMLSuite.commonObj.getSrcElement(e);
		var initActivePageNumber = this.activePageNumber;
		var numberOfPages = Math.ceil(this.totalNumberOfRows/this.rowsPerPage);
		
		if(src.id.indexOf('pageLink_')>=0){
			var pageNo = src.id.replace(/[^0-9]/gi,'')/1;
			this.activePageNumber = pageNo;
			
		}
		if(src.id=='next'){	// next link clicked
			this.activePageNumber++;
			if(this.activePageNumber>numberOfPages)this.activePageNumber = numberOfPages;		
		}
		if(src.id=='previous'){
			this.activePageNumber--;
			if(this.activePageNumber<1)this.activePageNumber=1;
		}
				
		if(this.activePageNumber!=initActivePageNumber){
			this.tableRef.serversideSortCurrentStartIndex = ((this.activePageNumber-1)*this.rowsPerPage);
			this.tableRef.__getItemsFromServer(this.callbackOnAfterNavigate);
			this.setHTMLOfResultList();
			this.__createPageLinks();
		}
		return false;
		
	}
	// }}}
	,
	// {{{ __resetActivePageNumber()
    /**
     *
     * 	Reset active page number - called from the tableWidget
	 *
     * 
     * @private
     */   	
	__resetActivePageNumber : function()
	{
		this.activePageNumber = 1;
		this.setHTMLOfResultList();
		this.__createPageLinks();
	}
}


/************************************************************************************************************
*	Table widget class
*
*	Created:			August, 18th, 2006
*	Purpose of class:	Make HTML tables sortable
*						Apply application look to the table
*						Create one object for each HTML table.
*
*	CSS used:			table-widget.css
*	images used:		arrow_up.gif
* 						arrow_down.gif
*
* 	Update log:
*
************************************************************************************************************/

/**
* @constructor
* @class Purpose of class:	Make HTML tables sortable<br><br>
*						Apply application look to the table<br>
*						Create one object for each HTML table.<br>
*<br>
*	Remember to have both &lt;THEAD> and &lt;TBODY> in your table.
* <br>
*	&lt;DIV><br>
*	&lt;table><br>
*		&lt;thead><br>
*			&lt;tr><br>
*				&lt;td>Header cell&lt;/td><br>
*				&lt;td>Header cell&lt;/td><br>
*			&lt;/tr><br>
*		&lt;/thead><br>
*		&lt;tbody><br>
*			&lt;tr><br>
*				&lt;td>Table data&lt;/td><br>
*				&lt;td>Table data&lt;/td><br>
*			&lt;/tr><br>
*			&lt;tr><br>
*				&lt;td>Table data&lt;/td><br>
*				&lt;td>Table data&lt;/td><br>
*			&lt;/tr><br>
*		&lt;/tbody><br>
*	&lt;/table><br>
*	&lt;/div><br>
*	<br><br>
*	Also remember:	If you put a table inside a non-displayed element, example an inactive tab(the tabView script), remember to create
*	and initialize the table objects before you create the tab objects. In some browsers, that's nescessary in order for the table to
*	display properly. <br>
*	(<a href="../../demos/demo-tablewidget.html" target="_blank">demo 1</a>)
*
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.tableWidget = function()
{
	var tableWidget_okToSort;				// Variable indicating if it's ok to sort. This variable is "false" when sorting is in progress
	var activeColumn;						// Reference to active column, i.e. column currently beeing sorted	
	var idOfTable;							// Id of table, i.e. the <table> tag
	var tableObj;							// Reference to <table> tag.
	var widthOfTable;						// Width of table	(Used in the CSS)
	var heightOfTable; 						// Height of table	(Used in the CSS)
	var columnSortArray;					// Array of how table columns should be sorted
	var layoutCSS;							// Name of CSS file for the table widget.
	var noCssLayout;						// true or false, indicating if the table should have layout or not, if not, it would be a plain sortable table.
	var serversideSort;						// true or false, true if the widget is sorted on the server.
	var serversideSortAscending;
	var tableCurrentlySortedBy;
	var serversideSortFileName;				// Name of file on server to send request to when table data should be sorted
	var serversideSortNumberOfRows;			// Number of rows to receive from the server
	var serversideSortCurrentStartIndex;	// Index of first row in the dataset, i.e. if you move to next page, this value will be incremented
	var serversideSortExtraSearchCriterias;	// Extra param to send to the server, example: &firstname=Alf&lastname=Kalleland
	var pageHandler;						// Object of class DHTMLSuite.tableWidgetPageHandler
	var rowClickCallBackFunction;			// Row click call back function.
	var objectIndex;						// Index of this object in the DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects array
	
	this.serversideSort = false;			// Default value for serversideSort(items are sorted in the client)
	this.serversideSortAscending = true;	// Current sort ( ascending or descending)
	this.tableCurrentlySortedBy = false;
	this.serversideSortFileName = false;
	this.serversideSortCurrentStartIndex=0;
	this.serversideSortExtraSearchCriterias = '';
	this.rowClickCallBackFunction = false;
	this.setRowDblClickCallBackFunction = false;
	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.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[this.objectIndex] = this;
}

DHTMLSuite.tableWidget.prototype = {	
	/**
	* Public method used to initialize the table widget script. First use the set methods to configure the script, then
	* call the init method.
	**/
	// {{{ init()
    /**
     *
     * 	Initializes the table widget object
	 *
     * 
     * @public
     */    	
	init : function()
	{		
		this.tableWidget_okToSort = true;
		this.activeColumn = false;
		if(!this.layoutCSS)this.layoutCSS = 'table-widget.css';
		DHTMLSuite.commonObj.loadCSS(this.layoutCSS);
		this.__initTableWidget();
	}
	// }}}	
	,
	// {{{ setLayoutCss()
    /**
     *
     *  This function updates name of CSS file. This method should be called before init().
     *
     * @param String newCssFile = (File name of CSS file, not path)
     * 
     * @public
     */	
	setLayoutCss : function(newCssFile)
	{
		this.layoutCSS = newCSSFile;			
	}
	// }}}	
	,	
	// 	// {{{ setRowClickCallBackFunction()
    /**
     *
     *  This method specifies call back function to be called when a row is clicked. A reference to that row is sent as argument to this function
     *
     * @param String rowClickCallBackFunction = (Row click - call back function)
     * 
     * @public
     */	
	setRowClickCallBack : function(rowClickCallBackFunction)
	{
		this.rowClickCallBackFunction = rowClickCallBackFunction;			
	}
	// }}}	
	,
	// 	// {{{ setRowDblClickCallBackFunction()
    /**
     *
     *  This method specifies call back function to be called when a row is double clicked. A reference to that row is sent as argument to this function
     *
     * @param String setRowDblClickCallBackFunction = (Row click - call back function)
     * 
     * @public 
     */	
	setRowDblClickCallBack : function(setRowDblClickCallBackFunction)
	{
		this.setRowDblClickCallBackFunction = setRowDblClickCallBackFunction;			
	}
	// }}}	
	,	
	// {{{ setServerSideSort()
    /**
     *
     *  This method is used to specify if you want to your tables to be sorted on the server or not.
     *
     * @param Boolean serversideSort = Sort items on the server? (true = yes, false = no). 
     * 
     * @public
     */	
	setServerSideSort : function(serversideSort)
	{
		this.serversideSort = serversideSort;			
	}
	// }}}	
	,	
	// {{{ setServersideSearchCriterias()
    /**
     *
     *  This method is used to add extra params to the search url sent to the server.
     *
     * @param String serversideSortExtraSearchCriterias = String added to the url, example: "&firstname=John&lastname=Doe". This can be used in the sql query on the server.
     * 
     * @public
     */	
	setServersideSearchCriterias : function(serversideSortExtraSearchCriterias)
	{
		this.serversideSortExtraSearchCriterias = serversideSortExtraSearchCriterias;			
	}
	// }}}	
	,	
	// {{{ getServersideSortNumberOfRows()
    /**
     *
     *  Return numer of rows per page.
     *
     * @return Integer serversideSort = Number of rows
     * 
     * @public
     */	
	getServersideSortNumberOfRows : function(serversideSort)
	{
		return this.serversideSortNumberOfRows;		
	}
	// }}}	
	,		
	// {{{ setServersideSortNumberOfRows()
    /**
     *
     *  Specify how many records to receive from the server ( server side sort )
     *
     * @param Integer serversideSortNumberOfRows = Number of rows
     * 
     * @public
     */	
	setServersideSortNumberOfRows : function(serversideSortNumberOfRows)
	{
		this.serversideSortNumberOfRows = serversideSortNumberOfRows;			
	}
	// }}}	
	,	
	// {{{ setServersideSortFileName()
    /**
     *
     *  This method is used to specify which file to send the ajax request to when data should be sorted. (i.e. sort items on server instead of client).
     *
     * @param String serversideSortFileName = Path to file on server. This file will receive the request, parse it and send back new table data.
     * 
     * @public
     */	
	setServersideSortFileName : function(serversideSortFileName)
	{
		this.serversideSortFileName = serversideSortFileName;			
	}
	// }}}	
	,
	/* Start public methods */

	// {{{ setNoCssLayout()
    /**
     *
     *  No CSS layout
     *
     * 
     * @public
     */	
    setNoCssLayout : function()
	{
		this.noCssLayout = true;		
	}	
	// }}}	
	,	
	// {{{ sortTableByColumn()
    /**
     *
     *  This method sorts a table by a column
     *	You can call this method after the call to init if you want to sort the table by a column when the table is beeing displayed.
     *
     * @param Int columnIndex = Column to sort by (0 = first column)
     * @param String howToSort How to sort the table ("ascending" or "descending"
     * 
     * @public
     */	
	sortTableByColumn : function(columnIndex,howToSort)
	{
		if(!howToSort)howToSort = 'ascending';
		var tableObj = document.getElementById(this.idOfTable);
		var firstRow = tableObj.rows[0];
		var tds = firstRow.cells;
		if(tds[columnIndex] && this.columnSortArray[columnIndex]){
			this.__sortTable(tds[columnIndex],howToSort);
		}	
	}	
	// }}}	
	,		
	// {{{ setTableId()
    /**
     *
     *  Set id of table, i.e. the id of the <table> tag you want to apply the table widget to
     *
     * @param String idOfTable = Id of table
     * 
     * @public
     */	
	setTableId : function(idOfTable)
	{
		this.idOfTable = idOfTable;	
		try{
			this.tableObj = document.getElementById(idOfTable);
		}catch(e){
			
		}	
	}
	// }}}	
	,
	
	
	// {{{ setTableWidth()
    /**
	 *
     *  Set width of table
     *
     * @param Mixed width = (string if percentage width, integer if numeric/pixel width)
     * 
     * @public
     */	
	setTableWidth : function(width)
	{
		this.widthOfTable = width;			
	}
	// }}}	
	,	
	// {{{ setTableHeight()
    /**
	 *
     *  Set height of table
     *
     * @param Mixed height = (string if percentage height, integer if numeric/pixel height)
     * 
     * @public
     */	
	setTableHeight : function(height)
	{
		this.heightOfTable = height;
	}
	// }}}	
	,	
	// {{{ setColumnSort()
    /**
     *
     *  How to sort the table
     *
     * @param Array columnSortArray = How to sort the columns in the table(An array of the items 'N','S' or false)
     * 
     * @public
     */		
	setColumnSort : function(columnSortArray)
	{
		this.columnSortArray = columnSortArray;	
	}
	// }}}	
	,	
	
	// {{{ addNewRow()
    /**
     *  Adds a new row to the table dynamically
     *
     * @param Array cellContent = Array of strings - cell content
     * 
     * @public
     */		
	addNewRow : function(cellContent)
	{
		var tableObj = document.getElementById(this.idOfTable);
		var tbody = tableObj.getElementsByTagName('TBODY')[0];
		
		var row = tbody.insertRow(-1);
		for(var no=0;no<cellContent.length;no++){
			var cell = row.insertCell(-1);
			cell.innerHTML = cellContent[no];
		}
		this.__parseDataRows(tableObj);
		
	}
	// }}}	
	,
	
	
	// {{{ addNewColumn()
    /**
     *  Adds a new row to the table dynamically
     *
     * @param Array columnContent = Array of strings - content of new cells.
     * @param String headerText = Text - column header
     * @param mixed sortMethod = How to sort the new column('N','S' or false)
     * 
     * @public
     */		
	addNewColumn : function(columnContent,headerText,sortMethod)
	{
		this.columnSortArray[this.columnSortArray.length] = sortMethod;
		var tableObj = document.getElementById(this.idOfTable);	// Reference to the <table>
		var tbody = tableObj.getElementsByTagName('TBODY')[0];	// Reference to the <tbody>		
		var thead = tableObj.getElementsByTagName('THEAD')[0];	// Reference to the <tbody>		
		
		var bodyRows = tbody.rows;	// Reference to all the <tr> inside the <tbody> tag
		var headerRows = thead.rows;	// Reference to all <tr> inside <thead>
		
		cellIndexSubtract = 1;	// Firefox have a small cell at the right of each row which means that the new column should not be the last one, but second to last.
		if(DHTMLSuite.clientInfoObj.isMSIE) cellIndexSubtract = 0;	// Browser does not have this cell at the right
		// Add new header cell		
		var headerCell = headerRows[0].insertCell(headerRows[0].cells.length-cellIndexSubtract);
		if(!this.noCssLayout)headerCell.className = 'DHTMLSuite_tableWidget_headerCell';
		headerCell.onselectstart = DHTMLSuite.commonObj.cancelEvent;
		DHTMLSuite.commonObj.__addEventElement(headerCell);
		headerCell.innerHTML = headerText;
		if(sortMethod){
			this.__parseHeaderCell(headerCell);			
		}else{
			headerCell.style.cursor = 'default';	
		}
		
		// Setting width of header cells. The last cell shouldn't have any right border
		headerRows[0].cells[headerRows[0].cells.length-1].style.borderRightWidth = '0px';
		headerRows[0].cells[headerRows[0].cells.length-2].style.borderRightWidth = '1px';
		
		// Add rows to the table
		
		for(var no=0;no<columnContent.length;no++){
			var dataCell = bodyRows[no].insertCell(bodyRows[no].cells.length-cellIndexSubtract);
			dataCell.innerHTML = columnContent[no];			
		}
		
		this.__parseDataRows(tableObj);
					
	}
	// }}}	
	,
	// {{{ setPageHandler()
    /**
     *  Specify a reference to a page handler for this widget (in case of server side sort)
     *
     * @param tableWidgetPageHandler ref = Page handler reference
     * 
     * @public
     */		
	setPageHandler : function(ref)
	{
		this.pageHandler = ref;
	}
	,
	
	/* START PRIVATE METHODS */
	
	
	// {{{ __handleCallBackFromEvent()
    /**
     *  Handle call back events for the table widget ( this method is used to find the element triggering a callback function)
     *
     * @param Event e = Event object - we will use this to find the element triggering the vent
     * @param String whichCallBackAction = What kind of callback
     * 
     * @private
     */	
	__handleCallBackFromEvent : function(e,whichCallBackAction)
	{
		if(document.all)e = event;
		var src = DHTMLSuite.commonObj.getSrcElement(e);
		
		if((whichCallBackAction=='rowClick' || whichCallBackAction=='rowDblClick') && src.tagName.toLowerCase()!='tr'){
			while(src.tagName.toLowerCase()!='tr')src = src.parentNode;
		}
		
		this.__createCallBackJavascriptString(whichCallBackAction,src);
		
	}
	// }}}
	,
	// {{{ __createCallBackJavascriptString()
    /**
     *  Handle call back events for the table widget
     *
     * @param String whichCallBackAction = Which call back, example "rowClick"
     * @param Object el = Reference to the element triggering the event.
     * 
     * @private
     */		
	__createCallBackJavascriptString : function(whichCallBackAction,el)
	{
		var callbackString = "";
		switch(whichCallBackAction){
			case "rowClick":
				if(!this.rowClickCallBackFunction)return;
				callbackString = this.rowClickCallBackFunction + '(el)';
				break;	
			case "rowDblClick":
				if(!this.setRowDblClickCallBackFunction)return;
				callbackString = this.setRowDblClickCallBackFunction + '(el)';
				break;
		}	
		
		this.__executeCallBack(callbackString,el);
		
	}
	,
	// {{{ __executeCallBack()
    /**
     *  Execute a javascript call back string
     *
     * @param String callbackString = Javascript code
     * @param Object el = Reference to the element triggering the event.
     * 
     * @private
     */		
	__executeCallBack : function(callbackString,el)
	{
		if(!callbackString)return;
		try{
			eval(callbackString);
		}catch(e){
			
		}
		
	}	
	,
	// {{{ __parseHeaderCell()
    /**
     *  Parses a header cell, i.e. add mouse events, and a arrow image to it.
     *
     * @param Object inputCell = Reference to <TD>
     * 
     * @private
     */	
	__parseHeaderCell : function(inputCell)
	{
		if(!this.noCssLayout){
			inputCell.onmouseover = this.__highlightTableHeader;
			inputCell.onmouseout =  this.__removeHighlightEffectFromTableHeader;
			inputCell.onmousedown = this.__mousedownOnTableHeader;		
			inputCell.onmouseup = this.__highlightTableHeader;	
			
		}else{
			inputCell.style.cursor = 'pointer';	// No CSS layout -> just set cursor to pointer/hand.
		}
		
		var refToThis = this;	// It doesn't work with "this" on the line below, so we create a variable refering to "this".	
		inputCell.onclick = function(){ refToThis.__sortTable(this); };	
		DHTMLSuite.commonObj.__addEventElement(inputCell);

		var img = document.createElement('IMG');
		img.src = DHTMLSuite.configObj.imagePath + 'table-widget/arrow_up.gif';
		inputCell.appendChild(img);	
		img.style.visibility = 'hidden';
	}
	// }}}	
	,
	
	// {{{ __parseDataRows()
    /**
     *  Parses rows in a table, i.e. add events and align cells.
     *
     * @param Object parentObj = Reference to <table>
     * 
     * @private
     */	
	__parseDataRows : function(parentObj)
	{
		var ind = this.objectIndex;
		// Loop through rows and assign mouseover and mouse out events + right align numeric cells.
		for(var no=1;no<parentObj.rows.length;no++){
			if(!this.noCssLayout){
				parentObj.rows[no].onmouseover = this.__highlightTableRow;
				parentObj.rows[no].onmouseout = this.__removeHighlightEffectFromTableRow;
			}
			parentObj.rows[no].onclick = function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__handleCallBackFromEvent(e,'rowClick'); };
			parentObj.rows[no].ondblclick = function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__handleCallBackFromEvent(e,'rowDblClick'); };
			DHTMLSuite.commonObj.__addEventElement(parentObj.rows[no]);
			
			for(var no2=0;no2<this.columnSortArray.length;no2++){	/* Right align numeric cells */
				try{
					if(this.columnSortArray[no2] && this.columnSortArray[no2]=='N')parentObj.rows[no].cells[no2].style.textAlign='right';
				}catch(e){
					alert('Error in __parseDataRows method - row: ' + no + ', column : ' + no2);
				}
			}
		}	
		// Right align header cells for numeric data
		for(var no2=0;no2<this.columnSortArray.length;no2++){	/* Right align numeric cells */
			if(this.columnSortArray[no2] && this.columnSortArray[no2]=='N')parentObj.rows[0].cells[no2].style.textAlign='right';
		}	
	}
	// }}}		
	,
	// {{{ __initTableWidget()
    /**
     *  Initializes the table widget script. This method formats the table and add events to the header cells.
     *
     * 
     * @private
     */	
	__initTableWidget : function()
	{
		
		if(!this.columnSortArray)this.columnSortArray = new Array();
		this.widthOfTable = this.widthOfTable + '';
		this.heightOfTable = this.heightOfTable + '';
		var obj = document.getElementById(this.idOfTable);
		obj.parentNode.className = 'DHTMLSuite_widget_tableDiv';
		
		
		
		if(navigator.userAgent.toLowerCase().indexOf('safari')==-1 && !this.noCssLayout){
			if(!DHTMLSuite.clientInfoObj.isMSIE)
				obj.parentNode.style.overflow='hidden';
			else {
				obj.parentNode.style.overflowX = 'hidden';
				obj.parentNode.style.overflowY = 'scroll';
			}
		}
		
		
		if(!this.noCssLayout){
			if(this.widthOfTable.indexOf('%')>=0){			
				obj.style.width = '100%';
				obj.parentNode.style.width = this.widthOfTable;			
			}else{
				obj.style.width = this.widthOfTable + 'px';
				obj.parentNode.style.width = this.widthOfTable + 'px';
			}		
			if(this.heightOfTable.indexOf('%')>=0){
				obj.parentNode.style.height = this.heightOfTable;				
			}else{
				obj.parentNode.style.height = this.heightOfTable + 'px';
			}
		}
		if(!DHTMLSuite.clientInfoObj.isMSIE){
			this.__addEndCol(obj);
		}else{
			obj.style.cssText = 'width:expression(this.parentNode.clientWidth)';
		}	
		
		obj.cellSpacing = 0;
		obj.cellPadding = 0;
		if(!this.noCssLayout)obj.className='DHTMLSuite_tableWidget';
		var tHead = obj.getElementsByTagName('THEAD')[0];
		var cells = tHead.getElementsByTagName('TD');
		
		var tBody = obj.getElementsByTagName('TBODY')[0];
		tBody.className = 'DHTMLSuite_scrollingContent';
		
		/* Add the last "cosmetic" cell in ie so that the scrollbar gets it's own column */
		if(DHTMLSuite.clientInfoObj.isMSIE && 1==2){	/* DEPRECATED */
			lastCell = tHead.rows[0].insertCell(-1);
			lastCell.innerHTML = '&nbsp;&nbsp;&nbsp;';	
			lastCell.className='DHTMLSuite_tableWidget_MSIESPACER';

		}
				
		for(var no=0;no<cells.length;no++){
			if(!this.noCssLayout)cells[no].className = 'DHTMLSuite_tableWidget_headerCell';
			cells[no].onselectstart = DHTMLSuite.commonObj.cancelEvent;
			DHTMLSuite.commonObj.__addEventElement(cells[no]);
			if(no==cells.length-1 && !this.noCssLayout){
				cells[no].style.borderRightWidth = '0px';	
			}
			if(this.columnSortArray[no]){
				this.__parseHeaderCell(cells[no]);			
			}else{
				cells[no].style.cursor = 'default';	
			}			
		}
		
		if(!this.noCssLayout){
			var tBody = obj.getElementsByTagName('TBODY')[0];
			if(document.all && navigator.userAgent.indexOf('Opera')<0){
				tBody.className='DHTMLSuite_scrollingContent';
				tBody.style.display='block';			
			}else{
				if(!this.noCssLayout)tBody.className='DHTMLSuite_scrollingContent';
				tBody.style.height = (obj.parentNode.clientHeight-tHead.offsetHeight) + 'px';
				if(navigator.userAgent.indexOf('Opera')>=0){
					obj.parentNode.style.overflow = 'auto';
				}
			}
		}		
		this.__parseDataRows(obj);
		var ind = this.objectIndex;				
	}	
	// }}}	
	,
	
	// {{{ __addEndCol()
    /**
     *  Adds a small empty cell at the right of the header row. This is done in order to make the table look pretty when the scrollbar appears.
     *
     * @param Object obj = Reference to <table>
     * 
     * @private
     */	
	__addEndCol : function(obj)
	{	
		var rows = obj.getElementsByTagName('TR');
		for(var no=0;no<rows.length;no++){
			var cell = rows[no].insertCell(rows[no].cells.length);
			cell.innerHTML = '<img src="' + DHTMLSuite.configObj.imagePath + 'table-widget/transparent.gif" width="10" style="visibility:hidden">';
			cell.style.width = '13px';
			cell.width = '13';
			cell.style.overflow='hidden';
		}	
		
	}	
	// }}}
	,
	
	// {{{ __highlightTableHeader()
    /**
     *  Mouse over event: Highlights header cell on mouse over, i.e. applies an orange line at the top.
     *
     * 
     * @private
     */	
	__highlightTableHeader : function()
	{
		// Here, "this" is a reference to the HTML tag triggering this event and not the table widget object
		this.className='DHTMLSuite_tableWigdet_headerCellOver';
		if(document.all){	// I.E fix for "jumping" headings
			var divObj = this.parentNode.parentNode.parentNode.parentNode;
			this.parentNode.style.top = divObj.scrollTop + 'px';	
		}		
	}
	// }}}	
	,
	
	// {{{ __removeHighlightEffectFromTableHeader()
    /**
     *  Mouse out event: Remove the orange line at the top of header cells when the mouse moves away from the cell.
     *
     * 
     * @private
     */	
	__removeHighlightEffectFromTableHeader : function()
	{
		// Here, "this" is a reference to the HTML tag triggering this event and not the table widget object
		this.className='DHTMLSuite_tableWidget_headerCell';		
	}	
	// }}}
	,
	
	// {{{ __mousedownOnTableHeader()
    /**
     *  Mouse down event header cells. It changes the color of the header from light gray to dark gray.
     * 
     * @private
     */	
	__mousedownOnTableHeader : function()
	{
		// Here, "this" is a reference to the HTML tag triggering this event and not the table widget object
		this.className='DHTMLSuite_tableWigdet_headerCellDown';
		if(document.all){	// I.E fix for "jumping" headings
			var divObj = this.parentNode.parentNode.parentNode.parentNode;
			this.parentNode.style.top = divObj.scrollTop + 'px';
		}		
	}
	// }}}
	,
	// {{{ __sortNumeric()
    /**
     *  Sort the table numerically
	 *	ps! If you know that your tables always contains valid numbers(i.e. digits or decimal numbers like 7 and 7.5), 
	 * 	then you can remove everything except return a/1 - b/1; from this function. By removing these lines, the sort
	 *	process be faster.     
     *
     * @param String a = first number to compare
     * @param String b = second number to compare
     * 
     * @private
     */	
	__sortNumeric : function(a,b){
		// changing commas(,) to periods(.)
		a = a.replace(/,/,'.');
		b = b.replace(/,/,'.');
		// Remove non digit characters - example changing "DHTML12.5" to "12.5"
		a = a.replace(/[^\d\.\/]/g,'');
		b = b.replace(/[^\d\.\/]/g,'');
		// Dealing with fractions(example: changing 4/5 to 0.8)
		if(a.indexOf('/')>=0)a = eval(a);
		if(b.indexOf('/')>=0)b = eval(b);
		return a/1 - b/1;
	}	
	// }}}
	,
	
	// {{{ __sortString()
    /**
     *  Sort the table alphabetically
     *
     * @param String a = first number to compare
     * @param String b = second number to compare
     * 
     * @private
     */	
	__sortString : function(a, b) {	
	  if ( a.toUpperCase() < b.toUpperCase() ) return -1;
	  if ( a.toUpperCase() > b.toUpperCase() ) return 1;
	  return 0;
	}
	// }}}
	,
	// {{{ __parseDataContentFromServer()
    /**
     * This method parses data content from server and calls the __fillDataRow method with parsed data as argument.
     *
     * 
     * @private
     */		
	__parseDataContentFromServer : function(ajaxIndex)
	{
		var content = DHTMLSuite.variableStorage.ajaxObjects[ajaxIndex].response;
		if(content.indexOf('|||')==-1 && content.indexOf('###')==-1){
			alert('Error in data from server\n'+content);
			return;
		}
		
		this.__clearDataRows();	// Clear existing data
		var rows = content.split('|||');	// Create an array of each row
		for(var no=0;no<rows.length;no++){
			var items = rows[no].split('###');
			if(items.length>1)this.__fillDataRow(items);
			
		}	
		this.__parseDataRows(this.tableObj);
	}
	
	// }}}
	,
	// {{{ __clearDataRows()
    /**
     * This method clear all data from the table(except header cells).
     *
     * 
     * @private
     */		
	__clearDataRows : function()
	{
		if(!this.tableObj)this.tableObj = document.getElementById(this.idOfTable);
		while(this.tableObj.rows.length>1){
			this.tableObj.rows[this.tableObj.rows.length-1].parentNode.removeChild(this.tableObj.rows[this.tableObj.rows.length-1]);	
		}
	}
	
	// }}
	,
	// {{{ __fillDataRow()
    /**
     * Adds a new row of data to the table.
     *
     * @param Array data = Array of data
     * 
     * @private
     */		
	__fillDataRow : function(data)
	{
		if(!this.tableObj)this.tableObj = document.getElementById(this.idOfTable);
		var tbody = this.tableObj.getElementsByTagName('TBODY')[0];
		var row = tbody.insertRow(-1);
		for(var no=0;no<data.length;no++){
			var cell = row.insertCell(no);
			cell.innerHTML = data[no];
		}
		
	}
	// }}}
	,
	// {{{ updateTableHeader()
    /**
     * Updates the header of the table,i.e. shows the correct arrow. This is a method you call if you're sorting the table on the server
     *
     *
     * @param Integer columnIndex = Index of column the table is currently sorted by
     * @param String direction = How the table is sorted(ascending or descending)
     * 
     * @public
     */		
	updateTableHeader : function(columnIndex,direction)
	{
		var tableObj = document.getElementById(this.idOfTable);
		var firstRow = tableObj.rows[0];
		var tds = firstRow.cells;
		var tdObj = tds[columnIndex];
		tdObj.setAttribute('direction',direction);
		tdObj.direction = direction;
		var sortBy = tdObj.getAttribute('sortBy');
		if(!sortBy)sortBy = tdObj.sortBy;
		this.tableCurrentlySortedBy = sortBy;
		this.__updateSortArrow(tdObj,direction);		
	}
	// }}}
	,
	// {{{ reloadDataFromServer()
    /**
     * Simply reload data from server. 
     *
     * 
     * @public
     */			
	reloadDataFromServer : function()
	{
		this.__getItemsFromServer();
		if(this.pageHandler)this.pageHandler.__resetActivePageNumber();			
	}
	// }}}
	,
	// {{{ resetServersideSortCurrentStartIndex()
    /**
     * Reset current server side sort start index
     * It may be useful to call this method and then the reloadDataFromServer() 
     * method in case you want to reload data from the server starting with the first row in the record set.
     *
     * 
     * @public
     */			
	resetServersideSortCurrentStartIndex : function()
	{
		this.serversideSortCurrentStartIndex = 0;
		
	}
	// }}}
	,	
	// {{{ __updateSortArrow()
    /**
     * Sort table - This method is called when someone clicks on the header of one of the sortable columns
     *
     * @param Object obj = reference to header cell
     * @param String direction = How the table is sorted(ascending or descending)
     * 
     * @private
     */		
	__updateSortArrow : function(obj,direction)
	{
		var images = obj.getElementsByTagName('IMG');	// Array of the images inside the clicked header cell(i.e. arrow up and down)
		if(direction=='descending'){	// Setting visibility of arrow image based on sort(ascending or descending)
			images[0].src = images[0].src.replace('arrow_up','arrow_down');
			images[0].style.visibility='visible';
		}else{
			images[0].src = images[0].src.replace('arrow_down','arrow_up');
			images[0].style.visibility='visible';
		}		
		if(this.activeColumn && this.activeColumn!=obj){
			var images = this.activeColumn.getElementsByTagName('IMG');
			images[0].style.visibility='hidden';
			this.activeColumn.removeAttribute('direction');			
		}		
		
		this.activeColumn = obj;	// Setting this.activeColumn to the cell trigger this method 

	}
	// }}}
	,
	// {{{ __getParsedCallbackString()
    /**
     * __getParsedCallbackString - return call back javascript to execute. 
     *
     * @param String functionName = Name of call back function
     * 
     * @private
     */		
	__getParsedCallbackString : function(functionName)
	{
		var objIndex = this.objectIndex;	
		if(!functionName)
			functionName='true';
		else
			functionName = functionName + '(DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[' + objIndex + '])';	
		return functionName;	
	}	
	// }}}
	,
	// {{{ __getItemsFromServer()
    /**
     * Send ajax request to the server in order to get new data.
     *
     * @param String callbackFunctionNavigation = Name of eventual call back function to execute when new content has been received.
     * 
     * @private
     */		
	__getItemsFromServer : function(callbackFunctionNavigation)
	{
		callbackFunctionNavigation = this.__getParsedCallbackString(callbackFunctionNavigation);			
		var objIndex = this.objectIndex;	
		var url = this.serversideSortFileName + '?sortBy=' + this.tableCurrentlySortedBy + '&numberOfRows=' + this.serversideSortNumberOfRows + '&sortAscending=' + this.serversideSortAscending + '&startIndex=' + this.serversideSortCurrentStartIndex + this.serversideSortExtraSearchCriterias;
		var index = DHTMLSuite.variableStorage.ajaxObjects.length;	
		try{
			DHTMLSuite.variableStorage.ajaxObjects[index] = new sack();
		}catch(e){	// Unable to create ajax object - send alert message and return from sort method.
			alert('Unable to create ajax object. Please make sure that the sack js file is included on your page(js/ajax.js)');	
			return;
		}
		DHTMLSuite.variableStorage.ajaxObjects[index].requestFile = url;	// Specifying which file to get
		DHTMLSuite.variableStorage.ajaxObjects[index].onCompletion = function(){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[objIndex].__parseDataContentFromServer(index);eval(callbackFunctionNavigation) };	// Specify function that will be executed after file has been found
		DHTMLSuite.variableStorage.ajaxObjects[index].runAJAX();		// Execute AJAX function	
	}	
	// }}}
	,	
	// {{{ __sortTable()
    /**
     * Sort table - This method is called when someone clicks on the header of one of the sortable columns
     *
     * @param Object obj = reference to header cell triggering the sortTable method
     * 
     * @private
     */	
	__sortTable : function(obj,howToSort)
	{
		// "this" is a reference to the table widget obj
		// "obj" is a reference to the header cell triggering the sortTable method.
		
		// Server side sort ?
		if(this.serversideSort){
			// tableCurrentlySortedBy
					

			if(!this.serversideSortFileName){	// Server side file name defined.
				alert('No server side file defined. Use the setServersideSortFileName to specify where to send the ajax request');
				return;
			}
			var sortBy = obj.getAttribute('sortBy');
			if(!sortBy)sortBy = obj.sortBy;
			if(!sortBy){
				alert('Sort is not defined. Remember to set a sortBy attribute on the header <td> tags');
				return;
			}
			if(sortBy==this.tableCurrentlySortedBy)this.serversideSortAscending = !this.serversideSortAscending;else this.serversideSortAscending = true;
			if(howToSort)this.serversideSortAscending = (howToSort=='ascending'?true:false);
			this.tableCurrentlySortedBy = sortBy;
			this.serversideSortCurrentStartIndex =0;
			this.__getItemsFromServer();	
			
			if(this.pageHandler)this.pageHandler.__resetActivePageNumber();		
			this.__updateSortArrow(obj,this.serversideSortAscending?'ascending':'descending');
			
			return;	
		}
		
		
		
		if(!this.tableWidget_okToSort)return;
		this.tableWidget_okToSort = false;
		/* Getting index of current column */

		var indexThis = 0;
		
		var tmpObj = obj;
		while(tmpObj.previousSibling){
			tmpObj = tmpObj.previousSibling;
			if(tmpObj.tagName=='TD')indexThis++;		
		}		
		if(obj.getAttribute('direction') || obj.direction){	// Determine if we should sort ascending or descending
			direction = obj.getAttribute('direction');
			if(navigator.userAgent.indexOf('Opera')>=0)direction = obj.direction;
			if(direction=='ascending' || howToSort=='descending'){
				direction = 'descending';
				obj.setAttribute('direction','descending');
				obj.direction = 'descending';	
			}else{
				direction = 'ascending';
				obj.setAttribute('direction','ascending');		
				obj.direction = 'ascending';		
			}
		}else{ // First call to the sort method	
			var curDir = 'ascending';	// How to sort the table
			if(howToSort)curDir = howToSort; // Initial sort method sent as argument to this method, call it by this method.
			direction = curDir;
			obj.setAttribute('direction',curDir);
			obj.direction = curDir;
		}		

		this.__updateSortArrow(obj,direction);
				
		var tableObj = obj.parentNode.parentNode.parentNode;
		var tBody = tableObj.getElementsByTagName('TBODY')[0];
		
		var widgetIndex = tableObj.id.replace(/[^\d]/g,'');
		var sortMethod = this.columnSortArray[indexThis]; // N = numeric, S = String
		

		var cellArray = new Array();
		var cellObjArray = new Array();
		for(var no=1;no<tableObj.rows.length;no++){
			var content= tableObj.rows[no].cells[indexThis].innerHTML+'';
			cellArray.push(content);
			cellObjArray.push(tableObj.rows[no].cells[indexThis]);
		}
		// Calling sort methods
		if(sortMethod=='N'){
			cellArray = cellArray.sort(this.__sortNumeric);
		}else{
			cellArray = cellArray.sort(this.__sortString);
		}
		if(direction=='descending'){
			for(var no=cellArray.length;no>=0;no--){
				for(var no2=0;no2<cellObjArray.length;no2++){
					if(cellObjArray[no2].innerHTML == cellArray[no] && !cellObjArray[no2].getAttribute('allreadySorted')){
						cellObjArray[no2].setAttribute('allreadySorted','1');	
						tBody.appendChild(cellObjArray[no2].parentNode);				
					}				
				}			
			}
		}else{
			for(var no=0;no<cellArray.length;no++){
				for(var no2=0;no2<cellObjArray.length;no2++){
					if(cellObjArray[no2].innerHTML == cellArray[no] && !cellObjArray[no2].getAttribute('allreadySorted')){
						cellObjArray[no2].setAttribute('allreadySorted','1');	
						tBody.appendChild(cellObjArray[no2].parentNode);				
					}				
				}			
			}				
		}		
		for(var no2=0;no2<cellObjArray.length;no2++){
			cellObjArray[no2].removeAttribute('allreadySorted');		
		}	
		this.tableWidget_okToSort = true;		
	}	
	// }}}
	,
	
	// {{{ __highlightTableRow()
    /**
     *  Highlight data row on mouse over, i.e. applying css class tableWidget_dataRollOver
     *	To change the layout, look inside table-widget.css
     *
     * 
     * @private
     */	
	__highlightTableRow : function()
	{
		if(navigator.userAgent.indexOf('Opera')>=0)return;
		this.className='DHTMLSuite_tableWidget_dataRollOver';
		if(document.all){	// I.E fix for "jumping" headings
			var divObj = this.parentNode.parentNode.parentNode;
			var tHead = divObj.getElementsByTagName('TR')[0];
			tHead.style.top = divObj.scrollTop + 'px';			
		}	
	}
	// }}}
	,
	// {{{ __removeHighlightEffectFromTableRow()
    /**
     * Reset data row layout when mouse moves away from it.
     * 
     * @private
     */	
	__removeHighlightEffectFromTableRow : function()
	{
		if(navigator.userAgent.indexOf('Opera')>=0)return;
		this.className=null;
		if(document.all){	// I.E fix for "jumping" headings
			var divObj = this.parentNode.parentNode.parentNode;
			var tHead = divObj.getElementsByTagName('TR')[0];
			tHead.style.top = divObj.scrollTop + 'px';
		}			
	}	
	// }}}		
}	

/*[FILE_START:dhtmlSuite-dragDropSimple.js] */
/************************************************************************************************************
*	Drag and drop class - simple class - used by the DHTMLSuite.imageEnlarger script
*
*	Created:			January, 8th, 2007
*
* 	Update log:
*
************************************************************************************************************/
var DHTMLSuite_dragDropSimple_curZIndex = 100000;
var DHTMLSuite_dragDropSimple_curObjIndex=false;
/**
* @constructor
* @class Purpose of class:	A very simple drag and drop script. It makes a single element dragable but doesn't offer other features.
*		<br>
* @version				1.0
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/
DHTMLSuite.dragDropSimple = function(propertyArray)
{
	
	
	var divElement;
	var dragTimer;	// -1 no drag, 0-4 = initializing , 5 = drag in process
	var cloneNode;
	this.cloneNode = true;
	

	var callbackOnAfterDrag;
	var callbackOnBeforeDrag;
	var callbackOnDuringDrag;
	
	var mouse_x;
	var mouse_y;
	var positionSet;
	var dragHandle;	// If a specific element is specified to be a drag handle.
	
	var allowMoveX;
	var allowMoveY;
	var maxY;
	var minY;
	var minX;
	var maxX;
	
	var initialXPos;
	var initialYPos;
	
	this.positionSet = false;
	this.dragHandle = new Array();
	var initOffsetX;
	var initOffsetY;
	
	this.allowMoveX = true;
	this.allowMoveY = true;
	this.maxY = false;
	this.maxX = false;
	this.minX = false;
	this.minY = false;
	
	this.callbackOnAfterDrag = false;
	this.callbackOnBeforeDrag = false;
	
	this.dragStatus = -1;
	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.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[this.objectIndex] = this;

	this.__setInitialProperties(propertyArray);
	this.__init();
	
}

DHTMLSuite.dragDropSimple.prototype = {
	// {{{ __init()
    /**
     * Initializes the script
     * 
     * @private
     */		
    __setInitialProperties : function(propertyArray)
    {
		if(propertyArray.cloneNode===false || propertyArray.cloneNode)this.cloneNode=propertyArray.cloneNode;
		if(propertyArray.allowMoveX===false || propertyArray.allowMoveX)this.allowMoveX=propertyArray.allowMoveX;
		if(propertyArray.allowMoveY===false || propertyArray.allowMoveY)this.allowMoveY=propertyArray.allowMoveY;
		if(propertyArray.minY || propertyArray.minY===0)this.minY=propertyArray.minY;
		if(propertyArray.maxY || propertyArray.maxY===0)this.maxY=propertyArray.maxY;
		if(propertyArray.minX || propertyArray.minX===0)this.minX=propertyArray.minX;
		if(propertyArray.maxX || propertyArray.maxX===0)this.maxX=propertyArray.maxX;
	
		if(!propertyArray.initOffsetX)propertyArray.initOffsetX = 0;
		if(!propertyArray.initOffsetY)propertyArray.initOffsetY = 0;    	
	 	this.initOffsetX = propertyArray.initOffsetX;
		this.initOffsetY = propertyArray.initOffsetY;   	
    	if(propertyArray.callbackOnBeforeDrag)this.callbackOnBeforeDrag = propertyArray.callbackOnBeforeDrag; 	
    	if(propertyArray.callbackOnAfterDrag)this.callbackOnAfterDrag = propertyArray.callbackOnAfterDrag; 	
    	if(propertyArray.callbackOnDuringDrag)this.callbackOnDuringDrag = propertyArray.callbackOnDuringDrag; 	
		if(typeof propertyArray.elementReference == 'string'){
			propertyArray.elementReference = document.getElementById(propertyArray.elementReference);
		}
		this.divElement = propertyArray.elementReference;
	
		this.initialXPos = DHTMLSuite.commonObj.getLeftPos(this.divElement);
		this.initialYPos = DHTMLSuite.commonObj.getTopPos(this.divElement);    	
    }
    
    
    // }}}
    ,	
	// {{{ __init()
    /**
     * Initializes the script
     * 
     * @private
     */		
	__init : function()
	{
		var ind = this.objectIndex;		
		
		
		this.divElement.objectIndex = ind;
		this.divElement.setAttribute('objectIndex',ind);
		
		this.divElement.style.padding = '0px';

		if(this.allowMoveX){
			this.divElement.style.left = (DHTMLSuite.commonObj.getLeftPos(this.divElement) + this.initOffsetX) + 'px';
		}
		if(this.allowMoveY){
			this.divElement.style.top = (DHTMLSuite.commonObj.getTopPos(this.divElement) + this.initOffsetY) + 'px';
		}
		this.divElement.style.position = 'absolute';
		this.divElement.style.margin = '0px';
			
		if(this.divElement.style.zIndex && this.divElement.style.zIndex/1>DHTMLSuite_dragDropSimple_curZIndex)DHTMLSuite_dragDropSimple_curZIndex=this.divElement.style.zIndex/1;		
		DHTMLSuite_dragDropSimple_curZIndex = DHTMLSuite_dragDropSimple_curZIndex/1 + 1;
		this.divElement.style.zIndex = DHTMLSuite_dragDropSimple_curZIndex;	
				
		if(this.cloneNode){
			var copy = this.divElement.cloneNode(true);		
			this.divElement.parentNode.insertBefore(copy,this.divElement);
			copy.style.visibility = 'hidden';
			document.body.appendChild(this.divElement);
		}
		
		
		DHTMLSuite.commonObj.addEvent(this.divElement,'mousedown',function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__initDragProcess(e); },ind);
		DHTMLSuite.commonObj.addEvent(document.documentElement,'mousemove',function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__moveDragableElement(e); },ind);
		DHTMLSuite.commonObj.addEvent(document.documentElement,'mouseup',function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__stopDragProcess(e); },ind);
				
		if(!document.documentElement.onselectstart)document.documentElement.onselectstart = function() { return DHTMLSuite.commonObj.__isTextSelOk(); };
	}
	// }}}
	,
	// {{{ setCallbackOnAfterDrag()
    /**
     * Specify name of function to execute after drag is completed.
     *	
     *	@param String functionName - Name of function to execute
     * 
     * @private
     */		
	setCallbackOnAfterDrag : function(functionName)
	{
		this.callbackOnAfterDrag = functionName;
	}
	// }}}
	,
	// {{{ setCallbackOnBeforeDrag()
    /**
     * Specify name of function to execute before drag is executed.
     *	
     *	@param String functionName - Name of function to execute
     * 
     * @private
     */		
	setCallbackOnBeforeDrag : function(functionName)
	{
		this.callbackOnBeforeDrag = functionName;
	}
	// }}}
	,
	// {{{ addDragHandle()
    /**
     * Specify a drag handle
     *	
     *	@param Object HTML Element - element inside the dragable element specified to act as a drag handle.
     * 
     * @private
     */		
	addDragHandle : function(dragHandle)
	{
		this.dragHandle[this.dragHandle.length] = dragHandle;
	}
	// }}}
	,
	// {{{ __initDragProcess()
    /**
     * Initializes drag process
     * 
     * @private
     */		
	__initDragProcess : function(e)
	{
		if(document.all)e = event;		
		var ind = this.objectIndex;
		DHTMLSuite_dragDropSimple_curObjIndex = ind;	
			
		var thisObject = DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind];
		if(!DHTMLSuite.commonObj.isObjectClicked(thisObject.divElement,e))return;	

		if(thisObject.divElement.style.zIndex && thisObject.divElement.style.zIndex/1>DHTMLSuite_dragDropSimple_curZIndex)DHTMLSuite_dragDropSimple_curZIndex=thisObject.divElement.style.zIndex/1;		
		DHTMLSuite_dragDropSimple_curZIndex = DHTMLSuite_dragDropSimple_curZIndex/1 +1;
		thisObject.divElement.style.zIndex = DHTMLSuite_dragDropSimple_curZIndex;	
				
		if(thisObject.callbackOnBeforeDrag){
			thisObject.__handleCallback('beforeDrag',e);	
		}
		
		if(thisObject.dragHandle.length>0){	// Drag handle specified?		
			var objectFound;
			for(var no=0;no<thisObject.dragHandle.length;no++){
				if(!objectFound)objectFound = DHTMLSuite.commonObj.isObjectClicked(thisObject.dragHandle[no],e);
			}	
			if(!objectFound)return;
		}			

		DHTMLSuite.commonObj.__setTextSelOk(false);
		
		thisObject.mouse_x = e.clientX;
		thisObject.mouse_y = e.clientY;
		
		thisObject.el_x = thisObject.divElement.style.left.replace('px','')/1;
		thisObject.el_y = thisObject.divElement.style.top.replace('px','')/1;

		thisObject.dragTimer = 0;
		thisObject.__waitBeforeDragProcessStarts();
		return false;				
	}	
	// }}}
	,
	// {{{ __waitBeforeDragProcessStarts()
    /**
     * Small delay from mouse is pressed down till drag starts.
     * 
     * @private
     */		
	__waitBeforeDragProcessStarts : function()
	{
		var ind = this.objectIndex;
		if(this.dragTimer>=0 && this.dragTimer<5){
			this.dragTimer++;			
			setTimeout('DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[' + ind + '].__waitBeforeDragProcessStarts()',5);
		}	
	}
	// }}}
	,
	// {{{ __moveDragableElement()
    /**
     * Move dragable element if drag is in process
     *
     *	@param Event e - Event object - since this method is triggered by an event
     *
     * @private
     */		
	__moveDragableElement : function(e)
	{	
		if(document.all)e = event;
		var ind = this.objectIndex;
		// if(DHTMLSuite_dragDropSimple_curObjIndex===false)return false;
		var thisObj = DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind];
	
		if(DHTMLSuite.clientInfoObj.isMSIE && e.button!=1)return thisObj.__stopDragProcess();
		
		if(thisObj.dragTimer==5){				
			if(thisObj.allowMoveX){
				var leftPos = (e.clientX - this.mouse_x + this.el_x);	
	
				if(this.maxX!==false){
					if(leftPos + document.documentElement.scrollLeft>this.initialXPos+this.maxX){
						leftPos = this.initialXPos+this.maxX;
					}	
				}
				if(this.minX!==false)
				{
					if(leftPos + document.documentElement.scrollLeft<this.initialXPos+this.minX){
						leftPos = this.initialXPos+this.minX;	
					}					
				}						
				thisObj.divElement.style.left =leftPos + 'px';
			}	
			if(thisObj.allowMoveY){
				var topPos = (e.clientY - thisObj.mouse_y + thisObj.el_y);
				if(this.maxY!==false){
					if(topPos>this.initialYPos+this.maxY){
						topPos = this.initialYPos+this.maxY;	
					}
				}	
				if(this.minY!==false)
				{
					if(topPos <this.initialYPos+this.minY){
						topPos = this.initialYPos+this.minY;	
					}					
				}	
					
				thisObj.divElement.style.top = topPos + 'px';	
			}
			
			if(this.callbackOnDuringDrag)this.__handleCallback('duringDrag',e);
		}	
		return false;
	}
	// }}}
	,
	// {{{ __stopDragProcess()
    /**
     * Stop the drag process
     * 
     * @private
     */		
	__stopDragProcess : function(e)
	{
		var ind = this.objectIndex;
		DHTMLSuite.commonObj.__setTextSelOk(true);
		var thisObj = DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind];	
		if(thisObj.dragTimer==5){
			thisObj.__handleCallback('afterDrag',e);
		}	
		thisObj.dragTimer = -1;
	}
	// }}}
	,
	// {{{ __handleCallback()
    /**
     * Execute callback function
     *	@param String action - callback action
     * 
     * @private
     */		
	__handleCallback : function(action,e)
	{
		var callbackString = '';
		switch(action){
			case "afterDrag":
				callbackString = this.callbackOnAfterDrag;
				break;	
			case "beforeDrag":
				callbackString = this.callbackOnBeforeDrag;
				break;
			case "duringDrag":
				callbackString = this.callbackOnDuringDrag;
				break;
		}
		if(callbackString){
			callbackString = callbackString + '(e)';
			try{
				eval(callbackString);
			}catch(e){
				alert('Could not execute callback function(' + callbackString + ') after drag');
			}
		}
		
	}
	// }}}
	,
	// {{{ __setNewCurrentZIndex()
    /**
     * Updates current z index. 
     *	@param Integer zIndex - This method is called by the window script when z index has been read from cookie
     * 
     * @private
     */		
	__setNewCurrentZIndex : function(zIndex)
	{
		if(zIndex > DHTMLSuite_dragDropSimple_curZIndex){
			DHTMLSuite_dragDropSimple_curZIndex = zIndex/1+1;
		}	
	}
		
}

/*[FILE_START:dhtmlSuite-dragDrop.js] */
/************************************************************************************************************
*	Drag and drop class
*
*	Created:			August, 18th, 2006
*
* 	Update log:
*
************************************************************************************************************/


/**
* @constructor
* @class Purpose of class:	A general drag and drop class. By creating objects of this class, you can make elements
*		 on your web page dragable and also assign actions to element when an item is dropped on it.
*		 A page should only have one object of this class.<br>
*		<br>
*		IMPORTANT when you use this class: Don't assign layout to the dragable element ids
*		Assign it to classes or the tag instead. example: If you make <div id="dragableBox1" class="aBox">
*		dragable, don't assign css to #dragableBox1. Assign it to div or .aBox instead.<br>
*		(<a href="../../demos/demo-drag-drop-1.html" target="_blank">demo 1</a>, <a href="../../demos/demo-drag-drop-2.html" target="_blank">demo 2</a>),
*		<a href="../../demos/demo-drag-drop-3.html" target="_blank">demo 3</a>, <a href="../../demos/demo-drag-drop-4.html" target="_blank">demo 4</a>
*		and <a href="../../demos/demo-drag-drop-4.html" target="_blank">demo 5</a>)
* @version				1.0
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/


DHTMLSuite.dragDrop = function()
{
	var mouse_x;					// mouse x position when drag is started
	var mouse_y;					// mouse y position when drag is started.
	
	var el_x;						// x position of dragable element
	var el_y;						// y position of dragable element
	
	var dragDropTimer;				// Timer - short delay from mouse down to drag init.
	var numericIdToBeDragged;		// numeric reference to element currently being dragged.
	var dragObjCloneArray;			// Array of cloned dragable elements. every
	var dragDropSourcesArray;		// Array of source elements, i.e. dragable elements.
	var dragDropTargetArray;		// Array of target elements, i.e. elements where items could be dropped.
	var currentZIndex;				// Current z index. incremented on each drag so that currently dragged element is always on top.
	var okToStartDrag;				// Variable which is true or false. It would be false for 1/100 seconds after a drag has been started.
									// This is useful when you have nested dragable elements. It prevents the drag process from staring on
									// parent element when you click on dragable sub element.
	var moveBackBySliding;			// Variable indicating if objects should slide into place moved back to their location without any slide animation.
	var dragX_allowed;				// Possible to drag this element along the x-axis?
	var dragY_allowed;				// Possible to drag this element along the y-axis?
	
	var currentEl_allowX;
	var currentEl_allowY;
	var drag_minX;
	var drag_maxX;
	var drag_minY;
	var drag_maxY;
	var dragInProgress;				// Variable which is true when drag is in progress, false otherwise
	
	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.dragX_allowed = true;
	this.dragY_allowed = true;
	this.currentZIndex = 21000;
	this.dragDropTimer = -1;
	this.dragObjCloneArray = new Array();
	this.numericIdToBeDragged = false;	

	this.okToStartDrag = true;
	this.moveBackBySliding = true;	  
	this.dragInProgress = false;
	
	var objectIndex;
	this.objectIndex = DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[this.objectIndex] = this;
		
}

DHTMLSuite.dragDrop.prototype = {
	
	// {{{ init()
    /**
     * Initialize the script
     * This method should be called after you have added sources and destinations.
     * 
     * @public
     */	
	init : function()
	{
		this.__initDragDropScript();	

	}
	// }}}	
	,
	// {{{ addSource()
    /**
     * Add dragable element
     *
     * @param String sourceId = Id of source
     * @param boolean slideBackAfterDrop = Slide the item back to it's original location after drop.
     * @param boolean xAxis = Allowed to slide along the x-axis(default = true, i.e. if omitted).
     * @param boolean yAxis = Allowed to slide along the y-axis(default = true, i.e. if omitted).
     * @param String dragOnlyWithinElId = You will only allow this element to be dragged within the boundaries of the element with this id.
     * 
     * @public
     */	
	addSource : function(sourceId,slideBackAfterDrop,xAxis,yAxis,dragOnlyWithinElId)
	{
		if(!this.dragDropSourcesArray)this.dragDropSourcesArray = new Array();
		if(!document.getElementById(sourceId)){
			alert('The source element with id ' + sourceId + ' does not exists. Check your HTML code');
			return;
		}
		if(xAxis!==false)xAxis = true;
		if(yAxis!==false)yAxis = true;
		var obj = document.getElementById(sourceId);
		this.dragDropSourcesArray[this.dragDropSourcesArray.length]  = [obj,slideBackAfterDrop,xAxis,yAxis,dragOnlyWithinElId];		
		obj.setAttribute('dragableElement',this.dragDropSourcesArray.length-1);
		obj.dragableElement = this.dragDropSourcesArray.length-1;
		
	}
	// }}}	
	,
	// {{{ addTarget()
    /**
     * Add drop target
     *
     * @param String targetId = Id of drop target
     * @param String functionToCallOnDrop = name of function to call on drop. 
	 *		Input to this the function specified in functionToCallOnDrop function would be 
	 *		id of dragged element 
	 *		id of the element the item was dropped on.
	 *		mouse x coordinate when item was dropped
	 *		mouse y coordinate when item was dropped     
     * 
     * @public
     */	
	addTarget : function(targetId,functionToCallOnDrop)
	{
		if(!this.dragDropTargetArray)this.dragDropTargetArray = new Array();
		if(!document.getElementById(targetId))alert('The target element with id ' + targetId + ' does not exists.  Check your HTML code');
		var obj = document.getElementById(targetId);
		this.dragDropTargetArray[this.dragDropTargetArray.length]  = [obj,functionToCallOnDrop];		
	}
	// }}}	
	,	
	// {{{ setSlide()
    /**
     * Activate or deactivate sliding animations.
     *
     * @param boolean isSlidingAnimationEnabled = Move element back to orig. location in a sliding animation
     * 
     * @public
     */	
	setSlide : function(isSlidingAnimationEnabled)
	{
		this.moveBackBySliding = isSlidingAnimationEnabled;		
	}
	// }}}	
	,		
	/* Start private methods */
	
	// {{{ __initDragDropScript()
    /**
     * Initialize drag drop script - this method is called by the init() method.
     * 
     * @private
     */	
	__initDragDropScript : function()
	{
		var ind = this.objectIndex;
		var refToThis = this;
		var startIndex = Math.random() + '';
		startIndex = startIndex.replace('.','')/1;
		
		for(var no=0;no<this.dragDropSourcesArray.length;no++){			
			var el = this.dragDropSourcesArray[no][0].cloneNode(true);	
			var el2 = this.dragDropSourcesArray[no][0];
					
			eval("el.onmousedown =function(e,index){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[" + ind + "].__initializeDragProcess(e," + no + "); }");	
			DHTMLSuite.commonObj.__addEventElement(el);
			var tmpIndex = startIndex + no;
			// el.id = 'DHTMLSuite_dragableElement' + tmpIndex;
			el.id = el2.id;	/* Override the value above */
			el.style.position='absolute';
			el.style.visibility='hidden';
			el.style.display='none';			
			// 2006/12/02 - Changed the line below because of positioning problems.			
			document.body.appendChild(el);			
			//this.dragDropSourcesArray[no][0].parentNode.insertBefore(el,this.dragDropSourcesArray[no][0]);
			
			el.style.top = DHTMLSuite.commonObj.getTopPos(this.dragDropSourcesArray[no][0]) + 'px';
			el.style.left = DHTMLSuite.commonObj.getLeftPos(this.dragDropSourcesArray[no][0]) + 'px';
					
			eval("el2.onmousedown =function(e,index){ return DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[" + ind + "].__initializeDragProcess(e," + no + "); }");	
			DHTMLSuite.commonObj.__addEventElement(this.dragDropSourcesArray[no][0]);						
			this.dragObjCloneArray[no] = el; 
			
			
		}
		
		eval("DHTMLSuite.commonObj.addEvent(document.documentElement,\"mousemove\",function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[" + ind + "].__moveDragableElement(e); } )");
		eval("DHTMLSuite.commonObj.addEvent(document.documentElement,\"mouseup\",function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[" + ind + "].__stopDragProcess(e); } );");
		
		if(!document.documentElement.onselectstart)document.documentElement.onselectstart = function() { return DHTMLSuite.commonObj.__isTextSelOk(); };
		document.documentElement.ondragstart = function() { return DHTMLSuite.commonObj.cancelEvent() };		

		
		DHTMLSuite.commonObj.__addEventElement(document.documentElement);
		
	}	
	// }}}	
	,		
	// {{{ __initializeDragProcess()
    /**
     * Initialize drag process
     *
     * @param Event e = Event object, used to get x and y coordinate of mouse pointer
     * 
     * @private
     */	
	__initializeDragProcess : function(e,index)
	{
		var ind = this.objectIndex;		
		if(!this.okToStartDrag)return false; 
	
		setTimeout('DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[' + ind + '].okToStartDrag = true;',100);
		if(document.all)e = event;

		this.numericIdToBeDragged = index;
		this.numericIdToBeDragged = this.numericIdToBeDragged + '';

		this.dragDropTimer=0;
		DHTMLSuite.commonObj.__setTextSelOk(false);
		this.mouse_x = e.clientX;
		this.mouse_y = e.clientY;
		
		this.currentZIndex = this.currentZIndex + 1;		
		this.dragObjCloneArray[this.numericIdToBeDragged].style.zIndex = this.currentZIndex;		
	
		this.currentEl_allowX = this.dragDropSourcesArray[this.numericIdToBeDragged][2];
		this.currentEl_allowY = this.dragDropSourcesArray[this.numericIdToBeDragged][3];

		var parentEl = this.dragDropSourcesArray[this.numericIdToBeDragged][4];
		this.drag_minX = false;
		this.drag_minY = false;
		this.drag_maxX = false;
		this.drag_maxY = false;
		if(parentEl){
			var obj = document.getElementById(parentEl);
			if(obj){
				this.drag_minX = DHTMLSuite.commonObj.getLeftPos(obj);
				this.drag_minY = DHTMLSuite.commonObj.getTopPos(obj);
				this.drag_maxX = this.drag_minX + obj.clientWidth;
				this.drag_maxY = this.drag_minY + obj.clientHeight;				
			}		
		}			
		
		// Reposition dragable element
		if(this.dragDropSourcesArray[this.numericIdToBeDragged][1]){
			this.dragObjCloneArray[this.numericIdToBeDragged].style.top = DHTMLSuite.commonObj.getTopPos(this.dragDropSourcesArray[this.numericIdToBeDragged][0]) + 'px';
			this.dragObjCloneArray[this.numericIdToBeDragged].style.left = DHTMLSuite.commonObj.getLeftPos(this.dragDropSourcesArray[this.numericIdToBeDragged][0]) + 'px';
		}
		this.el_x = this.dragObjCloneArray[this.numericIdToBeDragged].style.left.replace('px','')/1;
		this.el_y = this.dragObjCloneArray[this.numericIdToBeDragged].style.top.replace('px','')/1;
				
		this.__waitBeforeDragProcessStarts();
				
		return false;
	}	
	// }}}	
	,	
	// {{{ __waitBeforeDragProcessStarts()
    /**
     * A small delay from mouse down to drag starts 
     * 
     * @private
     */	
	__waitBeforeDragProcessStarts : function()
	{
		var ind = this.objectIndex;
		
		if(this.dragDropTimer>=0 && this.dragDropTimer<5){
			this.dragDropTimer = this.dragDropTimer + 1;
			setTimeout('DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[' + ind + '].__waitBeforeDragProcessStarts()',2);
			return;			
		}
		if(this.dragDropTimer>=5){
			if(this.dragObjCloneArray[this.numericIdToBeDragged].style.display=='none'){
				this.dragDropSourcesArray[this.numericIdToBeDragged][0].style.visibility = 'hidden';
				this.dragObjCloneArray[this.numericIdToBeDragged].style.display = 'block';
				this.dragObjCloneArray[this.numericIdToBeDragged].style.visibility = 'visible';
				this.dragObjCloneArray[this.numericIdToBeDragged].style.top = DHTMLSuite.commonObj.getTopPos(this.dragDropSourcesArray[this.numericIdToBeDragged][0]) + 'px';
				this.dragObjCloneArray[this.numericIdToBeDragged].style.left = DHTMLSuite.commonObj.getLeftPos(this.dragDropSourcesArray[this.numericIdToBeDragged][0]) + 'px';
			}
		}		
	}	
	// }}}	
	,
	// {{{ __moveDragableElement()
    /**
     * Move dragable element according to mouse position when drag is in process.
     *
     * @param Event e = Event object, used to get x and y coordinate of mouse pointer
     * 
     * @private
     */	
	__moveDragableElement : function(e)
	{
		var ind = this.objectIndex;		
		if(document.all)e = event;		
		if(this.dragDropTimer<5)return false;	
		if(this.dragInProgress)return false;
		this.dragInProgress = true;
		var dragObj = this.dragObjCloneArray[this.numericIdToBeDragged];
		
		if(this.currentEl_allowX){			
			
			var leftPos = (e.clientX - this.mouse_x + this.el_x);
			if(this.drag_maxX){
				var tmpMaxX = this.drag_maxX - dragObj.offsetWidth;
				if(leftPos > tmpMaxX)leftPos = tmpMaxX
				if(leftPos < this.drag_minX)leftPos = this.drag_minX;				
			}
			dragObj.style.left = leftPos + 'px'; 
		
		}	
		if(this.currentEl_allowY){
			var topPos = (e.clientY - this.mouse_y + this.el_y);
			if(this.drag_maxY){	
				var tmpMaxY = this.drag_maxY - dragObj.offsetHeight;		
				if(topPos > tmpMaxY)topPos = tmpMaxY;
				if(topPos < this.drag_minY)topPos = this.drag_minY;					
			}			
			dragObj.style.top = topPos + 'px'; 
		}
		this.dragInProgress = false;
		return false;
	}
	// }}}	
	,	
	// {{{ __stopDragProcess()
    /**
     * Drag process stopped.
     *
     * @param Event e = Event object, used to get x and y coordinate of mouse pointer
     * 
     * @private
     */	
	__stopDragProcess : function(e)
	{
		if(this.dragDropTimer<5)return false;
		if(document.all)e = event;
			
		// Dropped on which element
		var dropDestination = DHTMLSuite.commonObj.getSrcElement(e);	
		
		var leftPosMouse = e.clientX + Math.max(document.body.scrollLeft,document.documentElement.scrollLeft);
		var topPosMouse = e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop);
		
		if(!this.dragDropTargetArray)this.dragDropTargetArray = new Array();
		// Loop through drop targets and check if the coordinate of the mouse is over it. If it is, call specified drop function.
		for(var no=0;no<this.dragDropTargetArray.length;no++){
			var leftPosEl = DHTMLSuite.commonObj.getLeftPos(this.dragDropTargetArray[no][0]);
			var topPosEl = DHTMLSuite.commonObj.getTopPos(this.dragDropTargetArray[no][0]);
			var widthEl = this.dragDropTargetArray[no][0].offsetWidth;
			var heightEl = this.dragDropTargetArray[no][0].offsetHeight;
			
			if(leftPosMouse > leftPosEl && leftPosMouse < (leftPosEl + widthEl) && topPosMouse > topPosEl && topPosMouse < (topPosEl + heightEl)){
				if(this.dragDropTargetArray[no][1]){
					try{
						eval(this.dragDropTargetArray[no][1] + '("' + this.dragDropSourcesArray[this.numericIdToBeDragged][0].id + '","' + this.dragDropTargetArray[no][0].id + '",' + e.clientX + ',' + e.clientY + ')');
					}catch(e){
						alert('Unable to execute \n' + this.dragDropTargetArray[no][1] + '("' + this.dragDropSourcesArray[this.numericIdToBeDragged][0].id + '","' + this.dragDropTargetArray[no][0].id + '",' + e.clientX + ',' + e.clientY + ')');
					}
				}				
				break;
			}			
		}	
		
		if(this.dragDropSourcesArray[this.numericIdToBeDragged][1]){
			this.__slideElementBackIntoItsOriginalPosition(this.numericIdToBeDragged);
		}		
		// Variable cleanup after drop
		this.dragDropTimer = -1;		
		DHTMLSuite.commonObj.__setTextSelOk(true);
		this.numericIdToBeDragged = false;									
	}	
	// }}}	
	,	
	// {{{ __slideElementBackIntoItsOriginalPosition()
    /**
     * Slide an item back to it's original position
     *
     * @param Integer numId = numeric index of currently dragged element	
     * 
     * @private
     */	
	__slideElementBackIntoItsOriginalPosition : function(numId)
	{
		// Coordinates current element position
		var currentX = this.dragObjCloneArray[numId].style.left.replace('px','')/1;
		var currentY = this.dragObjCloneArray[numId].style.top.replace('px','')/1;
		
		// Coordinates - where it should slide to
		var targetX = DHTMLSuite.commonObj.getLeftPos(this.dragDropSourcesArray[numId][0]);
		var targetY = DHTMLSuite.commonObj.getTopPos(this.dragDropSourcesArray[numId][0]);;
		
		if(this.moveBackBySliding){
			// Call the step by step slide method
			this.__processSlideByPixels(numId,currentX,currentY,targetX,targetY);
		}else{
			this.dragObjCloneArray[numId].style.display='none';
			this.dragDropSourcesArray[numId][0].style.visibility = 'visible';			
		}			
	}
	// }}}	
	,	
	// {{{ __processSlideByPixels()
    /**
     * Move the element step by step in this method
     *
     * @param Int numId = numeric index of currently dragged element
     * @param Int currentX = Elements current X position
     * @param Int currentY = Elements current Y position
     * @param Int targetX = Destination X position, i.e. where the element should slide to
     * @param Int targetY = Destination Y position, i.e. where the element should slide to
     * 
     * @private
     */	
	__processSlideByPixels : function(numId,currentX,currentY,targetX,targetY)
	{				
		// Find slide x value
		var slideX = Math.round(Math.abs(Math.max(currentX,targetX) - Math.min(currentX,targetX)) / 10);		
		// Find slide y value
		var slideY = Math.round(Math.abs(Math.max(currentY,targetY) - Math.min(currentY,targetY)) / 10);
		
		if(slideY<3 && Math.abs(slideX)<10)slideY = 3;	// 3 is minimum slide value
		if(slideX<3 && Math.abs(slideY)<10)slideX = 3;	// 3 is minimum slide value
		
		
		if(currentX > targetX) slideX*=-1;	// If current x is larger than target x, make slide value negative<br>
		if(currentY > targetY) slideY*=-1;	// If current y is larger than target x, make slide value negative
		
		// Update currentX and currentY
		currentX = currentX + slideX;	
		currentY = currentY + slideY;

		// If currentX or currentY is close to targetX or targetY, make currentX equal to targetX(or currentY equal to targetY)
		if(Math.max(currentX,targetX) - Math.min(currentX,targetX) < 4)currentX = targetX;
		if(Math.max(currentY,targetY) - Math.min(currentY,targetY) < 4)currentY = targetY;

		// Update CSS position(left and top)
		this.dragObjCloneArray[numId].style.left = currentX + 'px';
		this.dragObjCloneArray[numId].style.top = currentY + 'px';	
		
		// currentX different than targetX or currentY different than targetY, call this function in again in 5 milliseconds
		if(currentX!=targetX || currentY != targetY){
			window.thisRef = this;	// Reference to this dragdrop object
			setTimeout('window.thisRef.__processSlideByPixels("' + numId + '",' + currentX + ',' + currentY + ',' + targetX + ',' + targetY + ')',5);
		}else{	// Slide completed. Make absolute positioned element invisible and original element visible
			this.dragObjCloneArray[numId].style.display='none';
			this.dragDropSourcesArray[numId][0].style.visibility = 'visible';
		}		
	}
}

/*[FILE_START:dhtmlSuite-tabView.js] */	
/************************************************************************************************************
*	Tab view class
*
*	Created:			August, 21st, 2006
*
* 	Update log:
*
************************************************************************************************************/

	
var refToTabViewObjects = new Array();	// Reference to objects of this class. 
										// We need this because the script doesn't allways know which object to use

/**
* @constructor
* @class Purpose of class:	Tab view class - transfors plain HTML into tabable layers.<br>
* (See <a target="_blank" href="../../demos/demo-tabs-1.html">demo 1</A> and <a target="_blank" href="../../demos/demo-tabs-2.html">demo 2</A>)
* @version 1.0
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.tabView = function()
{
	var textPadding;				// Tab spacing
	var strictDocType ; 			// Using a strict document type, i.e. <!DOCTYPE>

	var DHTMLSuite_tabObj;		// Reference to div surrounding the tab set
	var activeTabIndex;				// Currently displayed tab(index - 0 = first tab)
	var initActiveTabIndex;			// Initially displayed tab(index - 0 = first tab)
	var ajaxObjects;				// Reference to ajax objects
	var tabView_countTabs;
	var tabViewHeight;
	var tabSetParentId;				// Id of div surrounding the tab set.
	var tabTitles;					// Tab titles
	var width;						// width of tab view
	var height;						// height of tab view
	var layoutCSS;
	var outsideObjectRefIndex;		// Which index of refToTabViewObjects refers to this object.
	var maxNumberOfTabs;
	var dynamicContentObj;	
	var closeButtons;
	var refActiveTabContent;
	
	var callbackOnTabSwitch;
	
	this.initActiveTabIndex = 0;
	this.callbackOnTabSwitch = '';
	this.refActiveTabContent = '';
	// Default variable values
	this.textPadding = 3;
	this.strictDocType = true; 	
	this.ajaxObjects = new Array();
	this.tabTitles = new Array();
	this.layoutCSS = 'tab-view.css';
	this.maxNumberOfTabs = 6;
	this.dynamicContentObj = false;
	this.closeButtons = new Array();
	this.width = '100%';
	this.height = '500';
	
	try{
		if(!standardObjectsCreated)DHTMLSuite.createStandardObjects();	// This line starts all the init methods
	}catch(e){
		alert('You need to include the dhtmlSuite-common.js file');
	}
}

DHTMLSuite.tabView.prototype = {
	// {{{ init()
    /**
     * Initialize the script
     * 
     * @public
     */	
	init : function()
	{
		
		DHTMLSuite.commonObj.loadCSS(this.layoutCSS);
		this.outsideObjectRefIndex = refToTabViewObjects.length;
		refToTabViewObjects[this.outsideObjectRefIndex] = this;
		try{
			this.dynamicContentObj = new DHTMLSuite.dynamicContent();
		}catch(e){
			alert('You need to include DHTMLSuite-dynamicContent.js');
		}
		this.__initializeAndParseTabs(false,false);
		
	}
	// }}}
	,
	// {{{ setCallbackOnTabSwitch()
    /**
     * Set callback on tab switch
     * 
     * @param String callbackOnTabSwitch = Name of function to execute when the user switches to a different tab.
     *
     * @public
     */			
	setCallbackOnTabSwitch : function(callbackOnTabSwitch)
	{
		this.callbackOnTabSwitch = callbackOnTabSwitch;
	}
	// }}}
	,
	// {{{ getMaximumNumberOfTabs()
    /**
     * Return maximum number of tabs
     * 
     * @return Int maximumNumberOfTabs = Maximum number of tabs
     *
     * @public
     */		
	getMaximumNumberOfTabs : function()
	{
		return this.maxNumberOfTabs;
	}
	// }}}	
	,
	// {{{ setMaximumTabs()
    /**
     * Set maximum number of tabs
     * 
     * @param Int maximumNumberOfTabs = Maximum number of tabs
     *
     * @public
     */	
	setMaximumTabs : function(maximumNumberOfTabs)
	{
		this.maxNumberOfTabs = maximumNumberOfTabs;
	}       
    // }}}	
    ,
	// {{{ setParentId()
    /**
     * Set padding on tabs
     * 
     * @param String idOfParentHTMLElement = id of parent div
     *
     * @public
     */	
	setParentId : function(idOfParentHTMLElement)
	{
		this.tabSetParentId = idOfParentHTMLElement;
		this.DHTMLSuite_tabObj = document.getElementById(idOfParentHTMLElement);
	}       
    // }}}	
    ,
	// {{{ setWidth()
    /**
     * Set width of tab view
     * 
     * @param String Width of tab view
     *
     * @public
     */	
	setWidth : function(newWidth)
	{
		this.width = newWidth;
	}   
    
    // }}}	
    ,
	// {{{ setHeight()
    /**
     * Set height of tab view on tabs
     * 
     * @param String Height of tab view
     *
     * @public
     */	
	setHeight : function(newHeight)
	{
		this.height = newHeight;
	}   
    // }}}	
    ,	
	// {{{ setIndexActiveTab()
    /**
     * Set index of initially active tab
     * 
     * @param Int indexOfNewActiveTab = Index of active tab(0 = first tab)
     *
     * @public
     */	
	setIndexActiveTab : function(indexOfNewActiveTab)
	{
		this.initActiveTabIndex = indexOfNewActiveTab;
	}   
    
    // }}}	
    ,	
	// {{{ setTabTitles()
    /**
     * Set title of tabs
     * 
     * @param Array titleOfTabs = Title of tabs
     *
     * @public
     */	
	setTabTitles : function(titleOfTabs)
	{
		this.tabTitles = titleOfTabs;
	}    
    
    // }}}	
    ,	
	// {{{ setCloseButtons()
    /**
     * Specify which tabs that should have close buttons
     * 
     * @param Array closeButtons = Array of true or false
     *
     * @public
     */	
	setCloseButtons : function(closeButtons)
	{
		this.closeButtons = closeButtons;
	}    
    // }}}
    ,
	// {{{ getReferenceToDivElement()
    /**
     * 
     * Returns a reference to the div element of a tab.
     *
     * @param String tabTitle = Title of tab
     * @return Object Element to HTML div element for this tab.
     *
     * @public
     */	    
    getReferenceToDivElementByTitle : function(tabTitle)
    {
    	var index = this.getTabIndexByTitle(tabLabel);	// Get index of tab
    	if(index!=-1){
    		var obj = document.getElementById('tabView' + this.tabSetParentId + '_' + index);
    		return obj;    		
    	}   	
    	return false;
    }
    // }}}
    ,
	// {{{ getReferenceToDivElementById()
    /**
     * 
     * Returns a reference to the div element of a tab.
     *
     * @param String idOfTab = id of tab
     * @return Object Element to HTML div element for this tab.
     *
     * @public
     */	     
    getReferenceToDivElementById : function(idOfTab)
    {
		var divs = this.DHTMLSuite_tabObj.getElementsByTagName('DIV');
		
		for(var no=0;no<divs.length;no++){
			var attr = divs[no].getAttribute('originalId');
			if(!attr)attr = divs[no].originalid;
			if(attr == idOfTab)return divs[no];
		}
		return false;
    	
    }
    // }}}	
	,
	// {{{ createNewTab()
    /**
     * 
     * Creates new tab dynamically
     *
     * @param String parentId = Id of tabset
     * @param String tabTitle = Title of new tab
     * @param String tabContent = Content of new tab(Optional)
     * @param String tabContentUrl = Url to content of new tab(Optional) - Ajax is used to get this content
     *
     * @return Boolean Success - true if the tab was created, false otherwise, i.e. tab with same label already exists.
     *
     * @public
     */		
	createNewTab : function(parentId,tabTitle,tabContent,tabContentUrl,closeButton) 
    { 
      var index = this.getTabIndexByTitle(tabTitle);   // Get index of tab 
      if(index!=-1){   // Tab exists if index<>-1 
         this.displayATab(tabTitle,index); 
         return false; 
      } 
      if(this.tabView_countTabs>=this.maxNumberOfTabs)return;   // Maximum number of tabs reached - return 
      var div = document.createElement('DIV');   // Create new tab content div. 
      div.className = 'DHTMLSuite_aTab';   // Assign new tab to CSS class DHTMLSuite_aTab 
      this.DHTMLSuite_tabObj.appendChild(div);         // Appending new tab content div to main tab view div 
      var tabId = this.__initializeAndParseTabs(true,tabTitle,closeButton);   // Call the init method in order to create tab header and tab images 
      if(tabContent)div.innerHTML = tabContent;   // Static tab content specified, put it into the new div 
      if(tabContentUrl){   // Get content from external file 
         this.dynamicContentObj.loadContent('tabView' + parentId +'_' + tabId,tabContentUrl); 
      } 
      return true;
   } 

	// }}}	    
    ,	
 	// {{{ deleteTab()
    /**
     *
     * Delete a tab 
     *
     * @param String tabLabel = Label of tab to delete(Optional)
     * @param Int tabIndex = Index of tab to delete(Optional)
     *
     * @public
     */		
	deleteTab : function(tabLabel,tabIndex)
	{		
		if(tabLabel){	// Delete tab by tab title
			var index = this.getTabIndexByTitle(tabLabel);	// Get index of tab
			if(index!=-1){	// Tab exists if index<>-1
				this.deleteTab(false,index);
			}
			
		}else if(tabIndex>=0){	// Delete tab by tab index.
			if(document.getElementById('tabTab' + this.tabSetParentId + '_' + tabIndex)){
				var obj = document.getElementById('tabTab' + this.tabSetParentId + '_' + tabIndex);
				var id = obj.parentNode.parentNode.id;
				obj.parentNode.removeChild(obj);
				var obj2 = document.getElementById('tabView' + this.tabSetParentId + '_' + tabIndex);
				obj2.parentNode.removeChild(obj2);
				this.__resetTabIds(this.tabSetParentId);
				this.initActiveTabIndex=-1;
				var newIndex = 0;
				if(refToTabViewObjects[this.outsideObjectRefIndex].activeTabIndex==tabIndex)refToTabViewObjects[this.outsideObjectRefIndex].activeTabIndex=-1;
				this.__showTab(this.tabSetParentId,newIndex,this.outsideObjectRefIndex);
			}			
		}		
	}
	// }}}	
	,  	// {{{ addContentToTab()
    /**
     * Add content to a tab dynamically.
     * 
     * @param String tabLabel = Label of tab to delete(Optional)
     * @param String filePath = Path to file you want to show inside the tab.
     *
     * @public
     */		
	addContentToTab : function(tabLabel,filePath)
	{		
		var index = this.getTabIndexByTitle(tabLabel);	// Get index of tab
		if(index!=-1){	// Tab found
			this.dynamicContentObj.loadContent('tabView' + this.tabSetParentId + '_' + index,filePath);		
		}
	}
	// }}}	
	, 
 	// {{{ displayATab()
    /**
     * Display a tab manually
     * 
     * @param String tabTitle = Label of tab to show(Optional)
     * @param Int tabIndex = Index of tab to show(Optional)
     *
     * @public
     */		

	displayATab : function(tabLabel,tabIndex)
	{		
		if(tabLabel){	// Delete tab by tab title
			var index = this.getTabIndexByTitle(tabLabel);	// Get index of tab
			if(index!=-1){	// Tab exists if index<>-1
				this.initActiveTabIndex = index;
			}else return false;
			
		}else{
			this.initActiveTabIndex = tabIndex;
		}

		this.__showTab(this.tabSetParentId,this.initActiveTabIndex,this.outsideObjectRefIndex)
	}	
	// }}}	
	,  	
 	// {{{ getTabIndex()
    /**
     * Return index of active tab
     * 
     * @type Integer tabIndex = Index of active tab(0 = first tab)
     *
     * @public
     */		
	getTabIndex : function()
	{
		var divs = this.DHTMLSuite_tabObj.getElementsByTagName('DIV');
		var tabIndex = 0;
		for(var no=0;no<divs.length;no++){
			if(divs[no].id.indexOf('tabTab')>=0){
				if(divs[no].className!='tabInactive')return tabIndex;
				tabIndex++;		
			}
		}		
		//tabInactive	
		return tabIndex;		
	}	
	// }}}
	,   
	
	// {{{ __setPadding()
    /**
     * Set padding on tabs
     * 
     * @private
     */		
	__setPadding : function(obj,padding){
		var span = obj.getElementsByTagName('SPAN')[0];
		span.style.paddingLeft = padding + 'px';	
		span.style.paddingRight = padding + 'px';	
	}	
	// }}}	
	,
	// {{{ __showTab()
    /**
     * Set padding
     * 
     * @param String parentId = id of parent div
     * @param Int tabIndex = Index of tab to show
     * @param Int objectIndex = Index of refToTabViewObjects, reference to the object of this class.
     *
     * @private
     */		
	__showTab : function(parentId,tabIndex,objectIndex)
	{
		var parentId_div = parentId + "_";
		if(!document.getElementById('tabView' + parentId_div + tabIndex)){			
			return;
		}
		
		if(refToTabViewObjects[objectIndex].activeTabIndex>=0){
			if(refToTabViewObjects[objectIndex].activeTabIndex==tabIndex){
				return;
			}	
			var obj = document.getElementById('tabTab'+parentId_div + refToTabViewObjects[objectIndex].activeTabIndex);	
			if(!obj){
				refToTabViewObjects[objectIndex].activeTabIndex = 0;
				var obj = document.getElementById('tabTab'+parentId_div + refToTabViewObjects[objectIndex].activeTabIndex);	
			}
			obj.className='tabInactive';
			obj.style.backgroundImage = 'url(\'' + DHTMLSuite.configObj.imagePath + 'tab-view/tab_left_inactive.gif' + '\')';
			var imgs = obj.getElementsByTagName('IMG');
			var img = imgs[imgs.length-1];
			img.src = DHTMLSuite.configObj.imagePath + 'tab-view/tab_right_inactive.gif';
			document.getElementById('tabView' + parentId_div + refToTabViewObjects[objectIndex].activeTabIndex).style.display='none';
		}
		
		var thisObj = document.getElementById('tabTab'+ parentId_div +tabIndex);	
			
		thisObj.className='tabActive';
		thisObj.style.backgroundImage = 'url(\'' + DHTMLSuite.configObj.imagePath + 'tab-view/tab_left_active.gif' + '\')';
		var imgs = thisObj.getElementsByTagName('IMG');
		var img = imgs[imgs.length-1];		
		img.src = DHTMLSuite.configObj.imagePath + 'tab-view/tab_right_active.gif';
		
		document.getElementById('tabView' + parentId_div + tabIndex).style.display='block';
		this.refActiveTabContent = document.getElementById('tabView' + parentId_div + tabIndex);
		refToTabViewObjects[objectIndex].activeTabIndex = tabIndex;
		
		refToTabViewObjects[objectIndex].__handleCallback('tabSwitch');

		var parentObj = thisObj.parentNode;
		var aTab = parentObj.getElementsByTagName('DIV')[0];
		countObjects = 0;
		var startPos = 2;
		var previousObjectActive = false;
		while(aTab){
			if(aTab.tagName=='DIV'){
				if(previousObjectActive){
					previousObjectActive = false;
					startPos-=2;
				}
				if(aTab==thisObj){
					startPos-=2;
					previousObjectActive=true;
					refToTabViewObjects[objectIndex].__setPadding(aTab,refToTabViewObjects[objectIndex].textPadding+1);
				}else{
					refToTabViewObjects[objectIndex].__setPadding(aTab,refToTabViewObjects[objectIndex].textPadding);
				}
				
				aTab.style.left = startPos + 'px';
				countObjects++;
				startPos+=2;
			}			
			aTab = aTab.nextSibling;
		}
		
		return;
	}
	// }}}
	,
	__handleCallback : function(action)
	{
		
		var callbackString = '';
		switch(action)
		{
			case "tabSwitch":
				callbackString = this.callbackOnTabSwitch;			
				break;			
		}	
		
		if(callbackString){
			callbackString = callbackString + '(this.refActiveTabContent)';
			eval(callbackString);
		}		
	}
	// }}}	
	,
	// {{{ tabClick()
    /**
     * Set padding
     * 
     * @param String parentId = id of parent div
     * @param Int tabIndex = Index of tab to show
     *
     * @private
     */	
	__tabClick : function(inputObj,index)
	{
		var idArray = inputObj.id.split('_');	
		var parentId = inputObj.getAttribute('parentRefId');
		if(!parentId)parentId=  inputObj.parentRefId;
		this.__showTab(parentId,idArray[idArray.length-1].replace(/[^0-9]/gi,''),index);
		
	}	
	// }}}
	,
	// {{{ rolloverTab()
    /**
     * Set padding
     * 
     *
     * @private
     */		
	__rolloverTab : function()
	{
		if(this.className.indexOf('tabInactive')>=0){
			this.className='inactiveTabOver';
			this.style.backgroundImage = 'url(\'' + DHTMLSuite.configObj.imagePath + 'tab-view/tab_left_over.gif' + '\')';
			var imgs = this.getElementsByTagName('IMG');
			var img = imgs[imgs.length-1];
			
			img.src = DHTMLSuite.configObj.imagePath + 'tab-view/tab_right_over.gif';
		}
		
	}	
	// }}}
	,	
	// {{{ rolloutTab()
    /**
     * 
     *
     * @private
     */			
	__rolloutTab : function()
	{
		if(this.className ==  'inactiveTabOver'){
			this.className='tabInactive';
			this.style.backgroundImage = 'url(\'' + DHTMLSuite.configObj.imagePath + 'tab-view/tab_left_inactive.gif' + '\')';
			var imgs = this.getElementsByTagName('IMG');
			var img = imgs[imgs.length-1];
			img.src = DHTMLSuite.configObj.imagePath + 'tab-view/tab_right_inactive.gif';
		}		
	}
	// }}}
	,
	// {{{ __initializeAndParseTabs()
    /**
     * 
     * @param Int additionalTab = Additional tabs to the existing
     * @param String nameOfAdditionalTab = Title of additional tab.
     *
     * @private
     */	
	__initializeAndParseTabs : function(additionalTab,nameOfAdditionalTab,additionalCloseButton)
	{
		this.DHTMLSuite_tabObj.className = ' DHTMLSuite_tabWidget';
		
		window.refToThisTabSet = this;
		if(!additionalTab || additionalTab=='undefined'){			
			this.DHTMLSuite_tabObj = document.getElementById(this.tabSetParentId);
			this.width = this.width + '';
			if(this.width.indexOf('%')<0)this.width= this.width + 'px';
			this.DHTMLSuite_tabObj.style.width = this.width;
						
			this.height = this.height + '';
			if(this.height.length>0){
				if(this.height.indexOf('%')<0)this.height= this.height + 'px';
				this.DHTMLSuite_tabObj.style.height = this.height;
			}
			
			var tabDiv = document.createElement('DIV');		
			var firstDiv = this.DHTMLSuite_tabObj.getElementsByTagName('DIV')[0];	
			
			this.DHTMLSuite_tabObj.insertBefore(tabDiv,firstDiv);	
			tabDiv.className = 'DHTMLSuite_tabContainer';			
			this.tabView_countTabs = 0;
			var tmpTabTitles = this.tabTitles;	// tmpTab titles set to current tab titles - this variable is used in the loop below
												// We don't want to loop through all the tab titles in the object when we add a new one manually.
			
		}else{	// A new tab being created dynamically afterwards.
			var tabDiv = this.DHTMLSuite_tabObj.getElementsByTagName('DIV')[0];
			var firstDiv = this.DHTMLSuite_tabObj.getElementsByTagName('DIV')[1];
			this.initActiveTabIndex = this.tabView_countTabs;		
			var tmpTabTitles = Array(nameOfAdditionalTab);	// tmpTab titles set to only the new tab
		}		
		
		
		
		for(var no=0;no<tmpTabTitles.length;no++){
			var aTab = document.createElement('DIV');
			aTab.id = 'tabTab' + this.tabSetParentId + "_" +  (no + this.tabView_countTabs);
			aTab.onmouseover = this.__rolloverTab;
			aTab.onmouseout = this.__rolloutTab;
			aTab.setAttribute('parentRefId',this.tabSetParentId);
			aTab.parentRefId = this.tabSetParentId;
			var numIndex = window.refToThisTabSet.outsideObjectRefIndex+'';
			aTab.onclick = function() { window.refToThisTabSet.__tabClick(this,numIndex); };
			DHTMLSuite.commonObj.__addEventElement(aTab);
			aTab.className='tabInactive';
			aTab.style.backgroundImage = 'url(\'' + DHTMLSuite.configObj.imagePath + 'tab-view/tab_left_inactive.gif' + '\')';
			tabDiv.appendChild(aTab);
			var span = document.createElement('SPAN');
			span.innerHTML = tmpTabTitles[no];
			aTab.appendChild(span);

			if(this.closeButtons[no] || additionalCloseButton){
				var closeButton = document.createElement('IMG');
				closeButton.src = DHTMLSuite.configObj.imagePath + 'tab-view/tab-view-close.gif';
				closeButton.style.position='absolute';
				closeButton.style.top = '4px';
				closeButton.style.right = '2px';
				closeButton.onmouseover = this.__mouseOverEffectCloseButton;
				closeButton.onmouseout = this.__mouseOutEffectForCloseButton;
				DHTMLSuite.commonObj.__addEventElement(closeButton);
				span.innerHTML = span.innerHTML + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';	
				
				var deleteTxt = span.innerHTML+'';

				// function() { window.refToThisTabSet.__tabClick(this,numIndex); };
				closeButton.onclick = function(){ refToTabViewObjects[numIndex].deleteTab( this.parentNode.innerHTML) };
				span.appendChild(closeButton);
			}
						
			var img = document.createElement('IMG');
			img.valign = 'bottom';
			img.src = DHTMLSuite.configObj.imagePath + 'tab-view/tab_right_inactive.gif';
			// IE5.X FIX
			if((DHTMLSuite.clientInfoObj.navigatorVersion && DHTMLSuite.clientInfoObj.navigatorVersion<6) || (DHTMLSuite.clientInfoObj.isMSIE && !this.strictDocType)){
				img.style.styleFloat = 'none';
				img.style.position = 'relative';	
				img.style.top = '4px'
				span.style.paddingTop = '4px';
				aTab.style.cursor = 'hand';
			}	// End IE5.x FIX
			aTab.appendChild(img);
		}

		var tabs = this.DHTMLSuite_tabObj.getElementsByTagName('DIV');
		var divCounter = 0;
		for(var no=0;no<tabs.length;no++){
			if(tabs[no].className=='DHTMLSuite_aTab' && tabs[no].parentNode == this.DHTMLSuite_tabObj){
				if(this.height.length>0){
					if(this.height.indexOf('%')==-1){
						var tmpHeight = (this.height.replace('px','')/1 - 22);
						tabs[no].style.height = tmpHeight + 'px';
					}else
						tabs[no].style.height = this.height;
				}
				tabs[no].style.display='none';
				if(tabs[no].id){
					tabs[no].setAttribute('originalId',tabs[no].id);
					tabs[no].originalId = tabs[no].id;					
				}
				tabs[no].id = 'tabView' + this.tabSetParentId + "_" + divCounter;
				divCounter++;
			}			
		}	
		if(additionalTab){
			this.tabView_countTabs++;
		}else{
			this.tabView_countTabs = this.tabView_countTabs + this.tabTitles.length;	
		}
		
		this.__showTab(this.tabSetParentId,this.initActiveTabIndex,this.outsideObjectRefIndex);

		return this.activeTabIndex;
	}
	// }}}	
	,
	// {{{ __mouseOutEffectForCloseButton()
    /**
     * 
     *
     * @private
     */	    	
	__mouseOutEffectForCloseButton : function()
	{
		this.src = this.src.replace('close-over.gif','close.gif');	
	}	
	// }}}	
	,	
	// {{{ __mouseOverEffectCloseButton()
    /**
     * 
     *
     * @private
     */	    	
	__mouseOverEffectCloseButton : function()
	{
		this.src = this.src.replace('close.gif','close-over.gif');	
	}	
	// }}}	
	,	
	
	// {{{ __fillTabWithContentFromAjax()
    /**
     * 
      * @param Int ajaxIndex = Index of Ajax array
      * @param String objId = Id of element where content from Ajax should be displayed
      * @param Int tabId = Id of element where content from Ajax should be displayed
     *
     * @private
     */	    	
	__fillTabWithContentFromAjax : function(ajaxIndex,objId,tabId)
	{
		var obj = document.getElementById('tabView'+objId + '_' + tabId);
		obj.innerHTML = this.ajaxObjects[ajaxIndex].response;		
	}	
	// }}}	
	,
	// {{{ __resetTabIds()
    /**
     * 
     *
     * @private
     */		
	__resetTabIds : function(parentId)
	{
		var tabTitleCounter = 0;
		var tabContentCounter = 0;		
		var divs = this.DHTMLSuite_tabObj.getElementsByTagName('DIV');	

		for(var no=0;no<divs.length;no++){
			if(divs[no].className=='DHTMLSuite_aTab' && divs[no].parentNode==this.DHTMLSuite_tabObj){
				divs[no].id = 'tabView' + parentId + '_' + tabTitleCounter;
				tabTitleCounter++;
			}
			if(divs[no].id.indexOf('tabTab')>=0 && divs[no].parentNode.parentNode==this.DHTMLSuite_tabObj){
				divs[no].id = 'tabTab' + parentId + '_' + tabContentCounter;	
				tabContentCounter++;
			}		
						
		}	
		this.tabView_countTabs = tabContentCounter;
	}
	// }}}	

	,
	// {{{ getTabIndexByTitle()
    /**
     * 
     *
     * @private
     */		
	getTabIndexByTitle : function(tabTitle)
	{
		tabTitle = tabTitle.replace(/(.*?)&nbsp.*$/gi,'$1');
		var divs = this.DHTMLSuite_tabObj.getElementsByTagName('DIV');
		
		for(var no=0;no<divs.length;no++){
			if(divs[no].id.indexOf('tabTab')>=0){
				var span = divs[no].getElementsByTagName('SPAN')[0];	
				var spanTitle = span.innerHTML.replace(/(.*?)&nbsp.*$/gi,'$1');
				if(spanTitle == tabTitle){
					var tmpId = divs[no].id.split('_');					
					return tmpId[tmpId.length-1].replace(/[^0-9]/g,'')/1;
				}		
			}
		}
	
		
		return -1;		
	}
	// }}}				
}

/*[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 = 3;
		this.indicator_offsetY = 14;
	}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.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[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 DHTMLSuite.commonObj.cancelEvent() };
		DHTMLSuite.commonObj.__addEventElement(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.arrayOfDhtmlSuiteObjects[ind].showHideNode(e); };
			DHTMLSuite.commonObj.__addEventElement(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 = this.__moveDragableNodes;
				DHTMLSuite.commonObj.addEvent(aTag,'mousemove',function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__moveDragableNodes(e,'text'); });
				
			}
			DHTMLSuite.commonObj.__addEventElement(aTag);
			menuItems[no].insertBefore(img,aTag);
			//menuItems[no].id = 'DHTMLSuite_treeNode' + nodeId;
			var folderImg = document.createElement('IMG');
			if(!noDrag)folderImg.onmousedown = this.__initializeDragProcess;
			if(!noChildren){
				DHTMLSuite.commonObj.addEvent(folderImg,'mousemove',function(e){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__moveDragableNodes(e,'folder'); });
			}
			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.__addEventElement(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.arrayOfDhtmlSuiteObjects[this.objectIndex].__moveDragableNodes);
		DHTMLSuite.commonObj.addEvent(document.documentElement,"mouseup",DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[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 : 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
				tmpObj.parentNode.removeChild(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;
		}	
	}	
	// }}}		
	,
	// {{{ __cancelSelectionEvent()
    /**
     * Cancel selection when drag is in process
     *
     * @private
     */		
	__cancelSelectionEvent : function()
	{		
		if(JSTreeObj.dragDropTimer<10)return true;
		return false;	
	}
	// }}}	

}
	
/*[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.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[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.arrayOfDhtmlSuiteObjects[ind].__onComplete(ajaxIndex,functionNameOnComplete); };	// Specify function that will be executed after file has been found
		this.ajaxObjects[ajaxIndex].onError = function(){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[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.arrayOfDhtmlSuiteObjects[' + ind + '].ajaxObjects[' + ajaxIndex + '])');
		}	
		
		setTimeout('DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[' + 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>).
* @version				1.0
* @version 1.0
* 
* @author	Alf Magne Kalleland(www.dhtmlgoodies.com)
**/

DHTMLSuite.dynamicContent = function()
{
	var enableCache;	// Cache enabled.
	var jsCache;
	var dynamicContent_ajaxObjects;
	var waitMessage;
	
	this.enableCache = true;
	this.jsCache = new Array();
	this.dynamicContent_ajaxObjects = new Array();
	this.waitMessage = 'İçerik Yükleniyor... Lütfen Bekleyin...';
	this.waitImage = 'images/yukleniyor.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.arrayOfDhtmlSuiteObjects.length;
	DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[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];
			this.__evaluateJs(document.getElementById(divId));	// Call private method which evaluates JS content
			this.__evaluateCss(document.getElementById(divId));	// Call private method which evaluates JS content		
			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="' + this.waitImage + '" border="0" alt=""></div>';
		}
		if(this.waitMessage){	// Wait message exists ?
			waitMessageToShow = waitMessageToShow + '<div style="text-align:center">' + this.waitMessage + '</div>';
		}		
		try{
			document.getElementById(divId).innerHTML = waitMessageToShow ;
		}catch(e){
			
		}		
		
		var ajaxIndex = this.dynamicContent_ajaxObjects.length;
		try{
			this.dynamicContent_ajaxObjects[ajaxIndex] = new sack();
		}catch(e){
			alert('Could not create ajax object. Please make sure that ajax.js is included');
		}
		this.dynamicContent_ajaxObjects[ajaxIndex].requestFile = url;	// Specifying which file to get

		
		this.dynamicContent_ajaxObjects[ajaxIndex].onCompletion = function(){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__ajax_showContent(divId,ajaxIndex,url,functionToCallOnLoaded); };	// Specify function that will be executed after file has been found
		this.dynamicContent_ajaxObjects[ajaxIndex].onError = function(){ DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[ind].__ajax_displayError(divId,ajaxIndex,url,functionToCallOnLoaded); };	// Specify function that will be executed after file has been found
		this.dynamicContent_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;		
	}
	// }}}
	,
	// {{{ __evaluateJs()
    /**
     * Evaluate Javascript in the inserted content
     *
     * @private
     */		
	__ajax_showContent :function(divId,ajaxIndex,url,functionToCallOnLoaded)
	{
		var obj = document.getElementById(divId);
		obj.innerHTML = this.dynamicContent_ajaxObjects[ajaxIndex].response;
		
		if(this.enableCache){	// Cache is enabled
			this.jsCache[url] = this.dynamicContent_ajaxObjects[ajaxIndex].response;	// Put content into cache
		}
		
		this.__evaluateJs(obj);	// Call private method which evaluates JS content
		this.__evaluateCss(obj);	// Call private method which evaluates JS content
		if(functionToCallOnLoaded)eval(functionToCallOnLoaded);
		this.dynamicContent_ajaxObjects[ajaxIndex] = null;	// Clear sack object
	}
	// }}}
	,
	// {{{ __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>';		
	}
	// }}}		
	,	
	// {{{ __evaluateJs()
    /**
     * Evaluate Javascript in the inserted content
     *
     * @private
     */	
	__evaluateJs : function(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);
	}
	// }}}
	,
	// {{{ __evaluateJs()
    /**
     *  "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)
	{
		var cssTags = obj.getElementsByTagName('STYLE');
		var head = document.getElementsByTagName('HEAD')[0];
		for(var no=0;no<cssTags.length;no++){
			head.appendChild(cssTags[no]);
		}	
	}
	
}





