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);

    Object.Inherits(this, WebControl);

    if (oCtlOrConstructorArguments == null || oCtlOrConstructorArguments == undefined || typeof (oCtlOrConstructorArguments) != 'object')
        throw new Error('Control element or constructor arguments object not passed to TextControl()');

    this.DayViewCalendarResourceId = null;     // When specified the DayViewCalendar will show items from this calendar item
    this.DayViewCalendarResourceType = null;    // As Above
    this.DayViewCalendarDisplayFormat = null;
    this.DayViewCalendarDuration = null;
    this.DayViewCalendarInitialDate = null;

    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',
    DayViewDatePicker: 'DAYVIEWDATETIMEPICKER',
    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 FunctionButtonDisabled = ConstructorArguments.FunctionButtonDisabled
    if (FunctionButtonDisabled == undefined) FunctionButtonDisabled = false;
    if (typeof (FunctionButtonDisabled) != "boolean")
        throw new Error('FunctionButtonDisabled 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 DayViewCalendarDisplayFormat = ConstructorArguments.DayViewCalendarDisplayFormat;
    var DayViewCalendarResourceType = ConstructorArguments.DayViewCalendarResourceType;
    var DayViewCalendarResourceId = ConstructorArguments.DayViewCalendarResourceId;
    var DayViewCalendarDuration = ConstructorArguments.DayViewCalendarDuration;
    var DayViewCalendarInitialDate = ConstructorArguments.DayViewCalendarInitialDate;

    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 TextControl.CaptionStyles.Side:
            ctlTopCaptionStyle = "display: none;"
            ctlSideCaptionStyle = "display: block;"
            break;

        case TextControl.CaptionStyles.None:
            ctlTopCaptionStyle = "display: none;"
            ctlSideCaptionStyle = "display: none;"
            break;

        case TextControl.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:
            // added by yong for make customer button has a default icon
        case TextControl.FunctionTypes.CustomButton:
            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:
        case TextControl.FunctionTypes.DayViewDatePicker:
            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.FunctionButtonDisabled = FunctionButtonDisabled;
    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();

    this.Control.DayViewCalendarDisplayFormat = DayViewCalendarDisplayFormat;
    this.Control.DayViewCalendarResourceType = DayViewCalendarResourceType;
    this.Control.DayViewCalendarResourceId = DayViewCalendarResourceId;
    this.Control.DayViewCalendarDuration = DayViewCalendarDuration;
    this.Control.DayViewCalendarInitialDate = DayViewCalendarInitialDate;


    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: if (GetParentJSControl(this).Control.FunctionButtonDisabled) return false; 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;
                o.className = "FuncButtonDropOver" + sStyle;
            } else {
                o.className = oJSCtl.FunctionButtonOverStyle;
            }
            break;

        case "EXTERNALEMAIL":
        case "EMAIL":
            o.className = "FuncButtonEmailOver" + sStyle;
            break;

        case "WEB":
            o.className = "FuncButtonWebOver" + sStyle;
            break;

        case "DAYVIEWDATETIMEPICKER":
        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;
                o.className = "FuncButtonDropNormal" + sStyle;

            } else {
                o.className = oJSCtl.FunctionButtonNormalStyle;
            }
            break;

        case "EXTERNALEMAIL":
        case "EMAIL":
            o.className = "FuncButtonEmailNormal" + sStyle;
            break;

        case "WEB":
            o.className = "FuncButtonWebNormal" + sStyle;
            break;

        case "DAYVIEWDATETIMEPICKER":
        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.get_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 "DAYVIEWDATETIMEPICKER":
            url = "/CTWebControls/Additional/PopupDayViewCalendar.aspx?Nothing";
            if (oCtl.DayViewCalendarDisplayFormat && oCtl.DayViewCalendarDisplayFormat.length > 0) {
                url += "&OutputFormat=" + oCtl.DayViewCalendarDisplayFormat;
            }

            if (oCtl.DayViewCalendarResourceId && oCtl.DayViewCalendarResourceId.length > 0) {
                url += "&ResourceId=" + oCtl.DayViewCalendarResourceId;
                url += "&ResourceType=" + oCtl.DayViewCalendarResourceType;
            }

            url += "&Duration=" + (oCtl.DayViewCalendarDuration == null ? 30 : oCtl.DayViewCalendarDuration);

            if (oCtl.DayViewCalendarInitialDate) {
                var dt = new Date();
                if (dt.ParseDate(oCtl.DayViewCalendarInitialDate)) {
                    url += "&InitialDate=" + dt.Format("yyyy-mm-dd");
                }
            }

            var oWnd = radopen(url, "DayViewTimePickerWindow");

            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.toString().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 = Popup.createPopup(true);

    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 = Popup.createPopup(true);
    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' && Object.ConstructorName(ListValues) == '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 = Popup.createPopup(true);
    oPopup.document.write(sOut)
    oPopup.show(0, 0, 0, 0);
    var fpIsOpenPoller = function () {
        if (oPopup.get_isOpen()) {
            setTimeout(fpIsOpenPoller, 250);
        }
        else {
            oJSCtl.List.Events.RaiseEvent("POPUP_CLOSED");
        }
    };

    setTimeout(fpIsOpenPoller, 250);

    var fWhenReady = function () {

        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)
    };

    setTimeout(fWhenReady, 50);
}

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)';
}


function DayViewTimePickerWindow_OnClientClose(oWnd, args) {
    var arg = args.get_argument();

    if (arg) {
        var time = arg.Time;

        oLastFunctionControl.value = time;

        var js = GetParentJSControl(oLastFunctionControl);
        js.Events.RaiseEvent("DAYVIEWTIMEPICKER_TIMESELECTED", js, time);
    }


}

function DayViewTimePickerWindow_ShowWindow() {
    var wndAvail = false;
    try {
        if (radopen)
            wndAvail = true;
    }
    catch (e) {
    }
    if (!wndAvail)
        throw new Error("You need to include a RadWindowManager with a window matching 'DayViewTimePickerWindow'");

    var oWnd = radopen("/CTWebControls/Additional/PopupDayViewCalendar.aspx", "DayViewTimePickerWindow");
}
