/*                                                                  
* Copyright © 1999-2008 TeaLeaf Technology, Inc.  
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY TEALEAF ``AS IS'' 
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED.  
* IN NO EVENT SHALL TEALEAF BE LIABLE FOR ANY DIRECT, INDIRECT, 
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
* @fileoverview 
* This is the main UI Client Event Capture JavaScript file that is  
* used by other JavaScript to register their onload routines.
*
* @requires 
* TeaLeaf.js
* TeaLeafEvent.js
* TeaLeafClientCfg.js
*
* @version 2008.5.15.1
*                                                                   
*/
if(TeaLeaf.Client && TeaLeaf.Client.Configuration){
	
	TeaLeaf.Client.tlTimoutID = null;
	
	/**
    * Enable all event handlers specified in the configuration.
    * @param obj parameter that determines to enable handlers to the window or document object or both.
    * @requires
    * TeaLeafClientCfg.js 
    * @addon
    */            	                                           
    TeaLeaf.Client.tlEnableAllEventHandlers = function(obj) {         
        if(obj){
            if(obj == window){
                TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlWindowHandlers, true, "all");
            }
            else if(obj == document){
                TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlDocumentHandlers, true, "all");
            }
        } 
        else{
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlWindowHandlers, true, "all");
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlDocumentHandlers, true, "all");        
        }        
    }
	/**
    * Enable a specific event handler defined in the configuration.
    * @param obj parameter that determines to enable handlers to the window or document object.
    * @param domEventName name of the event to enable.
    * @requires
    * TeaLeafClientCfg.js 
    * @addon
    */            	                                               
    TeaLeaf.Client.tlEnableEventHandler = function(obj, domEventName) { 
        if(obj == window){  
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlWindowHandlers, true, domEventName); 
        }
        else{
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlDocumentHandlers, true, domEventName); 
        }        
    }
	/**
    * Disable all event handlers specified in the configuration.
    * @param obj parameter that determines to disable handlers to the window or document object or both.
    * @requires
    * TeaLeafClientCfg.js 
    * @addon
    */            	                                           
    TeaLeaf.Client.tlDisableAllEventHandlers = function(obj) { 
        if(obj){
            if(obj == window){
                TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlWindowHandlers, false, "all");
            }
            else if(obj == document){
                TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlDocumentHandlers, false, "all");
            }
        } 
        else{
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlWindowHandlers, false, "all");
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlDocumentHandlers, false, "all");        
        }        
    }
	/**
    * Disable a specific event handler defined in the configuration.
    * @param obj parameter that determines to disable handlers to the window or document object.
    * @param domEventName name of the event to enable.
    * @requires
    * TeaLeafClientCfg.js 
    * @addon
    */            	                                                   
    TeaLeaf.Client.tlDisableEventHandlers = function(obj, domEventName) { 
        if(obj == window){                
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlWindowHandlers, false, domEventName); 
        }
        else{
            TeaLeaf.Client.tlClientJSONCfgUtil(TeaLeaf.Client.Configuration.tlDocumentHandlers, false, domEventName); 
        }        
    }    
	/**
    * Utility that helps enabling or disabling of event handlers.
    * @param tlJSONConfig configuration array.
    * @param tlEnable enable (true or false flag).
    * @param domEventName event name to enable or disable.
    * @addon
    */            	                                                       
    TeaLeaf.Client.tlClientJSONCfgUtil = function(tlJSONConfig, tlEnable, domEventName) {         
        for(var i = 0; i<tlJSONConfig.length; i++){
            if(domEventName == "all"){
                tlJSONConfig[i].load = tlEnable;
            }
            else if (domEventName == tlJSONConfig[i].domevent){
                tlJSONConfig[i].load = tlEnable;
            }
        }  
    }  
	TeaLeaf.Client.tlHasUserMovement = false;
	/**
    * Detect user movement.
    *
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                           
	TeaLeaf.Client.tlUserMovement = function() {
		TeaLeaf.Client.tlHasUserMovement = true;
		TeaLeaf.Event.tlRemoveHandler(document, "mousemove", TeaLeaf.Client.tlUserMovement, false);
	}
	/**
    * Add a unique Id to a DOM element.
    * @param itemSource DOM element that needs an id.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                
    TeaLeaf.Client.tlAddIdToControl = function(itemSource) {  	    
	    if (itemSource.id != "" || itemSource.name != "") {
		    return;
	    }
	    var idTag = itemSource.tagName;

	    var thereYet = TeaLeaf.Client.Configuration.tlIdCounter[idTag];
	    if (thereYet == undefined)
		    TeaLeaf.Client.Configuration.tlIdCounter[idTag] = 0;

        var idElement = "_TL_" + idTag + "_"
            + TeaLeaf.Client.Configuration.tlIdCounter[idTag];
        var item  = document.getElementById(idElement);
        var baseId = idElement;
        
        if(item){
            //loop through to check if there are items with such ids
            while(document.getElementById("_TL_" + idTag + "_"
                + TeaLeaf.Client.Configuration.tlIdCounter[idTag]++));
        }
        
        itemSource.id = baseId;
        TeaLeaf.Client.Configuration.tlIdCounter[idTag]++;
	}  

	/**
    * Loops through a JSON array to find the elemement if exists.
    * @param name or id of element.
    * @param JSON.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                
	TeaLeaf.Client.tlFindinJSON = function(tlElement, tlJSON) {        
        var tlNameorId = TeaLeaf.Client.tlGetName(tlElement);
        if(tlNameorId){
            for(var i=0; i<tlJSON.length; i++){ 
                if(tlNameorId == tlJSON[i].tlfieldname){  
                    return tlJSON[i];
                }
            }
        }
    }

	/**
    * Check if element is silent.
    * @param name or id of element.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                
	TeaLeaf.Client.tlIsReplace = function(name) {
		//	Nothing there
		if( !name ) {
			return false;
		}
		//	If this an object
		if( typeof name == "object" ) {			
			if( name.TeaLeafReplace) { 	
 				return true;
			}		    
		}
		else{
		    var tlReplace = document.getElementById(name);  
		    if(tlReplace.TeaLeafReplace == true){
 		        return true;		    
		    }		    
		    if(!tlReplace){
		        tlReplace = document.getElementsByName(name);     
		        for(var i=0; i<tlSilent.length; i++){
		            if(tlReplace[i].TeaLeafReplace == true){
 		                return true;
		            }
		        }
		    }
		}
		
		if( name.type == "password" ) {
			return TeaLeaf.Client.Configuration.tlpassword == 2;
		}

		return false;
	}

	/**
    * Replace element with dummy value, needed in some cases
    * when there is client validation.
    * @param element.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlReplaceValue = function(name) {
	    var tlRepValue = TeaLeaf.Client.tlFindinJSON(name, TeaLeaf.Client.Configuration.tlFieldBlock);
	    if(tlRepValue && tlRepValue.eventvaluereplace.length>0){
	        return tlRepValue.eventvaluereplace;
	    }    
    }
    
	/**
    * Check if element is excluded from capture.
    * @param name or id of element.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlIsExcluded = function(name) {
		//	Nothing there
		if( !name ) {
			return false;
		}
		//	If this an object
		if( typeof name == "object" ) {			
			if( name.TeaLeafExclude ) {
				return true;
			}		    
		}
		else{
		    var tlExclude = document.getElementById(name);   		    
		    if(tlExclude){
		        if(tlExclude.TeaLeafExclude){   
		            return true;		    
		        }		       
		    }
		    else{
		        tlExclude = document.getElementsByName(name);     
		        if(tlExclude){
		            for(var i=0; i<tlExclude.length; i++){
		                if(tlExclude[i].TeaLeafExclude){
		                    return true;
		                }
		            }
		        }		    
		    }
		    return false;
		}
		
		if( name.type == "password" ) {
			return TeaLeaf.Client.Configuration.tlpassword == 2;
		}

		return false;
	}
	/**
    * Get the name from a DOM node.
    * @param theNode DOM element.
    * @addon
    */            	                                                                
	TeaLeaf.Client.tlGetName = function(theNode) {
		if( theNode == null ) {
			return null;
		}
		var		name = theNode.name;
		if( name && name != "" ) {
			return name;
		}
		var		id = theNode.id;
		if( id && id != "" ) {
			return id;
		}
		return null;
	}
	/**
    * Get event source DOM element.
    * @param theEvent DOM event.
    * @addon
    */            	                                                                
    TeaLeaf.Client.tlGetEventSource = function(theEvent) {
        var	itemSource = null;       
        if(theEvent){	
	        if( theEvent.srcElement ) {	//	MSFT
	            itemSource = theEvent.srcElement;
	        }
	        else {	//	Mozilla
	            itemSource = theEvent.target;
		        if( itemSource == null ) {
		            itemSource = theEvent.explicitOriginalTarget;			
			        if( itemSource == null ) {
			            itemSource = theEvent.originalTarget;
			        }
	    	    }
	        }
	        if(itemSource && (itemSource.name == null || itemSource.name == "")) {
	            //	If an Anchor or link, I can look info up in the list
		        if( itemSource.parentNode && itemSource.parentNode.tagName ) {
		            if( itemSource.parentNode.tagName == "A" ||
			            itemSource.parentNode.tagName == "LINK" ) {
				            itemSource = itemSource.parentNode;
			            }
		            }
	            }
	        }
	    return itemSource;
    }	
	/**
    * If we don't have an name, get the index from either the anchors
    * or the links collection.
    * @param theNode DOM element.
    * @param full XML format.
    * @addon
    */            	                                                                
	TeaLeaf.Client.tlGetAnchor = function(theNode, full) {
		if( theNode == null ) {
			return null;
		}
		if( theNode.name && theNode.name != "" ) {
			return null;
		}
		var		idx;
		for(idx = 0; idx < document.anchors.length; idx++) {
			if( document.anchors[idx] == theNode ) {
				if( full ) {
					return "<AnchorElement>" + idx + "</AnchorElement>\r\n";
				}
				else {
					return "Anchor-" + idx;
				}
			}
		}
		for(idx = 0; idx < document.links.length; idx++) {
			if( document.links[idx] == theNode ) {
				if( full ) {
					return "<LinkElement>" + idx + "</LinkElement>\r\n";
				}
				else {
					return "Link-" + idx;
				}
			}
		}	
		return null;
	}
	/**
    * If we don't have an name, get the index from either the anchors
    * or the links collection.
    * @param str XML string.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                	
	TeaLeaf.Event.tlFormatXMLName = function(str) {
		//	Nothing handed in
		if( ! str || str.length <= 0 )
			return null;

		var	rtn = "";
		if( ! TeaLeaf.Event.tlNameStartChar(str.charCodeAt(0)) ) {
			rtn = "_";
		}
		var	max = str.length;
		var	ind;
		for(ind = 0; ind < max; ind++) {
			if( TeaLeaf.Event.tlNameChar(str.charCodeAt(ind)) ) {
				rtn = rtn + str.charAt(ind);
			}
			else {
				rtn = rtn + "_";
			}
		}
		return rtn;
	}
	/**
	* Utility function to help format the XML.
    * @param chr character.
    * @addon
    */            	                                                                	
    TeaLeaf.Event.tlNameStartChar = function(chr) {
		//	":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] |
		//	[#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] |
		//	[#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] |
		//	[#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD]
		//	Note:  ":" was removed because it is only valid when a namespace
		//	is defined
		return (chr >= 0x41 && chr <= 0x5A) || chr == 0x5F ||
			(chr >= 0x61   && chr <= 0x7A)   || (chr >= 0xC0   && chr <= 0xD6)   ||
			(chr >= 0xD8   && chr <= 0xF6)   || (chr >= 0xF8   && chr <= 0x2FF)  ||
			(chr >= 0x370  && chr <= 0x37D)  || (chr >= 0x37F  && chr <= 0x1FFF) ||
			(chr >= 0x200C && chr <= 0x200D) || (chr >= 0x2070 && chr <= 0x218F) ||
			(chr >= 0x2C00 && chr <= 0x2FEF) || (chr >= 0x3001 && chr <= 0xD7FF) ||
			(chr >= 0xF900 && chr <= 0xFDCF) || (chr >= 0xFDF0 && chr <= 0xFFFD);
	}
	/**
	* Utility function to help format the XML.
    * @param chr character.
    * @addon
    */            	                                                                	
    TeaLeaf.Event.tlNameChar = function(chr) {
		//	NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
		return TeaLeaf.Event.tlNameStartChar(chr) || chr == 0x2D || chr == 0x2E ||
			(chr >= 0x30 && chr <= 0x39) || chr == 0xB7  ||
			(chr >= 0x0300 && chr <= 0x036F) || (chr >= 0x203F && chr <= 0x2040);
	}

	TeaLeaf.Client.tlQueuedKeys = "";

	/**
    * Queues the keys
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlQueueKey = function(theEvent) {
        TeaLeaf.Client.tlSendResize();
        TeaLeaf.Client.tlSendScroll();
		if( ! theEvent ) {
			theEvent = window.event;
		}
		if( theEvent.keyCode < 0x20 ) {
			return;
		}
		//	Residual keys to send in?  Save the source for next time around
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		if( ! itemSource ) {
			return;
		}
		//	Do we need to set the onFocus time?
		if( ! itemSource.TeaLeafFocusTime ) {
			itemSource.TeaLeafFocusTime = new Date();
		}
		if( TeaLeaf.Client.tlQueuedKeySource ) {
			if( TeaLeaf.Client.tlQueuedKeySource != itemSource ) {
				if( TeaLeaf.Client.tlQueuedKeys && TeaLeaf.Client.tlQueuedKeys.length > 0 )
                    TeaLeaf.Client.tlSendKeys();
				TeaLeaf.Client.tlQueuedKeySource = itemSource;
			}
		}
		else {
			TeaLeaf.Client.tlQueuedKeySource = itemSource;
		}
		//	Get the name/anchor where the key happened.  If both are null,
		//	don't worry about logging
		var	name  = TeaLeaf.Client.tlGetName(itemSource);

		var	lev = null;
		if( ! name ) {
			lev = TeaLeaf.Client.tlGetAnchor(itemSource, false);
			if( ! lev ) {
				TeaLeaf.Client.tlQueuedKeySource = null;
				return;
			}
		}
		else {
			if( TeaLeaf.Client.tlIsReplace(itemSource) ) {
				TeaLeaf.Client.tlQueuedKeysCount++;
				return;
			}
			if( TeaLeaf.Client.tlIsExcluded(itemSource) ) {
			    TeaLeaf.Client.tlQueuedKeys=null;
				TeaLeaf.Client.tlQueuedKeysCount++;
				return;
			}
		}
		//	Put in the seperator if we need it
		if( TeaLeaf.Client.tlQueuedKeys ) {
			if( TeaLeaf.Client.tlQueuedKeys.length > 0 ) {
				TeaLeaf.Client.tlQueuedKeys = TeaLeaf.Client.tlQueuedKeys + ";";
			}
		}
		//	build the string
		if( theEvent.ctrlKey ) {
			if( TeaLeaf.Client.tlQueuedKeys ) {
				TeaLeaf.Client.tlQueuedKeys = TeaLeaf.Client.tlQueuedKeys + "ctrl-";
			}
			else {
				TeaLeaf.Client.tlQueuedKeys = "ctrl-";
			}
		}
		if( theEvent.altKey ) {
			if( TeaLeaf.Client.tlQueuedKeys ) {
				TeaLeaf.Client.tlQueuedKeys = TeaLeaf.Client.tlQueuedKeys + "alt-";
			}
			else {
				TeaLeaf.Client.tlQueuedKeys = "alt-";
			}
		}
		if( theEvent.shiftKey ) {
			if( TeaLeaf.Client.tlQueuedKeys ) {
				TeaLeaf.Client.tlQueuedKeys = TeaLeaf.Client.tlQueuedKeys + "shift-";
			}
			else {
				TeaLeaf.Client.tlQueuedKeys = "shift-";
			}
		}
		TeaLeaf.Client.tlQueuedKeys = TeaLeaf.Client.tlQueuedKeys + theEvent.keyCode;
	}
	/**
    * Send the keys.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlSendKeys = function() {	
		if( ! TeaLeaf.Client.tlQueuedKeySource ||
			( ! TeaLeaf.Client.tlQueuedKeys && ! TeaLeaf.Client.tlQueuedKeysCount ) ) {
				return;
		}
		//	Save the values to temp variables and null out the
		//	queue variables
		var	qSource = TeaLeaf.Client.tlQueuedKeySource;
		var	qKeys   = TeaLeaf.Client.tlQueuedKeys;
		var	qCount  = TeaLeaf.Client.tlQueuedKeysCount;
		TeaLeaf.Client.tlQueuedKeySource = null;
		TeaLeaf.Client.tlQueuedKeys      = "";
		TeaLeaf.Client.tlQueuedKeysCount = 0; 
    
        var tlreplace = false; 
		if( TeaLeaf.Client.tlIsReplace(qSource) ) {		
			tlreplace = true;
			return;
		}
		var	excluded = false;
 
		if( TeaLeaf.Client.tlIsExcluded(qSource) ) {

			excluded = true;
			qKeys = null;
		}
		//	Get the name/anchor where the key happened.  If both are null,
		//	don't worry about logging
		var	name  = TeaLeaf.Client.tlGetName(qSource);
		var	lev = null;
		if( name == null ) {
			lev = TeaLeaf.Client.tlGetAnchor(qSource, false);
			if( lev == null ) {
				return;
			}
		}
		else {
			if( TeaLeaf.Client.tlIsExcluded(name) ) {
				return null;
			}
		}
		//	The Reporting Event
		var	tlevt = new TeaLeaf.Event("GUI", "KeyUp");
        var tlAddNameValueArray = new Array("Name", qSource.name,
			                                "Id", qSource.id,
			                                "Lev", lev,
			                                "ElementType", qSource.type,
			                                "TagName", qSource.tagName,
			                                "KeyCount", qCount);
        tlevt.tlAddData(tlAddNameValueArray);

		if(excluded) {
		    var tlAddNameValueArrayExcluded = new Array("Excluded", "true");
            tlevt.tlAddData(tlAddNameValueArrayExcluded);
		}
		else if(tlreplace){
			
			var tlRepValue = TeaLeaf.Client.tlGetReplaceValue(qSource);			
			var tlAddNameValueArrayReplaceName = new Array("ValueIn", name,
				                                          name,   tlRepValue,
				                                          "KeyCode", qKeys);                                          
			tlevt.tlAddData(tlAddNameValueArrayReplaceName);
		}
		else {
			var	tlManualName = TeaLeaf.Event.tlFormatXMLName(name);			
			var tlAddNameValueArrayManualName = new Array("ValueIn", tlManualName,
				                                          tlManualName,   qSource.value,
				                                          "KeyCode", qKeys);                                          
			tlevt.tlAddData(tlAddNameValueArrayManualName);
		}
		//	Now send the data in
		tlevt.tlSend();
	}
	/**
    * Send resize event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlSendResize = function() {	
		if( ! TeaLeaf.Client.ResizeClientX && ! TeaLeaf.Client.ResizeClientY ) {
			return;
		}
		var	tlevt = new TeaLeaf.Event("GUI", "Resize");
        var tlAddNameValueArray = new Array("ClientX", TeaLeaf.Client.ResizeClientX,
			                                "ClientY", TeaLeaf.Client.ResizeClientY,
			                                "ScreenX", TeaLeaf.Client.ResizeScreenX,
			                                "ScreenY", TeaLeaf.Client.ResizeScreenY);
        tlevt.tlAddData(tlAddNameValueArray);
		TeaLeaf.Client.ResizeClientX = null;
		TeaLeaf.Client.ResizeClientY = null;
		TeaLeaf.Client.ResizeScreenX = null;
		TeaLeaf.Client.ResizeScreenY = null;
		//	Now send the data in
		tlevt.tlSend();
	}
	
	/**
    * Queue scroll event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	
    TeaLeaf.Client.tlQueueScroll = function(tlEvent) {

	    TeaLeaf.Client.tlSendKeys();
	    TeaLeaf.Client.tlSendResize();

	    if( ! tlEvent ) {
		    tlEvent = window.event;
	    }
	    
	    if( tlEvent.clientX ) {
		    //	IE
		    TeaLeaf.Client.ScrollClientX = tlEvent.clientX;
		    TeaLeaf.Client.ScrollClientY = tlEvent.clientY;
		    TeaLeaf.Client.ScrollScreenX = tlEvent.screenX;
		    TeaLeaf.Client.ScrollScreenY = tlEvent.screenY;
	    }
	    else {
		    //	Other
		    TeaLeaf.Client.ScrollHeight = tlEvent.target.scrollHeight;
		    TeaLeaf.Client.ScrollWidth  = tlEvent.target.scrollWidth;
		    TeaLeaf.Client.ScrollTop    = tlEvent.target.scrollTop;
		    TeaLeaf.Client.ScrollLeft   = tlEvent.target.scrollLeft;
	    }
    }

	/**
    * Send scroll event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlSendScroll = function() {	
		if( ! TeaLeaf.Client.ScrollClientX && ! TeaLeaf.Client.ScrollHeight ) {
			return;
		}
		var	tlevt = new TeaLeaf.Event("GUI", "Scroll");
        var tlAddNameValueArray = new Array("ClientX",      TeaLeaf.Client.ScrollClientX,
			                                "ClientY",      TeaLeaf.Client.ScrollClientY,
			                                "ScreenX",      TeaLeaf.Client.ScrollScreenX,
			                                "ScreenY",      TeaLeaf.Client.ScrollScreenY,
			                                "ScrollHeight", TeaLeaf.Client.ScrollHeight,
			                                "ScrollWidth",  TeaLeaf.Client.ScrollWidth,
			                                "ScrollTop",    TeaLeaf.Client.ScrollTop,
			                                "ScrollLeft",   TeaLeaf.Client.ScrollLeft);	
		tlevt.tlAddData(tlAddNameValueArray);	
		TeaLeaf.Client.ScrollClientX = null;
		TeaLeaf.Client.ScrollClientY = null;
		TeaLeaf.Client.ScrollScreenX = null;
		TeaLeaf.Client.ScrollScreenY = null;
		TeaLeaf.Client.ScrollHeight  = null;
		TeaLeaf.Client.ScrollWidth   = null;
		TeaLeaf.Client.ScrollTop     = null;
		TeaLeaf.Client.ScrollLeft    = null;
		//	Now send the data in
		tlevt.tlSend();
	}
	/**
    * Add an event.
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                	
	TeaLeaf.Client.tlAddEvent = function(theEvent) {
		//	Send in any queued keys and resizes		
        TeaLeaf.Client.tlSendKeys();
        TeaLeaf.Client.tlSendResize();
        TeaLeaf.Client.tlSendScroll();		
		//	Check for a null
		if( ! theEvent ) {
			theEvent = window.event;
		}	
		//	Get the target - If we have no way to identify then discard
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		
		if( ! itemSource ) {
			return;
		}
		//	Do we need to set the onFocus time?
		if( ! itemSource.TeaLeafFocusTime ) {
			if( theEvent.type == "keyup" || theEvent.type == "change" ||
				theEvent.type == "click" || theEvent.type == "dblclick" ||
				theEvent.type == "mousedown" ) {
					itemSource.TeaLeafFocusTime = new Date();
			}
		}
		
		//	Ignore flash for blur
		if( theEvent.type == "blur" && itemSource.type == "application/x-shockwave-flash" ) {
			return;
		}
		if(TeaLeaf.Client.Configuration.tlassignTLID){
		    //	If there is no id for this control, invent one        
		    if( !itemSource.id && !itemSource.name) {
   			    TeaLeaf.Client.tlAddIdToControl(itemSource);
		    }
		}
		
		//	Get Id information
		var	name  = TeaLeaf.Client.tlGetName(itemSource);
		var	lev;
		if( name == null ) {
			lev = TeaLeaf.Client.tlGetAnchor(itemSource, true);
			//	Nothing worth logging
			if( lev == null ) {
				return;
			}
		}
		else {
			lev = null;
		}
		//	We have no name - forget it.
		if( name == null && lev == null ) {
			return;
		}
		if(theEvent.type == "click"){
		    TeaLeaf.Event.Configuration.tlidoflastvisitedcontrol = itemSource.id;
		}
		//	The Reporting Event
		var	tlevt = new TeaLeaf.Event("GUI", theEvent.type);
		//	Start the node tag
		
		var tlAddNameValueArray = new Array("Name", itemSource.name,
			                                "Id", itemSource.id,
			                                "Lev", lev,
			                                "ElementType", itemSource.type,
			                                "TagName", itemSource.tagName,
			                                "AltKey", theEvent.altKey?"True":null,
			                                "CtrlKey", theEvent.ctrlKey?"True":null,
			                                "ShiftKey", theEvent.shiftKey?"True":null,
			                                "NodeName", theEvent.nodeName,
			                                "NodeValue", theEvent.nodeValue);
        tlevt.tlAddData(tlAddNameValueArray);

		if( theEvent.type == "blur" && itemSource.TeaLeafFocusTime ) {
			var	now = new Date();
			var tlAddNameValueArrayTimeIn = new Array("TimeInControl", TeaLeaf.Event.tlDateDiff(now, itemSource.TeaLeafFocusTime));
            tlevt.tlAddData(tlAddNameValueArrayTimeIn);
			itemSource.TeaLeafFocusTime = null;
		}
		if(theEvent.type == "change" && itemSource.TeaLeafReplace){
		    var tlRepValue = TeaLeaf.Client.tlReplaceValue(itemSource);		    		    
		    var tlAddNameValueArrayRepalceName = new Array("ValueIn", name, 
		                                                  name, tlRepValue,
				                                          "KeyCode", theEvent.keyCode); 				                                              
            tlevt.tlAddData(tlAddNameValueArrayRepalceName);		
		}		
        else{
            var	tlManualName = TeaLeaf.Event.tlFormatXMLName(name);
            var tlAddNameValueArrayManualName = new Array("ValueIn", tlManualName, 
                                                           tlManualName, itemSource.value,
				                                          "KeyCode", theEvent.keyCode);   
            tlevt.tlAddData(tlAddNameValueArrayManualName);		
        }
		tlevt.tlSend();
	}	
	/**
    * Send all the form field values with the form submit.
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlHandleFormSubmit = function(theEvent) {
		//	Log that we did a submit - this will be send in the unload
		TeaLeaf.Client.Configuration.tlactiontype = "Submit";	
		//	Send in any queued keys and resizes
        TeaLeaf.Client.tlSendKeys();
        TeaLeaf.Client.tlSendResize();
        TeaLeaf.Client.tlSendScroll();

		//	Check for a null
		if( ! theEvent ) {
			theEvent = window.event;
		}
		//	Get the target - If we have no way to identify then discard
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		if( ! itemSource ) {
			return;
		}
		//	If item Source.name is not definded, let's make one up
		var	i;
		if( ! itemSource.name ) {
			var	forms = document.forms;
			for(i = 0; i < forms.length; i++) {
				if( forms[i] == itemSource ) {
					itemSource.name = "Ordinal-" + i;
					break;
				}
			}
		}
		//	We have no name - forget it.
		if( ! itemSource.name ) {
			return;
		}
		//	Is this one of our silent controls
        if( TeaLeaf.Client.tlIsReplace(itemSource) ) {
            var tlRepValue = TeaLeaf.Client.tlGetReplaceValue(itemSource);			
            var name = TeaLeaf.Client.tlGetName(itemSource);
            var tlAddNameValueArrayReplaceName = new Array("ValueIn", name,
                name,   tlRepValue); 

            tlevt.tlAddData(tlAddNameValueArrayReplaceName);      
        }
		//	The Reporting Event
		var	tlevt = new TeaLeaf.Event("GUI", theEvent.type);
		//	Start the node tag
        var tlAddNameValueArray = new Array("Name", itemSource.name,
			                                "Id", itemSource.id,
			                                "ElementType", itemSource.type,
			                                "TagName", itemSource.tagName,
			                                "AltKey", theEvent.altKey?"True":null,
			                                "CtrlKey", theEvent.ctrlKey?"True":null,
			                                "ShiftKey", theEvent.shiftKey?"True":null,
			                                "NodeName", theEvent.nodeName,
			                                "NodeValue", theEvent.nodeValue,
			                                "VisitOrder", TeaLeaf.Client.Configuration.tlvisitorder);
        tlevt.tlAddData(tlAddNameValueArray);
		var	children = itemSource.getElementsByTagName("INPUT");
		var tlAddNameValueArrayInputFieldCount = new Array("InputFieldCount", children.length);
        tlevt.tlAddData(tlAddNameValueArrayInputFieldCount);
		tlevt.tlPushXML("InputFields");	
		//	Do through the children
		for(i = 0; i < children.length; i++) {
			var	child = children[i];
			//	No name, skip
			if( ! child.name ) {
				continue;
			}
			//	Put the field tag in
			tlevt.tlPushXML("Field"+i);
            var tlAddNameValueArrayNode = new Array("Name", child.name,
				                                    "Id", child.id,
				                                    "ElementType", child.type,
				                                    "TagName", child.tagName);
            tlevt.tlAddData(tlAddNameValueArrayNode);
				
			if( TeaLeaf.Client.tlIsExcluded(name) ) {
			    var tlAddNameValueArrayExcluded = new Array("Excluded", "true");
			    tlevt.tlAddData(tlAddNameValueArrayExcluded);
			}
			//	Is this one of our silent controls
			else if( TeaLeaf.Client.tlIsReplace(child.name) ) {
                var tlRepValue = TeaLeaf.Client.tlGetReplaceValue(child);			
                var name = TeaLeaf.Client.tlGetName(child);
                var tlAddNameValueArrayReplaceName = new Array("ValueIn", name,
                        name,   tlRepValue); 

                tlevt.tlAddData(tlAddNameValueArrayReplaceName);      
			}
			else {
				var	tlManualName = TeaLeaf.Event.tlFormatXMLName(child.name);
			    var tlAddNameValueArrayManualName = new Array("ValueIn", tlManualName, tlManualName, child.value);
                tlevt.tlAddData(tlAddNameValueArrayManualName);
			}
			tlevt.tlPopXML();
		}
		tlevt.tlPopXML();
		tlevt.tlSend();
		TeaLeaf.Client.Configuration.tlvisitorder = "";
	}
	/**
    * Handle the resize event.
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlQueueResize = function(tlEvent) {
		TeaLeaf.Client.tlSendKeys();
		TeaLeaf.Client.tlSendScroll();
		if( ! tlEvent ) {
			tlEvent = window.event;
		}
		if( tlEvent.clientX) {
			TeaLeaf.ResizeClientX = tlEvent.clientX;
			TeaLeaf.ResizeClientY = tlEvent.clientY;
			TeaLeaf.ResizeScreenX = tlEvent.screenX;
			TeaLeaf.ResizeScreenY = tlEvent.screenY;
		}
		else {
			TeaLeaf.ResizeClientX = tlEvent.target.width;
			TeaLeaf.ResizeClientY = tlEvent.target.height;
		}
	}
	/**
    * Handle the form reset event.
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlHandleFormReset = function(theEvent) {
		//	Send in any queued keys and resizes
		TeaLeaf.Client.tlSendKeys();
		TeaLeaf.Client.tlSendResize();
		TeaLeaf.Client.tlSendScroll();
		//	Check for a null
		if( ! theEvent ) {
			theEvent = window.event;
		}
		//	Get the target - If we have no way to identify then discard
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		if( ! itemSource ) {
			return;
		}
		//	If item Source.name is not definded, let's make one up
		var	i;
		if( ! itemSource.name ) {
			var	forms = document.forms;
			for(i = 0; i < forms.length; i++) {
				if( forms[i] == itemSource ) {
					itemSource.name = "Ordinal-" + i;
					break;
				}
			}
		}
		//	We have no name - forget it.
		if( name == null ) {
			return;
		}
		//	Is this one of our silent controls
		if( TeaLeaf.Client.tlIsReplace(itemSource) ) {
		    var tlRepValue = TeaLeaf.Client.tlGetReplaceValue(itemSource);			
            var tlname = TeaLeaf.Client.tlGetName(itemSource);
            var tlAddNameValueArrayReplaceName = new Array("ValueIn", tlname,
                                                tlname,   tlRepValue); 
            tlevt.tlAddData(tlAddNameValueArrayReplaceName);

		}
		//	The Reporting Event
		var	tlevt = new TeaLeaf.Event("GUI", theEvent.type);
		//	Start the node tag
        var tlAddNameValueArray = new Array("Name", itemSource.name,
			                                "Id", itemSource.id,
			                                "ElementType", itemSource.type,
			                                "TagName", itemSource.tagName,
			                                "AltKey", theEvent.altKey?"True":null,
			                                "CtrlKey", theEvent.ctrlKey?"True":null,
			                                "ShiftKey", theEvent.shiftKey?"True":null,
			                                "NodeName", theEvent.nodeName,
			                                "NodeValue", theEvent.nodeValue,
			                                "VisitOrder", TeaLeaf.Client.Configuration.tlvisitorder);
        tlevt.tlAddData(tlAddNameValueArray);
		tlevt.tlSend();
		TeaLeaf.tlVisitOrder = "";
	}	
	/**
    * Handle the before unload event and flush the queue of events client events captured.
    *
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlBeforeUnload = function() {
        if(TeaLeaf.Client.Configuration.tlbeforeunloadflag == true){ 
            TeaLeaf.Event.Configuration.tllastdwelltime = new Date();
            TeaLeaf.Client.Configuration.tlunloadflag = false;   
		    //	Send in the notice
		    var	tlevt = new TeaLeaf.Event("PERFORMANCE", "BeforeUnload");	
		    TeaLeaf.Event.SetType = tlevt.EventType;

		    if(TeaLeaf.Event.SetSubType == ""){
                TeaLeaf.Event.SetSubType = tlevt.EventSubType;
            }
            else{
                TeaLeaf.Event.SetSubType += "; " + tlevt.EventSubType;
            }                    
            TeaLeaf.Event.Configuration.tlbeforeunloadflag = true;
            var tlAddNameValueArray = new Array("MouseMove", TeaLeaf.Client.tlHasUserMovement?"TRUE":"FALSE",
		                                        "Action", TeaLeaf.Client.Configuration.tlactiontype, 
		                                        "VisitOrder", TeaLeaf.Client.Configuration.tlvisitorder);          
            tlevt.tlAddData(tlAddNameValueArray);        		
		    tlevt.tlSend();
	
		    TeaLeaf.Event.tlFlushQueue(true);
		    TeaLeaf.Client.Configuration.tlvisitorder = "";
		    TeaLeaf.Client.tlDetachFromAllControls();
		}
	}
	/**
    * Handle the unload event and flush the queue of events client events captured.
    *
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                				
	TeaLeaf.Client.tlUnload = function(){
        if( TeaLeaf.Client.Configuration.tlunloadflag ){         
            TeaLeaf.Event.Configuration.tllastdwelltime = new Date();
            TeaLeaf.Client.Configuration.tlbeforeunloadflag = false;

		    //	Send in the notice
		    var	tlevt = new TeaLeaf.Event("PERFORMANCE", "Unload");
		    TeaLeaf.Event.SetType = tlevt.EventType;
		    
		    if(TeaLeaf.Event.SetSubType == ""){
                TeaLeaf.Event.SetSubType = tlevt.EventSubType;
            }
            else{
                TeaLeaf.Event.SetSubType += "; " + tlevt.EventSubType;
            }
            var tlAddNameValueArray = new Array("MouseMove", TeaLeaf.Client.tlHasUserMovement?"TRUE":"FALSE",
		                                        "Action", TeaLeaf.Client.Configuration.tlactiontype, 
		                                        "VisitOrder", TeaLeaf.Client.Configuration.tlvisitorder);
            tlevt.tlAddData(tlAddNameValueArray);
		    tlevt.tlSend();
		    TeaLeaf.Event.tlFlushQueue(true);
		    TeaLeaf.Client.Configuration.tlvisitorder = "";
		    TeaLeaf.Client.tlDetachFromAllControls();
        }
	}
	/**
    * Attach listeners to all controls including controls in frames.
    *
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlAttachToAllControls = function() {
        TeaLeaf.Client.tlMarkBlocked();
		TeaLeaf.Client.Configuration.tlcontrolsattached = true;
		//	Attach to the main window
		TeaLeaf.Client.tlAttachToControls(window);
		//	Attach to the frame controls
		var	ind;
		for(ind = 0; ind < window.frames.length; ind++) {
			var	w = window.frames[ind];
			TeaLeaf.Client.tlAttachToControls(w);
		}
	}
	/**
    * Attach listeners to controls based on the configuration. It also attaches 
    * 'beforeunload' and 'unload' handlers.
    * @param win window object.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlAttachToControls = function(win) {
        TeaLeaf.Event.tlAddHandler(win, "beforeunload", eval(TeaLeaf.Client.tlBeforeUnload), false);
        TeaLeaf.Event.tlAddHandler(win, "unload", eval(TeaLeaf.Client.tlUnload), false);
		//	Attach to all listeners for all the window and document
		//	controls.
        var	handlers = TeaLeaf.Client.Configuration.tlWindowHandlers;
        for(var i=0; i<handlers.length; i++) {
            if(handlers[i].load == true){
			    var	func = eval(handlers[i].tlhandler);
        	    TeaLeaf.Event.tlAddHandler(win, handlers[i].domevent, func, false);
        	}
        }
        handlers = TeaLeaf.Client.Configuration.tlDocumentHandlers;
        for(var i=0; i<handlers.length; i++) {
            if(handlers[i].load == true){
			    var	func = eval(handlers[i].tlhandler);
        	    TeaLeaf.Event.tlAddHandler(win.document, handlers[i].domevent, func, false);
        	}
        }
		//	Look for the individual controls
        TeaLeaf.Client.tlCheckIndControls(win);
	}
	/**
    * Check if a handler is attached to a control, otherwhise,
    * if the control is INPUT or SELECT attach focus, blur and change 
    * @param control control to check.
    * @requires 
    * TeaLeafEvent.js
    * @addon
    */            	                                                                				
	TeaLeaf.Client.tlCheckAttach = function(control) {	
		//	Already got this control
		if( control.TeaLeaf ) {
			return;
		}
		//	Double check we have an INPUT or SELECT.  If so, attach
		//	for focus, blur and change
		if( control.tagName == "INPUT" || control.tagName == "SELECT" ) {
			if( ! control.TeaLeaf && !control.TeaLeafExclude) {
				if( TeaLeaf.Client.Configuration.tlsendfocus ) {
                    TeaLeaf.Event.tlAddHandler(control, 'focus',  TeaLeaf.Client.tlSetFocusTime, false);
				}				
				if( TeaLeaf.Client.Configuration.tlsendblur ) {
                        TeaLeaf.Event.tlAddHandler(control, 'blur',   TeaLeaf.Client.tlHandleBlur, false);
				}
				TeaLeaf.Event.tlAddHandler(control, 'change', TeaLeaf.Client.tlAddEvent, false);
				
				control.TeaLeaf = true;				
			}
		}
		if(TeaLeaf.Client.Configuration.tlassignTLID) {
			if( !control.id && !control.name) {
				TeaLeaf.Client.tlAddIdToControl(control);
			}
		}
	}
	/**
    * Attach to INPUT and SELECT. 
    * @param win window object.
    * @addon
    */            	                                                                					
	TeaLeaf.Client.tlCheckIndControls = function(win) {
	    if(win.document){  
		    var items = win.document.getElementsByTagName("INPUT");				    
		    for(var i = 0; i < items.length; i++) {			
			    TeaLeaf.Client.tlCheckAttach(items[i]);
		    }	
		    items = win.document.getElementsByTagName("SELECT");
		    for(var i = 0; i < items.length; i++) {
			    TeaLeaf.Client.tlCheckAttach(items[i]);
		    }
		    items = win.document.getElementsByTagName("BODY"); 
		    if(items.length>0){		
		        items = items[0].getElementsByTagName("*");		       
		        for(var i = 0; i < items.length; i++) {
			        TeaLeaf.Client.tlCheckAttach(items[i]);
		        }
		    }
		}
	}
	/**
    * Handle focus event.
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                						
	TeaLeaf.Client.tlSetFocusTime = function(theEvent) {
		//	Check for a null
		if( ! theEvent ) {
			theEvent = window.event;
		}
		//	We need the item source.  Ignore flash
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		if( ! itemSource || itemSource.type == "application/x-shockwave-flash" ) {
			return;
		}
		//	Get the target - If we have no way to identify then discard
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		if( ! itemSource ) {
			return;
		}
		if( ! itemSource.TeaLeafFocusTime ) {
			itemSource.TeaLeafFocusTime = new Date();
		}
		//	If we are sending the focus event, then send it!
		if(TeaLeaf.Client.Configuration.tlsendfocus ) {
			TeaLeaf.Client.tlAddEvent(theEvent);
		}
	}	
	/**
    * Handle blur event.
    * @param theEvent DOM event.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                						
	TeaLeaf.Client.tlHandleBlur = function(theEvent) {
		//	Check for a null
		if( ! theEvent ) {
			theEvent = window.event;
		}
		//	We need the item source.  Ignore flash
		var	itemSource = TeaLeaf.Client.tlGetEventSource(theEvent);
		if( ! itemSource || itemSource.type == "application/x-shockwave-flash" ) {
			return;
		}
		TeaLeaf.Client.tlEndVisit(itemSource);
		TeaLeaf.Event.Configuration.tlidoflastvisitedcontrol = itemSource.id;
		//	Send the event?
		if( TeaLeaf.Client.Configuration.tlsendblur ) {
			TeaLeaf.Client.tlAddEvent(theEvent);
		}
	}
	/**
    * Last element visited.
    * @param itemSource DOM element.
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                						
	TeaLeaf.Client.tlEndVisit = function(itemSource) {
		if( itemSource.TeaLeafFocusTime ) {
			var name = TeaLeaf.Client.tlGetName(itemSource);
			if( ! name ) {
				name = TeaLeaf.Client.tlGetAnchor(itemSource, false);
				if( name ) {
					name = "LEVEL" + name;
				}
				else {
					name = "unnamed";
				}
			}
			var diff = TeaLeaf.Event.tlDateDiff(itemSource.TeaLeafFocusTime, new Date());
			var entry = name + ':' + diff;

			if( TeaLeaf.Client.Configuration.tlvisitorder.length > 0 )
				TeaLeaf.Client.Configuration.tlvisitorder = TeaLeaf.Client.Configuration.tlvisitorder + ";" + entry;
			else
				TeaLeaf.Client.Configuration.tlvisitorder = entry;
		}
	}
	/**
    * Detach from all controls including frames.
    *
    * @requires 
    * TeaLeafClientCfg.js
    * @addon
    */            	                                                                						
	TeaLeaf.Client.tlDetachFromAllControls = function() {
		//	Mark as not attached
		TeaLeaf.Client.Configuration.tlcontrolsattached = false;

		//	Attach to this window
		TeaLeaf.Client.tlDetachFromControls(window);

		//	Do the frames
		var	ind;
		for(ind = 0; ind < window.frames.length; ind++) {
			var	w = window.frames[ind];
			TeaLeaf.Client.tlDetachFromControls(w);
		}
	}
	/**
    * Detach listeners to controls based on the configuration. 
    * @param win window object.
    * @requires 
    * TeaLeafClientCfg.js
    * TeaLeafEvent.js
    * @addon
    */            	                                                                			
	TeaLeaf.Client.tlDetachFromControls = function(win) {
        var	handlers = TeaLeaf.Client.Configuration.tlWindowHandlers;
        for(var i=0; i<handlers.length; i++) {
			var	func = eval(handlers[i].tlhandler);
        	TeaLeaf.Event.tlRemoveHandler(win, handlers[i].domevent, func, false);
        }
        handlers = TeaLeaf.Client.Configuration.tlDocumentHandlers;
        for(var i=0; i<handlers.length; i++) {
			var	func = eval(handlers[i].tlhandler);
        	TeaLeaf.Event.tlRemoveHandler(win.document, handlers[i].domevent, func, false);
		}

		//	Detach from Individual Items
		var	items = win.document.getElementsByTagName("INPUT");
		var	i;
		for(i = 0; i < items.length; i++) {
			TeaLeaf.Event.tlRemoveHandler(items[i], 'change', TeaLeaf.Client.tlAddEvent, false);
			items[i].TeaLeaf = false;
		}
		items = win.document.getElementsByTagName("SELECT");
		for(i = 0; i < items.length; i++) {
			TeaLeaf.Event.tlRemoveHandler(items[i], 'change', TeaLeaf.Client.tlAddEvent, false);
			items[i].TeaLeaf = false;
		}
  }
  /**
  * Attach a listener to a specific control. 
  * @param domelement DOM element.
  * @param eventtype TeaLeaf Event type.
  * @param eventHandler Event handler.
  * @requires 
  * TeaLeafEvent.js
  * @addon
  */            	                                                                			  
  TeaLeaf.Client.tlAttachToControl = function(domelement, eventtype, eventHandler) {
    if(eventHandler){
        TeaLeaf.Event.tlAddHandler(domelement, eventtype, eventHandler, false);
    }
    else{
        TeaLeaf.Event.tlAddHandler(domelement, eventtype, eval(TeaLeaf.Client.tlAddEvent), false);
    }
  }
  /**
  * Detach a listener to a specific control. 
  * @param domelement DOM element.
  * @param eventtype TeaLeaf Event type.
  * @param eventHandler Event handler.
  * @requires 
  * TeaLeafEvent.js
  * @addon
  */            	                                                                			  
  TeaLeaf.Client.tlDetachFromControl = function(domelement, eventtype, eventHandler) {
    if(eventHandler){
        TeaLeaf.Event.tlRemoveHandler(domelement, eventtype, eventHandler, false);
    }
    else{
        TeaLeaf.Event.tlRemoveHandler(domelement, eventtype, eval(TeaLeaf.Client.tlAddEvent), false);
    }
  }
  /**
  * Mark the blocked fields based on the configuration. 
  *
  * @requires 
  * TeaLeafClientCfg.js
  * @addon
  */            	                                                                			  
  TeaLeaf.Client.tlMarkBlocked = function() {
		//	Got through all the input fields and see which ones
		//	should be blocked.  First build an associated array
		//	of the ones to be blocked, then check       
		var	tlNameList = document.getElementsByTagName("INPUT");
		
		for(var i = 0; i < tlNameList.length; i++) {
		    for(j = 0; j < TeaLeaf.Client.Configuration.tlFieldBlock.length; j++) { 
		                  
                var	tlBListName  = TeaLeaf.Client.Configuration.tlFieldBlock[j].tlfieldname;
                var tlItem = tlNameList[i];
                var tlItemId;
                var tlItemName;
                if(tlItem.id){
                    tlItemId = tlItem.id;
                }
                if(tlItem.name){
                    tlItemName = tlItem.name;
                }
                
                if(TeaLeaf.Client.Configuration.tlFieldBlock[j].caseinsensitive){ 
			        if(tlBListName){   
	 			        tlBListName =  tlBListName.toLowerCase();
			        }
                    if(tlItemId){
				        tlItemId = tlItemId.toLowerCase();
			        }   
                   	if(tlItemName){ 
				        tlItemName = tlItemName.toLowerCase();
			        }   
                }
              
                if(tlBListName == tlItemId || tlBListName == tlItemName){
                    if(TeaLeaf.Client.Configuration.tlFieldBlock[j].eventnovalue){                    
                        tlItem.TeaLeafExclude = true;
                    }
                    else if (TeaLeaf.Client.Configuration.tlFieldBlock[j].eventvaluereplace.length >0 ){
                        tlItem.TeaLeafReplace = true;
                    }
                }
            }
        }
	}

  /**
  * Scan the DOM based on a timer set in the configuration and attach
  * to controls that might have been rendered due to a DOM update. 
  *
  * @requires 
  * TeaLeafClientCfg.js
  * @addon
  */            	                                                                			  
   TeaLeaf.Client.tlScanForAdditions = function() {
		//	Attach to the main window
		TeaLeaf.Client.tlCheckIndControls(window);
		//	attach to the frames
		var	ind;
		for(ind = 0; ind < window.frames.length; ind++) {
			var	w = window.frames[ind];
			TeaLeaf.Client.tlCheckIndControls(w);
		}			
		if(TeaLeaf.Client.tlTimoutID){
		    window.clearTimeout(TeaLeaf.Client.tlTimoutID);	
        }      
		TeaLeaf.Client.tlTimoutID = window.setTimeout(TeaLeaf.Client.tlScanForAdditions, TeaLeaf.Client.Configuration.tlscanupdate);		
	}
  /**
  * Setup function that attaches to all the controls on the page. 
  * @addon
  */            	                                           
  TeaLeaf.Client.tlSetup = function() {
		//	Get the lists we want to get
		TeaLeaf.Client.tlAttachToAllControls();	
		//	Hook on to the window open
		window.OrigOpen = window.open;
		window.open = function(url,name,features,replace) {
			var numberArgs = arguments.length;
			var	status = "blocked";
			var subWin = window.OrigOpen(url, name, features, replace);
			try {
				if(!subWin.closed)
					status = "visible";
			}
			catch(exc) {
				if( TeaLeaf.Event.Configuration.tlshowexceptions ) {
					alert(exc.name + ": " + exc.message + "\r\n\r\nPos 8");
				}
			};
			var	tlevt = new TeaLeaf.Event("GUI", "WindowOpen");	
			var tlAddNameValueArray = new Array("Status", status, 
				                                "Url", escape(url),
				                                "Name", name, 
				                                "Features", features, 
				                                "Replace", replace);
			tlevt.tlAddData(tlAddNameValueArray);
			tlevt.tlSend(); 
			return subWin;
		};	
		//	At this point, lets scan periodically for added controls
        TeaLeaf.Client.tlTimoutID = window.setTimeout(TeaLeaf.Client.tlScanForAdditions, TeaLeaf.Client.Configuration.tlscanupdate);
    }		
	/**
    * Initialize the call to tlSetup UI Client Event
    * Capture is not used as an SDK.
    * @requires
    * TeaLeafEvent.js
    * @addon
    */            	                                           
	TeaLeaf.Client.CallInit = function() {	
        TeaLeaf.Event.tlRemoveHandler(window, "beforeunload", eval(TeaLeaf.Client.tlBeforeUnload), false);
        TeaLeaf.Event.tlRemoveHandler(window, "unload", eval(TeaLeaf.Client.tlUnload), false);
    	TeaLeaf.addOnLoad(TeaLeaf.Client.tlSetup);
	}

	TeaLeaf.Client.CallInit();		
}