window.FieldListDownloader      = { startDownload : Downloader_startDownload }
window.DatePickerDownloader     = { startDownload : Downloader_startDownload }
window.CaptionPopupDownloader   = { startDownload : Downloader_startDownload }

function Downloader_startDownload(url, callback)
{

    if (this.XMLDownloader == undefined)
    {
        try
        {
            this.XMLDownloader = new ActiveXObject("MSXML2.XMLHTTP.4.0");
            
            var oThis = this;
            
            this.ReadyStateChangedCallBack = function() { Downloader_ReadyStateChangedCallBack(oThis) }
        }
        catch(err)
        {
            Msgbox("Unable to create XML downloader component", vbCritical + vbOKOnly);
            return;
        }
    }
    
    if (this.XMLDownloader.readyState != 0 && this.XMLDownloader.readyState != 4)
    {
        this.XMLDownloader.abort();
    }

    this.CallBack = callback;
    
    this.XMLDownloader.open("POST", url, true, "", "");
    this.XMLDownloader.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    this.XMLDownloader.send('');
    
    this.XMLDownloader.onreadystatechange = this.ReadyStateChangedCallBack;		      
}

function Downloader_ReadyStateChangedCallBack(thisDownloader)
{
    if (thisDownloader.XMLDownloader.readyState != 4)
        return;
           
    thisDownloader.CallBack(thisDownloader.XMLDownloader.responseText);
}


TextControl.ApplyScaling    = null;
TextControl.BuiltForHeight  = null;
TextControl.BuiltForWidth   = null;
TextControl.ResizeForHeight = window.screen.availHeight;
TextControl.ResizeForWidth  = window.screen.availWidth;   

// OBJECT
function TextControl(oCtlOrConstructorArguments) {
    /// <summary>TextControl</summary>
    /// <param name="oCtlOrConstructorArguments" type="Object">Constructor Arguments object or HTML Element</param>
    /// <field name="Control" type="Object" domElement="true"></field>
    /// <field name="AutoComplete" type="Boolean">Whether to turn auto complete on, requires a loaded datalist</field>
    /// <field name="List" type="Object">Can be either a serialized list, or DataList</field>
    /// <field name="Input" htmlElement="true">Text Input element for this text control</field>
	    
		GarbageHeap.Add(this);
		
		this.Inherits(WebControl);

        if (oCtlOrConstructorArguments == null || oCtlOrConstructorArguments == undefined || typeof(oCtlOrConstructorArguments) != 'object')
	        throw new Error('Control element or constructor arguments object not passed to TextControl()');
	
	    	    	
	    var oCtl = null;
	    if (oCtlOrConstructorArguments.tagName != undefined)
	    {    
	        // Old style - Pre rendered in ASP
	        oCtl = oCtlOrConstructorArguments;
    	
	        if (oCtl.ObjectType != "TEXTCONTROL") 
	        {
		        throw new Error('invalid control element passed to new TextControl()');		
	        }
    	    
	        this.Control = oCtl;
	        
	        this.TopCaption = oCtl.children[0].children[0].children[0].children[0];
		    this.SideCaption = oCtl.children[0].children[0].children[1].children[0];
		    this.Downloader = oCtl.children[3];
		    this.Input = oCtl.children[0].children[0].children[1].children[1].children[0]
		    this.FunctionButton = oCtl.children[0].children[0].children[1].children[2].children[0];
		    this.Hiddens =  oCtl.children[1];
		    this.ListCache = oCtl.children[2];
	    }
	    else
	    {
	        var ConstructorArguments = oCtlOrConstructorArguments;
	    
	        var sName = ConstructorArguments.Name;
	        var oParent = ConstructorArguments.Parent;	        
    	    
	        if (sName == undefined)
	            throw new Error('No name defined for TextControl');
    	    	    
	        if (oParent == undefined) oParent = document.body;
    	    
	        if (sName.substr(0,3) != "ctl") sName = 'ctl' + sName;
    	    
	        oCtl = document.createElement("div");
	        oCtl.setAttribute("id",sName);
	        oCtl.setAttribute("name", sName);
	        oCtl.style.overflow = "visible";
       
	        oCtl.unselectable = "on";
	        oCtl.ObjectType = "TEXTCONTROL";
    	    
	        if (oParent != null) oParent.appendChild(oCtl);
	        this.Control = oCtl;
    	    
	        this.Render(ConstructorArguments);
	    }
		
		
		this.Control.JSControl = this;
		
		
		this.FunctionButtonOverStyle   = null;
		this.FunctionButtonNormalStyle = null;
		
		this.Caption = function () {
			if (this.Caption.arguments.length) {
				TC_SetCaption(oCtl, this.Caption.arguments[0]);
			} else {
				return TC_GetCaption(oCtl);
			}
		}
		
		
		
		this.AutoComplete = false;
		this.__CharSizes = null;
		
		if (this.Control.FunctionType.toUpperCase() == 'CUSTOMDATALIST') {
		    this.List = new DataList();		
		        this.List.Behaviour     = "CUSTOM";
		        this.List.ParentControl = this; 
		        this.List.RaiseEvents   = true;
		        
		    	this.List.AlternateRowColors = false;
	            this.List.RowColor       = '';
	            this.List.RowAltColor    = '';
            	
	            this.List.SelectedColor  = '';  	
	            
	            this.List.RowHeight      = 22;	 
	            this.List.MaxRows        = 10;   
	            
	            this.List.Events.Add("DATALIST_CHANGE", TC_DataList_Change, this.List);
	            this.List.Events.Add("ROW_CLICK", TC_DataList_RowClick, this.List);
	            this.List.Cursor.Events.Add("MOVE", TC_DataList_CursorMove, this.List);
    	} else {
    	    this.List = new DropDownList(oCtl);
			    this.List.RowColors = new Array();
    	}
    		
		this.Show = function() { SetControlInvisible(oCtl, false); }
		
		this.Hide = function() { SetControlInvisible(oCtl, true); }
		
		this.Disable = function() { 
			switch(this.Disable.arguments.length)
			{
				case 0: 
					SetControlDisable(oCtl); 
					break;
				
				case 1:
					SetControlDisable(oCtl, this.Disable.arguments[0]); 
					break;
				
				default:
					alert('unsupported amount of arguments passed to control[' + oCtl.name + '] :: Disable()');
					break;
			}
		}
		
	}
	TextControl.prototype.GetTextRange = TC_GetTextRange;
	TextControl.prototype.InitCharSizes = TC_InitialiseCharacterSizes;
	TextControl.prototype.Render = TC_Render;
	
	// OBJECT
	function DropDownList(oCtl) {
		/* 
			Object:		DropDownList  (for CUSTOMDROPDOWN only)	
			Usage:		var o = new DropDownList(oCtl)
			Returns:	(null if oCtl passed is not a TEXTCONTROL) OR (new DropDownList object)
			
			Use this custom object to modify the contents of a drop down list.  As the cached drop down
			lists are handled quite complexly with encoding and multiple values per list item it is
			best to use the built in functionality of this control when dealing with the drop down.
			
			*NOTE* Properties point to an actual object such as an input field, or TD/TR
			
			***Properties***		***Usage****						***Notes***
			
			Control					Control								A pointer to the lists parent control container 
			ListCache				ListCache.innerHTML					A pointer to the listcaches container
									ListCache.SelectedIndex				Current selected index of the list
									ListCache.ColumnCount				amount of columns that get displayed on drop down
									ListCache.ReturnColumn				the column value that is returned (1-4) when an item is selected
		
			
			***Objects***
			NONE
			
			
			***Methods***			***Usage***								***Returns***				***Notes***
			
			Count()					Count()									integer						returns the count of items in the list
			Display()				Display()								null						displays the list to the user
			Clear()					Clear()									null						clears the list
			SelectedIndex()			SelectedIndex()							integer						returns the selected item index, -1 if nothing selected
			Delete()				Delete(n)								null						deletes an item at index location n
			Item()					Item(n,['VALUE','1','2','3'])			string						returns a value for an item at index n, can pass  '1','2','3' to get a hidden value for an item
			SelectItem()			SelectItem(Index[n] Or Entry Value[s])	null						selects an item at index n OR an item whos entry value = s, Entry value is put into controls input
			Add()					Add(s,[arg1],[arg2],[arg3])				null						adds an item (s) to the bottom of the list, can optionally pass 3 arguments that become the hidden values for the item		
		*/
	
	
		this.Control = oCtl;
		
		this.ListCache = oCtl.children[2];
		
		this.MaxDisplay = 10;
		
		this.Count = function () { return TC_GetListCount(oCtl) }
		
		this.Display = function () { TC_DisplayFieldList(oCtl) }
		
		this.Clear = function () { TC_ClearList(oCtl) }
		
		this.SelectedIndex = function() { 
			if (this.SelectedIndex.arguments.length) {
				TC_SelectListItem(oCtl, this.SelectedIndex.arguments[0]);
			} else {
				return TC_GetListSelectedIndex(oCtl); 
			}
		}

		this.Delete = function(Index) { TC_RemoveFromList(oCtl, this.Delete.arguments[0]) }
		this.Remove = this.Delete;
		
		this.SelectItem = function(Index) { TC_SelectListItem(oCtl, this.SelectItem.arguments[0]) }
		
		this.Find = function(Arg, Col) { return TC_FindListItem(oCtl, this.Find.arguments[0], this.Find.arguments[1]); }
		
		this.GetCell = function(Row, Col) {
			return TC_GetListCell(oCtl, this.GetCell.arguments[0], this.GetCell.arguments[1]);
		}
		
		this.SetCell = function(Row, Col, Value) {
			return TC_SetListCell(oCtl, this.SetCell.arguments[0], this.SetCell.arguments[1], this.SetCell.arguments[2]);
		}
		
		
		this.Item = function(Index) {
			switch (this.Item.arguments.length) 
			{
				case 1:
					return TC_GetListItem(oCtl, this.Item.arguments[0]);
					break;
					
				case 2:
					return TC_GetListItem(oCtl, this.Item.arguments[0], this.Item.arguments[1]);
					break;
					
				default:
					throw new Error('unsupported amount of arguments passed to control[' + oCtl.name + '] :: DropDownList.Item()');
					break;
			}		
		}
		
		
		this.Add = function(val) { 
			switch(this.Add.arguments.length)
			{
				case 1:
					TC_AddToFieldList(oCtl,val);
					break;
				
				case 2:
					TC_AddToFieldList(oCtl,val,this.Add.arguments[1]);
					break;
					
				case 3:
					TC_AddToFieldList(oCtl,val,this.Add.arguments[1],this.Add.arguments[2]);
					break;
					
				case 4:
					TC_AddToFieldList(oCtl,val,this.Add.arguments[1],this.Add.arguments[2], this.Add.arguments[3]);
					break;
					
				default:
					alert('unsupported amount of arguments passed to control[' + oCtl.name + '] :: DropDownList.Add()');
					break;
			} 
		}
			
		this.InsertAt = function(iIndex, val) {
		
		    switch (this.InsertAt.arguments.length)
		    {
		        case 2:
		            TC_AddToFieldListAtPosition(oCtl, iIndex, val);
		            break;
		            
                default:
                    alert('unsupported amount of arguments passed to control[' + oCtl.name + '] :: DropDownList.InsertAt()');		            
		    }				
		}
	}
	DropDownList.prototype.GetArrayEncoded = TC_GetListArrayEncoded;
	
	TextControl.InputTypes =    { 
	                            Text : "text",
	                            Checkbox : "checkbox",
	                            Radio : "radio"
	                            }
	                            
	TextControl.CaptionStyles  =    {   
                                    Top : 'TOP', 
                                    Side : 'SIDE',
                                    None : 'NONE'
                                    }
	
	TextControl.ControlTypes =  {
                                    Company : 'Company',
                                    Contact : 'Contact',
                                    Standard: 'Standard'
                                }

    TextControl.FunctionTypes = {
                                Dropdown                : 'DROPDOWN',
                                GroupUserList           : 'GROUPUSERLIST',
                                FullUserList            : 'FULLUSERLIST',
                                CustomDropDown          : 'CUSTOMDROPDOWN',
                                CustomDataList          : 'CUSTOMDATALIST',
                                CustomList              : 'CUSTOMLIST',
                                DateDropDown            : 'DATEDROPDOWN',
                                AllCountryDropdown      : 'ALLCOUNTRYDROPDOWN',
                                PostcodeCountryDropdown : 'POSTCODECOUNTRYDROPDOWN',
                                FullGroupList           : 'FULLGROUPLIST',
                                OrgGroupList            : 'ORGGROUPLIST',
                                MemberOfGroupList       : 'MEMBEROFGROUPLIST',
                                SelfGroupList           : 'SELFGROUPLIST',                                    
                                Email                   : 'EMAIL',
                                ExternalEmail           : 'EXTERNALEMAIL',
                                Web                     : 'WEB',
                                DatePicker              : 'DATEPICKER',
                                Calendar                : 'CALENDAR',
                                Namefield               : 'NAMEFIELD',
                                Postcoder               : 'POSTCODER',
                                CustomButton            : 'CUSTOMBUTTON',
                                PostcoderStates         : 'POSTCODERSTATES',
                                AddressSearch           : 'ADDRESSSEARCH',
                                StateSearch             : 'STATESEARCH',
                                Ticker                  : 'TICKER',
                                Sic                     : 'SIC',
                                Dialer                  : 'DIALER',
                                Mobile                  : 'MOBILE',
                                Sms                     : 'SMS',
                                SimpleSms               : 'SIMPLESMS',
                                None                    : 'NONE',
                                NotSpecified            : ''
                                }
    
    TextControl.ListBehaviours = {
                                    SimpleDropDown : 'SIMPLEDROPDOWN',
                                    Custom : 'CUSTOM',
                                    SimpleCheckedList : 'SIMPLECHECKEDLIST'
                                 }
    
                                                                
	function TC_Render(ConstructorArguments)
	{		    	
	    var Width = ConstructorArguments.Width;
        var Height = ConstructorArguments.Height;
        var Left = ConstructorArguments.Left;
        var Top = ConstructorArguments.Top;
        var zIndex = ConstructorArguments.zIndex;
        var Position = ConstructorArguments.Position;
        
        var ApplyScaling = ConstructorArguments.ApplyScaling;
	
	    var SideCaptionWidth = ConstructorArguments.SideCaptionWidth;
	    if (SideCaptionWidth == undefined) SideCaptionWidth = ConstructorArguments.CaptionWidth;
	    var HideOnNoCaption = ConstructorArguments.HideOnNoCaption;
	    
	    var TabNumber = ConstructorArguments.TabNumber;
        var Style = ConstructorArguments.Style;      
        if (Style == undefined) Style = WebControl.Styles.Standard;
          
	    var Name = ConstructorArguments.Name;
	    
	    var ControlType = ConstructorArguments.ControlType;
	    if (ControlType == undefined) ControlType = TextControl.ControlTypes.Standard;
	    
	    var DataObject = ConstructorArguments.DataObject;
        var DataField = ConstructorArguments.DataField;
    
	    var FunctionType = ConstructorArguments.FunctionType;
	    if (FunctionType == undefined) FunctionType = TextControl.FunctionTypes.None;
	    
	    var InputType = ConstructorArguments.InputType;
	    var MaxLength = ConstructorArguments.MaxLength;
	    
	    var Caption = ConstructorArguments.Caption;
	    if (Caption == undefined) Caption = '';
	    if (typeof(Caption) != 'string')
	        throw new Error('Caption must be a string value');
	    
	    var TabIndex = ConstructorArguments.TabIndex;
	    
	    var Disabled = ConstructorArguments.Disabled;
	    if (Disabled == undefined) Disabled = false;
	    if (typeof(Disabled) != 'boolean')
	        throw new Error('Disabled must be a boolean value');
	    
	    var Visible = ConstructorArguments.Visible;
	    if (Visible == undefined) Visible = true;
	    if (typeof(Visible) != 'boolean')
	        throw new Error('Visible must be a boolean value');
	    
	    var ReadOnly = ConstructorArguments.ReadOnly;
	    if (ReadOnly == undefined) ReadOnly = false;
	    if (typeof(ReadOnly) != 'boolean')
	        throw new Error('ReadOnly must be a boolean value');
	        
	    var CaptionStyle = ConstructorArguments.CaptionStyle;
	    var CaptionPopup = ConstructorArguments.CaptionPopup;
	    var CaptionSearch = ConstructorArguments.CaptionSearch;
	    var CaptionFieldList = ConstructorArguments.CaptionFieldList;
	    var CaptionFieldName = ConstructorArguments.CaptionFieldName;
	    
	    var FieldListBelongsTo = ConstructorArguments.ListObject;
	    var FieldListFieldID = ConstructorArguments.ListField;
	    
	    var SearchObject = ConstructorArguments.SearchObject;
	    var SearchField = ConstructorArguments.SearchField;
	    
	    var ListColumnCount = ConstructorArguments.ListColumnCount;
	    var ListColumnReturn = ConstructorArguments.ListColumnReturn;
	    
	    var DisplayFormat   = ConstructorArguments.DisplayFormat;
	    var DataType   = ConstructorArguments.DataType;
	    
	    var InputMask   = ConstructorArguments.InputMask;
	    if (InputMask == undefined) InputMask = "";
	    if (typeof(InputMask) != "string") 
	        throw new Error("Input mask must be a string");
	   
	    
	    if (Top == undefined) Top = 0;
	    if (isNaN(Top))
	        throw new Error("Top must be a number");
	        
	    if (Left == undefined) Left = 0;
	    if (isNaN(Left))
	        throw new Error("Left must be a number");
	       
	    if (Width == undefined) Width = 200;
	    if (isNaN(Width))
	        throw new Error("Width must be a number");
	        
	    if (zIndex == undefined) zIndex = 1;
	    if (Position == undefined) Position = "absolute";
	    if (InputType == undefined) InputType = TextControl.InputTypes.Text;
	    if (TabNumber == undefined) TabNumber = "";
	    if (SideCaptionWidth == undefined) SideCaptionWidth = 100;
	    
	    if (FieldListBelongsTo == undefined) FieldListBelongsTo = DataObject;
	    if (FieldListFieldID == undefined) FieldListFieldID = DataField;
	    
	    if (SearchObject == undefined) FieldListBelongsTo = DataObject;
	    if (SearchField == undefined) FieldListFieldID = DataField;
	    
	    if (ListColumnCount == undefined) ListColumnCount = 1;
	    if (ListColumnReturn == undefined) ListColumnReturn = 1;
	    
	    // Width must be atleast 50 bigger than side caption width
	    if (SideCaptionWidth > (Width - 50))
	    {
	        SideCaptionWidth = Width - 50;
	    }
	    
	    if (MaxLength != undefined && isNaN(MaxLength))
	        throw new Error("MaxLength must be a number");
	        
	    if (HideOnNoCaption == undefined) HideOnNoCaption = false;
	    if (typeof(HideOnNoCaption) != "boolean")
	        throw new Error("HideOnNoCaption must be a boolean");
	    	    
	    if (CaptionPopup == undefined) CaptionPopup = false;
	    if (typeof(CaptionPopup) != "boolean")
	        throw new Error("CaptionPopup must be a boolean");
	        
	    if (CaptionSearch == undefined) CaptionSearch = false;
	    if (typeof(CaptionSearch) != "boolean")
	        throw new Error("CaptionSearch must be a boolean");
	         
	    if (CaptionFieldList == undefined) CaptionFieldList = false;
	    if (typeof(CaptionFieldList) != "boolean")
	        throw new Error("CaptionFieldList must be a boolean");
	        
	    if (CaptionFieldName == undefined) CaptionFieldName = false;
	    if (typeof(CaptionFieldName) != "boolean")
	        throw new Error("CaptionFieldName must be a boolean");
	         	 
	    var ctlTopCaptionStyle = "";	    	    
	    var ctlSideCaptionStyle = "";
	    
	    if (CaptionStyle == undefined) CaptionStyle == TextControl.CaptionStyles.Top;
	    switch (CaptionStyle)
	    {	        
	        case TextAreaControl.CaptionStyles.Side:
	            ctlTopCaptionStyle = "display: none;"
			    ctlSideCaptionStyle = "display: block;"
	            break;
	            
	        case TextAreaControl.CaptionStyles.None:
	            ctlTopCaptionStyle = "display: none;"
			    ctlSideCaptionStyle = "display: none;"
	            break;
	            
	        case TextAreaControl.CaptionStyles.Top:
	        default:
	            ctlTopCaptionStyle = "display: block;"
			    ctlSideCaptionStyle = "display: none;"
			    SideCaptionWidth = 0;
			    Width -= 4;
	            break;
	    } 
	        
	    
	    if (HideOnNoCaption && Caption.length == 0)
	    {
	        Visible = false;
	    }
	    
	    
	    var ctlStyle;
	    switch (Style)
	    {
	        case WebControl.Styles.Glass:
	        case "4":
	        case "Vista":	        	        
	            ctlStyle = "Vista";
	            Style = WebControl.Styles.Glass;
	            break;
	        
	        case WebControl.Styles.XP:
            case "2":
            case "XP":            
	            ctlStyle = "XP";
	            Style = WebControl.Styles.XP;
	            break;
            
            case WebControl.Styles.Standard:	            
	        default:
	            Style = WebControl.Styles.Standard;
	            ctlStyle = "";	    
	    }
	  
	    var ctlClass;
	    var ctlInputClass;
	    var ctlInputCellClass;
	    var ctlSideInputStyle;
	    
	    switch (ControlType)
	    {
	        case TextControl.ControlTypes.Contact:
	            ctlClass = "ContactCtlCaptionNormal" + ctlStyle;
			    ctlInputClass = "ContactCtlNormal" + ctlStyle;
			    ctlInputCellClass = "ContactInputCellNormal" + ctlStyle;
	            break;
	            
	        case TextControl.ControlTypes.Company:
	            ctlClass = "CompanyCtlCaptionNormal" + ctlStyle;
			    ctlInputClass = "CompanyCtlNormal" + ctlStyle;
			    ctlInputCellClass = "CompanyInputCellNormal" + ctlStyle;
	            break;
	        
	        case TextControl.ControlTypes.Standard:	        
	            ctlClass = "StandardCtlCaptionNormal" + ctlStyle;
			    ctlInputClass = "StandardCtlNormal" + ctlStyle;
			    ctlInputCellClass = "StandardInputCellNormal" + ctlStyle;
	            break;	            
	    
	        default:
	            throw new Error('ControlType property is an invalid value.');
	    }
	    
	    // Apply scaling
	    if (ConstructorArguments.ApplyScaling == true || (ConstructorArguments.ApplyScaling == null && TextControl.ApplyScaling == true))
	    {	                       
	        // Use overridden BuiltForWidth / BuiltForHeight or use static members   
	        if (ConstructorArguments.BuiltForWidth != null && ConstructorArguments.BuiltForHeight != null)
	        {
	            // Calculate the resize ratios using the overridden values
	            ResizeHeightMultiplier = TextControl.ResizeForHeight / ConstructorArguments.BuiltForHeight;
                ResizeWidthMultiplier  = TextControl.ResizeForWidth  / ConstructorArguments.BuiltForWidth;
	        }
	        else
	        {
	            // Validate the BuiltForX values 
	            if (TextControl.BuiltForHeight == null) throw new Error("The controls 'BuiltForHeight' value was not specified when apply scaling has been set to true");
	            if (TextControl.BuiltForWidth  == null) throw new Error("The controls 'BuiltForWidth' value was not specified when apply scaling has been set to true");
	            
	            // Calculate the resize ratios using the static control values
	            ResizeHeightMultiplier = TextControl.ResizeForHeight / TextControl.BuiltForHeight;
                ResizeWidthMultiplier  = TextControl.ResizeForWidth  / TextControl.BuiltForWidth;
	        } 
	                    
            Left  = ResizeWidthMultiplier * Left;
            Width = ResizeWidthMultiplier * Width;                                    
        }
    
        Width -= 24;
        
        var funcVal     = "&nbsp;";
        var funcStyle   = "block";
        var funcButtonClass = "";
            
        switch (FunctionType)
        {
            case TextControl.FunctionTypes.Dropdown:
            case TextControl.FunctionTypes.GroupUserList:
            case TextControl.FunctionTypes.FullUserList:
            case TextControl.FunctionTypes.CustomDropDown:
            case TextControl.FunctionTypes.CustomDataList:
            case TextControl.FunctionTypes.CustomList:
            case TextControl.FunctionTypes.DateDropDown:
            case TextControl.FunctionTypes.AllCountryDropdown:
            case TextControl.FunctionTypes.PostcodeCountryDropdown:
            case TextControl.FunctionTypes.FullGroupList:
            case TextControl.FunctionTypes.OrgGroupList:
            case TextControl.FunctionTypes.MemberOfGroupList:
            case TextControl.FunctionTypes.SelfGroupList:
                funcButtonClass = "FuncButtonDropNormal" + ctlStyle;
                break;
                
            case TextControl.FunctionTypes.Email:
            case TextControl.FunctionTypes.ExternalEmail:
                funcButtonClass = "FuncButtonEmailNormal" + ctlStyle;
                break;
            case TextControl.FunctionTypes.Web:
                funcButtonClass = "FuncButtonWebNormal" + ctlStyle;
                break;
            case TextControl.FunctionTypes.DatePicker:
            case TextControl.FunctionTypes.Calendar:            
                funcButtonClass = "FuncButtonCalNormal" + ctlStyle;
                break;
            case TextControl.FunctionTypes.Namefield:
            case TextControl.FunctionTypes.Postcoder:
            case TextControl.FunctionTypes.CustomButton:
            case TextControl.FunctionTypes.PostcoderStates:
            case TextControl.FunctionTypes.AddressSearch:
            case TextControl.FunctionTypes.StateSearch:
            case TextControl.FunctionTypes.Ticker:
            case TextControl.FunctionTypes.Sic:
                funcButtonClass = "funcButtonNormal" + ctlStyle;
                break;
            case TextControl.FunctionTypes.Dialer:
                funcButtonClass = "FuncButtonDialerNormal" + ctlStyle;
                break;
            case TextControl.FunctionTypes.Mobile:
            case TextControl.FunctionTypes.Sms:
            case TextControl.FunctionTypes.SimpleSms:
                funcButtonClass = "FuncButtonMobileNormal" + ctlStyle;
                break;
            case TextControl.FunctionTypes.None:
            case TextControl.FunctionTypes.NotSpecified:
                FunctionType = TextControl.FunctionTypes.None;
                funcButtonClass = "";
                funcStyle = "none";
                if (CaptionStyle == TextControl.CaptionStyles.Top) Width += 8;
                break;
            default:
                throw new Error("FunctionType specified does not match to a valid choice");
        }
        
        
        if (CaptionStyle == TextControl.CaptionStyles.Side)
        {
            ctlSideCaptionStyle += " width: " + SideCaptionWidth + "px";
            
            if (FunctionType == TextControl.FunctionTypes.None)
            {
                ctlSideInputStyle = "width: " + (Width - SideCaptionWidth + 15) + "px";
            }
            else
            {
                ctlSideInputStyle = "width: " + (Width - SideCaptionWidth - 3) + "px" ;
            }
        }
        else
        {
            ctlSideInputStyle += "; width: 0px";
            
            if (FunctionType == TextControl.FunctionTypes.None)
            {
                ctlSideInputStyle = "width: " + (Width + 15)  + "px";
            }
            else
            {
                ctlSideInputStyle = "width: " + (Width + 2) + "px"; 
            }  
        }
        
        var ctlValidation = "";
        if (InputMask.length != 0)  ctlValidation = "this.value = ForceInputMask(this);";
        
        if (Caption.length == 0) Caption = "&nbsp;";
        
        this.Control.className = ctlClass;
        this.Control.style.position = Position;
        this.Control.style.top = Top;
        this.Control.style.left = Left;
        this.Control.style.display = (Visible ? "block" : "none");
        this.Control.style.zIndex = zIndex;
        this.Control.style.width = Width;
        this.Control.TabNum = TabNumber;
        //this.Control.TabName = TabName;    
        this.Control.ControlType = ControlType;
        this.Control.ControlDataObject = DataObject;
        this.Control.ControlDataField = DataField;
        this.Control.FunctionType = FunctionType;
        this.Control.InputMask = InputMask;
        this.Control.DisplayFormat = DisplayFormat == undefined ? 'dd/mm/yyyy' : DisplayFormat;
        this.Control.DataType = DataType;
        this.Control.AllowCaptionClick = CaptionPopup;
        this.Control.AllowCaptionSearch = CaptionSearch;
        this.Control.AllowCaptionFieldList = CaptionFieldList;
        this.Control.AllowCaptionName = CaptionFieldName;
        this.Control.SelectedIndex = "-1";
        this.Control.ItemSelected = "false";     
        this.Control.ControlStyle = Style.toString();
  
        var aRender = new Array(0)
        var z = 0;
        
        aRender[z++]  = '<table style="width: ' + (Width + 20) + 'px" cellpadding=0 cellspacing=1 ContainerType="ControlInterface">';
        aRender[z++]  =     '<tr style="' + ctlTopCaptionStyle + '" onmouseup="javascript: TC_CtlCaptionMouseUp(this);" ondblclick="javascript: TC_CaptionCtlDoubleClick(this);">';
        aRender[z++]  =         '<td colspan=3 class="' + ctlClass + '" unselectable="on"><nobr>' + Caption + '</nobr></td>';
        aRender[z++]  =     '</tr>';
        aRender[z++]  =     '<tr style="border: none;">';
        aRender[z++]  =         '<td style="' + ctlSideCaptionStyle + ';" unselectable="on" class="' + ctlClass + '" onmouseup="javascript: TC_SideCaptionMouseUp(this);"><div style="overflow: hidden; width: ' + SideCaptionWidth + 'px;" nowrap>' + Caption + '</div></td>';
        aRender[z++]  =         '<td class="' + ctlInputCellClass + '" width=0><input type=\'' + InputType + '\' name="' + Name + '" id="' + Name + '" class="' + ctlInputClass + '" style="' + ctlSideInputStyle + '" ' + (ReadOnly ? 'readonly': '') + ' tabIndex="' + TabIndex + '" onkeyup="javascript: TC_AutoComplete(this); if (EventCollector(this, \'INPUT_KEYUP\', \'TEXTCONTROL\') == false) return; TC_InputChange(this);" onchange="javascript: if(EventCollector(this, \'INPUT_CHANGE\', \'TEXTCONTROL\') == false) return;" onkeydown="javascript: TC_InputKeyDown(this);" onmouseover="javascript: TC_InputMouseOver(this);" onmouseout="javascript: TC_InputMouseOut(this);" onblur="javascript: EventCollector(this, \'INPUT_LOSTFOCUS\', \'TEXTCONTROL\'); TC_InputMouseOut(this,\'unfocus\'); ' + ctlValidation + '" onfocus="javascript: TC_InputMouseOver(this,\'focus\'); EventCollector(this, \'INPUT_GOTFOCUS\', \'TEXTCONTROL\');" ' + (MaxLength != undefined ? 'maxlength=' + MaxLength : '') + '></td>';
        aRender[z++]  =         '<td style="display: ' + funcStyle + '"><input type=button value="' + funcVal + '" class="' + funcButtonClass + '" onmouseover="javascript: TC_FuncButtonMouseOver(this);" onmouseout="javascript: TC_FuncButtonMouseOut(this);" onmouseup="javascript: EventCollector(this, \'FUNCTIONBUTTON_CLICK\', \'TEXTCONTROL\'); TC_FuncButtonClick(this);" tabIndex="-1"></td>';
        aRender[z++]  =     '</tr>';
        aRender[z++]  = '</table>';
        
        aRender[z++]  = '<div id="ctl' + Name + 'Hidden" name="ctl' + Name + 'Hidden">';
        aRender[z++]  = '';
        aRender[z++]  = '';
        aRender[z++]  = '';
        aRender[z++]  = '';
        aRender[z++]  = '';
        aRender[z++]  = '';
        aRender[z++]  = '</div>';
        
        aRender[z++]  = '<div id="' + Name + 'ListCache" name="' + Name + 'ListCache" style="display: none;" Initialized="false" ContainerType="ListCache" ColumnCount="' + ListColumnCount + '" ColumnReturn="' + ListColumnReturn + '"></div>';
        aRender[z++]  = '<DOWNLOAD ID="' + Name + 'Downloader" STYLE="behavior:url(#default#download)" />';
        
        var sOut = aRender.join("");
        this.Control.innerHTML = sOut;
                
        if (this.Control.onmouseover == undefined)  this.Control.onmouseover = function() { TC_CtlMouseOver(this); }
        if (this.Control.onmouseout == undefined)   this.Control.onmouseout =  function() { TC_CtlMouseOut(this);  }
        if (this.Control.onmouseup == undefined)    this.Control.onmouseup =   function() { TC_CtlMouseUp(this); }               
        
        this.TopCaption = this.Control.children[0].children[0].children[0].children[0];
	    this.SideCaption = this.Control.children[0].children[0].children[1].children[0];
	    this.Downloader = this.Control.children[3];
	    this.Input = this.Control.children[0].children[0].children[1].children[1].children[0]
	    this.FunctionButton = this.Control.children[0].children[0].children[1].children[2].children[0];
	    this.Hiddens =  this.Control.children[1];
	    this.ListCache = this.Control.children[2];
	}
	
	
	
	function TC_GetCaption(oCtl) {
		var oTopCaption;
		var oSideCaption;
		oSideCaption = oCtl.children[0].children[0].children[1].children[0];
		oTopCaption = oCtl.children[0].children[0].children[0].children[0];
		
		if (oSideCaption.innerText.length) {
			return oSideCaption.innerText.replace('&nbsp;',' ');
		} else {
			return oTopCaption.innerText.replace('&nbsp;',' ');
		}
	}
	
	
	function TC_SetCaption(oCtl, val) {

		var oTopCaption;
		var oSideCaption;
		oSideCaption = oCtl.children[0].children[0].children[1].children[0];
		oTopCaption = oCtl.children[0].children[0].children[0].children[0];
		
		oSideCaption.innerText = val;
		oTopCaption.innerText = val;
	}
	
	
	function TC_CtlMouseOver(oCtl) {
		var oTopCaption;
		var oSideCaption;
		var oInput;
		var oInputCol;
		var oFuncBtn;
	
		var CtlClass;
		var CaptionClass;
		
		if (oCtl.disabled) return;
		
		oSideCaption = oCtl.children[0].children[0].children[1].children[0];
		oTopCaption = oCtl.children[0].children[0].children[0].children[0];
		oInput = oCtl.children[0].children[0].children[1].children[1].children[0];		

        var sStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "VISTA";
                break;
            case "3":
                sStyle = "XP";
                break;                
            case "1":
            default:
                sStyle = "";
		        break;
		}
		
        switch (oCtl.ControlType) 
        {
	        case "Contact":
		        CtlClass = "ContactCtlCaptionOver" + sStyle;
		        CaptionClass = "ContactCtlCaptionOver"  + sStyle;
		        break;
					
	        case "Company":
		        CtlClass = "CompanyCtlCaptionOver" + sStyle;
		        CaptionClass = "CompanyCtlCaptionOver" + sStyle;
		        break;
		
	        case "Standard":
		        CtlClass = "StandardCtlCaptionOver" + sStyle;
		        CaptionClass = "StandardCtlCaptionOver" + sStyle;
		        break;
        }
		
		oCtl.className = CtlClass;
		oTopCaption.className = CaptionClass;
		oSideCaption.className = CaptionClass;
	}
	
	
	
	function TC_CtlMouseOut(oCtl) {
		var oTopCaption;
		var oSideCaption;
		var oInput;
		var oInputCol;
		var oFuncBtn;
		
		var CtlClass;
		var CaptionClass;
	
		oTopCaption = oCtl.children[0].children[0].children[0].children[0];
		oSideCaption = oCtl.children[0].children[0].children[1].children[0];
		oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		
		try  { 
			if (document.readyState != "complete" || document.activeElement == oInput) return;
		}
		catch(e) { return }
		
        var sStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "VISTA";
                break;
            case "3":
                sStyle = "XP";
                break;     
            case "1":
            default:
                sStyle = "";
		        break;
		}
		
        switch (oCtl.ControlType) 
		{
			case "Contact":
				CtlClass = "ContactCtlCaptionNormal" + sStyle;
				CaptionClass = "ContactCtlCaptionNormal" + sStyle;
				break;
					
			case "Company":
				CtlClass = "CompanyCtlCaptionNormal" + sStyle;
				CaptionClass = "CompanyCtlCaptionNormal" + sStyle;
				break;
				
			case "Standard":
				CtlClass = "StandardCtlCaptionNormal" + sStyle;
				CaptionClass = "StandardCtlCaptionNormal" + sStyle;
				break;
		}
		
		oCtl.className = CtlClass;
		oTopCaption.className = CaptionClass;
		oSideCaption.className = CaptionClass;
	}
	
	
	
	function TC_CtlMouseUp(oCtl) {
		var oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		var url;
		
		if (oCtl.disabled) return;

        var oJSCtl = GetParentJSControl(oCtl);		
		if (oJSCtl != null)
		{
		    var sButton = ButtonPressed();
		    oJSCtl.Events.RaiseEvent("CONTROL_" + sButton + "CLICK");
		}

		switch (window.event.button)
		{
			case 1:			// Left Button
				TC_InputMouseOver(oInput);
				
				if (!oInput.disabled) { oInput.focus() }
				
				break;
				
			case 2:			// Right Button
				//nothing
				return;
		}
	}
	
	
	
	function TC_CaptionCtlDoubleClick(oCaption) {
		var oCtl = oCaption.offsetParent.offsetParent;
		
		if (oCtl.disabled) return;
		
		if (oCtl.AllowCaptionSearch == "False") return;
		
		OpenSearchDialog(oCtl.ControlDataObject,oCtl.ControlDataField, oCtl.ControlType);	
	}
	
	
	
	function TC_CtlCaptionMouseUp(oCaption) {
		var oCtl = oCaption.offsetParent.offsetParent;
		var oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		var url = "";
		
		if (oCtl.disabled) return;
		
        var oJSCtl = GetParentJSControl(oCtl);		
		if (oJSCtl != null)
		{
		    var sButton = ButtonPressed();
		    oJSCtl.Events.RaiseEvent("CAPTION_" + sButton + "CLICK");
		}
		
		switch (window.event.button) 
		{
			case 1:
				TC_CtlMouseUp(oCtl);
				break;
				
			case 2:
				//The following fields are not allowed to catch caption clicks
				if (oCtl.ControlDataObject == "" || oCtl.ControlDataField == "") return;
				if (oCtl.AllowCaptionClick == "False") return;
			
			//	var AllowFieldList = oCtl.AllowCaptionFieldList;
			//	var AllowFieldName = oCtl.AllowCaptionName;
			//	var AllowFieldSearch = oCtl.AllowCaptionSearch;
				
				CatchContextMenu = true;
				
		//		url = "/CTWebControls/Additional/menu_ControlCaption.asp?SearchObject=" + oCtl.ControlDataObject + "&SearchField=" + oCtl.ControlDataField + "&AllowFieldList=" + AllowFieldList + "&AllowFieldName=" + AllowFieldName + "&AllowFieldSearch=" + AllowFieldSearch;

				//oLastFunctionControl = oInput;
				
				clickX = window.event.screenX;
				clickY = window.event.screenY;
				
				TC_ShowAdminCaptionPopup(oCtl, oCaption, clickX, clickY);
				
				//CaptionPopupDownloader.startDownload(url, CaptionPopupDownloadComplete);
				break;
		}
		
		
		
		window.event.cancelBubble = true;
		return false;
	}
	
	
	
	function TC_SideCaptionMouseUp(oSideCaption) {
		var oCtl = oSideCaption.offsetParent.offsetParent;
		var oCaption = oCtl.children[0].children[0].children[0].children[0];
		
		if (oCtl.disabled) return;
		
		TC_CtlCaptionMouseUp(oCaption);
	}
	
	
	
	function TC_InputMouseOver(oInput) {
		var oCtl = oInput.offsetParent.offsetParent.offsetParent;
		var oInputCell;
		var argCount = TC_InputMouseOver.arguments.length;
		
		var InputClass;
		var InputCellClass;
		
		if (oCtl.disabled) return;
		
		oInputCell = oInput.offsetParent;

		var sStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "VISTA";
                break;
            case "3":
                sStyle = "XP";
                break; 
            case "1":
            default:
                sStyle = "";
		        break;
		}
		
		switch (oCtl.ControlType) 
		{
			case "Contact":
				InputClass = "ContactCtlOver" + sStyle;
				InputCellClass = "ContactInputCellOver" + sStyle;
				break;
					
			case "Company": 
				InputClass = "CompanyCtlOver" + sStyle;
				InputCellClass = "CompanyInputCellOver" + sStyle;
				break;

			case "Standard":
				InputClass = "StandardCtlOver" + sStyle;
				InputCellClass = "StandardInputCellOver" + sStyle;
				break;
				
		}
		
		oInput.className = InputClass;
		if (oInputCell != undefined) oInputCell.className = InputCellClass;
		
		if (argCount > 1) TC_CtlMouseOver(oCtl);
	}
	
	
	
	function TC_InputMouseOut(oInput) {
		var oCtl = oInput.offsetParent.offsetParent.offsetParent;
		var oInputCell;
		var argCount = TC_InputMouseOut.arguments.length;
		
		var InputClass;
		var InputCellClass;
		
		try {
			if (document.readyState != "complete" || document.activeElement == oInput) {
				return;
			}
		} 
		catch(e) 
		{
			return;
		}


		oInputCell = oInput.offsetParent;

		var sStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "VISTA";
                break;
            case "3":
                sStyle = "XP";
                break; 
            case "1":
            default:
                sStyle = "";
		        break;
		}
		
		switch (oCtl.ControlType) 
		{
			case "Contact":
				InputClass = "ContactCtlNormal" + sStyle; 
				InputCellClass = "ContactInputCellNormal" + sStyle;
				break;
					
			case "Company": 
				InputClass = "CompanyCtlNormal" + sStyle;
				InputCellClass = "CompanyInputCellNormal" + sStyle;
				break;
				
			case "Standard":
				InputClass = "StandardCtlNormal" + sStyle;
				InputCellClass = "StandardInputCellNormal" + sStyle;
				break;
		}
		
		oInput.className = InputClass;
		if (oInputCell != undefined) oInputCell.className = InputCellClass;
		
		// check if this was raised by an onBlur
		if (argCount > 1) TC_CtlMouseOut(oCtl); 

	}
	
	
	function TC_InputChange(oInput) {
		var oCtl = oInput.offsetParent.offsetParent.offsetParent;
		
		if (oCtl.FunctionType != "NAMEFIELD") return;
		if (oInput.readOnly == true) return;
		
		var sVal = oInput.value;
		oCtl.children[1].children[0].value = '';
		oCtl.children[1].children[1].value = '';
		oCtl.children[1].children[2].value = '';
		oCtl.children[1].children[3].value = '';
		oCtl.children[1].children[4].value = 'True';
		oCtl.children[1].children[5].value = '';
		
		if (sVal.length == 0) {
			return;
		}
		
		if (sVal.indexOf(" ") == -1) {		
			oCtl.children[1].children[1].value = sVal;				// Last Name
			return;
		} else {
			var aNames = sVal.split(" ");
		
			switch (aNames.length)
			{
				case 2:
					oCtl.children[1].children[0].value = aNames[0];		// FirstName
					oCtl.children[1].children[1].value = aNames[1];		// Last Name
					break;
					
				default:
					oCtl.children[1].children[0].value = aNames[0];		// FirstName
					oCtl.children[1].children[1].value = aNames[2];		// Last Name
					
					var mNames = '';
					for (var i = 1; i < 2; i++)
						mNames += ' ' + aNames[i];
						
					mNames = Trim(mNames.substr(1));
					
					oCtl.children[1].children[2].value = mNames;		// Middle Name
					break;
			}
		}
		

	}
	
	
	function TC_InputKeyDown(oInput) {
		var oCtl = oInput.offsetParent.offsetParent.offsetParent;
		if (oInput.readOnly == true) return;
		oCtl.SelectedIndex = -1;
	}
	
	
	function TC_FuncButtonMouseOver(o) {
		var oCtl = o.offsetParent.offsetParent.offsetParent;
		
		if (oCtl.disabled) return;
		
		var sStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "VISTA";
                break;
            case "3":
                sStyle = "XP";
                break; 
            case "1":
            default:
                sStyle = "";
		        break;
		}
		
		switch (oCtl.FunctionType) 
		{
			case "NAMEFIELD":
			case "POSTCODER":
			case "POSTCODERSTATES":
			case "ADDRESSSEARCH":
			case "STATESEARCH":			
			case "TICKER":
			case "SIC":
				o.className = "FuncButtonOver" + sStyle;
				break;
				
			case "CUSTOMBUTTON":
			    var oJSCtl = GetParentJSControl(oCtl);
			    if (oJSCtl == null || oJSCtl.FunctionButtonOverStyle == null) {
			        o.className = "FuncButtonOver" + sStyle;
			    } else {
			        o.className = oJSCtl.FunctionButtonOverStyle;
			    }
			    break;
			    	
			case "EXTERNALEMAIL":
			case "EMAIL":
				o.className = "FuncButtonEmailOver" + sStyle;
				break;
			
			case "WEB":
				o.className = "FuncButtonWebOver" + sStyle;
				break;
				
			case "DATEPICKER":
				o.className = "FuncButtonCalOver" + sStyle;
				break;
				
			case "DIALER":
				o.className = "FuncButtonDialerOver" + sStyle;
				break;
				
            case "SMS":				
			case "MOBILE":
			case "SIMPLESMS":
				o.className = "FuncButtonMobileOver" + sStyle;
				break;
			
			case "FULLGROUPLIST":
			case "ORGGROUPLIST":
			case "MEMBEROFGROUPLIST":
			case "SELFGROUPLIST":
			case "GROUPUSERLIST":
			case "FULLUSERLIST":
			case "DROPDOWN":
			case "CUSTOMDROPDOWN":
			case "CUSTOMDATALIST":
			case "CUSTOMLIST":
			case "DATEDROPDOWN":
			case "POSTCODECOUNTRYDROPDOWN":
			case "ALLCOUNTRYDROPDOWN":
				o.className = "FuncButtonDropOver" + sStyle;
				break;
				
			case "NONE":
			case "":
				break;
			
		}
		
		TC_CtlMouseOver(oCtl);
	}
	
	
	
	function TC_FuncButtonMouseOut(o) {
		var oCtl;
		oCtl = o.offsetParent.offsetParent.offsetParent;
	    
	    var sStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "VISTA";
                break;
            case "3":
                sStyle = "XP";
                break; 
            case "1":
            default:
                sStyle = "";
		        break;
		}
		
		switch (oCtl.FunctionType) 
		{
		    case "NAMEFIELD":
			case "POSTCODER":
			case "POSTCODERSTATES":
			case "ADDRESSSEARCH":
			case "STATESEARCH":
			case "TICKER":
			case "SIC":
				o.className = "FuncButtonNormal" + sStyle;
				break;
				
			case "CUSTOMBUTTON":
			    var oJSCtl = GetParentJSControl(oCtl);
			    if (oJSCtl == null || oJSCtl.FunctionButtonNormalStyle == null) {
			        o.className = "FuncButtonNormal" + sStyle;
			    } else {
			        o.className = oJSCtl.FunctionButtonNormalStyle;
			    }
			    break;
				
			case "EXTERNALEMAIL":
			case "EMAIL":
				o.className = "FuncButtonEmailNormal" + sStyle;
				break;
				
			case "WEB":
				o.className = "FuncButtonWebNormal" + sStyle;
				break;
				
			case "DATEPICKER":
				o.className = "FuncButtonCalNormal" + sStyle;
				break;
				
			case "DIALER":
				o.className = "FuncButtonDialerNormal" + sStyle;
				break;
			
			case "SMS":
			case "MOBILE":
			case "SIMPLESMS":
				o.className = "FuncButtonMobileNormal" + sStyle;
				break;
					
			case "FULLGROUPLIST":
			case "ORGGROUPLIST":
			case "MEMBEROFGROUPLIST":
			case "SELFGROUPLIST":
			case "GROUPUSERLIST":
			case "FULLUSERLIST":
			case "DROPDOWN":
			case "CUSTOMDROPDOWN":
			case "CUSTOMDATALIST":
			case "CUSTOMLIST":
			case "DATEDROPDOWN":
			case "POSTCODECOUNTRYDROPDOWN":
			case "ALLCOUNTRYDROPDOWN":
				o.className = "FuncButtonDropNormal" + sStyle;
				break;
				
			case "NONE":
			case "":
				break;
			
		}
		
		TC_CtlMouseOut(oCtl);
	}
	
	function TC_InitialiseCharacterSizes()
	{
	    this.__CharSizes = new Array();
		    
		var oTxt = document.createElement("INPUT", "TEXT");
		
		var curStyle = this.Input.currentStyle;
		
		for (var n in curStyle)
		{
		    try
		    {
		        oTxt.style[n] = curStyle[n];
		    } catch (e)
		    {		    
		    }
		}
				
		oTxt.value = String.fromCharCode(80);		
		oTxt.style.position = "absolute";		
		document.body.appendChild(oTxt);
	                    		        
        for (var i = 0; i < 255; i++)
        {		        	    
            oTxt.value = String.fromCharCode(i);		                
            var oRange =  oTxt.createTextRange()	                
            this.__CharSizes[i] = oRange.boundingWidth;
        }		
        
        document.body.removeChild(oTxt); 		   	    
	}
	
	function TC_AutoComplete(o)
	{
	    // Ignore backspace	/ Delete    
	    if (window.event.keyCode == 8 || window.event.keyCode == 46) return;
	
	    var oJSCtl = GetParentJSControl(o, 'TEXTCONTROL');
	    if (oJSCtl == null) return;
	    
	    if (oJSCtl.AutoComplete != true) return;
	    
	    var sFunctionType = oJSCtl.Control.FunctionType;
	    if (sFunctionType != "CUSTOMDATALIST" && sFunctionType != "CUSTOMDROPDOWN") return;
	    
	    if (sFunctionType == "CUSTOMDATALIST")
	    {
	        if (oJSCtl.List.Columns.Count() < 1) return;	   
	        if (oJSCtl.List.Rows.Count() < 1) return;
	    }
	    
	    var oTxtRange = oJSCtl.GetTextRange();
	
	    if (oTxtRange.FinishIndex != oJSCtl.Input.value.length) return;
	       	    	    
	    var sUnselected = oJSCtl.Input.value.substr(0, oTxtRange.StartIndex);
	    	        
	    var dataRows = sFunctionType == "CUSTOMDATALIST" ? oJSCtl.List.Rows.Items : oJSCtl.List.GetArrayEncoded();
	    var firstMatch = null;
	    // Find first match

	    for (var i = 0; i < dataRows.length; i++)
	    {
	        var curVal = "";
	        if (sFunctionType == "CUSTOMDATALIST")
	        {
	            curVal = dataRows[i][0];
	        }
	        else 
	        {	        
	            var cols = dataRows[i].split(";");
	            curVal = UnencodeHTML(cols[0]);
	        }
	        	     
	    	if (curVal.substr(0, sUnselected.length).toUpperCase() != sUnselected.toUpperCase()) continue;
	        firstMatch = curVal;
	        break;
	    }
	      
	    // No matches available
	    if (firstMatch == null) 
	    {
	        oJSCtl.Input.fireEvent("onchange");
	        return;
	    }
	    
	    oJSCtl.Input.value = firstMatch;	    
	    
	    oTxtRange = oJSCtl.Input.createTextRange();
	    
	    var findThis = firstMatch.substring(sUnselected.length);	
        if (!findThis) return;
        
	    var b =  oTxtRange.findText(findThis , sUnselected.length * -1);
	    oTxtRange.select();	    
	    oJSCtl.Input.fireEvent("onchange");
	}
	
	function TC_InitialiseCharSizeArray()
	{
	    
	}
	
	function TC_SetTextRange(iStart, iLength)
	{
	
	}
	
	function TC_GetTextRange()
	{
	    var oJSCtl = this;
	    if (oJSCtl.__CharSizes == null) oJSCtl.InitCharSizes();
	    
	    var sCurText = oJSCtl.Input.value;
    
	    var oRange =  document.selection.createRange()
	    
	    var oTxtRange = oJSCtl.Input.createTextRange();
	    
	    var iStartLeft = oRange.offsetLeft;
	    var iWidth = oRange.boundingWidth;
	    var iEndLeft = iStartLeft + iWidth;
	    
	    var iStartIndex = 0;
	    var iFinishIndex = 0;
	    
	    // Find current position;
	    var iCurposLeft = oTxtRange.offsetLeft;
        var iCurCharPos = 0;
	    	    	    	   
	    while (iCurposLeft < iEndLeft && iCurCharPos < sCurText.length)
	    {
            var iCurCharCode = sCurText.charCodeAt(iCurCharPos);
            
            iCurposLeft += oJSCtl.__CharSizes[iCurCharCode];
 
            // Increase Start Index
            if (iCurposLeft <= iStartLeft) iStartIndex++;
                        
            // Increase Finish Index
            if (iCurposLeft >= iStartLeft && iCurposLeft <= iEndLeft) iFinishIndex++;

            // Increase Cursor Position
            iCurCharPos++;
	    }
	  
	    iFinishIndex+= iStartIndex
	    
	    // Determine finish index	    
	    iFinishIndex--;
	    
	    oTxtRange.StartIndex = iStartIndex;
	    oTxtRange.FinishIndex = iFinishIndex;
	    oTxtRange.CharacterLength = iFinishIndex - iStartIndex;
	    oTxtRange.Text = sCurText.substr(oTxtRange.StartIndex, oTxtRange.CharacterLength); 
	    return oTxtRange;
	}
	
	
	function TC_FuncButtonClick(o) {
		var oCtl;
		var oInput;
		var url="";
		
		oCtl = o.offsetParent.offsetParent.offsetParent;
		oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		
		if (oCtl.disabled) return;
		
		if (oLastFunctionControl == oInput && oPopup.isOpen == true) 
		{
			oLastFunctionControl = null;
			return;
		}

		switch (oCtl.FunctionType) 
		{
			case "NONE":
				break;
			
			case "EXTERNALEMAIL":
				window.location = 'mailto: ' + oInput.value;
				break;	
				
			case "EMAIL":
				OpenEmailDialog(oInput.value);
				break;
				
			case "WEB":
				if (oInput.value.length == 0) { break; }
				
				url = oInput.value.toLowerCase();
				if (url.indexOf("http") == -1) { url = "http://" + url }
				
				window.open(url);
				break;	
			
			case "NAMEFIELD":
				var oWindow = window.open("/CTWebControls/Additional/contactName.asp?OpenAsPopup=True","", "left=" + (window.event.screenX - 330) + ", top=" + window.event.screenY + ",width=330,height=150,resizable=no, scrollbars=no, directories=no, status=no, menubar=no, copyhistory=no");
				
				var bCaught = false;
				var oChildren = null;
				
				while (!bCaught)
				{
					try {
						if (oWindow.document.all.length > 0) bCaught = true;
						
					} catch (err) { }
					
				}
				
				oWindow.pFirstName = oCtl.children[1].children[0];
				oWindow.pLastName = oCtl.children[1].children[1];
				oWindow.pMiddleNames = oCtl.children[1].children[2];
				oWindow.pSuffix = oCtl.children[1].children[3];				
				break;
				
			
			case "POSTCODER":	
				OpenPostcodeDialog(oCtl.ControlType.toUpperCase(), oCtl.ControlDataObject);
				break;
				
			case "POSTCODERSTATES":
				OpenPostcodesStateDialog(oCtl.ControlType.toUpperCase(), oCtl.ControlDataObject);
				break;
			
			case "POSTCODECOUNTRYDROPDOWN":
				url = "/CTWebControls/Menus/menudropdown_postcodercountries.asp";				
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
				
				oLastFunctionControl = oInput;
				break;
				
			case "ALLCOUNTRYDROPDOWN":
				url = "/CTWebControls/Menus/menuDropDown_Countries.asp?" + "Style=" + oCtl.ControlStyle;				
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
				
				oLastFunctionControl = oInput;
				break;
				
			case "DATEPICKER":
				url = "/CTWebControls/Additional/datepicker.asp?IsPopup=True&IncludeTime=false&DisplayFormat=" + oCtl.DisplayFormat + "&Style=" + oCtl.ControlStyle;						
				DatePickerDownloader.startDownload(url,DatePickerDownloadComplete);
				
				oLastFunctionControl = oInput;
				break;
				
			case "DROPDOWN":
				url = "/CTWebControls/Menus/menuDropDown_FieldListEntries.asp?BelongsTo=" + oCtl.ControlDataObject + "&FieldID=" + oCtl.ControlDataField + "&Style=" + oCtl.ControlStyle;
				
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
				
				oLastFunctionControl = oInput;
				break;
				
			case "DATEDROPDOWN":
				url = "/CTWebControls/Menus/menuDropDown_Times.asp";
				
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
		
				oLastFunctionControl = oInput;
				break;
			
			case "CUSTOMLIST":
				// Do nothing, this should be handled via the events model (FUNCTIOBUTTON_CLICK)
				break;
			
			case "CUSTOMDROPDOWN":
				TC_DisplayFieldList(oCtl);
				break;
				
			case "CUSTOMDATALIST":
			    TC_RenderCustomDataList(oCtl);
			    break;
				
			case "GROUPUSERLIST":
				url = "/CTWebControls/Menus/menuDropDown_UserNameList.asp?GroupOnly=True";
				
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
				
				oLastFunctionControl = oInput;
				break;
				
			case "FULLUSERLIST":
				url = "/CTWebControls/Menus/menuDropDown_UserNameList.asp?GroupOnly=False";
				
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
				
				oLastFunctionControl = oInput;
				break;
				
			case "FULLGROUPLIST":
				url = "/CTWebControls/Menus/menuDropDown_GroupList.asp?Scope=FULL";
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
			
				oLastFunctionControl = oInput;
				break;
				
			case "ORGGROUPLIST":
				url = "/CTWebControls/Menus/menuDropDown_GroupList.asp?Scope=ORGANISATION";
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
			
				oLastFunctionControl = oInput;
				break;
			
			case "MEMBEROFGROUPLIST":
				url = "/CTWebControls/Menus/menuDropDown_GroupList.asp?Scope=MEMBEROF";					// Returns as self.
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
			
				oLastFunctionControl = oInput;
				break;
			
			case "SELFGROUPLIST":
				url = "/CTWebControls/Menus/menuDropDown_GroupList.asp?Scope=SELF";
				FieldListDownloader.startDownload(url,FieldListDownloadComplete);
			
				oLastFunctionControl = oInput;
				break;
				
			case "DIALER":
				url = "/CTWebTAPI/Dialer.asp?PhoneNumber=" + oInput.value;
				newDialog(url, 300, 200);
			
				oLastFunctionControl = oInput;
				break;
				
			case "TICKER":
			    url = "/TickerDialog.asp";
				newDialog(url, 300, 200);
			
				oLastFunctionControl = oInput;
			    break;
			    
			case "SIC":
			    url = "/SicDialog.asp";
				newDialog(url, 300, 200);
			
				oLastFunctionControl = oInput;
			    break;			                

            
            case "MOBILE":
            case "SMS":			    
            case "SIMPLESMS":
            
                //url = "/SimpleSMSDialog.asp?PhoneNumber=" + oInput.value;
                //newDialog(url, 500, 300);			   
                
                var oSingleSMSDialog = new SingleSMSDialogOptions();
                oSingleSMSDialog.Destination = oInput.value;
                oSingleSMSDialog.Show();
                
                oLastFunctionControl = oInput; 
                break;			    
		}
		
		window.event.cancelBubble = true;
		return false;
		
	}
	
	
	function TC_AddToFieldListAtPosition(oCtl, iIndex, val) {

        // ** Return if invalid index is supplied	
	    if (iIndex == -1)   return;
	
	    val = EncodeHTML(val);    
	
	    var oListCache = oCtl.children[2];
	    var outString = val + ";;;";
	    
	    var s = oListCache.innerText;	    
	    	  	    	    	    	    
        var arrElements = s.split("{#}");	    
                       
        arrElements.splice(iIndex, 0, val);
            
        var strNewListCache = "";                        
        for (var i = 0; i < arrElements.length; i++)
            strNewListCache += arrElements[i] + "{#}";
        
        // ** Remove the last '{#}'
        if (strNewListCache.length >= 3)
            strNewListCache = strNewListCache.substr(0, strNewListCache.length - 3);
                
        oListCache.innerText = strNewListCache;
	}
	
	function TC_AddToFieldList(oCtl, val) {
		// Adds a value to the field list cache of the field
		// these values are used when the function type of the
		// item is set to [CUSTOMDROPDOWN]
		val = EncodeHTML(val);
	
		var oListCache = oCtl.children[2];
		var TableHeader;
		var TableFooter;
		var s = "";
		var outString = val;
		
		s = oListCache.innerText;		
				
		//check if they passed in any of the optional arguments
		if (TC_AddToFieldList.arguments.length > 2)
		{
			for (var i = 2; i < TC_AddToFieldList.arguments.length; i++)
			{
				if (i == 6) break;	//dont count more than 3 optional arguments
				
				outString = outString + ";" + EncodeHTML(TC_AddToFieldList.arguments[i]);
			}
			
			//add any extra arguments not passed
			if (TC_AddToFieldList.arguments.length < 6)
			{
				for (var i = 1; i < (6 - TC_AddToFieldList.arguments.length); i++)
				{
					outString = outString + ";";
				}
			} 
			
			
		} else {
			outString = outString + ";;;";
		}
		
		
		if (s.length)
		{
			oListCache.innerText = oListCache.innerText + "{#}" + outString;
		} else {
			oListCache.innerText = outString;
		}
		
	}
	
	
	function TC_GetListCount(oCtl) {
		var oListCache = oCtl.children[2];
		var ListItems;
		var cachetext = oListCache.innerText;

		if (cachetext.length == 0) return 0;
		
		ListItems = oListCache.innerText.split("{#}");
		return ListItems.length; 
	}
	
	
	function TC_ClearList(oCtl) {
		var oListCache = oCtl.children[2];
		oListCache.innerHTML = "";
	}
	
	
	function TC_RemoveFromList(oCtl, Index) {
		var oListCache = oCtl.children[2];
		var ListItems;
		var s="";
		
		ListItems = oListCache.innerText.split("{#}");
		
		if (ListItems.length < Index || Index < 0) return;			// bounds checking
				
		//re-write the list
		for (var i = 0; i < ListItems.length; i++)
		{
			if (i != Index) s = s + "{#}" + ListItems[i];
		}
		
		//remove starting delimiter, check existing length
		if (s.length) s = s.substr(3);
		
		//re-assign data back to cache
		oListCache.innerText = s;
	}
	
	
	function TC_SelectListItem(oCtl, sArg) {
		var oListCache = oCtl.children[2];
		var oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		var ListItems;
		var s = "";
		var Index = -1;
		var oVals;
		var ReturnColumnIndex = parseInt(oListCache.ColumnReturn) - 1;
		
				
		if (TC_SelectListItem.arguments.length > 2)
		{	
			// Override the lists standard return column
			ReturnColumnIndex = TC_SelectListItem.arguments[2];
		} 
		
		
		ListItems = oListCache.innerText.split("{#}");
		
		if (sArg.IsNumeric() == true) { 
			Index = sArg;
		} else {
		
			for (var i=0; i < ListItems.length; i++)
			{
				oVals = ListItems[i].split(";");
				
				if (UnencodeHTML(oVals[0]) == sArg)
				{
					Index = i;
					break;
				}
			}
		}
		
		if (ListItems.length <= Index || Index < 0) return;			// bounds checking
		
		if (Index != -1) {		    
			oVals = ListItems[Index].split(";");
			oInput.value = UnencodeHTML(oVals[ReturnColumnIndex]);
		} else {
			oInput.value = "";
		}
			
			
		oCtl.SelectedIndex = Index;
		oInput.fireEvent('onchange');
	}
	
	
	function TC_FindListItem(oCtl, Arg, Col) {
		// Returns the index of the first matching item
	
		var oListCache = oCtl.children[2];
		var ListItems = oListCache.innerText.split("{#}");
		
		if (Col == null || Col == undefined) Col = 0;
					
		for (var i = 0; i < ListItems.length; i++)
		{
			var Cols = ListItems[i].split(";");
		
			if (UnencodeHTML(Cols[Col]) == Arg)
			{
				return i;
			}
		}
		
		return -1;
	}
	
	function TC_GetListArrayEncoded()
	{
	    var oListCache = this.Control.children[2];
	    ListItems = oListCache.innerText.split("{#}");
	    return ListItems;
	}
	
	function TC_GetListItem(oCtl, sIndex) {
		// Pass in a Control, either its Index or a string, 
		// prop = value to be returned (value, arg1, arg2, arg3)
	
		var oListCache = oCtl.children[2];
		var oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		var ListItems;
		var s="";
		var Index = -1;
		var oVals;
		var retIndex = 0;
		var prop;
		
		if (TC_GetListItem.arguments.length == 3 ) {
			prop = TC_GetListItem.arguments[2];
		} else {
			prop = "VALUE";
		}
		
		
		ListItems = oListCache.innerText.split("{#}");
		
		if (IsNumeric(sIndex)) { 
			Index = sIndex;
		} else {
		
			for (var i=0; i < ListItems.Length; i++)
			{
				oVals = Listitems[Index].split(";")
			
				if (UnencodeHTML(oVals[0]) == sIndex)
				{
					Index = i;
					break;
				}
			}
		}
		
		if ((ListItems.length - 1) < Index || Index < 0) return "";			// bounds checking
		
		if (Index != -1) 
		{
			
			oVals = ListItems[Index].split(";");
			
			switch (prop.toUpperCase())
			{
				case "VALUE","":
					retIndex = 0;
					break;
					
				case "ARG1","1":
					retIndex = 1;
					break;
					
				case "ARG2","2":
					retIndex = 2;
					break;
					
				case "ARG3","3":
					retIndex = 3;
					break;
					
				case "INDEX":
					retIndex = -1;
					break;
			}
			
			if (RetIndex != -1) {	// return a value from the list
				return UnencodeHTML(oVals[retIndex]);
			} else {
				return Index;		// return the index from the list
			}
			
		} else {
			return "";
		}
	}
		
	
	function TC_FieldListItemMouseOver(oItem, sStyle) {
		if (oItem.origClass == "") {
			oItem.origClass = oItem.className;
		}
		oItem.className = "SelectedRow" + sStyle;
	}
	
	
	function TC_FieldListItemMouseOut(oItem) {
		oItem.className = oItem.origClass;
	}
	
	
	function TC_FieldListItemMouseUp(oRowItem) {
	    try {
		    var oInput = oLastFunctionControl;
		    var oCtl = oInput.offsetParent.offsetParent.offsetParent;
    		
		    oPopup.hide();
		    TC_SelectListItem(oCtl,oRowItem.rowIndex);
		}catch (err) {
		}
	}
	
		
	function TC_GetListSelectedIndex(oCtl) {
		return oCtl.SelectedIndex;
	}
	
	
	
	function TC_GetListCell(oCtl, Row, Col) {
		var oListCache = oCtl.children[2];
		var ListItems;
		var Cols;
		
		if (oCtl == undefined || Row == undefined || Col == undefined) return "";		//make sure arguments are passed
			
		if (Row < 0 || Col < 0) return "";								//check lower bounds on column and rows
			
		if (oListCache.innerText.length == 0) return "";			//check for zero length cache
		
						
		ListItems = oListCache.innerText.split("{#}");				// Retrieve and split rows	
			
		if (Row >= ListItems.length)	return "";						// check upper bound on the rows
		
	
		Cols = ListItems[Row].split(";");							// split to cols
				
		if (Col >= Cols.length) return "";							// check upper bound on the columns				
				
		return UnencodeHTML(Cols[Col]);
	}
	
	
	function TC_SetListCell(oCtl, Row, Col, Value) {
		var oListCache = oCtl.children[2];
		var ListItems;
		var sListItem="";
		var aRow; 
		var sRow = "";
		
		if (Row < 0 || Col < 0) return false;								// check lower bounds on column and rows
		
		if (oListCache.innerText.length == 0) return false;					// check for zero length cache
		
		ListItems = oListCache.innerText.split("{#}");						// Retrieve and split row entries	
		
		if (Row > ListItems.length) return false;							// check upper bound on the rows
		
		aRow = ListItems[Row].split(";");									// split target row to column values
		
		if (Col > aRow.length) return false;								// check column upper bound value
	
		aRow[Col] = EncodeHTML(Value);										// save value
		
		for (var i = 0; i < aRow.length; i++)								// recompile row
		{
			sRow = sRow + ";" + aRow[i];
		}
		sRow = sRow.substr(1);												// clip starting delimiter
		
		ListItems[Row] = sRow;												// re-insert row
		
		for (var i = 0; i < ListItems.length; i++) {						// recompile values
			sListItem = sListItem + "{#}" + ListItems[i];
		}
		
		sListItem = sListItem.substr(3);									// clip starting delimiters
		oListCache.innerText = sListItem;
		
		return true;
	}
	
	
	function TC_ShowAdminCaptionPopup(oCtl, oCaption, clickX, clickY) {
        oPopup = window.createPopup();
        
        var aOut = new Array(0);
        var idx = 0;
        
        if (ApplicationObjects == null) return;
        if (ApplicationObjects.User == undefined) return;
        if (ApplicationObjects.User.Permissions == undefined) return;
        if (ApplicationObjects.User.Permissions.General == undefined) return;                       
        if (ApplicationObjects.User.Permissions.General.FieldAdministration != true) return;
        
        
        aOut[idx++] = '<html><head></head><body style="margin: 0; border: 1px solid black; overflow: hidden; ">';
        aOut[idx++] =   '<table style="width: 100%;" cellpadding=2 cellspacing=0>';
        aOut[idx++] =       '<tr>';
        aOut[idx++] =           '<td onclick="document.EditFieldName(\'' + oCtl.ControlDataObject + '\', \'' + oCtl.ControlDataField + '\')" style="width: 100%; cursor: hand; white-space: nowrap; overflow: hidden; font: 9pt tahoma; background-color: #D9E1F2; width: 100%; color: #687492;">Edit field name</td>';
        aOut[idx++] =       '</tr>';
        aOut[idx++] =       '<tr>';
        aOut[idx++] =           '<td onclick="document.EditFieldList(\'' + oCtl.ControlDataObject + '\', \'' + oCtl.ControlDataField + '\')" style="width: 100%; cursor: hand; white-space: nowrap; overflow: hidden; font: 9pt tahoma; background-color: #EEF4FF; width: 100%; color: #687492;">Edit field list</td>';
        aOut[idx++] =       '</tr>';
        aOut[idx++] =    '</table>';        
        aOut[idx++] =   '</body>';
        aOut[idx++] = '</html>';
        
        var sOut = aOut.join("");
        oPopup.document.write(sOut);
        oPopup.document.EditFieldName = TC_EditFieldName;
        oPopup.document.EditFieldList = TC_EditFieldList;
        
        var offsetX = 0;
        var offsetY = 0;
        var Width = 200;
        var Height = 40;
        
        oPopup.show(clickX, clickY, Width, Height);
	}
	
	
	function TC_EditFieldList(BelongsTo, FieldID) {
	    var o = new FieldListOptionsDialogOptions();
	    o.BelongsTo = BelongsTo;
	    o.FieldID = FieldID;
	    o.Show();
	}
	
	function TC_EditFieldName(BelongsTo, FieldID) {	
	    var o = new FieldOptionsDialogOptions();
	    o.BelongsTo = BelongsTo;
	    o.FieldID = FieldID;
	    o.Show();   
	}
	
	function TC_DisplayFieldList(oCtl) {
		/*
		This function displays a custom drop down control
		List items are expected to be in the Controls cache, use functions below
		
			Add an item to the list		TC_AddToFieldList(oCtl, val) 
			Remove an item from list	TC_RemoveFromList(oCtl, Index)
		*/
	
		var oListCache = oCtl.children[2];
		var oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
		var iListCount = 0;
		var ListHeight = 0;
		var w=0;
		var ListItems;
		var ItemClass;
		var j=0;
		var iTop = 0;
		var selectedIndex = parseInt(oCtl.SelectedIndex,10);
		var oJSCtl = GetParentJSControl(oCtl);
		
		var sStyle = '';
		var sBodyStyle = '';
        switch (oCtl.ControlStyle)
        {
            case "4":
                sStyle = "Vista";
                sBodyStyle = 'border: 1px solid #5EB1D8; background-color: #D1DCFF; overflow-x: hidden; overflow-y: scroll;';
                break;
            default:
                sStyle = "";
                sBodyStyle = 'border: 1px solid #0A246A; background-color: #D1DCFF; overflow-x: hidden; overflow-y: scroll;';
		        break;
		}
		
		oLastFunctionControl = oInput;

		// Retrieve and split entries					
		ListItems = oListCache.innerText.split("{#}");	
		
		var aOut = new Array(0);
		var idx = 0;
			
		// Build the header of the poup
		aOut[idx++] = "<html><head><link rel='stylesheet' href='/CTWebStyles/main.css'><script language=javascript>function popKeyUp() { }</script></head>";
		aOut[idx++] = "<body topmargin=0 leftmargin=0 style='" + sBodyStyle + "' unselectable='on'>";		
		aOut[idx++] = "<table cellpadding=2 cellspacing=0 width=100% unselectable='on'>";
		
		
		var oVals;
		var Col2Style = "none";
		var Col3Style = "none";
		var Col4Style = "none";
		
		
		switch (parseInt(oListCache.ColumnCount,10))
		{
			case 1:
				break;
			
			case 2:
				Col2Style = "block; width: 25%";
				break;
			
			case 3:
				Col2Style = "block; width: 25%";
				Col3Style = "block; width: 25%";
				break;
				
			case 4:
				Col2Style = "block; width: 25%";
				Col3Style = "block; width: 25%";
				Col4Style = "block; width: 25%";
				break;
		}
		
		var RowColors = new Array(0);
		
		if (oCtl.JSControl) RowColors = oCtl.JSControl.List.RowColors;
		
			
		// Insert entries, perform Item/AltItem/SelectedItem class traversing
		if (ListItems.length > -1)
		{
			iListCount = ListItems.length;
		
			for (var i = 0; i < ListItems.length; i++)
			{
				if (j == 0) { ItemClass = ("Item" + sStyle); j++ } else { ItemClass = ("AltItem" + sStyle); j-- }
								
				oVals = ListItems[i].split(";");

				if (i == selectedIndex) {ItemClass = ("SelectedRow" + sStyle) }
				
				aOut[idx++] = "  <tr unselectable='on' style='" + ((RowColors[i] != undefined) ? 'color: ' + RowColors[i] + ';' : '') + "' class='" + ItemClass + "' origClass='" + ItemClass + "' onmouseover='window.parent.TC_FieldListItemMouseOver(this, \"" + sStyle + "\");' onmouseout='window.parent.TC_FieldListItemMouseOut(this);' onclick='window.parent.TC_FieldListItemMouseUp(this);'>";
				
				aOut[idx++] = "<td unselectable='on' style='display: block; width: 25%;'><nobr>&nbsp;";
				aOut[idx++] = UnencodeHTML(oVals[0]);
				aOut[idx++] = "</nobr></td>";
				aOut[idx++] = "<td unselectable='on' style='display: ";
				aOut[idx++] = Col2Style;
				aOut[idx++] = "; border-left: 1px solid #ACA899;'><nobr>&nbsp;"
				aOut[idx++] = UnencodeHTML(oVals[1]);
				aOut[idx++] = "</nobr></td>";
				aOut[idx++] = "<td unselectable='on' style='display: ";
				aOut[idx++] = Col3Style;
				aOut[idx++] = "; border-left: 1px solid #ACA899;'><nobr>&nbsp;";
				aOut[idx++] = UnencodeHTML(oVals[2]);
				aOut[idx++] = "</nobr></td>";
				aOut[idx++] = "<td unselectable='on' style='display: ";
				aOut[idx++] = Col4Style;
				aOut[idx++] = "; border-left: 1px solid #ACA899;'><nobr>&nbsp;";
				aOut[idx++] = UnencodeHTML(oVals[3]);
				aOut[idx++] = "</nobr></td>";
	
				aOut[idx++] = "</tr>";
			}
			
		} else {
			iListCount = 1;
		
			aOut[idx++] = "  <tr origClass='' onmouseover='window.parent.TC_FieldListItemMouseOver(this, \"" + sStyle + "\");' onmouseout='window.parent.TC_FieldListItemMouseOut(this);' onclick='window.parent.TC_FieldListItemMouseUp(this);'>";
			aOut[idx++] = "<td class='Item'>&nbsp</td></tr>";
		}		
		
		
		// Create footer of the list
		aOut[idx++] = "</table>";
		
		
		var iMaxListRowDisplay = (oJSCtl != null) ? oJSCtl.List.MaxDisplay : 10;
		if (iMaxListRowDisplay < 1) iMaxListRowDisplay = 1;
		
		// Determine popup height for the drop down
		if (iListCount <= iMaxListRowDisplay) {
			ListHeight = (iListCount * 17) + 2
		} else if (iListCount > iMaxListRowDisplay) {
			ListHeight = (17*iMaxListRowDisplay) + 2;
		}
		
		var sOut = aOut.join("");
		
		// Create and show the drop down list
		oPopup = window.createPopup();
		oPopup.document.innerHTML = "";
		oPopup.document.write(sOut);
		
		w = parseInt(oInput.style.width,10) + 22;
        
        

		if (oInput.parentElement.parentElement.children[0].style.display == "block")
		{
			// Side Caption
			var oInputTable = oInput.offsetParent.offsetParent;
			
			w = parseInt(oInputTable.style.width,10);
			
			refObject = oInput.parentElement.parentElement.children[0];
			iTop = 20;
		} else {
			// Top Caption
			w = parseInt(oInput.style.width,10) + 22;
			
			refObject = oInput;
			iTop = 19;
		}


		//oPopup.show(-1,20,w,ListHeight,oInput);
		oPopup.show(-1,iTop,w,ListHeight,refObject);
	}
	
	
	
function TC_ConstructorArguments(strArguments) {
/*    Dim funcStyle
	Dim funcButtonClass
	Dim funcVal
	Dim ctlClass
	Dim ctlInputClass
	Dim ctlInputCellClass
	Dim sEnabled
	Dim sValidation
	Dim sInputMask
	
	Dim ctlCaptionPopup
	Dim ctlSearchPopup
	Dim ctlFieldListPopup
	Dim ctlFieldListName
	
	this.Top = 0;
	this.Left = 0;
	this.Width = 200;
	this.Position = 'absolute';
*/	
	
}



function TC_RenderTextControl(constructorArguments) {
    // Paints the display of the control, all visual stuff
}

function TC_CreateBaseTextControlContainer(constructorArguments) {
    // Creates the outer div, only called once.
}


function PageStartup() {
//<% CreateTextControl "name: mikey;" %>

//    var o = new TC_ConstructorArguments("name: mikey;");
        
//    var c = new TextControl(o);
}



function TC_RenderCustomDataList(oCtl) {
    if (oCtl.JSControl == undefined) return;
    var oJSCtl = oCtl.JSControl;

    var ColStyle = '';
    var iHeight = oJSCtl.List.RowHeight;

	switch (2)
	{
		case 1:	// White data grid style
			ColStyle = 'border-right: 1px solid #C0C0C0; border-bottom: 1px solid #C0C0C0';
			if (oJSCtl.List.SelectedColor == "") oJSCtl.List.SelectedColor = '#3c76c1';
			if (oJSCtl.List.RowColor == "")     oJSCtl.List.RowColor = '#ffffff';
			if (oJSCtl.List.RowAltColor == "")  oJSCtl.List.RowAltColor = '#ffffff';			
			break;
			
		case 2: // ContactTracker style
			oJSCtl.List.AlternateRowColors = true;
			
			ColStyle = 'border-right: 1px solid #C0C0C0';			
			if (oJSCtl.List.RowColor == "") oJSCtl.List.RowColor = '#e1ecff';
			if (oJSCtl.List.RowAltColor == "") oJSCtl.List.RowAltColor = '#d1dcff';
			if (oJSCtl.List.SelectedColor == "") oJSCtl.List.SelectedColor = '#8592b5';
			
			break;
			
		case 3:
			oJSCtl.List.AlternateRowColors = true;	
			ColStyle = '';
			if (oJSCtl.List.RowColor == "") oJSCtl.List.RowColor = '#EEF4FF';
			if (oJSCtl.List.RowAltColor == "") oJSCtl.List.RowAltColor = '#CBDEFF';
			if (oJSCtl.List.SelectedColor == "") oJSCtl.List.SelectedColor = '#8592b5';
			
			break;
		
		case 4:
			oJSCtl.List.AlternateRowColors = true;	
			ColStyle = '';
			if (oJSCtl.List.RowColor == "") oJSCtl.List.RowColor = '#EEF4FF';
			if (oJSCtl.List.RowAltColor == "") oJSCtl.List.RowAltColor = '#D9E1F2';
			if (oJSCtl.List.SelectedColor == "") oJSCtl.List.SelectedColor = '#8592b5';
			
			break;
	}	

    

    var aOutput = new Array(0);
    var idx     = 0;

    var aRows = oJSCtl.List.Rows.Items;
    var Columns = oJSCtl.List.Columns.Items;

    aOutput[idx++] = '<html><head><link rel=stylesheet href="/CTWebStyles/main.css"></link></head><body style="border: 1px solid black; margin: 0px; overflow: auto;">';
    aOutput[idx++] = '<table style="table-layout: fixed; width: 100%;" cellpadding=1 cellspacing=0 id="__RenderedTable">';	
		 
	for (var i = 0; i < aRows.length; i++)
	{
	    var row = aRows[i];
	    
		aOutput[idx++] = '<tr zondblclick="EventCollector(this, \'ROW_DOUBLECLICK\');" onclick="document.ParentList.Events.RaiseEvent(\'ROW_CLICK\', this, this.rowIndex);"  zonclick="if (GetParentJSControl(this, \'DATAGRIDCONTROL\').Control.disabled == true) return; EventCollector(this, \'ROW_BEFORESELECT\'); DGC_SelectRow(this);"  zonmouseover="DGC_RowMouseOver(this);" zonmouseout="DGC_RowMouseOut(this);" style="display: block;">';
		
		for (var n = 0; n < Columns.length; n++)
		{
			aOutput[idx++] = '<td zonclick="EventCollector(this, \'CELL_BEFORESELECT\'); DGC_Cell_Select(this);" style="height: ';
			aOutput[idx++] = iHeight;
			aOutput[idx++] = '; background-color: ';
			aOutput[idx++] = ((oJSCtl.List.AlternateRowColors) ? (((i % 2 == 0)) ? oJSCtl.List.RowColor : oJSCtl.List.RowAltColor) : '#ffffff');
			aOutput[idx++] = '; ';
			aOutput[idx++] = ColStyle;
			aOutput[idx++] = '; width: ';
			aOutput[idx++] = Columns[n].Width;
			aOutput[idx++] = '; display: ';
			aOutput[idx++] = ((Columns[n].Visible) ? "block" : "none") + ';">';
			aOutput[idx++] = '<div zondblclick="DGC_Cell_DoubleClick(this); EventCollector(this.parentElement, \'CELL_DOUBLECLICK\')" zonblur="DGC_Cell_LostFocus(this); EventCollector(this.parentElement, \'CELL_LOSTFOCUS\')" zonclick="__DGC_CellClick(this.parentElement);" style="white-space: nowrap; overflow: hidden; vertical-align: middle; ';
			aOutput[idx++] = Columns[n].Style + '">';
			
			var sColumnType = Columns[n].ColumnType;
			if (typeof(sColumnType) == 'string') sColumnType = sColumnType.toUpperCase();
			
									
			switch (sColumnType)
			{
				case "TEXTBOX":
				    aOutput[idx++] = '  <input type="text" value="" style="width: 100%;" zonkeyup="DGC_Cell_TextBox_OnKeyUp(this)"/>';
				    break;
				
				case "IMAGE":
					aOutput[idx++] = '	<img src="" style="display: none;">';
					break;
		
				case "RADIO":
					aOutput[idx++] = '	<input type=radio style="border: none; position: relative; left: -2;" ID="Radio1" VALUE="Radio1" NAME="RadioGroup">';
					break;
					
				case "CHECKBOX":
					aOutput[idx++] = '	<input type=checkbox onclick="document.ParentList.SetCell(' + i + ', ' + n + ', this.checked)"  style="border: none; position: relative; left: -2;" ' + (row[n] == true ? ' checked ': '') + '>';
					break;
					
					
				case "DROPDOWN":

					aOutput[idx++] = '	<select style="width: 100%;" zonchange="DGC_Cell_DropDownChange(this);" zonclick="DGC_Cell_DropDownClick(this);">';
					var ListValues = Columns[n].ListValues;
					
					// Check they've given a collection
					if (ListValues != null && typeof(ListValues) == 'object' && ListValues.ConstructorName() == 'Collection') {
						ListValues = ListValues.Items;

						if (ListValues.length > 0) {	
							for (var iOption = 0; iOption < ListValues.length; iOption++) {						
								aOutput[idx++] = '<option value="' + ListValues[iOption].Value + '">';
								aOutput[idx++] = ListValues[iOption].Text;
								aOutput[idx++] = '</option>';
							}
						}
					}
					
					aOutput[idx++] =	'	</select>';
					break;
				
				case "DATE":
					aOutput[idx++] = '<div style="width: 100%; text-align: right;"><span></span><span style="display: ';
					aOutput[idx++] = ((Columns[n].Calendar) ? 'display':'none');
					aOutput[idx++] = '; padding-right: 2px;"><img style="cursor: hand;" alt="Click to change the date" src="/CTWebImages/Calendar/CalendarIcon.gif" zonclick="DGC_Cell_ShowCalendar(this);"></span></div>';
					break;
					
				case "CUSTOM":
				                            // (Column Index, RowIndex, Columns, DataGridControl)
					if (Columns[n].CellParser != null && Columns[n].CellParser != undefined) {
						aOutput[idx++] = Columns[n].CellParser(n, i, Columns, oJSCtl);	// Fires a custom renderer event that passes the column index, the rowIndex and the columns collection, and the datagrid control
						break;															// the custom function should return a valid HTML string
					}	// Allow drop through.
				case null:
				case undefined:
				case "TEXT":
				    aOutput[idx++] = '<div style="padding-left: 3px;">' + row[n] + '</div>';
				    break;
				    
				case "HTML":
				case "INDEX":
				default:
					break;

			}

			
			aOutput[idx++] = '</div>';
			aOutput[idx++] = '</td>';
		}
		
		aOutput[idx++] = '</tr>';
	}
	
	aOutput[idx++] = '</table>';
	
	var sOut = aOutput.join("");
	var iTop = 0;

	var refObject = null;
	var oInput = oCtl.children[0].children[0].children[1].children[1].children[0];
    var w = 0;
    
	if (oInput.parentElement.parentElement.children[0].style.display == "block")
	{
		// Side Caption
		var oInputTable = oInput.offsetParent.offsetParent;
		
		w = parseInt(oInputTable.style.width,10);
		
		refObject = oInput.parentElement.parentElement.children[0];
		iTop = 20;
	} else {
		// Top Caption
		w = parseInt(oInput.style.width,10) + 22;
		
		refObject = oInput;
		iTop = 19;
	}
		
	
	aOutput.splice(0, aOutput.length);
	
	oPopup = window.createPopup();
	oPopup.document.write(sOut)
	oPopup.show(0, 0, 0, 0);
	var fpIsOpenPoller = function() 
	{ 
	    if (oPopup.isOpen) 
	    {
	        setTimeout(fpIsOpenPoller, 250);
	    }
	    else
	    {
	        oJSCtl.List.Events.RaiseEvent("POPUP_CLOSED");
	    }
	};

	setTimeout(fpIsOpenPoller, 250);
		
	var iFullHeight = parseInt(oPopup.document.all.__RenderedTable.clientHeight, 10);
	var iAvHeight = aRows.length > 0 ? iFullHeight / aRows.length : 0;	
	var iHeight = aRows.length > oJSCtl.List.MaxRows ? iAvHeight * 10 : iFullHeight;

	
	if (aRows.length < oJSCtl.List.MaxRows) {
	    oPopup.document.body.style.overflow = 'hidden';
	}

	oPopup.document.ParentList = oJSCtl.List;
	
	oPopup.show(-1,iTop,w,iHeight,refObject)
}

function TC_DataList_RowClick(oSrc, aArgs1, aArgs2) 
{
    var dl = aArgs1[0];
    var iRowIndex = aArgs2[0];
    
    switch (dl.Behaviour.toUpperCase())
    {        
        case "SIMPLEDROPDOWN":
            dl.Cursor.Index(iRowIndex);
            oPopup.hide();
            break;                       
        
        case "SIMPLECHECKEDLIST":
        case "CUSTOM":
        default:
            break;
    }
}

function TC_DataList_Change(oSrc, aArgs1, aArgs2)
{
    var dlList = aArgs1[0];

    switch (dlList.Behaviour.toUpperCase())
    {
        case "SIMPLECHECKEDLIST":
            TC_CheckedList_RefreshInput(dlList);
            break;        
    }
}

function TC_CheckedList_RefreshInput(dlList)
{
    var sOut = '';
    var aRows = dlList.Rows.Items;
    
    if (typeof(dlList.CheckedListIncludeColumn) == 'number')
    {
        var iCount = 0;
        
        for (var i = 0; i < aRows.length; i++)
        {
            if (aRows[i][dlList.CheckedListIncludeColumn] != true) continue;
            
            iCount++;            
            sOut += ', ' + aRows[i][dlList.CheckedListDisplayColumn];
        }
        
        if (iCount > 0)
            sOut = sOut.substr(2);
    }
    
    dlList.ParentControl.Input.value = sOut;
}

function TC_DataList_CursorMove(oSrc, aArgs1, aArgs2) 
{   
    var dl = aArgs1[0];
    var cols = dl.Columns.Items;

    for (var i = 0; i < cols.length; i++) 
    {
        if (cols[i].Visible) 
        {
            dl.ParentControl.Input.value = dl.Cursor.Row()[i];
            dl.ParentControl.Input.fireEvent("onchange");
            return;
        }
    }
    
    dl.ParentControl.Input.value = '(Selected)';
}
