﻿PAT.QueryPanel = Class.create({
    domObj: null,
    menuContainer: null,
    queryBy: null,
    queryBySelect: null,
    //callbackObj -- an object has member
    //   -- id,
    //   -- name,
    //   -- value,
    //   -- selectControlId
    callbackObj: null,
    callbackObjMaster: null,
    //controlObjs -- contains menu, menuitem information has member
    //   -- menuId,
    //   -- menuItemId,
    //   -- fieldId,
    //   -- ordinal,
    //   -- control
    //   -- name (field name)
    //   -- title (field alias)
    //   -- operatorGroup
    //   -- operator
    //        an array of operator[
    //       -- name
    //       -- function
    //       -- id                 ]
    controlObjs: null,
    currentMenuId: null,
    firstCtrl: null,
    autoCompletePopup: null,
    autoCompleteRow: null,
    autoCompleteInterval: 500,
    autoCompleteTimer: null,
    autoCompletePopupSrc: null,
    lastMouseOverRow: null,
    currentMouseX: 0,
    currentMouseY: 0,
    lastMouseX: 0,
    lastMouseY: 0,
    searchResult: null,
    tabIndex: 0,
    initialize: function()
    {
        this.domObj = new Element('div', { 'id': 'queryContainer' });
        this.domObj.setStyle("overflow:hidden;");
        this.domObj.observe("PAT.Query:MENU_CLICK", this.loadQueriesFromMenu.bind(this));

        this.domObj.excludeOptions = new Element('div', { 'id': 'excludeOptions' });
        this.domObj.excludeOptions.setStyle("position:absolute;top:0px");
        var excludeHTML = [];
        excludeHTML.push("<hr /><table><tr><td><input id='chkExcludeBlank' type='checkbox' onclick='query.applyExcludeFilter(\"BLANK\")'>");
        excludeHTML.push(getText("ExcludeBlank"));
        excludeHTML.push("</input></td></tr><tr><td><input id='chkExcludeZero' type='checkbox' onclick='query.applyExcludeFilter(\"ZERO\")'>");
        excludeHTML.push(getText("ExcludeZero"));
        excludeHTML.push("</input></td></tr><tr><td><input id='chkExcludeNull' type='checkbox' onclick='query.applyExcludeFilter(\"NULL\")'>");
        excludeHTML.push(getText("ExcludeNull"));
        excludeHTML.push("</input></td></tr></table>");
        this.domObj.excludeOptions.innerHTML = excludeHTML.join('');
        this.domObj.queryContent = new Element('div', { 'id': 'queryContent' });
        this.domObj.insert(this.domObj.queryContent);
        this.domObj.insert(this.domObj.excludeOptions);
        if (enableExcludeOptions == "false")
            this.domObj.excludeOptions.hide();

        this.domObj.queryContent.setStyle("overflow:auto;position:absolute");

        this.domObj.queryContent.setStyle("top:" + this.domObj.excludeOptions.getHeight() + "px");

        this.callbackObj = [];
        if (PAT.alwaysVisibleMenuId != null)
            this.callbackObjMaster = [];

        this.domObj.observe("PAT.Query:ComboChanged", this.comboboxTextChanged.bind(this));
        this.domObj.observe("PAT.Query:SelectChanged", this.selectionIndexChanged.bind(this));

        this.autoCompletePopup = new Element('div', { 'id': 'autoCompletePopup' }).addClassName("autoCompletePopup");
        //this.domObj.queryContent.insert(this.autoCompletePopup);
        $('appContainer').insert(this.autoCompletePopup);
        $('appContainer').observe("mousemove", this.autoCompleteParentContainerMouseMove.bind(this));
        this.autoCompletePopup.hide();
    },

    loadMasterQuery: function()
    {
        if (PAT.alwaysVisibleMenuId != null)
        {
            this.domObj.queryContent.masterQueryHolder = new Element('div');
            this.domObj.queryContent.insert(this.domObj.queryContent.masterQueryHolder);
            this.domObj.queryContent.masterQueryHolder.identify();
            this.domObj.queryContent.masterQueryHolder.setStyle("position:absolute;border-width:0px;width:" + this.domObj.queryContent.getWidth() + "px;height:" + this.domObj.queryContent.getHeight());
            this.loadQueries(PAT.alwaysVisibleMenuId, 'always');
        }
    },
    loadDefaultQuery: function()
    {
        this.domObj.queryContent.secondaryQueryHolder = new Element('div');
        this.domObj.queryContent.insert(this.domObj.queryContent.secondaryQueryHolder);
        this.domObj.queryContent.secondaryQueryHolder.identify();
        this.domObj.queryContent.secondaryQueryHolder.setStyle("width:" + this.domObj.queryContent.getWidth());
        if (PAT.defaultMenuId != null)
            this.loadQueries(PAT.defaultMenuId, 'default');
    },
    /******************************************************************
    *
    * selectionIndexChanged
    * when select control selected index changed  not used
    *******************************************************************/
    selectionIndexChanged: function()
    {
        var controler = event.memo.controler;
        //debugger;
        //var controlerIndex = controler.tabIndex;
        var count = this.callbackObj.size();

        for (i = 0; i < count; i++)
        {
            for (j = 0; j < this.callbackObj[i].operatorList.size(); j++)
            {
                if (this.callbackObj[i].operatorList[j].checked)
                {
                    this.callbackObj[i].operator = this.callbackObj[i].operatorList[j].value;
                    break;
                }
            }
        }

        new Ajax.Request(top.currLocation.getDirectory() + 'Query/GetQueryData.aspx', {
            method: 'post',
            parameters: { "menuId": this.currentMenuId, "callback": this.callbackObj.toJSON(), "masterCallback": this.callbackObjMaster == null ? null : this.callbackObjMaster.toJSON() }, //fieldName:this.configObjs[i].name, conditionField:conditonField, conditionValue:controler.value },
            onSuccess: this.reloadOtherContol.bind(this),

            onFailure: function()
            {
                alert(getText("GetQueryDataFailed"));
            }
        });
    },
    /*******************************************
    *
    *  comboboxTextChanged 
    *  combox text changed
    ********************************************/
    comboboxTextChanged: function(event)
    {
        var controler = event.memo.controler;
        var isMaster = event.memo.isMaster;
        //var controlerIndex = controler.tabIndex;
        var controlerIndex;
        var callObj = isMaster ? this.callbackObjMaster : this.callbackObj;
        var count = callObj.size();
        var menuId = isMaster ? PAT.alwaysVisibleMenuId : this.currentMenuId;
        var lastConditionField;
        //need skip data which is before sender;

        var ii;
        var keep = false;

        //for last control except master
        if (!isMaster)
        {
            if (controler.id == callObj[count - 1].id)
                return;
        }

        for (ii = 0; ii < count; ii++)
        {
            if (callObj[ii].id == controler.id)
            {
                keep = true;
                lastConditionField = controler.id;
                break;
            }
        }
        this.lastConditionField = lastConditionField;
        //get operator
        for (i = 0; i < count; i++)
        {
            for (j = 0; j < callObj[i].operatorList.size(); j++)
            {
                if (callObj[i].operatorList[j].checked)
                {
                    callObj[i].operator = callObj[i].operatorList[j].value;
                    break;
                }
            }
        }
        $('btnSubmitSearch').disabled = true;
        new Ajax.Request(top.currLocation.getDirectory() + 'Query/GetQueryData.aspx', {
            method: 'post',
            parameters: { "menuId": menuId, "callback": callObj.toJSON(), "masterCallback": this.callbackObjMaster == null ? null : this.callbackObjMaster.toJSON(), "lastCondition": lastConditionField, "index": controler.index }, //fieldName:this.configObjs[i].name, conditionField:conditonField, conditionValue:controler.value },
            onSuccess: this.reloadOtherContol.bindAsEventListener(this, isMaster),

            onFailure: function()
            {
                alert(getText("GetQueryDataFailed"));
                $('btnSubmitSearch').disabled = false;
            }
        });
    },
    onComboBoxFocus: function()
    {
        this.select();
    },
    //******************************************************************/
    /*  cascading load other control  
    /*  after select changed                                                             */
    /********************************************************************/
    reloadOtherContol: function(transport)
    {
        //conditionControl when false, need to reload control data
        var conditionControl = true;
        var isMaster = arguments[1];
        var dataList = eval('(' + transport.responseText + ')');
        var arrsize = dataList.size();
        for (var j = 0; j < arrsize; j++)
        {
            var ele = $(dataList[j].name);
            var tIndex = dataList[j].tabIndex;
            var blankIndex = dataList[j].blankIndex;
            var zeroIndex = dataList[j].zeroIndex;
            var nullIndex = dataList[j].nullIndex;
            var preload = dataList[j].preload;
            var child = dataList[j].child;

            //combobox
            if (ele.tagName == "SELECT")
            {
                var up = ele.up();
                if (up.tagName == "DIV")
                {
                    var data = dataList[j].data;
                    if (data == null) data = [];

                    var dataCount = data.size();
                    var allDataCount = dataCount + 1;

                    var allText;
                    if (predefinedSelectedSearchValue)
                        allText = getText("All") + " " + this.getPlural(dataList[j].title);
                    else allText = "";

                    var arr = new Array(allDataCount);
                    arr[0] = "<OPTION value = '' SELECTED = 'selected'>" + allText + "</OPTION>";

                    //populate only PRELOADED controls                            
                    if (preload || (child && !preload))
                    {
                        for (var k = 1; k < allDataCount; k++)
                        {
                            if (data[k - 1] == null)
                            {
                                arr[k] = "<OPTION title='' value=''></OPTION>";
                            }
                            else
                            {
                                var className = "";
                                if (blankIndex == (k - 1))
                                    className = " class='excludeBlank' ";
                                else if (zeroIndex == (k - 1))
                                    className = " class='excludeZero' ";
                                else if (nullIndex == (k - 1))
                                    className = " class='excludeNull' ";
                                arr[k] = "<OPTION " + className + " title='" + data[k - 1].text + "'  value='" + data[k - 1].value + "'>" + data[k - 1].text + "</OPTION>";
                            }
                        }
                    }
                    var strSelect = "<SELECT ID='" + ele.identify() + "' class='selectAutocomplete' tabIndex=" + tIndex + ">" + arr.join("") + "</SELECT>";

                    up.innerHTML = strSelect;

                    ele = $(ele.identify());
                    ele.observe("change", this.changeControlerSelection.bindAsEventListener(this, isMaster));
                }
            }
            else
            {
                if (ele.tagName == "INPUT" && ele.type == "text")
                {
                    ele.observe("keydown", this.firedByKey.bindAsEventListener(this, isMaster));
                    ele.observe("focus", this.onComboBoxFocus.bindAsEventListener(ele));
                }
                var next = ele.next();
                if (next != null && next.tagName == "DIV")
                {
                    var sel = next.down();

                    if (sel != null && sel.tagName == "SELECT")
                    {
                        ele.value = "";

                        var data = dataList[j].data;
                        if (data == null)
                            data = [];

                        var dataCount = data.size();
                        var allDataCount = dataCount + 1;
                        var arr = new Array(allDataCount);

                        var allText;
                        if (predefinedSelectedSearchValue)
                            allText = getText("All") + " " + this.getPlural(dataList[j].title);
                        else allText = "";

                        arr[0] = "<OPTION value = '' SELECTED = 'selected'>" + allText + "</OPTION>";
                        for (var k = 1; k < allDataCount; k++)
                        {
                            if (data[k - 1] == null)
                                arr[k] = "<OPTION title='' value=''></OPTION>";
                            else
                            {
                                var className = "";
                                if (blankIndex == (k - 1))
                                    className = " class='excludeBlank' ";
                                else if (zeroIndex == (k - 1))
                                    className = " class='excludeZero' ";
                                else if (nullIndex == (k - 1))
                                    className = " class='excludeNull' ";
                                arr[k] = "<OPTION " + className + " title='" + data[k - 1].text + "' + value='" + data[k - 1].value + "'>" + data[k - 1].text + "</OPTION>";
                            }
                        }

                        var strSelect = "<SELECT ID='" + sel.identify() + "' class='selectAutocomplete' tabIndex=" + tIndex + ">" + arr.join("") + "</SELECT>";

                        next.innerHTML = strSelect;
                        sel = $(sel.identify());

                        sel.up().previous().value = sel.options[sel.selectedIndex].text;
                        sel.observe("change", this.changeComboSelection.bindAsEventListener(this, isMaster));
                    }
                }
            }
        }
        //debugger;
        //$(dataList[0].name).focus();
        if (dataList[0] != null)
            Form.Element.activate($(dataList[0].name).id);

        if (isMaster)
            this.domObj.fire("PAT.Query:MENU_CLICK", { menuId: this.currentMenuId });

        queryLoaded = true;
        $('btnSubmitSearch').disabled = false;
    },
    /********************************************************************
    *
    * loadQueriesFromMenu
    * this function will be fired when menu item fire event
    *********************************************************************/
    loadQueriesFromMenu: function(event)
    {
        var menuId = event.memo.menuId;
        var type = event.memo.type;
        //Get Query controls by menu id
        this.loadQueries(menuId, type);
    },
    loadQueries: function(menuId, type)
    {
        if (type != 'always')
            this.currentMenuId = menuId;
        new Ajax.Request(top.currLocation.getDirectory() + 'Query/GetQueriesByMenuId.aspx', {
            method: 'post',
            parameters: { "menuId": menuId, "hasMaster": ((PAT.alwaysVisibleMenuId || null) != null), "isMaster": type == 'always', "masterCallback": this.callbackObjMaster == null ? null : this.callbackObjMaster.toJSON() },
            onSuccess: this.loadQueryControls.bindAsEventListener(this, { 'type': type }),
            onFailure: function()
            {
                alert(getText("LoadQueryFailed"))
            }
        });
    },
    /*******************************************************************
    *
    * loadQueryControls
    * load query controls
    * first load by menu id and menu items
    ********************************************************************/
    loadQueryControls: function(transport, parms)
    {
        this.callbackObj = [];
        var contentHolder;
        var isAlawys = false;
        var showExcludeOptions = false;

        if (parms.type == 'always')
        {
            isAlawys = true;
            contentHolder = this.domObj.queryContent.masterQueryHolder;
            contentHolder.setStyle("position:absolute;top:0px");
            contentHolder.show();
        }
        else
        {
            var h;
            contentHolder = this.domObj.queryContent.secondaryQueryHolder;
            if (this.domObj.queryContent.masterQueryHolder != null)
            {
                var masterOffsetSize = Element.getContentBoxSize(this.domObj.queryContent.masterQueryHolder);
                var h = masterOffsetSize.height
                if (h <= 0) //h = 300;
                    h = parseInt(this.domObj.queryContent.masterQueryHolder.getStyle("height"));
            }
            else h = 0;

            contentHolder.setStyle("position:absolute;top:" + h + "px");
            contentHolder.innerHTML = "";
            var aLine = new Element('hr');
            contentHolder.insert(aLine);
            var w = Element.getContentBoxSize(contentHolder.up().up()).width;
            aLine.setStyle("position:absolute;top:0px;width:" + (w - 5) + "px");
        }

        var resObj = eval('(' + transport.responseText + ')');
        this.menuInfo = resObj.menuInfo;
        this.configObjs = resObj.menuItems;

        //set the search menu title only when it's not the primary filter
        if (!this.menuInfo.menuAlwaysVisible)
            searchMenuText = this.menuInfo.menuName;

        var callObj = [];
        var configObjsSize = this.configObjs.size();

        if (parms.type == 'always')
            this.tabIndex = PAT.layout.taskbar.tabs.size() + 1; //tab index goes after the tab index for tab menus
        //else
        //    this.tabIndex += resObj.menuItems.length;   //for the secondary search, tab index goes after primary search 

        //var currentTabIndex = PAT.layout.taskbar.tabs.size() + 1;        
        for (var index = 0; index < configObjsSize; index++)
        {
            var configObj = this.configObjs[index];
            callObj[index] = {};
            callObj[index].name = configObj.name;
            callObj[index].fieldId = configObj.fieldId;
            callObj[index].dataType = configObj.operatorGroup;
            //operator list
            callObj[index].operatorList = [];
            callObj[index].operator = configObj.operatorId;

            var divtop = 20 + 40 * index;
            var holder = new Element('div');
            holder.identify();
            contentHolder.insert(holder);
            holder.setStyle("position: absolute;top:" + divtop + "px;left:0px;border-width:2px;");
            var titleLabel = new Element('label').update(configObj.title).addClassName("titleLabel");
            holder.insert(titleLabel);
            titleLabel.setStyle("position:absolute;top:2px;left:0px;width:" + (Element.getContentBoxSize(this.domObj).width) + "px;height:20px");
            var titleOffsetDimension = Element.getBorderBoxSize(titleLabel);

            var operatorList = configObj.operator;
            var fieldDataType = configObj.operatorGroup;
            var operatorCount = operatorList.size();
            var titletop; // = 20 + parseInt(titleLabel.getStyle("top"));  
            var strOperator = "";

            //operator list            
            var divOperatorHolder = new Element('span');
            divOperatorHolder.setStyle("position:absolute;top:2px;left:120px;");
            holder.insert(divOperatorHolder);
            for (var i = 0; i < operatorCount; i++)
            {
                var operatorRadio = new Element('input', { type: "radio", name: configObj.name, value: operatorList[i].id, "tabIndex": ++this.tabIndex });
                operatorRadio.setStyle("position:absolute");
                operatorRadio.setStyle("left:" + (i * 53) + "px;top:0px");
                var left = i * 40;
                var labLeft = i * 53 + 20;
                var lab = new Element('label').update(operatorList[i].name.escapeHTML());
                lab.htmlFor = operatorRadio.identify();
                lab.setStyle("position:absolute;left:" + labLeft + "px;top:0px");
                divOperatorHolder.insert(operatorRadio);
                divOperatorHolder.insert(lab);

                //check the default operator for the current menu item
                if (configObj.operatorId > 0)
                {
                    if (operatorRadio.value == configObj.operatorId)
                        operatorRadio.checked = true;
                }
                else
                {
                    if (i == 0)
                        operatorRadio.checked = true;
                }

                //add operator into callbackObj operatorList
                callObj[index].operatorList[i] = operatorRadio;

            }
            if (this.menuInfo.menuShowOperator)
            {
                //operatorRadio.show();
                //we can't use visibility here because when we try to hide the query panel (e.g. switch to legend panel) by setting visibility to hidden, this operator holder will remain visible because
                //its visibility property will overide its parent's visibility property
                //divOperatorHolder.setStyle("visibility:visible");
                divOperatorHolder.show();
            }
            else
                divOperatorHolder.hide();

            titletop = 18 + parseInt(titleLabel.getStyle("top"))
            var controlLeft = 40;
            var combotop = titletop;
            var blankIndex = configObj.blankIndex;
            var zeroIndex = configObj.zeroIndex;
            var nullIndex = configObj.nullIndex;

            if (configObj.control == "COMBOBOX")
            {
                showExcludeOptions = true;

                //if no message in database, get it from xml
                var title = configObj.itemMessage == "" ? getText('validation' + configObj.type) : configObj.itemMessage;
                var txtBox = new Element('input', { "type": "textbox", "title": title, "name": "query", "tabIndex": ++this.tabIndex }).addClassName("textAutocomplete");
                callObj[index].id = txtBox.identify();

                holder.insert(txtBox);
                //style
                txtBox.setStyle("left:" + (controlLeft + 0) + "px;top:" + (combotop + 0) + "px;position:absolute;z-index:1");
                txtBox.observe("keydown", this.firedByKey.bindAsEventListener(this, isAlawys));
                txtBox.observe("focus", this.onComboBoxFocus.bindAsEventListener(txtBox));

                var selHolder = new Element('div');
                selHolder.setStyle("position: absolute;left:" + controlLeft + "px;top:" + combotop + "px;width:175px;z-index:0");

                if (configObj.data == null)
                    configObj.data = [];

                var dataCount = configObj.data.size();
                var arr = new Array(dataCount);

                var allText;
                if (predefinedSelectedSearchValue)
                    allText = getText("All") + " " + this.getPlural(configObj.title);
                else allText = "Type Name";

                arr[0] = "<OPTION value = '' SELECTED = 'selected'>" + allText + "</OPTION>";

                var allSize = dataCount + 1;

                for (var i = 1; i < allSize; i++)
                {
                    var item = configObj.data[i - 1];
                    if (item == null)
                        arr[i] = "<OPTION title = '' value = ''></OPTION>";

                    else
                    {
                        var className = "";
                        if (blankIndex == (i - 1))
                            className = " class='excludeBlank' ";
                        else if (zeroIndex == (i - 1))
                            className = " class='excludeZero' ";
                        else if (nullIndex == (i - 1))
                            className = " class='excludeNull' ";

                        arr[i] = "<OPTION " + className + " title=\"" + item.text + "\" value=\"" + item.value + "\">" + item.text + "</OPTION>";
                    }
                }

                var selId = 'sel' + Math.random();
                selHolder.innerHTML = "<SELECT hidefocus ID='" + selId + "' class='selectAutocomplete' tabIndex='" + ++this.tabIndex + "'>" + arr.join("") + "</SELECT>";
                selHolder.identify();
                //muster add textbox first then add selection for further reference sel.up() to get textbox
                holder.insert(selHolder);
                callObj[index].selectControlId = selId;

                //set the textbox value use the 1 data                
                txtBox.value = allText;

                //bind change and keyup event for select and txtbox
                $(selId).observe("change", this.changeComboSelection.bindAsEventListener(this, isAlawys));
                txtBox.observe("keyup", this.autoComplete.bindAsEventListener(this, isAlawys));
                txtBox.setStyle("width:" + ($(selId).getWidth() - 22) + "px");
                if (this.firstCtrl == null)
                    this.firstCtrl = txtBox;
            }
            else if (configObj.control == "SELECT")
            {
                showExcludeOptions = true;
                var selHolder = new Element('div');
                selHolder.setStyle("position: absolute;left:" + controlLeft + "px;top:" + combotop + "px;width:175px;z-index:1");

                if (configObj.data == null)
                    configObj.data = [];
                var dataCount = configObj.data.size();
                var i = 1;

                var arr = new Array(allSize);
                var allSize = dataCount + 1;

                var allText;
                if (predefinedSelectedSearchValue)
                    allText = getText("All") + " " + this.getPlural(configObj.title);
                else allText = "";

                arr[0] = "<OPTION value = '' SELECTED = 'selected'>" + allText + "</OPTION>";
                for (; i < allSize; i++)
                {
                    var item = configObj.data[i - 1];
                    var className = "";
                    if (blankIndex == (i - 1))
                        className = " class='excludeBlank' ";
                    else if (zeroIndex == (i - 1))
                        className = " class='excludeZero' ";
                    else if (nullIndex == (i - 1))
                        className = " class='excludeNull' ";
                    if (item == null)
                    {
                        arr[i] = "<OPTION title = '' value = ''></OPTION>";
                    }
                    else
                    {
                        arr[i] = "<OPTION" + className + " title=\"" + item.text + "\" value=\"" + item.value + "\">" + item.text + "</OPTION>";
                    }
                }

                var selId = 'sel' + Math.random();
                selHolder.innerHTML = "<SELECT ID='" + selId + "' class='selectAutocomplete' tabIndex='" + ++this.tabIndex + "' >" + arr.join("") + "</SELECT>";
                callObj[index].id = selId;
                holder.insert(selHolder);
                $(selId).observe("change", this.changeControlerSelection.bindAsEventListener(this, isAlawys));
            }
            else if (configObj.control == "RADIO")
            {
                configObj.data.each(function(radioItem, ind)
                {
                    var left = ind * 40;
                    var labLeft = ind * 40 + 20;
                    var radio = new Element('input', { "type": "radio", "name": "r" + uniqueId, "value": radioItem, "tabIndex": + ++this.tabIndex });
                    var id = radio.identify();
                    radio.writeAttribute("outerText:" + radioItem);

                    this.callbackObj[index].id = this.callbackObj[index].id + ":" + id;
                    var lab = new Element('label');
                    lab.innerText = radioItem;
                    lab.htmlFor = id;
                    lab.setStyle("position:absolute;left:" + labLeft + "px;top:" + combotop + "px");
                    holder.insert(radio);
                    holder.insert(lab);

                    if (ind == 0)
                        radio.checked = true;

                    radio.setStyle("position: absolute;left:" + left + "px;top:" + combotop + "px");
                });

                uniqueId++;
            }
            else if (configObj.control == "TEXTBOX" || configObj.control == "AUTOCOMPLETE" || configObj.control == "PASSWORD")
            {
                var tbType = "textbox";
                if (configObj.control == "PASSWORD")
                    tbType = "password";

                //if no message in database, get it from xml
                var title = configObj.itemMessage == "" ? getText('validation' + configObj.type) : configObj.itemMessage;
                var txtBox = new Element('input', { "type": tbType, "name": "query", "title": title, "tabIndex": + ++this.tabIndex }).addClassName("textInput");
                txtBox.setStyle("left:" + controlLeft + "px;top:" + combotop + "px;position:relative;width:150px;z-index:3");
                holder.insert(txtBox);

                callObj[index].id = txtBox.identify();

                if (configObj.control == "TEXTBOX" || configObj.control == "PASSWORD")
                    txtBox.observe("keydown", this.firedByKey.bindAsEventListener(this, isAlawys, configObj.control));
                else
                {
                    txtBox.observe("keyup", this.autoCompleteKeyUp.bindAsEventListener(txtBox, isAlawys, configObj.control));
                    txtBox.observe("blur", this.onAutoCompleteBlur.bind(txtBox)); //function() { query.autoCompletePopup.hide(); query.setAutoCompleteWatermark(txtBox); });
                    txtBox.observe("focus", this.removeAutoCompleteWatermark.bind(txtBox));
                    txtBox.addClassName("autoCompleteWatermark");
                    txtBox.value = getText("AutoCompleteWatermark");
                    this.autoCompletePopup.observe("focus", function() { query.autoCompletePopup.show(); });
                    this.autoCompletePopup.setStyle("left:" + Element.viewportOffset(txtBox).left.toString() + "px");
                }

                if (this.firstCtrl == null)
                    this.firstCtrl = txtBox;
            }
            callObj[index].tabIndex = this.tabIndex;
        }
        if (enableExcludeOptions != "false")
        {
            if (showExcludeOptions)
                this.domObj.excludeOptions.show();
            else
                this.domObj.excludeOptions.hide();

            this.resize();
            this.applyExcludeFilter('ALL');
        }
        if (this.configObjs.size() > 0)
        {
            var btnText = this.menuInfo.menuCommandText;

            if (null == btnText)
                btnText = getText("Submit");
            else if (btnText == "")
                btnText = getText("Submit");

            var btnSubmit = new Element("button").update(btnText).addClassName('Button');
            btnSubmit.tabIndex = ++this.tabIndex;
            btnSubmit.observe("click", this.submitQuery.bindAsEventListener(this, isAlawys));
            btnSubmit.id = "btnSubmitSearch";
            btnSubmit.setStyle("position:absolute;left:" + controlLeft + "px;width:150px;top:" + (this.configObjs.size() * 40 + 30) + "px");

            contentHolder.setStyle("height:" + (this.configObjs.size() * 40 + 60) + "px");
            contentHolder.insert(btnSubmit);
        }
        if (isAlawys)
            this.callbackObjMaster = callObj;
        else
            this.callbackObj = callObj;

        if (this.firstCtrl != null)
        {
            if (parms.type == 'always')
                Form.Element.activate(this.firstCtrl.id); //select and focus on the first element, this.firstCtrl.focus() doesn't work
            this.firstCtrl = null;
        }
        if (this.searchResult)
            this.resize(null, true);
    },
    onAutoCompleteBlur: function()
    {
        query.autoCompletePopup.hide();
        query.setAutoCompleteWatermark(this);
    },
    onAutoCompleteMouseOver: function(row)
    {
        //when we change the scroll of autocomplete popup with arrow key, it's going to generate mouse over event as well as cursor will point to a different
        //row even if the cursor is not moving, which causes the highlight row to jump to the mouse cursor row and look confusing, so we want to keep track
        //of the mouse position in the parent container, and only select the row if mouse position actually changed when handling mouse over event.
        if ((this.currentMouseX != this.lastMouseX) || (this.currentMouseY != this.lastMouseY))
        {
            this.highlightAutoCompleteRow(row);
            this.lastMouseX = this.currentMouseX;
            this.lastMouseY = this.currentMouseY;
        }
    },
    autoCompleteParentContainerMouseMove: function(e)
    {
        if (e != null)
        {
            this.currentMouseX = e.pageX;
            this.currentMouseY = e.pageY;
        }
        else
        {
            this.currentMouseX = event.clientX;
            this.currentMouseY = event.clientY;
        }
    },
    autoCompleteKeyUp: function(e)
    {
        var keyEvent = e ? e : event;
        var key = (window.event) ? event.keyCode : e.keyCode;
        var keyChar;

        keyChar = String.fromCharCode(key);

        if (key != 13 && !(key >= 37 && key <= 40)) //13 - enter key, 37 to 40 are direction keys
        {
            if (query.autoCompleteTimer == null) //we don't want to have too many request within an interval
            {
                var filterSubset = false; //disable this feature for now, this is still buggy, we'll hit the server to filter the result instead
                if (filterSubset)
                {
                    var currentValue = this.value.toUpperCase();
                    if (key != 8 && getCaretPosition(this) == this.value.length)
                    {  // 8 - backspace, pressing backspace will produce more results instead of filter, and we also don't want the prefix to change so we have to make sure caret pos is at the end
                        var TRs = query.autoCompletePopup.getElementsByTagName("TR");
                        //if the current results are less than the max # of results, this means we have retrieved all possible values so we can 
                        //simply filter out the result without hitting the server, but we only want to do this while the popup is visible
                        if (query.autoCompletePopup.visible && TRs.length > 0 && TRs.length < 50) //hardcoded for now - the max returned results,
                        {
                            var newHTML = [];
                            newHTML.push("<table id='autoCompleteTable' class='autoCompleteTable' cellspacing=0>");
                            for (var i = 0; i < TRs.length; i++)
                            {
                                var value = Element.firstDescendant(TRs[i]).innerHTML;
                                var valueToUpper = value.toUpperCase();
                                if (valueToUpper.indexOf(currentValue) >= 0)
                                {
                                    newHTML.push("<tr style='overflow:hidden;background-color:White' ");
                                    newHTML.push("onmousedown='query.setAutoComplete(\"" + this.id + "\", \"" + value + "\");' ");
                                    newHTML.push("onmouseover='query.highlightAutoCompleteRow(this);' >");
                                    newHTML.push("<td>");
                                    newHTML.push(value);
                                    newHTML.push("</td></tr>");
                                }
                            }
                            newHTML.push("</table>");
                            newHTML = newHTML.join('');
                            var data = { html: newHTML };
                            var transport = {};
                            transport.responseText = Object.toJSON(data);
                            query.showAutoCompletePopup(transport);
                            //query.autoCompletePopup.innerHTML = newHTML;
                            return;
                        }
                    }
                }
                var srcObj = this;
                var f = function() { query.getAutoCompleteData(srcObj) };
                query.autoCompleteTimer = setTimeout(f, query.autoCompleteInterval);
            }
        }
        else
        {
            if (key == 40) //down arrow
            {
                var nextRow = Element.next(query.autoCompleteRow);
                if (nextRow != null)
                {

                    var rowBottom = nextRow.offsetTop + nextRow.getHeight();

                    var popupHeight = Element.getHeight(query.autoCompletePopup);
                    if (rowBottom > popupHeight + query.autoCompletePopup.scrollTop)
                    {
                        var scrollDif = rowBottom - popupHeight;
                        query.autoCompletePopup.scrollTop = scrollDif;
                    }
                    query.highlightAutoCompleteRow(nextRow);
                }
            }
            else if (key == 38) //up arrow
            {
                var prevRow = Element.previous(query.autoCompleteRow);
                if (prevRow != null)
                {
                    var rowBottom = prevRow.offsetTop;
                    if (rowBottom < query.autoCompletePopup.scrollTop)
                        query.autoCompletePopup.scrollTop = prevRow.offsetTop;

                    query.highlightAutoCompleteRow(prevRow);
                }
            }
            else if (key == 13) //enter key
            {
                var td = Element.firstDescendant(query.autoCompleteRow);
                query.setAutoComplete(query.autoCompletePopupSrc.id, td.innerHTML);
                query.focusOnSource(query.autoCompletePopupSrc);
                query.autoCompletePopup.hide();
            }
        }
    },
    getAutoCompleteData: function(src)
    {
        if (src.value == null || src.value == '')
        {
            query.autoCompletePopup.hide();
            this.autoCompleteTimer = null;
            return;
        }
        var count = query.callbackObj.size();
        var i = 0;
        for (i = 0; i < count; i++)
        {
            if (query.callbackObj[i].id == src.id)
                break;
        }

        for (j = 0; j < query.callbackObj[i].operatorList.size(); j++)
        {
            if (query.callbackObj[i].operatorList[j].checked)
            {
                query.callbackObj[i].operator = query.callbackObj[i].operatorList[j].value;
                break;
            }
        }
        var textBoxTop = Element.cumulativeOffset(src).top;
        var autoCompleteTop = textBoxTop + src.getHeight();
        query.autoCompletePopup.setStyle("top:" + autoCompleteTop + "px");

        var queryParams = query.callbackObj.slice(0, i); //we only need to consider the field value before the current auto complete control  

        if (query.getQueryParams(queryParams) == false)
            return;

        new Ajax.Request(top.currLocation.getDirectory() + 'Query/GetAutoCompleteData.aspx', {
            method: 'post',
            parameters: { "menuId": query.currentMenuId, "callbackId": src.id, "queryParams": Object.toJSON(queryParams), "hasMaster": ((PAT.alwaysVisibleMenuId || null) != null), "fieldId": query.callbackObj[i].fieldId, "operatorId": query.callbackObj[i].operator, "prefix": src.value, "masterCallback": query.callbackObjMaster == null ? "" : query.callbackObjMaster.toJSON(), "numOfResults": 50 },
            onSuccess: query.showAutoCompletePopup.bind(query),
            onFailure: function()
            {
                alert(getText("GetAutoCompleteFailed"));
                query.autoCompleteTimer = null;
            }
        });
    },
    setAutoCompleteWatermark: function(src)
    {
        if (src.value == '')
        {
            src.value = getText("AutoCompleteWatermark");
            src.addClassName("autoCompleteWatermark");
            src.removeClassName("autoCompleteTextBox");
        }

    },
    removeAutoCompleteWatermark: function()
    {
        if (this.hasClassName("autoCompleteWatermark"))
        {
            this.value = "";
            this.removeClassName("autoCompleteWatermark");
            this.addClassName("autoCompleteTextBox");
        }
        query.autoCompletePopupSrc = this;
    },
    focusOnSource: function(src) //focus on autoComplete textbox and set the caret position to the end
    {
        if (src != null)
        {
            var caretPos = src.value.length;
            if (src.createTextRange)
            {

                var range = src.createTextRange();
                range.move('character', caretPos);
                range.select();
                src.focus();
            }
            else
            {
                if (src.selectionStart)
                {
                    src.focus();
                    src.setSelectionRange(caretPos, caretPos);
                }
                else
                    src.focus();
            }
        }
    },
    highlightAutoCompleteRow: function(row)
    {
        row.style.backgroundColor = "#ababab";
        if (this.autoCompleteRow != null && this.autoCompleteRow != row)
            this.autoCompleteRow.style.backgroundColor = "White";

        this.autoCompleteRow = row;
    },
    showAutoCompletePopup: function(transport)
    {
        var result = eval('(' + transport.responseText + ')');
        this.autoCompletePopup.innerHTML = result.html;
        //highlight first element
        var table = $('autoCompleteTable');
        var rows = table.getElementsByTagName("tr");
        if (rows.length > 0)
        {
            this.autoCompleteRow = null;
            this.highlightAutoCompleteRow(rows[0]);
        }
        //reset scroll position
        this.autoCompletePopup.scrollTop = 0;
        this.autoCompletePopup.show();
        query.autoCompleteTimer = null;
    },
    setAutoComplete: function(id, result)
    {
        var txtBox = $(id);
        if (txtBox != null)
        {
            //doesn't set focus
            if (result != "Continue typing for more results")
                txtBox.value = result;

            this.autoCompletePopup.hide();
            this.focusOnSource(txtBox);
        }
    },
    applyExcludeFilter: function(filter)
    {
        var itemsToExclude = [];
        if (this.domObj.excludeOptions.visible())
        {

            var excludeBlank = $('chkExcludeBlank').checked;
            var excludeZero = $('chkExcludeZero').checked;
            var excludeNull = $('chkExcludeNull').checked;
            if (filter == "BLANK" || filter == "ALL")
            {
                itemsToExclude = document.getElementsByClassName('excludeBlank');
                if (excludeBlank && itemsToExclude.length > 0)
                {

                    for (var i = 0; i < itemsToExclude.length; i++)
                    {
                        itemsToExclude[i].parentElement.remove(itemsToExclude[i].index);
                    }
                }
                else
                {
                    var selectCtrls = this.domObj.document.getElementsByClassName("selectAutocomplete");
                    if (itemsToExclude.length == 0)
                    {
                        for (var j = 0; j < this.configObjs.length; j++)
                        {
                            var obj = this.configObjs[j];
                            var blankIndex = obj.blankIndex;
                            if (blankIndex >= 0)
                            {
                                var blankOption = new Element('option', { "text": obj.data[blankIndex].text, "value": obj.data[blankIndex].value, "class": "excludeBlank" });
                                $selectCtrls[j].add(blankOption, 1);
                            }
                        }
                    }
                }

            }

            if (filter == "ZERO" || filter == "ALL")
            {
                itemsToExclude = document.getElementsByClassName('excludeZero');
                if (excludeZero && itemsToExclude.length > 0)
                {
                    for (var i = 0; i < itemsToExclude.length; i++)
                    {
                        itemsToExclude[i].parentElement.remove(itemsToExclude[i].index);
                    }
                }
                else
                {
                    var selectCtrls = this.domObj.document.getElementsByClassName("selectAutocomplete");
                    if (itemsToExclude.length == 0)
                    {
                        for (var j = 0; j < this.configObjs.length; j++)
                        {
                            var obj = this.configObjs[j];
                            var zeroIndex = obj.zeroIndex;
                            if (zeroIndex >= 0)
                            {
                                var zeroOption = new Element('option', { "text": obj.data[zeroIndex].text, "value": obj.data[zeroIndex].value, "class": "excludeZero" });
                                selectCtrls[j].add(zeroOption, 1);
                            }
                        }
                    }
                }
            }
            if (filter == "NULL" || filter == "ALL")
            {
                itemsToExclude = document.getElementsByClassName('excludeNull');
                if (excludeNull && itemsToExclude.length > 0)
                {
                    for (var i = 0; i < itemsToExclude.length; i++)
                    {
                        itemsToExclude[i].parentElement.remove(itemsToExclude[i].index);
                    }
                }
                else
                {
                    if (itemsToExclude.length == 0)
                    {
                        var selectCtrls = this.domObj.document.getElementsByClassName("selectAutocomplete");

                        for (var j = 0; j < this.configObjs.length; j++)
                        {
                            var obj = this.configObjs[j];
                            var nullIndex = obj.nullIndex;
                            if (nullIndex >= 0)
                            {
                                var nullOption = new Element('option', { "text": "null", "value": "null", "class": "excludeZero" });
                                selectCtrls[j].add(nullOption, 1);
                            }
                        }
                    }
                }
            }
        }
    },
    firedByKey: function(e)
    {
        var controlType = arguments[2];
        if (controlType == "AUTOCOMPLETE")
            $('btnSubmitSearch').disabled = true;

        if (e.keyCode == 13 && $('btnSubmitSearch').disabled != true)
        {
            var isMaster = arguments[1];
            var ttt = new Date();
            var c = ttt.getHours() + ":" + ttt.getMinutes() + ":" + ttt.getSeconds();
            var parms = new Hash();
            var nameStr = "";
            var valueStr = "";
            var container = this.domObj.queryContent;
            var noError = true;

            var callObj = isMaster ? this.callbackObjMaster : this.callbackObj;
            if (this.getQueryParams(callObj) == false)
                return;

            var menuId = isMaster ? PAT.alwaysVisibleMenuId : this.currentMenuId;
            if (noError)
            {
                if (PAT.fireQueryTo == null)
                    report.domObj.fire("PAT.ResultPanel:queryFromQuery", { "queryFields": callObj, "menuId": menuId, "master": isMaster });
                else
                    PAT.fireQueryTo.fn(PAT.fireQueryTo.who, callObj, menuId, isMaster);
            }
        }

    },
    getPlural: function(word)
    {
        var upper = word.toUpperCase();
        // word = new String(word);
        var vowel = ['A', 'E', 'I', 'O', 'U'];
        var es = ['S', 'Z', 'CH', 'SH', 'X'];
        try
        {
            for (var i = 0; i < es.length; i++)
            {
                if (upper.endsWith(es[i]))
                {
                    word = word + "es";
                    return;
                }
            }
            var len = word.length;
            var lastChar = upper.charAt(len - 1);
            var secondLastChar = upper.charAt(len - 2);

            if (lastChar == 'Y')
                word = word.substring(0, len - 1) + "ies";
            else
                word = word + "s";
            return word;
        } catch (ex)
        {
            return word + "s";
        }
    },
    resize: function(size, loaded)
    {
        if (size == null)
        {
            var parentHolder = this.domObj.up('div');
            if (this.searchResult && loaded)
                size = { "width": parentHolder.getWidth(), "height": parseInt(query.domObj.getElementsByTagName("button")[0].style.top.substring(0, query.domObj.getElementsByTagName("button")[0].style.top.length - 2)) + 37 };
            else
                size = { "width": parentHolder.getWidth(), "height": parentHolder.getHeight() };
        }
        Element.setBorderBoxSize(this.domObj, size);

        this.domObj.excludeOptions.setStyle("top:0px; width:" + size.width + "px");
        var excludeHeight = this.domObj.excludeOptions.getHeight();
        if (!this.domObj.excludeOptions.visible())
            excludeHeight = 0;
        this.domObj.queryContent.setStyle("top:" + excludeHeight + "px");
        Element.setBorderBoxSize(this.domObj.queryContent, { "width": size.width, "height": size.height - excludeHeight });

        if (this.searchResult && loaded)
        {
            report.resize(null, true);
            report.domObj.setStyle("position:absolute;left:0px;top:" + (parseInt(this.domObj.getElementsByTagName("button")[0].style.top.substring(0, this.domObj.getElementsByTagName("button")[0].style.top.length - 2)) + 35) + "px;");
        }
    },
    loadData: function(event)
    {
        var sel = event.element();
        var objId = (sel.options[sel.selectedIndex]).value;
        new Ajax.Request(top.currLocation.getDirectory() + '/QueryObject.aspx', {
            method: 'post',
            parameters: { "objectId": objId },
            onSuccess: this.updateInterface.bind(this),
            onFailure: function()
            {
                alert(getText("GetQueryDataFailed"));
            }
        });
    },
    getQueryParams: function(callObj)
    {
        for (var n = 0; n < callObj.size(); n++)
        {
            var item = callObj[n];
            var ctrl = $(item.id);
            if (ctrl.type != null)
            {
                if (ctrl.type == "password")
                    item.password = true;
            }

            if ((item.selectControlId || null) != null)
                item.value = $F(item.selectControlId);
            else
                item.value = $F(item.id);

            if (item.dataType == "Number")
            {
                if (isNaN(item.value))
                {
                    $(item.id).focus();
                    $(item.id).select();
                    noError = false;
                    messageCenter.domObj.fire("PAT.MessageBox:onMessage", { "title": getText("DataTypeError"), "message": getText("InputNotNumber") });
                    return false;
                }
            }
            //here may cause performance down
            var operatorList = item.operatorList; //Element.getElementsBySelector(container, '[name="' + operatorName + '"]');
            var operatorListSize = operatorList.size();
            var i;
            //if we are showing operaters(operatorListSize > 0), we'll use the selected operator
            if (operatorListSize > 0)
            {
                for (i = 0; i < operatorListSize; i++)
                {
                    var it = operatorList[i];
                    if (it.checked)
                    {
                        item.operator = it.value;
                    }
                }
            }
            else
            {
                //set default operator to equal (operatorId = 1) if no default operator is assigned to this menu item
                if (item.operator == null)
                    item.operator = 1;
            }
        }
        return true;
    },
    submitQuery: function(event)
    {
        var isMaster = arguments[1];
        var ttt = new Date();
        var c = ttt.getHours() + ":" + ttt.getMinutes() + ":" + ttt.getSeconds();
        var parms = new Hash();
        var nameStr = "";
        var valueStr = "";
        var container = this.domObj.queryContent;
        var noError = true;

        var callObj = isMaster ? this.callbackObjMaster : this.callbackObj;
        if (this.getQueryParams(callObj) == false)
            return;

        var menuId = isMaster ? PAT.alwaysVisibleMenuId : this.currentMenuId;
        if (noError)
        {
            if (PAT.fireQueryTo == null)
                report.domObj.fire("PAT.ResultPanel:queryFromQuery", { "queryFields": callObj, "menuId": menuId, "master": isMaster });
            else
                PAT.fireQueryTo.fn(PAT.fireQueryTo.who, callObj, menuId, isMaster);
        }
    },
    loadResult: function(transport)
    {
        report.updateResultPanel(transport);
    },
    //*****************************************************************
    // 
    // select control 
    // change selected index
    //
    //******************************************************************/
    changeControlerSelection: function(event)
    {
        var isMaster = arguments[1];
        var sel = event.element();

        var callObj = isMaster ? this.callbackObjMaster : this.callbackObj;
        var conditionField = true;
        for (var i = 0; i < callObj.size(); i++)
        {
            var item = callObj[i];
            if (item.id == sel.id)
            {
                if (sel.selectedIndex == 0)
                    item.value = "";
                else
                    item.value = sel.options[sel.selectedIndex].value;
                conditionField = false;
            }
            else
            {
                if (conditionField == false)
                    item.value = null;
                else
                {
                    if (item.value == null)
                        item.value = "";
                }
            }
        }
        this.domObj.fire("PAT.Query:ComboChanged", { "controler": { value: sel.options[sel.selectedIndex].text, "id": sel.id, "index": sel.selectedIndex }, "isMaster": isMaster });
    },

    //*********************************
    //
    // combobox control 
    // change selected index
    // 
    //**********************************
    changeComboSelection: function(event)
    {
        var sel = event.element();
        var up = Element.up(sel);
        var isMaster = arguments[1];

        var textBox = up.previous();

        if (textBox == null) return;
        textBox.value = sel.options[sel.selectedIndex].text
        var callObj = isMaster ? this.callbackObjMaster : this.callbackObj;

        var conditionField = true;
        for (var i = 0; i < callObj.size(); i++)
        {
            var item = callObj[i];
            if (item.id == textBox.id)
            {
                if (sel.selectedIndex == 0)
                    item.value = "";
                else
                {
                    item.condition = true;
                    item.value = sel.options[sel.selectedIndex].value;
                }
                conditionField = false;
            }
            else
            {
                if (conditionField == false)
                {
                    item.condition = true;
                    item.value = null;
                }
                else
                {
                    if (item.value == null)
                        item.value = null;
                }
            }
        }
        this.domObj.fire("PAT.Query:ComboChanged", { controler: { value: textBox.value, id: textBox.id, index: sel.selectedIndex }, "isMaster": isMaster });
    },
    clickText: function(field, event)
    {
        field.focus();
    },
    autoComplete: function(event) //this function is for combobox autocomplete, not autocopmlete control
    {
        $('btnSubmitSearch').disabled = true;
        var isMaster = arguments[1];
        var field = event.element();
        var property = 'text';
        var forcematch = true;
        var next = Element.next(field);
        var callObj = isMaster ? this.callbackObjMaster : this.callbackObj;
        var sel = Element.firstDescendant(next);

        if (sel == null) return;

        var found = false;
        for (var i = 0; i < sel.options.length; i++)
        {
            if (sel.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0)
            {
                found = true;
                break;
            }
        }

        if (found) { sel.selectedIndex = i; }
        else { sel.selectedIndex = -1; }

        //IE
        if (field.createTextRange)
        {
            if (forcematch && !found)
            {
                field.value = field.value.substring(0, field.value.length - 1);
                $('btnSubmitSearch').disabled = false;
                return;
            }
            //  cursorKeys ="46;37;38;39;40;33;34;35;36;45;";
            var cursorKeys = [8, 46, 37, 38, 39, 40, 33, 34, 35, 36, 45];
            //if (cursorKeys.indexOf(event.keyCode+";") == -1) 
            if (cursorKeys.indexOf(event.keyCode) == -1)
            {

                var r1 = field.createTextRange();
                var oldValue = r1.text;
                var newValue = found ? sel.options[i][property] : oldValue;
                if (newValue != field.value)
                {
                    field.value = newValue;
                    var rNew = field.createTextRange();
                    rNew.moveStart('character', oldValue.length);
                    rNew.select();
                }
            }
        }
        else
        {
            if (forcematch && !found)
            {
                field.value = field.value.substring(0, field.value.length - 1);
                $('btnSubmitSearch').disabled = true;
                return;
            }

            // cursorKeys ="8;46;37;38;39;40;33;34;35;36;45;";
            var cursorKeys = [8, 46, 37, 38, 39, 40, 33, 34, 35, 36, 45];
            //alert(event.keyCode);
            if (cursorKeys.indexOf(event.keyCode) == -1)
            {
                var oldValue = field.value;
                var newValue = found ? sel.options[i][property] : oldValue;
                if (newValue != field.value)
                {
                    field.value = newValue;
                    field.setSelectionRange(oldValue.length, newValue.length);
                }
            }
        }
        var conditionField = true;
        for (var i = 0; i < callObj.size(); i++)
        {
            var item = callObj[i];
            if (item.id == field.id)
            {
                var selCtl;
                if (item.selectControlId != null)
                {
                    selCtl = $(item.selectControlId);

                    item.value = selCtl.options[selCtl.selectedIndex].value;
                }
                conditionField = false;
            }
            else
            {
                if (conditionField == false)
                {
                    item.value = null;
                }
                else
                {
                    if (item.value == null)
                        item.value = "";
                }
            }
        }
        if (sel.identify() != callObj[callObj.size() - 1].id)
            this.domObj.fire("PAT.Query:ComboChanged", { controler: { value: field.value, id: field.id }, "isMaster": isMaster });

        $('btnSubmitSearch').disabled = false;
    }
});

var handle = {
    onCreate: function() 
    {
        if(PAT.showDimer)
        {
            Element.show('loader'); 
            Element.show('loaderImg');
        }
        else
            Element.show('loaderImg');
    },
    onComplete: function() 
    {
        if (Ajax.activeRequestCount == 0) 
        {
            if(PAT.showDimer){
                Element.hide('loader');
                Element.hide('loaderImg');
            }
            else
                Element.hide('loaderImg');
        }
    }
};
Ajax.Responders.register(handle);

