function WGrid76(Prefix)
{
	this.Prefix = Prefix;
	this.name = '';
	this.xml = '';
	this.UrlToImages = '';
	this.Curr_RowKind = 'Unknow';
	this.Curr_ID = '';
	this.RowStylesCount = 2;
	this.ShowCurRow = true;
	this.ShowHeader = false;
	this.ShowRowAll = false;
	this.ShowNewRecord = true;
	this.ReadOnly = true;
	this.ClientMsgControlID = '';
	this.isEmpty = false;
	this.container = null;
	this.uniqueId = '';
	this.rowHoverColor = '';
	this.multiSelect = false;
	this.allowEmptySelection = false;
	this.showStatusBar = true;
	this.showStatusBarMessages = true;
	this.rowSelectionDelay = 250;
	this.rowSelectionTimer = null;
	this.autoPostBackOnRowSelect = true;
	this.rowHoverTimer = null;
	this.rowHoverDelay = 10;
	this.panelId = null;
	this.autoPostBackOnColumnCheckBoxClick = false;
	this.orderField = '';
	this.rowMoving = 'None';
	this.isDataLoaded = false;
	this.serverId = '';
	this.allowCollapse = false;
	this.loadingMode = 'All';
	this.isConfirmInPlaceChanges = true;
	this.height = 'auto';
	this.width = 'auto';
	this.borderWidth = 1;
	this.settedHeight;
	this.settedWidth;
	this.settedColumnWidths = new Array();
	
	this.contPaddingTop = 0;
	this.contPaddingBottom = 0;

	this.xmlDOM = null;
	this.xslDOM = null;
	
	this.stateDOM = null;
	this.trs = null;

	this.divMain = null;
	this.edtToForm = null;
	this.edttoFormParams = null;
	this.edtState = null;
	this.divNoData = null;
	this.tblMain = null;
	this.tblStatusBar = null;
	this.tdStatus0 = null;
	this.tdStatus1 = null;
	this.divCont = null;
	this.xmlData = null;
	this.edtScrollTop = null;
	this.trHeader = null;
	this.tblHeader = null;
	this.divHeader = null;
	this.divFooter = null;
	this.headerInTable = false;
	
	this.selectedRows = null;
	this.embeddedGrids = new WEmbeddedGrids76(this);
	this.masterGrid = null;
	this.masterId = null;
	
	this.CurTR = null;
	this.wcbParent = null;
	this.readyState = 'uninitialized';
	this.currentEditableTR = null;
	this.paramsNode = null;
	this.requestParams = new Array();
	this.groupsCount = 0;

    //// events
    this.onSelectItem = null;
    this.beforePostBackOnSelectionChanged = null;

    //// consts
    this.dataGroupLevel = 1000;
    this.pageRowCount = 12;//for page up/page down 
    this.AllValueID = -1;
    this.CAPTION_HEIGHT = 25;
    
    this.initVariables = function()
    {
        this.divMain = $(this.Prefix + 'divMain');
	    this.edtToForm = $('toForm');
	    this.edttoFormParams = $('toFormParams');
	    this.edtState = $(this.Prefix + 'edtState');
	    this.divNoData = $(this.Prefix + 'divNoData');
	    this.tblStatusBar = $(this.Prefix + 'tblStatusBar');
	    this.tdStatus0 = $(this.Prefix + 'tdStatus0');
	    this.tdStatus1 = $(this.Prefix + 'tdStatus1');
	    this.xmlData = $(this.Prefix + 'xmlData');
	    this.edtScrollTop = $(this.Prefix + 'edtScrollTop');
	    this.divCont = $(this.Prefix + 'divCont');
	    this.divFooter = $(this.Prefix + 'divFooter');
	    
	    if (this.xmlData)
        {
            this.xml = this.xmlData.value;
            this.xmlData.parentNode.removeChild(this.xmlData);
        }
	}
    
    this.init = function()
    {
        this.initVariables();
        if (!window.xmlWGrid76_xsl || window.xmlWGrid76_xsl.tagName == 'DIV')
        {
            window.xmlWGrid76_xsl = this.newXMLDOM();
            var edtWGrid76_xsl = $('xmlWGrid76_xsl');
            if (edtWGrid76_xsl)  window.xmlWGrid76_xsl.loadXML(edtWGrid76_xsl.getAttribute('value'));
        }
        this.xslDOM = window.xmlWGrid76_xsl;
        
        if (this.edtState)
        {
            try
            {
                this.stateDOM = this.newXMLDOM();
                this.stateDOM.loadXML(this.decode(this.edtState.value));
            }
            catch(ex)
            {
                this.stateDOM = null;
            }
        }
        
        
        this.selectedRows = new WGridSelectedRows76(this);
        if (!this.isEmpty)  this.out();
        
        if (this.divMain && this.divMain.addEventListener)
            this.divMain.addEventListener('DOMMouseScroll', Function.createDelegate(this, this.divMain_onmousewheel), false);
    }
    
    this.encode = function(s)
    {
        var d1 = new Date();
        s = s.ReplaceAll("<", "&lt;").ReplaceAll(">", "&gt;");
        var dur = (new Date()).getTime() - d1.getTime();
        return s;
    }

    this.decode = function(s)
    {
        return s.ReplaceAll("&lt;", "<").ReplaceAll("&gt;", ">");
    }
	
	this.out = function()
	{
		if (this.edtToForm) 
		{
			this.edtToForm.value = '';
			this.edttoFormParams.value = '';
		}
		
		try
		{
			this.xmlDOM = this.newXMLDOM();
			this.xmlDOM.loadXML(this.xml);
		}
		catch(e)
		{
			this.divMain.innerHTML = '<span class="ErrorText">Sorry, you don\'t have XSL transformer.</span>';
			
			this.isEmpty = true;
			return;
		}
		
		try
		{
    	    this.divMain.innerHTML = this.xmlDOM.transformNode(this.xslDOM);
		}
		catch(ex)
		{
			this.divMain.innerHTML = '<span class="ErrorText">Transforming error</span>';
			this.isEmpty = true;
			return;
		}
        
        this.paramsNode = this.xmlDOM.selectSingleNode('Data/Params');
		this.tblMain = document.getElementById(this.Prefix + 'tblMain');
		if (this.tblMain) this.trs = this.tblMain.getElementsByTagName('TR');
		this.trHeader = document.getElementById(this.Prefix + 'trHeader');
		this.tblHeader = this.trHeader ? this.trHeader.parentNode.parentNode : null;
		if (this.tblHeader)
		    this.divHeader = this.tblHeader.parentNode;
		this.groupsCount = parseInt(this.getParamFromXML('GroupsCount'));
        this.CurTR = this.findTR(this.Curr_RowKind, this.Curr_ID);
        
        this.settedHeight = null;
        this.settedWidth = null;
        this.settedColumnWidths = new Array();
        
    	var __this = this;
		var timer = window.setTimeout(
			function()
			{
				__this.firstScrollToCurTR();
			}, 1);
	
		this.readyState = 'complete';
	}
	
	this.splitCode = function(val)
	{
	    h = val.replace(/<\/?script[^>]*>/gi,"\07");
        h = h.replace(/\07[^\07]+\07/g,"");

        pre = val.replace(/<\/script[^>]*>/gi,"\07");
        pre = pre.replace(/<\bscript[^>]*>/gi,"\06");
        pre = ("\07" + pre + "\06").replace(/\07[^\06]+\06/g,"");
        pre = pre.replace(/(\07|\06)/gi,"");
        
        return {html: h, js: pre};
	}
	
	this.saveState = function()
	{
	1;
	    this.edtState.value = this.encode(this.stateDOM.xml);
	}
	
	this.firstScrollToCurTR = function()
	{
 	    if (this.divMain != null && this.edtScrollTop != null && this.edtScrollTop.value != 0)
	    {
	        if (!this.wcbParent  &&  this.edtScrollTop.value != -1)
    	        this.divMain.scrollTop = this.edtScrollTop.value;
    	    else 
    	        this.scrollToCurTR(false);
    	}
	}
	
	this.newXMLDOM = function()
	{
		return xml.DOMDocument.create();
	}
	
	this.saveScrollPosition = function()
	{
	    this.edtScrollTop.value = this.divMain.scrollTop;
	}
	
	this.RowDBClick = function(event, tr)
	{
        1;
        if (!this.ReadOnly) this.beginEditTR(event.srcElement ? event.srcElement : event.target);
	}
	
	this.RowClick = function(event, tr)
	{
	    if (this.currentEditableTR && this.currentEditableTR.tr && this.currentEditableTR.tr.id == tr.id)
	        return;
	
        if (!this.wcbParent && this.tblMain.setActive) this.tblMain.setActive();
		if (this.multiSelect)
		{
		    this.selectedRows.beginTransaction();
            if (event.ctrlKey)
            {
                if(this.selectedRows.isSelectedTR(tr))
                {
                    if (this.allowEmptySelection || this.selectedRows.count() > 1)
                        this.selectedRows.unselectTR(tr);
                }                        
                else
                    if (this.getParamFromXML('RowSelectionMethod') != 'ItselfOnlyWithoutGroups' || !this.isGroupTR(tr))
                        this.selectedRows.selectTR(tr);
                    else
                    {
                        var groupNode = this.getNodeByTr(tr);
                        if (groupNode) 
                        {
                            if (this.selectedRows.isSelectedNoneRowsInGroup(groupNode))
                                this.selectedRows.selectAllTR(groupNode);
                            else
                                this.selectedRows.unSelectGroup(groupNode);
                        }                            
                    }
            }
            else if (event.shiftKey)
                this.selectedRows.selectRangeBeforeTR(tr);
            else
            {                
                this.selectedRows.unselectAllTR();
                if (this.getParamFromXML('RowSelectionMethod') != 'ItselfOnlyWithoutGroups' || !this.isGroupTR(tr))
                    this.selectedRows.selectTR(tr);
                else
                {
                    var groupNode = this.getNodeByTr(tr);
                    if (groupNode) this.selectedRows.selectAllTR(groupNode);
                }                    
            }
            
            if (this.selectedRows.isChanged()) 
            {
                this.selectionChanged();
                this.saveState();
            }                
            this.selectedRows.commit();
        }
		
        this.setCurTR(tr);		     
		if (!this.ReadOnly)
		    if (this.isNewRecordTR(tr)) 
		        this.beginEditTR(tr);
		        
        if (this.wcbParent) this.wcbParent.RowClick(tr);
	}
	
	this.getTrLevel = function(tr)
	{
        if (this.isGroupTR(tr))
        {
            var groupNode = this.groupNodeFromXmlDOM(this.getTRID(tr));
            if (groupNode)
                return parseInt(groupNode.getAttribute('Level'));
            else
                return this.dataGroupLevel;
        }
        else
            return this.dataGroupLevel;
	}
	
	this.showGroup = function(group_id, deep)
	{
	    var groupTr = document.getElementById(this.Prefix  + 'gtr_' + group_id);
	    var groupLevel = this.getTrLevel(groupTr);
	    	    
	    if (deep) groupTr.style.display = '';
	    
	    if (!deep  ||  deep  &&  this.groupIsExpanded(group_id))
	    {
            if (groupLevel + 1 == this.groupsCount) //last group level
            {
                var tbody = document.getElementById(this.Prefix + 'bd_' + group_id);
                tbody.style.display = '';
            }
            else
            {
                var groupNode = this.groupNodeFromXmlDOM(group_id);
                var subGroupNode = groupNode.firstChild;
                while (subGroupNode  &&  (subGroupNode.nodeName == 'Group'  || subGroupNode.nodeName == 'Row'))
                {
                   this.showGroup(subGroupNode.getAttribute('ID'), true);
                   subGroupNode = subGroupNode.nextSibling;
                }
            }
            
            var gf = document.getElementById(this.Prefix  + 'gf_' + group_id);
	        if (gf) gf.style.display = ''; 
        }
	}
	
	this.hideGroup = function(group_id, deep)
	{
        var groupTr = document.getElementById(this.Prefix  + 'gtr_' + group_id);
	    var groupLevel = this.getTrLevel(groupTr);
	    
	    if (deep) groupTr.style.display = 'none';
        var gf = document.getElementById(this.Prefix  + 'gf_' + group_id);
        if (gf) gf.style.display = 'none';
	    
	    if (this.groupIsExpanded(group_id))
            if (groupLevel + 1 == this.groupsCount) //last group level
            {
                var tbody = document.getElementById(this.Prefix + 'bd_' + group_id);
                tbody.style.display = 'none';
            }
            else
            {
                var groupNode = this.groupNodeFromXmlDOM(group_id);
                var subGroupNode = groupNode.firstChild;
                while (subGroupNode  &&  (subGroupNode.nodeName == 'Group'  || subGroupNode.nodeName == 'Row'))
                {
                    this.hideGroup(subGroupNode.getAttribute('ID'), true);
                    subGroupNode = subGroupNode.nextSibling;
                }
            }
	}
	
	this.expandGroup = function(group_id)
	{
	1;
	    if (group_id == this.AllValueID)
	    {
	        var allGroupNode = this.groupNodeFromXmlDOM(group_id);
            var childNode = allGroupNode.firstChild;
            while (childNode)
            {
                if (childNode.nodeName == 'Group' && !this.groupIsExpanded(childNode.getAttribute('ID')))  
                    this.expandGroup(childNode.getAttribute('ID'));
                childNode = childNode.nextSibling;
            }
            var gf = document.getElementById(this.Prefix  + 'gf_' + group_id);
            if (gf) gf.style.display = '';
	    }
	    else this.showGroup(group_id);
	
	    var img = document.getElementById(this.Prefix + 'img_' + group_id);
        img.src = this.UrlToImages + 'minus.gif';
        
        var expGrNode = this.stateDOM.selectSingleNode('state/expGr');
        this.dom_appendNode(expGrNode, 'g', group_id);
        
        var groupNode = this.groupNodeFromXmlDOM(group_id);
        if (groupNode)
            groupNode.setAttributeNode( this.xmlDOM.createAttribute('Expanded') );
       
       this.refreshFooterPosition();
       
        this.saveState();
	}
	
	this.refreshFooterPosition = function()
	{
	    var grid = this;
	
        while (grid)	
        {
	        if (grid.tblStatusBar.parentNode.style.margin) /* ie bag */
                grid.tblStatusBar.parentNode.style.margin = "";
            else            
                grid.tblStatusBar.parentNode.style.margin = '0px';
            
            grid = grid.masterGrid;                
        }
	}
	
	this.collapseGroup = function(group_id)
	{   
	    if (group_id == this.AllValueID)
	    {
	        var allGroupNode = this.groupNodeFromXmlDOM(group_id);
            var childNode = allGroupNode.firstChild;
            while (childNode)
            {
                if (childNode.nodeName == 'Group' && this.groupIsExpanded(childNode.attributes.getNamedItem('ID').value))
                    this.collapseGroup(childNode.attributes.getNamedItem('ID').value);
                childNode = childNode.nextSibling;
            }
            var gf = document.getElementById(this.Prefix  + 'gf_' + group_id);
            if (gf) gf.style.display = 'none';
	    }
	    else this.hideGroup(group_id);
	        
        var img = document.getElementById(this.Prefix + 'img_' + group_id);
        img.src = this.UrlToImages + 'plus.gif';   
	    
        var expGrNode = this.stateDOM.selectSingleNode('state/expGr');
        var stateGroupNode = this.groupNodeFromStateDOM(group_id);
	    if (stateGroupNode) stateGroupNode.parentNode.removeChild(stateGroupNode);
	    
	    var groupNode = this.groupNodeFromXmlDOM(group_id);
        if (groupNode)
            groupNode.removeAttribute('Expanded');
            
        this.refreshFooterPosition();
            
	    this.saveState();
	}
	
	this.groupImg_click = function(event, group_id)
	{
	   	if (this.groupIsExpanded(group_id)) this.collapseGroup(group_id);
		else this.expandGroup(group_id);
		event.cancelBubble = true;
	}
	
	this.rowImg_click = function(event, row_id)
	{
        if (this.rowIsExpanded(row_id)) this.collapseRow(row_id);
		else if (this.container)
	    {
	        var masterGrid = this;
	        var lastDownloadedGrid = this.embeddedGrids.lastDownloadedGrid(row_id);
	        this.embeddedGrids.forEachGrid(row_id,
                function()
                {
                    if (!this.isDataLoaded && (!this.allowCollapse || this.gridExpanded()))
                        this.loadDataXML(row_id, 
                            lastDownloadedGrid && lastDownloadedGrid.Prefix == this.Prefix ? 
                                Function.createDelegate(masterGrid, function(){this.expandRow(row_id);}) : null
                        );
                }
            );
            if (!lastDownloadedGrid) this.expandRow(row_id);
        }
        else
        {
            var lastDownloadedGrid = this.embeddedGrids.lastDownloadedGrid(row_id);
            this.expandRow(row_id, lastDownloadedGrid);
            if (lastDownloadedGrid)
                this.doPostBack();
        }

		event.cancelBubble = true;
	}
	
    this.loadDataXML = function(masterRowId, afterLoadDelegate)
    {
        if (this.container)
        {
            var argsDOM = this.newXMLDOM();
            var methodNode = argsDOM.createElement('method');
            this.dom_appendAttr(methodNode, 'name', 'GetDataXML')
            argsDOM.appendChild(methodNode);
            methodNode.setAttribute('MasterID', masterRowId);
            methodNode.setAttribute('ServerID', this.serverId);
            
            methodNode.setAttribute('WithScript', '');

        
	        this.container.CallServer(this.uniqueId, 'GetDataXML', argsDOM.xml, this, 
                Function.createDelegate(this, function(args, context){ context.callbackLoadDataXML(args, afterLoadDelegate); }), 
                this.onCalbackError
            );
        }            
    }
    
    this.callbackLoadDataXML = function(args, afterLoadDelegate)
    {
        1;
        var responseDOM = this.newXMLDOM()
        responseDOM.loadXML(args);
        
        var dataNode = responseDOM.selectSingleNode('result/Data');
        var scriptNode = responseDOM.selectSingleNode('result/script');
        
        this.reload(dataNode ? dataNode.xml : null);
        
        if (scriptNode && scriptNode.text)
        {
            for (rowId in this.rows)
                for (var i = 0; i <  this.rows[rowId].length; i++)
                    delete this.embeddedGrids.rows[ri][egi];
            this.embeddedGrids.rows = new Array();

            if (window.execScript)
                window.execScript(scriptNode.text);
            else
                window.eval(scriptNode.text);
        }            
        
        this.isDataLoaded = true;
        if (afterLoadDelegate) afterLoadDelegate();
    }
	
	this.expandRow = function(row_id, notVisual)
	{
	    var etr = $(this.Prefix + 'etr_' + row_id);
	    if (etr && !notVisual) etr.style.display = '';
	
	    var img = $(this.Prefix + 'rimg_' + row_id);
        img.src = this.UrlToImages + 'minus.gif';
        
        var expRNode = this.stateDOM.selectSingleNode('state/expR');
        this.dom_appendNode(expRNode, 'r', row_id);
        
        var rowNode = this.rowNodeFromXmlDOM(row_id);
        if (rowNode)
            rowNode.setAttribute('Expanded', '');
        
        this.refreshFooterPosition();
        
        this.saveState();
	}
	
	this.collapseRow = function(row_id)
	{
	    var etr = $(this.Prefix + 'etr_' + row_id);
	    if (etr) etr.style.display = 'none';
	        
        var img = $(this.Prefix + 'rimg_' + row_id);
        img.src = this.UrlToImages + 'plus.gif';
	    
        var expRNode = this.stateDOM.selectSingleNode('state/expR');
        var stateRowNode = this.rowNodeFromStateDOM(row_id);
	    if (stateRowNode) stateRowNode.parentNode.removeChild(stateRowNode);
	    
	    var rowNode = this.rowNodeFromXmlDOM(row_id);
        if (rowNode)
            rowNode.removeAttribute('Expanded');
            
        this.refreshFooterPosition();
	    this.saveState();
	}
	
	this.selectSingleNodeByText = function(list, text)
	{
	    if (list)
            for (var i = 0; i < list.length; i++) 
                if (list[i].text == text) return list[i];
        return null;
	}
	
	this.selectSingleNodeByAttr = function(list, name, val)
	{
	     if (list)
            for (var i = 0; i < list.length; i++) 
                if (list[i].getAttribute(name) == val) return list[i];
        return null;
	}
	
	this.groupNodeFromStateDOM = function(group_id)
	{
	    if (this.stateDOM)
	        if (group_id.indexOf('"') >= 0)
	            return this.selectSingleNodeByText(this.stateDOM.selectNodes('state/expGr/g'), group_id );
            else
                return this.stateDOM.selectSingleNode('state/expGr/g[.="' +  group_id +  '"]');
	    else
	        return null;
	}
	
	this.rowNodeFromStateDOM = function(row_id)
	{
	    return this.stateDOM != null ? this.stateDOM.selectSingleNode('state/expR/r[.=\'' +  row_id +  '\']') : null;
	}
	
	this.groupNodeFromXmlDOM = function(group_id)
	{
	    if (group_id.indexOf('"') >= 0)
	        return this.selectSingleNodeByAttr(this.xmlDOM.selectNodes('//Group'), 'ID', group_id);
        else
            return this.xmlDOM.selectSingleNode('//Group[@ID="' + group_id + '"]');
	}
	
   	this.rowNodeFromXmlDOM = function(id)
	{
	    return this.xmlDOM.selectSingleNode('//Row[ID=\'' + id + '\']');
	}
	
	this.getNodeByTr = function(tr)
	{
	    return this.isGroupTR(tr) ? this.groupNodeFromXmlDOM(this.getTRID(tr)) : this.rowNodeFromXmlDOM(this.getTRID(tr));
	}

	this.groupIsExpanded = function(group_id)
	{
	    return this.groupNodeFromStateDOM(group_id) != null;
	}
	
	this.rowIsExpanded = function(row_id)
	{
	     return this.rowNodeFromStateDOM(row_id) != null;
	}
	
	this.getClassName = function(tr)
	{
		if (this.isNewRecordTR(tr))
		    return 'w76_grid_new_tr';
		else if (this.isGroupTR(tr))
		{
		   if (tr && this.selectedRows.isSelectedTR(tr))
		       if (this.multiSelect)
                    return  'w76_grid_selected_group_multiselect';
                else 
                    return  'w76_grid_selected_group';
            else
                return 'w76_grid_group_tr';
        }		    
		else if (tr && this.selectedRows.isSelectedTR(tr))
		    if (this.multiSelect)
                return  'w76_grid_selected_tr_multiselect';
            else 
                return  'w76_grid_selected_tr';
        else
		{   
            if (tr.getAttribute('originalBG'))
                tr.style.background = tr.getAttribute('originalBG');
			var rowPosition = (tr ? tr.sectionRowIndex : 0);
			if (this.embeddedGrids.count())  rowPosition /= 2;
			return 'w76_grid_tr_' + ((rowPosition + 1) % this.RowStylesCount).toString();
	    }
	}
	
	this.getCurrentClassName = function(tr)
	{
        if (this.isNewRecordTR(tr))
		    return 'w76_grid_selected_new_tr';
		else if (this.isGroupTR(tr))
		{
		    if (this.multiSelect && tr)
		        return this.selectedRows.isSelectedTR(tr) ? 'w76_grid_current_selected_tr_multiselect' : 'w76_grid_current_tr_multiselect';
		    else
		        return  this.getParamFromXML('RowSelectionMethod') == 'ItselfOnlyWithoutGroups' ? 'w76_grid_focused_group' : 'w76_grid_selected_group';
         }		    
        else if (this.multiSelect && tr)
            return this.selectedRows.isSelectedTR(tr) ? 'w76_grid_current_selected_tr_multiselect' : 'w76_grid_current_tr_multiselect';
        else
		    return 'w76_grid_selected_tr';		    
	}

	this.changeClassForGroup = function(group_id, isSelect, deep)
	{
	    var groupTr = document.getElementById(this.Prefix  + 'gtr_' + group_id);
	    var groupLevel = this.getTrLevel(groupTr);
	    
	    if (deep) groupTr.className = isSelect ? this.getCurrentClassName(groupTr) : this.getClassName(groupTr);
	    if (this.getParamFromXML('RowSelectionMethod') != 'ItselfAndEmbedded') return;
	    
        if (groupLevel + 1 == this.groupsCount) //last group level
        {
            var tbody = this.tblMain.all.item(this.Prefix + 'bd_' + group_id);
            tbody.className = isSelect ? 'w76_grid_selected_tbody' : '';
        }
        else
        {
            var groupNode = this.groupNodeFromXmlDOM(group_id);
            var subGroupNode = groupNode.firstChild;
            while (subGroupNode)
            {
               this.changeClassForGroup(subGroupNode.attributes.getNamedItem('ID').value, isSelect, true);
               subGroupNode = !subGroupNode.nextSibling  || subGroupNode.nextSibling.nodeName == 'Group' ? subGroupNode.nextSibling : subGroupNode.nextSibling.nextSibling;
            }
        }
	}
	
	this.getStateChildNode = function(nodeName)
	{
	    var node = this.stateDOM ? this.stateDOM.selectSingleNode('state/' + nodeName) : null;
	    //VP: If the this.stateDOM is null then next construction crushs.
		if (node == null)
		    node = this.dom_appendNode(this.stateDOM.selectSingleNode('state'), nodeName, '');
		return node;
	}
	
	this.setCurTR = function(value)
	{
	    if (this.readyState != 'complete') return;
	    
	    var oldTR = this.CurTR;
	    
        this.CurTR = value;
        this.saveScrollPosition();

        if (oldTR)
            if (this.multiSelect)
                oldTR.className = this.selectedRows.isSelectedTR(oldTR) ? 'w76_grid_selected_tr_multiselect' : this.getClassName(oldTR);
            else
                this.selectedRows.unselectTR(oldTR);
                
        if (this.CurTR)
		{
		    this.Curr_RowKind = this.isGroupTR(this.CurTR) ? 'Group' : 'Data';
	        this.Curr_ID = this.getTRID(this.CurTR);
	        
	        if (this.multiSelect)
	            this.CurTR.className = this.getCurrentClassName(this.CurTR);
	        else if (this.ShowCurRow) 
                this.selectedRows.selectTR(this.CurTR);
		}
		else this.Curr_ID = '';
		
		if (value && oldTR && value.id == oldTR.id) return;
		
		if (!this.multiSelect) this.saveState();
		if (this.onSelectItem &&  value && (!this.isGroupTR(value) || this.isGroupTR(value) && this.getParamFromXML('RowSelectionMethod') != 'ItselfOnlyWithoutGroups')) 
		    if (typeof(this.onSelectItem) == 'function') this.onSelectItem();
		    else eval(this.onSelectItem);
		    
        
        if (this.CurTR && this.autoPostBackOnRowSelect && !this.multiSelect)
            if (!this.container)
                this.selectionChanged();
            else
            {
                window.clearTimeout(this.rowSelectionTimer);
                this.rowSelectionTimer = window.setTimeout(Function.createDelegate(this, this.remittedRowSelect), this.rowSelectionDelay);
            }                
        
        if (!this.multiSelect) this.outClientMsg('');
	}

	this.remittedRowSelect = function()
	{
	    if (this.CurTR && this.autoPostBackOnRowSelect && this.container  && (!this.currentEditableTR || this.currentEditableTR.readyState == 'complete' ))
	        this.selectionChanged();
	}
	
	this.getSimpleStateNode = function(name)
	{
        var node = this.stateDOM ? this.stateDOM.selectSingleNode('state/simpleState/' + name) : null;
		if (node == null)
		    node = this.dom_appendNode(this.stateDOM.selectSingleNode('state/simpleState'), name, '');
		return node;
	}
	
	this.findTR = function(Curr_RowKind, Curr_ID)
	{   
		var res = this.trs ? this.trs[this.Prefix + (Curr_RowKind == 'Data' ? 'tr_' : 'gtr_') + Curr_ID] : null;
		return res && res.length ? res[0] : res;
	}
	
	this.scrollToCurTR = function(tr)
	{
		if (!tr) tr = this.CurTR;
		try
		{
		    if (tr)
		    {
		        var headerHeight = this.trHeader ? this.trHeader.offsetHeight : 0;
		        if (tr.offsetTop +  tr.offsetHeight >= this.divMain.scrollTop + this.divMain.clientHeight)
		            this.divMain.scrollTop = tr.offsetTop - this.divMain.clientHeight + tr.offsetHeight;
                else if (tr.offsetTop < this.divMain.scrollTop + headerHeight)
                    this.divMain.scrollTop = tr.offsetTop - headerHeight;
            }
        }
        catch(ex)
        {}
            
	}
	
	this.nextNode = function(curNode, Step, steped)
	{
	    if (!Step ||  Step == steped ||  !curNode) return curNode;
	    else
	    {
            var newNode = null;
            if (curNode.nodeName == 'Group'  &&  (this.groupIsExpanded(curNode.attributes.getNamedItem('ID').value) || curNode.attributes.getNamedItem('ID').value == '-1')) 
                newNode = curNode.firstChild;
            else
            { 
                if (curNode.nextSibling  &&  (curNode.nextSibling.nodeName == 'Group'  ||  curNode.nextSibling.nodeName == 'Row')) newNode = curNode.nextSibling;
                else 
                {
                    var parentNode = curNode.parentNode;
                    while (parentNode  &&  (!parentNode.nextSibling || parentNode.nextSibling.nodeName == 'Totals' )) parentNode = parentNode.parentNode;
                    if (parentNode) newNode =  parentNode.nextSibling;
                } 
            }
            if (newNode)
                return this.nextNode(newNode, Step, (steped ? steped : 0) + 1);
            else
                return this.nextNode(curNode, Step, Step);
       }
	}
	
	this.previousNode = function(curNode, Step, steped)
	{
	    if (!Step ||  Step == steped ||  !curNode) return curNode;
	    else
	    {
            var newNode = null;
            if (curNode.nodeName == 'Group')
            {
                if (curNode.previousSibling  &&  curNode.previousSibling.nodeName == 'Group') 
                {
                     if ( this.groupIsExpanded(curNode.previousSibling.attributes.getNamedItem('ID').value) )
                     {
                        var lastChild = curNode.previousSibling.lastChild; 
                        if (lastChild.nodeName != 'Group' ||  lastChild.nodeName != 'Row') lastChild = lastChild.previousSibling;
                        while (lastChild  &&  lastChild.nodeName == 'Group'  &&  this.groupIsExpanded(lastChild.attributes.getNamedItem('ID').value))
                        {
                            lastChild = lastChild.lastChild;
                            if (lastChild.nodeName != 'Group' ||  lastChild.nodeName != 'Row') lastChild = lastChild.previousSibling;
                        }
                        newNode = lastChild.nodeName == 'Row' || lastChild.nodeName == 'Group'  ? lastChild : lastChild.previousSibling;
                     }
                     else
                        newNode = curNode.previousSibling;
                }                        
                else
                    if (curNode.parentNode  &&  curNode.parentNode.nodeName == 'Group')
                        newNode = curNode.parentNode;
            }
            else
            {
                if  (curNode.previousSibling  &&  (curNode.previousSibling.nodeName == 'Group' ||  curNode.previousSibling.nodeName == 'Row' ))
                    newNode = curNode.previousSibling;
                else
                    if (curNode.parentNode  &&  curNode.parentNode.nodeName == 'Group')
                        newNode = curNode.parentNode;
                       
            }                
            if (newNode)
                return this.previousNode(newNode, Step, (steped ? steped : 0) + 1);
            else
                return this.previousNode(curNode, Step, Step);
       }   
	}
	
    this.firstNode = function()
    {
        return this.xmlDOM.documentElement.childNodes[1];
    }

    this.lastNode = function()
    {
        var lastChild = this.xmlDOM.documentElement.lastChild;
        while (lastChild  &&  lastChild.nodeName == 'Group'  &&  this.groupIsExpanded(lastChild.attributes.getNamedItem('ID').value))
        {
            lastChild = lastChild.lastChild;
            if (lastChild.nodeName != 'Group' &&  lastChild.nodeName != 'Row') lastChild = lastChild.previousSibling;
        }
        return lastChild.nodeName == 'Row' || lastChild.nodeName == 'Group'  ? lastChild : lastChild.previousSibling;
    }
	
	this.moveTR = function(Step)
	{
	    var curNode = this.getNodeByTr(this.CurTR);
	    var newNode = null;
	    
	    if (this.isNewRecordTR(this.CurTR)  &&  Step > 0) Step = 'home';
	    
	    
	    switch (Step)
	    {
            case 'home': newNode = this.firstNode(); break;
            case 'end': newNode = this.lastNode(); break;
            default: newNode = Step > 0 ? this.nextNode(curNode, Step) :  this.previousNode(curNode, -Step);
        }
        

        var nextIsNewTr = Step < 0 && this.getParamFromXML('ShowNewRecord') != null  &&   curNode != null && newNode != null && newNode.xml == curNode.xml;
        
        if (!newNode  &&  !nextIsNewTr) curNode = newNode;

 	    var newTr = null;
 	    if (nextIsNewTr)
 	        newTr = this.findTR('Data', this.getParamFromXML('Const_NewRecordID'));
 	    else
    	    if (newNode)
	            if (newNode.nodeName == 'Group')
	                newTr = document.getElementById(this.Prefix + 'gtr_' + newNode.getAttribute('ID'));
	            else if (newNode.nodeName == 'Row')
	                newTr = document.getElementById(this.Prefix + 'tr_' + newNode.selectSingleNode('ID').text);
	    
		if (newTr)
		{
		    this.scrollToCurTR(newTr);
		    this.setCurTR(newTr);
		}
		return this.CurTR;
	}
	
	this.tblMain_onblur = this.tblMain_onmouseout = function()
	{
	    if (this.multiSelect && this.CurTR)
	    {
            this.CurTR.className = this.selectedRows.isSelectedTR(this.CurTR) ? 'w76_grid_selected_tr_multiselect' : this.getClassName(this.CurTR);
            this.CurTR = this.firstTR(true);
        }            
	}
	
    this.hover = function(tr, over)
	{
	    if (this.multiSelect)
	    {
	        if (over) 
	        {
	            if (this.rowHoverTimer) window.clearTimeout(this.rowHoverTimer);
	            this.rowHoverTimer = window.setTimeout(
	                Function.createDelegate(this,
	                    function(){
	                    1;
	                        this.setCurTR(tr);
	                    }
	                ), this.rowHoverDelay);
	        }
	    }
        else if (tr.className.indexOf('selected') < 0)
        {
			if (over)
				tr.style.background = this.rowHoverColor;
			else 
			    if (tr.getAttribute('originalBG'))
			        tr.style.background = tr.getAttribute('originalBG');
                else
                    tr.style.backgroundColor = '';
        }                    
	}

	this.firstTR = function(isDataTR)
	{
	1;
		var firstIndex = this.headerInTable && this.ShowHeader ? 1 : 0;
		if (isDataTR && this.ShowRowAll) 
		    return this.tblMain.rows.length > firstIndex + 1 ? this.tblMain.rows.item(firstIndex + 1) : this.tblMain.rows.item(firstIndex);
		else
		    return this.tblMain.rows.length > firstIndex ? this.tblMain.rows.item(firstIndex) : null;
	}
	
	this.nextTR = function(Step)
	{
		if (this.CurTR)
		{
			var	curIndex = this.CurTR.rowIndex;
			var nextIndex = curIndex + Step;
				
			if (nextIndex < 0) nextIndex = 0;
			else if (nextIndex >= this.rowCount()) nextIndex = this.rowCount() - 1;
		
    		return this.tblMain.rows.item(nextIndex);
		}
		else return null;
	}	
	
	this.getMasterValueFromXML = function(id)
	{
		var node = this.xmlDOM.selectSingleNode('Data/Row[ID=' + id + ']/mID')
		return node ? node.text : null;
	}
	
	this.rowCount = function()
	{
		var res =  this.tblMain.rows.length;
		if (this.ShowHeader) res--;
		if (this.ShowRowAll) res--;
		if (this.getParamFromXML('ShowNewRecord')) res--;
		return res;
	}
	
	this.isAllTR = function(tr)
	{
		return tr.id.indexOf('gtr_-1') > 0;
	}
	
	this.isNewRecordTR = function(tr)
	{
		return this.getTRID(tr) == this.getParamFromXML('Const_NewRecordID');
	}
	
	this.isGroupTR = function(tr)
	{
		return tr ? tr.id.indexOf('_gtr_') > 0 : false;
	}
	
	this.beginEditTR = function(element)
	{
	    if (!this.ReadOnly && this.currentEditableTR == null  && element)
	    {
	        var tr = null;
	        var td = null;
	        if (element.nodeName == 'TR') td = (tr = element).cells.length > 0 ? tr.cells.item(0) : null;
	        else tr = (td = element).parentNode;
	        
	        if (tr && this.multiSelect)
	            for (var i = 0; i < tr.cells.length; i++)
	                tr.cells.item(i).unselectable = 'off';
	        
            this.currentEditableTR = this.getParamFromXML('EditModeKind') != 'ImmediatelyAll' ? new editableTRByOne(this, tr) : new editableTRImmediatelyAll(this, tr);
            this.currentEditableTR.beginEdit(td);
            this.outClientMsg('');
         }
	}
	
	this.endEditTR = function(DirectionNextEditTR)
	{
	    if (this.currentEditableTR && this.currentEditableTR.tr)
	    {
	        var tr  = this.currentEditableTR.tr;
	        if (tr && this.multiSelect)
	            for (var i = 0; i < tr.cells.length; i++)
	                tr.cells.item(i).unselectable = 'on';
        }	                
	    
	    this.currentEditableTR = null;
	    
	    if (DirectionNextEditTR)
	    {
	        var lastTrId = this.CurTR.id;
	        var nextTR = this.moveTR(DirectionNextEditTR);
	       
	        if (lastTrId != this.CurTR.id) this.beginEditTR(nextTR);
	    }
	    else
	        try
	        {
	            this.tblMain.focus();
                this.scrollToCurTR(this.CurTR);
	        }
	        catch(ex){}
	}

	this.serverTarget = function()
    {
        return this.getParamFromXML('UniqueID');
    }
    
    this.getParamFromXML = function (paramName)
    {
        var paramNode = this.getParamNodeFromXML(paramName);
        if (paramNode) return paramNode.text;
        else return null;
    }
    
    this.getParamNodeFromXML = function (paramName)
    {
        if (this.paramsNode)
            return this.paramsNode.selectSingleNode(paramName);
        return null;
    }
    
    this.reloadAsEmbedded = function()
    {
    1;
        this.initVariables();
        this.reload(this.xml);
        if (this.loadingMode != 'All')
            this.isDataLoaded = false;
    }
    
    this.reload = function(xml)
    {
        if (this.currentEditableTR)
            this.currentEditableTR.endEdit('oldValue');
    
        if (xml)
        {
            this.divNoData.style.display = 'none';
            if (this.gridExpanded())
            {
                if (this.showStatusBar &&  this.tblStatusBar) this.tblStatusBar.parentNode.style.display = '';
                this.divMain.style.display = '';
                this.divCont.style.paddingTop = this.contPaddingTop + 'px';
                this.divCont.style.paddingBottom =  this.contPaddingBottom + 'px';
            }                
            
            this.isEmpty = false;
            this.xml = xml;
            this.out();
            this.embeddedGrids.forEachGrid(null, this.reloadAsEmbedded);
        }
        else
        {
            if (this.gridExpanded())
            {
                this.divNoData.style.display = '';
                this.divMain.style.display = 'none';
                if (this.tblStatusBar) this.tblStatusBar.parentNode.style.display = 'none';
                this.divCont.style.paddingTop = '0px';
                this.divCont.style.paddingBottom = '0px';
            }
  //          else
//                this.divCont.style.paddingBottom = this.CAPTION_HEIGHT + 'px';
            
            
            if (this.xmlDOM && this.xmlDOM.documentElement)
                while (this.xmlDOM.documentElement.childNodes.length > 1)
                    this.xmlDOM.documentElement.removeChild( this.xmlDOM.documentElement.childNodes[1] );
            
            this.isEmpty = true;
        }
    }
    
    this.onCalbackError = function(args, context)
    {
    1;
        context.outClientMsg(args);
        if (context.currentEditableTR) context.currentEditableTR.readyState = 'complete';
    }
    
    this.outClientMsg = function(msg)
    {
        var lblMessage = this.ClientMsgControlID != '' ? document.getElementById(this.ClientMsgControlID) : null;
        if (lblMessage) 
            lblMessage.innerHTML = msg;
        else if (this.tdStatus0)
            this.tdStatus0.innerHTML = msg;
        
    }
    
	this.goToForm = function(Form, Params)
	{
		1;
		if (this.edtToForm)
		{
			this.edtToForm.value = Form;
			this.edttoFormParams.value = Params;
			if (!this.IsSubmited)
			{
				var theform = document.forms[0];
				theform.submit();
				this.IsSubmited = true;
			}
		}
	}
	
	this.doPostBack = function(eventTarget, eventArgument) 
	{
		if (!this.container)
			{
			    var theform = document.forms[0];
			    theform.__EVENTTARGET.value = this.uniqueId;
			    theform.__EVENTARGUMENT.value = eventTarget + ':' + eventArgument;
			    theform.submit();
			}
			else
			{
			    __doWCPostBack(this.container, this.uniqueId, eventTarget + ':' + eventArgument)
			    this.readyState = 'loading';
            }			    
	}
	
	this.doCallback = function(args, callbackMethod)
	{
        if (!this.container)
        {
	        WebForm_DoCallback(this.uniqueId, args.xml, callbackMethod, this, this.onCalbackError, false);
	    }
        else	        
        {
            var methodNode = args ? args.documentElement : null;
            var methodName = methodNode ? methodNode.attributes.getNamedItem('name').value : '';
	        this.container.CallServer(this.uniqueId, methodName, args.xml, this, callbackMethod, this.onCalbackError)
	    }
	}
	
    this.onKeyUp = function()
    {
    }
    
    this.onKeyDown = function(event)
    {
        if (!this.wcbParent)
            switch (event.keyCode)
		    {
			    case 40: //down
			    {
				    this.moveTR(1);
				    event.returnValue = false; 
				    if (event.preventDefault) event.preventDefault();
			    }break;
    		
			    case 38: //up
			    {
				    this.moveTR(-1);
				    if (this.getTRID(this.CurTR) == this.getParamFromXML('Const_NewRecordID')) this.beginEditTR(this.CurTR); 
				    event.returnValue = false; 
				    if (event.preventDefault) event.preventDefault();
			    }break;
    			
    			case 34: case 33: //page down, page up
			    {
			        if (!this.currentEditableTR)
			        {
		                this.moveTR( event.keyCode == 34 ? this.pageRowCount : -this.pageRowCount);
		                event.returnValue = false; 
		                if (event.preventDefault) event.preventDefault();
		            }
			    }break;
    			
    			case 36: case 35: //home, end
			    {
			        if (event.ctrlKey && !this.currentEditableTR)
			        {
			            this.moveTR( event.keyCode == 36 ? 'home' : 'end');
		                event.returnValue = false; 
		                if (event.preventDefault) event.preventDefault();
		            }
			    }break;
    			
			    case 13: //enter
			    {
				    this.beginEditTR(this.CurTR);
				    event.returnValue = false;
				    if (event.preventDefault) event.preventDefault();
    				
			    } break;
			    
			    case 37: //left
			    {
				    if (this.isGroupTR(this.CurTR) && this.groupIsExpanded(this.getTRID(this.CurTR)))
				    {
				        this.collapseGroup(this.getTRID(this.CurTR));
				        event.returnValue = false;
				        if (event.preventDefault) event.preventDefault();
				    }
				    else if (!this.isGroupTR(this.CurTR) && this.hasGroup(this.CurTR))
				    {
				        var groupTR = this.findTR('Group', this.getGroupID(this.CurTR));
				        if (groupTR != null)
				        {
				          this.setCurTR(groupTR);
				          this.collapseGroup(this.getTRID(groupTR));
				          event.returnValue = false;
				          if (event.preventDefault) event.preventDefault();
				        }
				    }
    		    } break;
    		    
    		    case 39: //right
			    {
				    if (this.isGroupTR(this.CurTR) && !this.groupIsExpanded(this.getTRID(this.CurTR)))
				    {
				        this.expandGroup(this.getTRID(this.CurTR));
				        event.returnValue = false;
				        if (event.preventDefault) event.preventDefault();
                    }				        
    		    } break;
			    
			    case 32: //space
			    {
			        if (this.multiSelect && this.CurTR)
			        {
			            this.selectedRows.beginTransaction();
			            if (this.getParamFromXML('RowSelectionMethod') != 'ItselfOnlyWithoutGroups' || !this.isGroupTR(this.CurTR))
			                if(this.selectedRows.isSelectedTR(this.CurTR))
                            {
                                if (this.allowEmptySelection || this.selectedRows.count() > 1)  this.selectedRows.unselectTR(this.CurTR);
                            }                        
                            else this.selectedRows.selectTR(this.CurTR);
                        else
                        {
                            var groupNode = this.getNodeByTr(this.CurTR);
                            if (groupNode) 
                            {
                                if (this.selectedRows.isSelectedNoneRowsInGroup(groupNode))
                                    this.selectedRows.selectAllTR(groupNode);
                                else
                                    this.selectedRows.unSelectGroup(groupNode);
                            }         
                        }                            
                        
                        if (this.selectedRows.isChanged()) 
                        {
                            this.saveState();
                            this.selectionChanged();
                        }                            
                        this.selectedRows.commit();
                        event.returnValue = false;
                        if (event.preventDefault) event.preventDefault();
                    }
    		    } break;
    		    
    		    case 65: // a
    		    {
                    if (event.ctrlKey && this.multiSelect)
                    {
                        if (this.selectedRows.selectAllTR())
                        {
                            this.saveState();
                            this.selectionChanged();
                        }                            
                        event.returnValue = false;
                        if (event.preventDefault) event.preventDefault();
                    }
    		    } break;
		    }
    }
    
    this.divMain_onmousewheel = function(event)
    {
        if (this.currentEditableTR)
        {
            if (event.preventDefault) 
                event.preventDefault();
            return event.returnValue = false;
        }            
    }
    
    this.hasGroup = function(tr)  
    {
        return tr.parentNode.id != '';
    }
    
    this.getGroupID = function(tr)
    {
        if (!this.isGroupTR(tr) && this.hasGroup(tr))
            return this.getTRID(tr.parentNode)
        else return this.getTRID(tr);
    }
      
    this.getTRID = function(tr)
    {
          return tr ? tr.id.replace(this.Prefix + 'tr_' , '').replace(this.Prefix + 'gtr_' , '').replace(this.Prefix + 'bd_' , '') : null;
    }
    
    this.focus = function()
    {
        if (document.selection) 
            document.selection.createRange().collapse(true);
        if (this.tblMain)
        {   
            try
            {
	            this.tblMain.focus();
	            this.tblMain.setActive();
	        }
	        catch(ex){}
	    }
    }
    
    this.fastFind = function(startingString, DataTextFieldIndex)
    {
        if (this.tblMain == null) return null;
        startingString = startingString.toUpperCase();
        for (var tr_index = 0; tr_index < this.rowCount(); tr_index++)
        {
            var tr = this.tblMain.rows.item(tr_index);
            var txt = tr.cells.item(DataTextFieldIndex).firstChild.nodeValue != null ? tr.cells.item(DataTextFieldIndex).firstChild.nodeValue : 
                tr.cells.item(DataTextFieldIndex).firstChild.innerText;
            if (txt.toUpperCase().indexOf(startingString) == 0) 
                return tr;
        }
        return null;
    }
    
	this.getRequestParams = function()
	{
	    var res = '';
	    for (var param_i = 0; param_i < this.requestParams.length; param_i++)
	    {
	        var param = this.requestParams[param_i];
	        if (param)
	            switch (param.type)
	            {
	                case 'WCombo76': case 'ExtComboBox': res += param.serverId + '=' + param.getSelectedValue() + ';'; break;
	                case 'checkbox': res += param.serverId + '=' + param.checked + ';'; break;
	            }
	    }
	    return res.substring(0, res.length - 1);
	}
	
	this.tdHeader_onclick = function(colIndex)
	{
	    if (this.getParamFromXML('AllowClientSorting') != null  &&  this.stateDOM) 
	    {   
	        var srtNode = this.stateDOM.selectSingleNode('state/srt');
	        var curSort = '';
	        if (srtNode.childNodes[0]  &&  srtNode.childNodes[0].text == colIndex)
	            curSort = srtNode.childNodes[0].attributes.getNamedItem('order').value;
	        
            this.dom_removeChilds(srtNode);  
            cNode = this.dom_appendNode(srtNode, 'c', colIndex);
            this.dom_appendAttr(cNode, 'order', curSort == 'asc' ? 'desc' : 'asc');
            this.saveState();
            
            var argsDOM = this.newXMLDOM();
            var methodNode = argsDOM.createElement('method');
            this.dom_appendAttr(methodNode, 'name', 'Sort')
            methodNode.appendChild(this.stateDOM.documentElement.cloneNode(true));
            argsDOM.appendChild(methodNode);
            
            if (this.stateDOM.selectSingleNode('state/clientUpdates/rowValues'))
                this.dom_removeChilds(this.getRowValuesNode());
            this.doCallback(argsDOM, this.callbackSort);
        }
	}
	
	this.callbackSort = function(args, context)
	{
	    context.edtScrollTop.value = '-1';
	    context.reload(args);
	    context.focus();
	}
	
	this.dom_removeChilds = function(node)
	{
        while (node.hasChildNodes())
            node.removeChild(node.childNodes[0]);
	}
	
	this.dom_appendNode = function(parentNode, name, text)
	{
	    var res = parentNode.ownerDocument.createElement(name);
	    res.text = text;
	    parentNode.appendChild(res);
	    return res;
	}
	
	this.dom_appendAttr = function(node, name, value)
	{
	    var res = node.ownerDocument.createAttribute(name);
	    res.value = value;
	    node.setAttributeNode(res);
	    return res;
	}
	
    this.getAbsolutePosition = function()
    {
        return WebForm_GetElementPosition(this.divMain);
    }
    
    this.StoreState = function()
	{
	1;
	    return this.stateDOM ? this.stateDOM.documentElement : null;
	}
   	
	this.RestoreState = function(node)
	{
	    var oldStateDOM = this.newXMLDOM();
	    if (this.stateDOM) oldStateDOM.appendChild( this.stateDOM.documentElement.cloneNode(true) );
	   
	    if (this.stateDOM && this.stateDOM.selectSingleNode('state/clientUpdates/rowValues')) 
	        this.dom_removeChilds(this.getRowValuesNode());
	    if (node)
	    {
	        var newAllTextValueNode = node.selectSingleNode('state/simpleState/AllTextValue');
	        if (newAllTextValueNode)
	            this.setAllTextValue(newAllTextValueNode.text);
	    
	        var needRefreshTr = false;
	        var stateNode = node.selectSingleNode('state');
	        var dataNode = stateNode.selectSingleNode('Data');
            if (dataNode)
            {
                this.embeddedGrids = new WEmbeddedGrids76(this);
                if (this.stateDOM)
                {
                    var expRNode = this.stateDOM.selectSingleNode('state/expR');
                    if (expRNode) this.dom_removeChilds(expRNode);
                }
                
                //SNV[+]
                if (!dataNode.hasChildNodes() && !this.ReadOnly  && this.ShowNewRecord)
                {
                    var  paramsNode = this.xmlDOM.selectSingleNode('Data/Params');
                    if (paramsNode)
                        dataNode.appendChild(paramsNode);
                }
                ///SNV[+]
                this.reload(dataNode.hasChildNodes() ? dataNode.xml : null);

                needRefreshTr = true;
                if (this.wcbParent && this.wcbParent.MasterCB)
                {
                    this.reload(null);
                    this.wcbParent.settedParams = 'new!!!';
                }
            }

            var newTotalsNode = stateNode.selectSingleNode('NewTotals');
            if (newTotalsNode)
            {
                this.updateTotals(newTotalsNode);
                needRefreshTr = true;
            }
            
            var groupInfoNode = stateNode.selectSingleNode('groupInfo');
            if (groupInfoNode)
                this.updateGroupInfo(groupInfoNode);
            
            var newRecordsNode = stateNode.selectSingleNode('NewRecords');
            if (newRecordsNode)
            {
                this.updateRecords(newRecordsNode);
                needRefreshTr = true;
            }
	        
            var selectedRowsNode = stateNode.selectSingleNode('selectedRows');
            if (needRefreshTr || selectedRowsNode)
            {
                this.selectedRows.refreshSelectedRows(selectedRowsNode);
                this.edtScrollTop.value = '-1';
                this.scrollToCurTR();
            }
            
            var statusBarNode = node.selectSingleNode('state/statusBar');
            if (statusBarNode)
            {
                if (temp = statusBarNode.selectSingleNode('msg0')) this.outClientMsg(temp.text);
                if ((temp = statusBarNode.selectSingleNode('msg1')) && this.tdStatus1) 
                    this.tdStatus1.innerHTML = temp.text;
            }
            
            var displayNode = stateNode.selectSingleNode('simpleState/Display');
            if (displayNode) this.setVisibility(displayNode.text != 'none');
            
            var IDFieldNameNode = stateNode.selectSingleNode('simpleState/IDFieldName');
            if (IDFieldNameNode) this.getSimpleStateNode('IDFieldName').text = IDFieldNameNode.text;
            
            var srtNode = stateNode.selectSingleNode('srt');
            var curStateNode = this.stateDOM.selectSingleNode('state');
            if (srtNode && curStateNode)
                curStateNode.replaceChild(srtNode, this.stateDOM.selectSingleNode('state/srt'));
                
            
            var expGrNode = stateNode.selectSingleNode('expGr');
            if (expGrNode && this.stateDOM)
            {
                var oldExpGrNode = this.stateDOM.selectSingleNode('state/expGr');
                if (oldExpGrNode) oldExpGrNode.parentNode.removeChild(oldExpGrNode);
                this.stateDOM.documentElement.appendChild(expGrNode.cloneNode(true));
            }
            
            var columnsNode = stateNode.selectSingleNode('cols');
            if (columnsNode && this.stateDOM)
            {
                var oldColumnsNode = this.stateDOM.selectSingleNode('state/cols');
                if (oldColumnsNode) oldColumnsNode.parentNode.removeChild(oldColumnsNode);
                this.stateDOM.documentElement.appendChild(columnsNode.cloneNode(true));
            }
            
            var autoPostBackOnRowSelectNode = stateNode.selectSingleNode('simpleState/AutoPostBackOnRowSelect');
            if (autoPostBackOnRowSelectNode) 
            {
                this.autoPostBackOnRowSelect = autoPostBackOnRowSelectNode.text == 'true';
                this.getSimpleStateNode('AutoPostBackOnRowSelect').text = this.autoPostBackOnRowSelect.toString();
            }
            
            var readOnlyNode = stateNode.selectSingleNode('simpleState/ReadOnly');
            if (readOnlyNode) 
            {
                this.ReadOnly = readOnlyNode.text == 'true';
                this.getSimpleStateNode('ReadOnly').text = this.ReadOnly.toString();
            }
            
            var contPaddingTopNode = stateNode.selectSingleNode('simpleState/ContPaddingTop');
            if (contPaddingTopNode)
                this.setContPaddingTop(contPaddingTopNode.text);
                
            var contPaddingBottomNode = stateNode.selectSingleNode('simpleState/ContPaddingBottom');
            if (contPaddingBottomNode)
                this.setContPaddingBottom(contPaddingBottomNode.text);                
            
            
            var scriptNode = stateNode.selectSingleNode('script');
            if (scriptNode) 
                if (window.execScript)
                    window.execScript(scriptNode.text);
                else
                    window.eval(scriptNode.text);
	    }
	    
	    this.readyState = 'complete';
	    this.saveState();
	}
	
	this.setContPaddingTop = function(value)
	{
        this.contPaddingTop = value;
        if (this.gridExpanded())
            this.divCont.style.paddingTop = value.toString() + 'px';
	}
	
	this.setContPaddingBottom = function(value)
	{
        this.contPaddingBottom = value;
        if (this.gridExpanded())
            this.divCont.style.paddingBottom = value.toString() + 'px';
	}
	
	this.updateGroupInfo = function(groupInfoNode)
	{
	    var giNode = groupInfoNode.firstChild;
        while (giNode)
        {
            var groupId = giNode.getAttribute('ID');
            var groupNode = groupId ? this.groupNodeFromXmlDOM(groupId) : null;
            
            if (groupNode)
                groupNode.setAttribute('Text', giNode.getAttribute('Text'));
            
            giNode = giNode.nextSibling;
        }
	}
	
	this.updateTotals = function(newTotalsNode)
	{
	    1;
	    var newTotalNode = newTotalsNode.firstChild;
        while (newTotalNode)
        {
            var groupId = newTotalNode.getAttribute('ID');
            var groupNode = null;
            
            if (!this.ShowRowAll && groupId == -1)
                groupNode = this.xmlDOM.documentElement;
            else                
                groupNode = groupId ? this.groupNodeFromXmlDOM(groupId) : null;
            
            if (groupNode)
            {
                var oldTotalNode = groupNode.selectSingleNode('Totals');
                if (oldTotalNode) groupNode.removeChild(oldTotalNode);
                groupNode.appendChild(newTotalNode.firstChild.cloneNode(true));
            }
            
            newTotalNode = newTotalNode.nextSibling;
        }
	}

	this.updateRecords = function(newRecordsNode)
	{
        var newRowNode = newRecordsNode.firstChild;
        while (newRowNode)
        {
            var rowNode = this.rowNodeFromXmlDOM( newRowNode.selectSingleNode('ID').text );
            
            if (newRowNode.selectSingleNode('@Deleted')) //delete
            {
                if (rowNode)
                {
                    var parentNode = rowNode.parentNode;
                    rowNode.parentNode.removeChild(rowNode);
                    while (parentNode.nodeName == 'Group' && !parentNode.selectSingleNode('Row')  && !parentNode.selectSingleNode('Group'))
                    {
                        var temp = parentNode.parentNode;
                        temp.removeChild(parentNode);
                        parentNode = temp;
                    }
                }
                this.embeddedGrids.clear(newRowNode.selectSingleNode('ID').text);
            }
            else if (rowNode) //update
            {
                rowNode.parentNode.replaceChild( newRowNode.cloneNode(true), rowNode );
                this.embeddedGrids.clear(newRowNode.selectSingleNode('ID').text);
            }
            else //insert
            {
                if (this.groupsCount > 0)
                {
                    if (newRowNode.getAttribute('GroupID'))
                    {
                        var groupNode = this.groupNodeFromXmlDOM(newRowNode.getAttribute('GroupID'));
                        if (groupNode) groupNode.appendChild( newRowNode.cloneNode(true) ); 
                    }                        
                }
                else
                    this.xmlDOM.documentElement.appendChild( newRowNode.cloneNode(true) );
            }                            
            
            newRowNode = newRowNode.nextSibling;
        }
        
        var newTotalRowsCount = newRecordsNode.getAttribute('TotalRowsCount');
        var TotalRowsCountNode  = this.getParamNodeFromXML('TotalRowsCount');
        if (newTotalRowsCount && TotalRowsCountNode) TotalRowsCountNode.text = newTotalRowsCount;
        this.reload(this.xmlDOM.xml);
	}
	
	this.setAllTextValue = function(value)
	{
	    var allTextValueNode = this.getSimpleStateNode('AllTextValue');
	    if (allTextValueNode) allTextValueNode.text = value;
	    
        if (this.ShowRowAll)
        {
            var tr = this.firstTR(false);
            if (tr) 
            {
                var spanCapt = tr.cells.item(0).getElementsByTagName('span')[0];
                if (spanCapt)
                    spanCapt.firstChild.nodeValue = value;
            }
        }
	}
	
	this.setVisibility = function(value)
	{
	    this.divCont.style.display = value ? '' : 'none';
	    this.getSimpleStateNode('Display').text = this.divCont.style.display;
	}
	
	this.statusBarRefresh_click = function()
	{
	    var argsDOM = this.newXMLDOM();
        var methodNode = argsDOM.createElement('method');
        this.dom_appendAttr(methodNode, 'name', 'Refresh')
        
        argsDOM.appendChild(methodNode);
   
        if (this.stateDOM)
            methodNode.appendChild(this.stateDOM.documentElement.cloneNode(true));   
        this.doCallback(argsDOM, this.callbackRefresh);
	}
	
	this.callbackRefresh = function()
	{
	}
	
	this.checkBox_onclick = function(event, chb) 
	{
	    var colIndex = -1;
	    try
	    {
	        colIndex = chb.name.replace(this.Prefix + 'chb', '').split('_')[0];
        }
        catch(ex)
        {}

        if (colIndex != -1  && new columnParam(this.paramsNode, colIndex).behavior() == 'IncludeToTotals' || this.autoPostBackOnColumnCheckBoxClick)
            this.doPostBack(chb.name, chb.checked ? 1 : 0);
        
        
	    event.cancelBubble = true;
	}
	
    this.getHeaderTop = function()
	{
	    return this.divMain.scrollTop;
	}

    this.gridExpanded = function()
    {
        return this.getSimpleStateNode('GridExpanded').text != 'false';
    }

    this.imgExpandGrid_click = function(img)
    {
        var gridExpandedNode = this.getSimpleStateNode('GridExpanded');
        
        if (gridExpandedNode.text != 'false')
            this.collapseGrid(img);
        else if (!this.isDataLoaded)
            if (this.container)
                this.loadDataXML(this.masterId, 
                    Function.createDelegate( this, function(){this.expandGrid(img);  this.saveState();} )
                );
            else
            {
                this.expandGrid(img, true);
                this.saveState();
                this.doPostBack();
                return;
            }
        else
            this.expandGrid(img);
                         
        this.saveState();
    }
    
    this.collapseGrid = function(img)
    {
        var gridExpandedNode = this.getSimpleStateNode('GridExpanded');

        var isIE = !!(window.attachEvent && !window.opera);     
        this.divCont.style.paddingTop = '0px';
        this.divCont.style.paddingBottom = this.CAPTION_HEIGHT + 'px';
        
        this.divMain.style.display = 'none';
        this.divNoData.style.display = 'none';
        if (this.divFooter) 
            this.divFooter.style.display = 'none';            
            
        this.refreshFooterPosition();
        img.src = this.UrlToImages + 'plus.gif';
        gridExpandedNode.text = 'false';
    }
    
    this.expandGrid = function(img, notVisual)
    {
        var gridExpandedNode = this.getSimpleStateNode('GridExpanded');
        
        
        
        if (!notVisual)
        {
            this.divCont.style.paddingTop = this.contPaddingTop + 'px';
            this.divCont.style.paddingBottom =  this.contPaddingBottom + 'px';
        }
        
        if (!this.isEmpty)
        {
            if (!notVisual) this.divMain.style.display = '';
            
            if (this.divFooter && !notVisual)
                this.divFooter.style.display = '';
        }
        else
            if (!notVisual)
                 this.divNoData.style.display = '';
                            
                            
        this.refreshFooterPosition();
        
        img.src = this.UrlToImages + 'minus.gif';
        gridExpandedNode.text = 'true';
    }
    
    this.selectionChanged = function()
    {
        1;
        if (this.autoPostBackOnRowSelect && (this.beforePostBackOnSelectionChanged == null || this.beforePostBackOnSelectionChanged(this)))
            this.doPostBack('', 'SelectionChanged');
    }
    
    this.setMasterGrid = function(masterId, grid)
    {
        if (grid)
        {
            this.masterGrid = grid;
            this.masterId = masterId;
            grid.embeddedGrids.add(masterId, this);
        }
    }
    
    this.getRowValuesNode = function()
    {
        var clientUpdatesNode = this.stateDOM.selectSingleNode('state/clientUpdates');
        var rowValuesNode = clientUpdatesNode.selectSingleNode('rowValues');
        return rowValuesNode ? rowValuesNode : clientUpdatesNode.appendChild( clientUpdatesNode.ownerDocument.createElement('rowValues') );
    }
    
    this.moveTrPos = function(tr, newPos)
    {
        var tbody = tr.parentNode;
        var oldPos = tr.sectionRowIndex; 
        newPos = Math.max(newPos, 0);
        newPos = Math.min(newPos, tbody.rows.length - 1);

        var afterTr = null;
        if (newPos < oldPos)
            afterTr = newPos != tbody.rows.length - 1 ?  tbody.rows.item(newPos) : null;
        else
            afterTr = newPos != tbody.rows.length - 1 ?  tbody.rows.item(newPos + 1) : null;
        
        tbody.insertBefore(tr, afterTr);
        
        var rowNode = this.getNodeByTr(tr);
        var afterRowNode = afterTr ? this.getNodeByTr(afterTr) : null;
        if (rowNode) rowNode.parentNode.insertBefore(rowNode, afterRowNode);
        
        var rowValuesNode = this.getRowValuesNode();
        
        var si = !this.groupsCount ? Math.min(oldPos, newPos) : 0;
        var ei = !this.groupsCount ? Math.max(oldPos, newPos) : tbody.rows.length - 1;
        for (var rowIndex = si; rowIndex <= ei; rowIndex++)
        {
            var curTr = tbody.rows.item(rowIndex);
            var trId = this.getTRID(curTr);
            var rNode = rowValuesNode.selectSingleNode('r[@ID="' + trId + '"]');
            if (!rNode)
            {
                rNode = rowValuesNode.appendChild( rowValuesNode.ownerDocument.createElement('r') );
                rNode.setAttribute('ID', trId);
            }
            this.dom_removeChilds(rNode);
            
            var orderFieldNode = rNode.appendChild( rNode.ownerDocument.createElement(this.orderField) );
            orderFieldNode.text = rowIndex;
        
            if (rowIndex != newPos) curTr.className = this.getClassName(curTr);
        }            
    }
    
    this.imgRowUpClick = function()
    {
        if (this.CurTR)
        {
            this.moveTrPos(this.CurTR, this.CurTR.sectionRowIndex ? this.CurTR.sectionRowIndex - 1 : this.CurTR.parentNode.rows.length -1);
            this.clearSort();
            this.saveState();
            if (this.rowMoving == 'AutoCallback')
                this.doPostBack('', 'onRowMove');
        }            
    }

    this.imgRowDownClick = function()
    {
        if (this.CurTR)
        {
            this.moveTrPos(this.CurTR, this.CurTR.sectionRowIndex != this.CurTR.parentNode.rows.length - 1 ? this.CurTR.sectionRowIndex + 1 : 0) ;
            this.clearSort();
            this.saveState();
            if (this.rowMoving == 'AutoCallback')
                this.doPostBack('', 'onRowMove');
        }
    }
    
    this.clearSort = function()
    {
        var srtNode = this.stateDOM.selectSingleNode('state/srt');
        this.dom_removeChilds(srtNode);

        if (this.trHeader)
        {
            var images = this.trHeader.getElementsByTagName('IMG');
            for (var i = 0; i < images.length; i++)
                if (images[i].src && images[i].src.indexOf('sort_') >= 0)
                    images[i].style.display = 'none';
        }
    }
    
    this.dispose = function()
    {
        this.xmlDOM = null;
        this.stateDOM = null;
    }
    
    this.setHeight = function(val)
    {
    1;
        this.divCont.style.height = val;
    }
    
    this.moveStateHiddens = function(dest)
    {
        if (this.edtState) dest.insertBefore(this.edtState, null);
        if (this.edtScrollTop) dest.insertBefore(this.edtScrollTop, null);
        if (this.edtToForm) dest.insertBefore(this.edtToForm, null);
        if (this.edttoFormParams) dest.insertBefore(this.edttoFormParams, null);
    }
    
    this.resizeColumns = function()
    {
    
        if (!this.tblMain)
            return;
    
        var str = this.tblMain.rows[this.tblMain.rows.length - 1];
        for (var i = 0; i < this.trHeader.cells.length; i++)
        {
            var paddingLeft = parseInt(getStyle(str.cells[i], 'paddingLeft')) || 0;
			var paddingRight = parseInt(getStyle(str.cells[i], 'paddingRight')) || 0;
			
			var spaddingLeft = parseInt(getStyle(this.trHeader.cells[i], 'paddingLeft')) || 0;
          
            var nv;
            
            if (str.cells[i])
            {
                nv = str.cells[i].clientWidth - spaddingLeft * 2;
                    
                nv = Math.max(nv, 0);
                
                if (!this.settedColumnWidths.length || this.settedColumnWidths[i] != nv)
                {
                    this.trHeader.cells[i].style.width = nv + 'px';
                    this.settedColumnWidths[i] = nv;
                }
            }                
    
        }
    }
    
    this.onresizeTick = function()
    {
        if (this.ShowHeader)
            this.resizeColumns();
    }
    
    this.divMain_onScroll = function(event)
    {
        if (this.ShowHeader)
            this.tblHeader.style.left = -this.divMain.scrollLeft;
          
          
    }
}

//// base class editableTR
function editableTR()
{
    this.parentGrid = null;
    this.tr = null;
    this.oldValues = new Array();
    this.processInputBlur = true;
    this.readyState = 'complete';
    this.DirectNextEditTR = 0;
    this.isNewTr = false;
    this.confirmChanges = true;
    
    //abstract methods
    this.onInputFocus = function(){};
    this.onInputClick = function(){};
    this.onInputKeyDown = function(){};
    this.onInputBlur = function(){};
    this.elementBelongThis = function(){};
    
    //virtual methods
    this.beginEdit = function(init_td){}
    this.endEdit = function(whenceValues){}
    
    this.beginEditTd = function(td)
    {
	    var td_index = td.cellIndex;
        var input = null;
        var colParam = new columnParam(this.parentGrid.paramsNode, td_index);
        
        if (colParam.readOnly()) return null;        
        this.tr.editableTR = this;
        switch (colParam.editKind())
        {
            case 'EditBox': 
            {
                input = document.createElement('input');
                var value = td.innerText;
                if (input.attachEvent)
                {
                    input.attachEvent('onclick', this.onInputClick);
                    input.attachEvent('onblur', this.onInputBlur);
                    input.attachEvent('onkeydown', this.onInputKeyDown);
                    input.attachEvent('onfocus', this.onInputFocus);
                }
                else
                {
                    input.addEventListener('click', this.onInputClick, false);
                    input.addEventListener('blur', this.onInputBlur, false);
                    input.addEventListener('keydown', this.onInputKeyDown, false);
                    input.addEventListener('focus', this.onInputFocus, false);
                }                    
                
                input.value = value;
                input.style.width = td.offsetWidth;
                if (td.currentStyle && td.currentStyle.paddingTop)
                    input.style.marginTop = -parseInt(td.currentStyle.paddingTop);
                td.nowrap = 'nowrap';
                td.innerHTML = '<div>' + (value == ' ' ? '&nbsp;' : value)  +  '</div>';
                input.wordWrap = 'true';
                input.setAttribute('autocomplete', 'off');
                input.className = 'w76_grid_input';
                td.insertBefore(input, td.firstChild);
                
                input.editableTR = this;
                input.inputIndex  = td_index;
            } break;
            case 'CheckBox': 
            {
                input = document.createElement('input');
                var value = td.innerText;
                input.type = 'checkbox';
                input.style.position = 'absolute';
                while (td.firstChild) td.removeChild(td.firstChild);
                td.insertBefore(input, td.firstChild);
                
                if (window.navigator.appName == 'Microsoft Internet Explorer')
                {
                    input.style.top = td.offsetTop +  (td.offsetHeight - input.offsetHeight )/ 2 + 'px';
                    input.style.left = td.offsetLeft + (td.offsetWidth - input.offsetWidth )/ 2 + 'px';
                }
                else
                {
                    var tdPos = getOffsetPosition(td);
                    input.style.top = tdPos.top + (td.offsetHeight - input.offsetHeight - 6)/ 2 -  this.parentGrid.divMain.scrollTop + 'px';
                    input.style.left = tdPos.left  + (td.offsetWidth - input.offsetWidth - 6)/ 2 -  this.parentGrid.divMain.scrollLeft + 'px';
                }                    
                
                if (value == colParam.trueText()) input.checked = true;
                
                if (input.attachEvent)
                {
                    input.attachEvent('onblur', this.onInputBlur);
                    input.attachEvent('onkeydown', this.onInputKeyDown);
                    input.attachEvent('onfocus', this.onInputFocus);
                }
                else
                {
                    input.addEventListener('blur', this.onInputBlur, false);
                    input.addEventListener('keydown', this.onInputKeyDown, false);
                    input.addEventListener('focus', this.onInputFocus, false);
                }
                
                input.editableTR = this;
                input.inputIndex = td_index;
            }break;
            case 'WCombo76':
            {
                var input = eval(colParam.EditControlID());
                input.setVisibility(true);
                input.setAbsolutePosition();
                
                var pos = position.getPositionInCont(td, this.parentGrid.divCont);
                input.setLeft(pos[0]+ 'px');
                input.setTop(pos[1] + 'px');

        	    input.setWidth(td.offsetWidth);

        	    input.onblur = this.onInputBlur;
        	    input.onkeydown = this.onInputKeyDown;
        	    input.onfocus = this.onInputFocus;
        	    input.edtMain.editableTR = this;
        	    if (!this.isNewTr) 
        	    {
        	        this.readyState = 'loading';
        	        input.onAfterSetFilter = Function.createDelegate(this, this.onComboLoaded);
        	        if (input.setSelectedValue('Data', td.attributes.getNamedItem('key').value))
        	         this.readyState = 'complete';
                }        	        
        	    input.inputIndex = td_index;
            }break;
            case 'WCalendar76':
            {
                var input = eval(colParam.EditControlID());
                input.setWidth(10);
                input.setVisibility(true);
                input.tblMain.style.position = 'absolute';
        	    
                var pos = position.getPositionInCont(td, this.parentGrid.divCont);
                input.setLeft(pos[0]+ 'px');
                input.setTop(pos[1] + 'px');
                
        	    input.setWidth(td.offsetWidth);
        	    
        	    input.onblur = this.onInputBlur;
        	    input.onkeydown = this.onInputKeyDown;
        	    input.onfocus = this.onInputFocus;
        	    input.edtMain.editableTR = this;
        	    input.setSelectedDate(td.innerText);
        	    input.inputIndex = td_index;
            }
        }
        if (input) input.id = this.parentGrid.Prefix + 'input_' + td_index.toString();
        return input;
    }
    
    this.onComboLoaded = function(combo)
    {
        this.readyState = 'complete';
        if (!this.parentGrid.multiSelect)
	        this.parentGrid.remittedRowSelect();
	       
        combo.onAfterSetFilter = null;
    }
    
    //whenceValues = {norWhence, input, oldValue}
    this.endEditTd = function(whenceValues, td, input) 
    {
        var td_index = td.cellIndex;
        if (whenceValues != 'norWhence')
	    {
            var colParam = new columnParam(this.parentGrid.paramsNode, td_index);
            if (!colParam.readOnly())
            {
                switch (colParam.editKind()) 
                {
                    case 'EditBox': 
                    {
                        if (input)
                        {
                            td.removeChild( td.childNodes[1] );
                            td.insertBefore( document.createTextNode(whenceValues == 'input' ? input.value : this.oldValues[td_index]), td.firstChild);
                            input.style.display = 'none';
                        }
                        else
                            td.innerText = whenceValues == 'input' ? input.value : this.oldValues[td_index];
                    }break;
                    case 'CheckBox': 
                    {
                        if (whenceValues == 'input')
                        {
                            td.innerHTML = input.checked ? colParam.trueText() : colParam.falseText();
                            if (colParam.kind() == 'Check')
                                td.className = input.checked ? 'w76_grid_isChecked_td' : 'w76_grid_isNoChecked_td';
                        }
                        else
                        {
                            td.innerHTML = this.oldValues[td_index];
                            if (colParam.kind() == 'Check')
                                td.className = this.oldValues[td_index] == colParam.trueText() ? 'w76_grid_isChecked_td' : 'w76_grid_isNoChecked_td';   
                        }
                    }break;
                    case 'WCombo76':
                    {
                        if (whenceValues == 'input')
                        {
                             td.attributes.getNamedItem('key').value = input.getSelectedValue();
                             td.innerText = input.getSelectedText();
                        }
                        else td.innerText =  this.oldValues[td_index].text;
                        if (input) input.setVisibility(false);
                    }break;
                    case 'WCalendar76':
                    {
                        if (whenceValues == 'input')
                            td.innerText = this.getControlValue(input);
                        else td.innerText =  this.oldValues[td_index];
                        if (input) input.setVisibility(false);
                    }break;
                }
	        }
	    }
    }
    
    this.initOldValues = function()
    {
        for (var td_index = 0; td_index < this.tr.cells.length; td_index++)
        {
             var colParam = new columnParam(this.parentGrid.paramsNode, td_index);
             var td = this.tr.cells.item(td_index);
             
             if (!colParam.readOnly())
                switch (colParam.editKind())
                {
                    case 'EditBox': case 'CheckBox': case 'WCalendar76':
                    {
                        this.oldValues[td_index] =  td.innerText;   
                    }break;
                    case 'WCombo76':
                    {
                        var oldValue = new Object();
                        oldValue.value = !this.isNewTr ? td.attributes.getNamedItem('key').value : '-1';
                        oldValue.text = td.innerText;
                        this.oldValues[td_index] = oldValue;
                    }break;
                }
            else this.oldValues[td_index] = null;
        }
    }
    
    this.getControlKind = function(control)
    {
        if (control)
            if (control.nodeName == 'INPUT') 
                switch (control.type)
                {
                    case 'text': return 'EditBox'; 
                    case 'checkbox': return 'CheckBox';
                    default: return 'unknow';
                }
            else  return control.type; 
        else return 'unknow';
    }
    
    this.getControlValue = function(control, colindex)
    {
        if (control && !colindex) colindex = control.inputIndex;
        var colParam = new columnParam(this.parentGrid.paramsNode, colindex);
        switch (this.getControlKind(control))    
        {
            case 'EditBox': return control.value;
            case 'CheckBox': return control.checked ? colParam.trueText() : colParam.falseText();
            case 'WCombo76': return control.getSelectedValue();
            case 'WCalendar76': return control.getSelectedText();
            default: return null;
        }
    }
    
    this.onError = function(args, editableTR)
    {
    1;
        editableTR.parentGrid.outClientMsg(args);
    }
    
    this.callbackSaveValues = function(args, parentGrid)
    {   
        var response = parentGrid.newXMLDOM();
        var editableTR = parentGrid.currentEditableTR;
        if (response.loadXML(args))
        {
            parentGrid.Curr_ID = response.selectSingleNode('response/ReturnCode').text;
            
            if (editableTR)
            {
                var dataNode = response.selectSingleNode('response/Data');
                if (dataNode) 
                {
                    var temp = editableTR.DirectNextEditTR;
                    editableTR.DirectNextEditTR = 0;
                    parentGrid.reload(dataNode.xml);
                    editableTR.DirectNextEditTR = temp;

                }
                editableTR.endEdit(dataNode ? 'norWhence' : 'input');
            }
            else
                window.setTimeout(
                    function()
                    {
                        try
                        {
                            parentGrid.tblMain.setActive();
                        }
                        catch(ex){}
                    }, 1);
        }

        if (editableTR) editableTR.readyState == 'complete';
        parentGrid.edtScrollTop.value = '-1';
    }
}

//// class editableTRByOne: editableTR
editableTRByOne.prototype = new editableTR();
function editableTRByOne(parentGrid, tr)
{
    this.parentGrid = parentGrid;
    this.tr = tr;
    this.input = null;
    this.isNewTr = this.parentGrid.isNewRecordTR(tr);
    this.confirmChanges = this.parentGrid.isConfirmInPlaceChanges;
    
    this.beginEdit = function(init_td)
    {
        try
        {
            this.initOldValues();
            if (init_td.offsetLeft < this.parentGrid.divMain.scrollLeft || 
                init_td.offsetLeft + init_td.offsetWidth > this.parentGrid.divMain.scrollLeft + this.parentGrid.divMain.offsetWidth)
                this.parentGrid.divMain.scrollLeft = init_td.offsetLeft;
            if (this.input = this.beginEditTd(init_td)) 
            {
                this.input.focus()
                if (this.input.select) this.input.select();
            }
            else
            {
                this.endEdit('oldValue');
            }                
        }
        catch(ex)
        {
            this.endEdit('oldValue');
        }
    }
    
    this.endEdit = function(whenceValues)
    {
        switch (whenceValues)
        {
            case 'input':
            {
                if (this.input)
                    this.endEditTd(whenceValues, this.getCurTd(), this.input);
            }break;
            case 'oldValue':
            {
                for (var td_index = 0; td_index < this.tr.cells.length; td_index++)
                    this.endEditTd(whenceValues, this.tr.cells.item(td_index), this.input &&  this.input.inputIndex == td_index ? this.input : null);
            }break;
        }

	    if (this.input && this.input.setVisibility) this.input.setVisibility(false);
	    
	    this.oldValues = this.input = null;
	    this.parentGrid.endEditTR(this.DirectNextEditTR);
    }
    
    this.onInputKeyDown = function(event)
    {
        var _editableTR = (event.srcElement ? event.srcElement : event.target).editableTR;
        
        switch (event.keyCode)
        {
            case 9: //tab
            {
                if (_editableTR.getControlKind(_editableTR.input) == 'WCalendar76' &&  event.returnValue == false) 
                {
                    if (event.preventDefault) event.preventDefault();
                    return event.returnValue = false;
                }                    
                
                var nextEditableTd = !event.shiftKey ?  _editableTR.nextEditableTd( _editableTR.getCurTd() ) :
                                                        _editableTR.previousEditableTd( _editableTR.getCurTd() );
                 
                if (nextEditableTd && !_editableTR.isNewTr)
                {
                    _editableTR.endEditTd('input', _editableTR.getCurTd(),  _editableTR.input);
                    if (nextEditableTd.offsetLeft < _editableTR.parentGrid.divMain.scrollLeft || 
                        nextEditableTd.offsetLeft + nextEditableTd.offsetWidth > _editableTR.parentGrid.divMain.scrollLeft + _editableTR.parentGrid.divMain.offsetWidth)
                        _editableTR.parentGrid.divMain.scrollLeft = nextEditableTd.offsetLeft;
                    _editableTR.input = _editableTR.beginEditTd(nextEditableTd);
                   
                    _editableTR.processInputBlur = false;
                    _editableTR.input.focus();
                    if (_editableTR.input && _editableTR.input.select) _editableTR.input.select();
                    _editableTR.processInputBlur = true;
                }
                else
                {
                    _editableTR.processInputBlur = false;
                    _editableTR.DirectNextEditTR = event.shiftKey ? -1 : 1;
                    if (_editableTR.valuesChanged()  &&  (!_editableTR.confirmChanges || window.confirm('Do you want save this record?')))
                        _editableTR.saveValues();
                    else 
                        _editableTR.endEdit('oldValue');
                    _editableTR.processInputBlur = true;                        
                }
               
                if (event.preventDefault) event.preventDefault();
                return event.returnValue = false;
            }break;
            case 13: //enter
            {
                if (_editableTR.getControlKind(_editableTR.curInput) != 'WCombo76'  || !_editableTR.curInput.beforeKeyDown_popupIsOpen)
                    if (event.ctrlKey)
                    {
                        if (_editableTR.valuesChanged()) _editableTR.saveValues();
                        else _editableTR.endEdit('input');
                        _editableTR.parentGrid.scrollToCurTR(_editableTR.tr);
                    }
                event.cancelBubble = true;
                return event.returnValue = false; 
            }break;
            case 37: /*left*/ case 39: /*right*/
            {               
                event.cancelBubble = true;
            }break;
            case 38: /*up*/ case 40: /*down*/
            {               
                if (event.preventDefault) event.preventDefault();
                event.cancelBubble = true;
                event.returnValue = false;
            }break;
            case 27: //escape
            {
                if ( _editableTR.getControlKind(_editableTR.curInput) != 'WCombo76'  || !_editableTR.curInput.beforeKeyDown_popupIsOpen )
                {
                    _editableTR.endEdit('oldValue');
                    _editableTR.parentGrid.scrollToCurTR(_editableTR.tr);
                } 
            }break;
        }
    }
    
    this.elementBelongThis = function(element)
    {
        var elementId = element ? element.id : '';
        if (element && element.nodeName == 'TD'  &&  element.parentNode.id == this.tr.id) return true;
        
        switch (this.getControlKind(this.input))
            {
                case 'WCombo76': case 'WCalendar76':
                    if (this.input.elementBelongThis(element)) return true;
                    break;
                default:
                    if (elementId.indexOf( this.parentGrid.Prefix + 'input_') != -1) return true;
            }            
    
	    return false;
    }
    
    this.valuesChanged = function()
    {
        var end_i = this.isNewTr ? 1 : this.tr.cells.length;
        for (var i = 0; i < end_i; i++)
        {
            var td = this.tr.cells.item(i);
            var oldValue = this.oldValues[i];
            var curValue =  this.tr.cells.item(i).innerText;
            
            if (typeof(oldValue) ==  'object'  &&  oldValue) 
            {
                oldValue = oldValue.value;
                curValue = td.attributes.getNamedItem('key').value;
            }
            if (this.input && this.input.inputIndex == i)
                curValue = this.getControlValue( this.input );
            
            if ( !(new columnParam(this.parentGrid.paramsNode, i)).readOnly()  &&  curValue != oldValue) 
                return true;
        }                
        return false;
    }
    
    this.getCurTdValue = function(td)
    {
        if (td)
        {
            var td_index = td.cellIndex;
            
            if (this.input && this.input.inputIndex == td_index)
                return this.getControlValue(this.input);
            else
            {
                var colParam = new columnParam(this.parentGrid.paramsNode, td_index);
                var res = null;
                
                if (!colParam.readOnly())
                    switch (colParam.editKind())
                    {
                        case 'EditBox': case 'CheckBox': case 'WCalendar76':
                        {
                            res = td.innerText;
                        }break;
                        case 'WCombo76':
                        {
                            res = td.attributes.getNamedItem('key').value;     
                        }break;
                    }
                else res = td.innerText;
                
                colParam = null;
                return res;
            }                
        }
        else return null;
    }
    
    this.saveValues = function()
    {
        var argsDOM = this.parentGrid.newXMLDOM();
        var methodNode = argsDOM.createElement('method');
        this.parentGrid.dom_appendAttr(methodNode, 'name', 'ModifyRecord')
        
        this.parentGrid.dom_appendNode(methodNode, 'ID', this.parentGrid.getTRID(this.tr));
        for (var i = 0; i < this.tr.cells.length; i++)
            this.parentGrid.dom_appendNode( methodNode, 'val', this.isNewTr && i > 0 ? '' : this.getCurTdValue(this.tr.cells.item(i)));
            
        argsDOM.appendChild(methodNode);
   
        if (this.parentGrid.stateDOM)
            methodNode.appendChild(this.parentGrid.stateDOM.documentElement.cloneNode(true));

        this.readyState = 'loading';
        this.parentGrid.doCallback(argsDOM, this.callbackSaveValues);
    }
    
    this.onInputBlur = function(event)
    {
        var editableTR = (event.srcElement ? event.srcElement : event.target).editableTR;
	    
	    var activeElement = event && event.explicitOriginalTarget ?  event.explicitOriginalTarget : document.activeElement
	    if (activeElement && activeElement.nodeType == 3 && activeElement.parentNode) activeElement = activeElement.parentNode;
	    
        if (editableTR.processInputBlur  &&  editableTR.input  &&  editableTR.readyState == 'complete')
            if (!editableTR.elementBelongThis(activeElement) ||  editableTR.isNewTr)
                if (editableTR.valuesChanged()  &&  (!editableTR.confirmChanges || window.confirm('Do you want save this record?')))
                    editableTR.saveValues();
                else
                    editableTR.endEdit('oldValue');
            else if (activeElement && activeElement.nodeName == 'TD')
            {
                var colParam = new columnParam(editableTR.parentGrid.paramsNode, activeElement.cellIndex)
                if ( !colParam.readOnly())
                {
                    editableTR.endEditTd('input', editableTR.getCurTd(), editableTR.input);
                    
                    if (activeElement.offsetLeft < editableTR.parentGrid.divMain.scrollLeft || 
                        activeElement.offsetLeft + activeElement.offsetWidth > editableTR.parentGrid.divMain.scrollLeft + editableTR.parentGrid.divMain.offsetWidth)
                        editableTR.parentGrid.divMain.scrollLeft = activeElement.offsetLeft;
                    editableTR.input = editableTR.beginEditTd(activeElement);
                }
                if (editableTR.input)
                {
                    editableTR.input.focus();
                    if (editableTR.input.select) editableTR.input.select();
                }
                colParam = null;
            }
    }
    
    this.getCurTd = function()
    {
        return this.input ?  this.tr.cells.item( this.input.inputIndex ) : null;
    }
    
    this.nextEditableTd = function(curTd)
    {
        if (curTd)
        {
            var nextIndex = curTd.cellIndex + 1;
            while (nextIndex < this.tr.cells.length)
            {
                if (  !(new columnParam(this.parentGrid.paramsNode, nextIndex)).readOnly()  )
                    return this.tr.cells.item(nextIndex);
                nextIndex++;
            }                    
        }
        return null;
    }
    
    this.previousEditableTd = function(curTd)
    {
        if (curTd)
        {
            var nextIndex = curTd.cellIndex - 1;
            while (nextIndex >= 0)
            {
                if (  !(new columnParam(this.parentGrid.paramsNode, nextIndex)).readOnly()  )
                    return this.tr.cells.item(nextIndex);
                nextIndex--;
            }                    
        }
        return null;
    }
}

//// class editableTRImmediatelyAll
editableTRImmediatelyAll.prototype = new editableTR();
function editableTRImmediatelyAll(parentGrid, tr)
{
    this.parentGrid = parentGrid;
    this.tr = tr;
    this.inputs = new Array();
    this.curInput = null;
    this.isNewTr = this.parentGrid.isNewRecordTR(tr);
    this.confirmChanges = this.parentGrid.isConfirmInPlaceChanges;

    this.getTRID = function(curTR)
    {
        var atoms = curTR.id.split('_');
        return atoms[atoms.length - 1];
    }
    
    this.getFirstInput = function()
    {
        for (var i = 0; i < this.inputs.length; i++)
            if (!(new columnParam(this.parentGrid.paramsNode, i)).readOnly())
                return this.inputs[i];
        return null;
    }   
    
    this.beginEdit = function(init_td)
    {
        if (this.parentGrid.ReadOnly) return;
        this.initOldValues();
        for (var td_index = 0; td_index < this.tr.cells.length; td_index++)
	        if (  !(new columnParam(this.parentGrid.paramsNode, td_index)).readOnly()  )
	            this.inputs[this.inputs.length] = this.beginEditTd(this.tr.cells.item(td_index));
            else  this.inputs[this.inputs.length] = null;
	    
	    var firstInput = this.getFirstInput();
	    if (firstInput) 
	    {
	        this.processInputBlur = false;
	        firstInput.focus();
	        if (firstInput.select) firstInput.select();
	        this.processInputBlur = true;
	    }
    }    
    
    //whenceValues = {norWhence, input, oldValue}
    this.endEdit = function(whenceValues)
    {
	    if (this.inputs.length == 0) return;
	    
	    if (whenceValues != 'norWhence')
	        for (var td_index = 0; td_index < this.tr.cells.length; td_index++)
                this.endEditTd(whenceValues, this.tr.cells.item(td_index), this.inputs[td_index]);
	    
	    this.inputs = new Array();
	    this.parentGrid.endEditTR(this.DirectNextEditTR);
    }       
    
    this.onInputFocus = function(event)
    {
        var editableTR = (event.srcElement ? event.srcElement : event.target).editableTR;
        editableTR.curInput = event.srcElement ? event.srcElement : event.target;
        if (editableTR.curInput.WCombo76)  editableTR.curInput = editableTR.curInput.WCombo76;
        else if (editableTR.curInput.WCalendar76)  editableTR.curInput = editableTR.curInput.WCalendar76;
    }
    
    this.onInputClick = function(event)
    {
        event.cancelBubble = true;
    }
    
    this.elementBelongThis = function(element)
    {
        var elementId = element ? element.id : '';
        for (var inputIndex = 0; inputIndex < this.inputs.length; inputIndex++)
            switch (this.getControlKind( this.inputs[inputIndex] ))
            {
                case 'WCombo76': case 'WCalendar76':
                    if (this.inputs[inputIndex].elementBelongThis(element)) return true;
                    break;
                default:
                    if (elementId.indexOf( this.parentGrid.Prefix + 'input_') != -1) return true;
            }
	    return false;
    }
    
    this.onInputBlur = function(event)
    {   
        var editableTR = (event.srcElement ? event.srcElement : event.target).editableTR;
	    editableTR.DirectNextEditTR = 0;
	    
	    var activeElement = document.activeElement ?  document.activeElement : event.explicitOriginalTarget;
	    if (activeElement && activeElement.nodeType == 3 && activeElement.parentNode) activeElement = activeElement.parentNode;
	    
        if (editableTR.processInputBlur  &&  !editableTR.elementBelongThis(activeElement)  && editableTR.inputs.length != 0  &&  editableTR.readyState == 'complete')
            if (editableTR.valuesChanged()  &&  (!editableTR.confirmChanges || window.confirm('Do you want save this record?')))
                editableTR.saveValues();
            else
                editableTR.endEdit('oldValue');
    }
    
    this.onInputKeyDown = function(event)
    {
        var editableTR = (event.srcElement ? event.srcElement : event.target).editableTR;
        
        if (editableTR.inputs.length == 0) return;
        
        editableTR.DirectNextEditTR = 0;
        switch (event.keyCode)
        {
            case 38: /*up*/ case 40: /*down*/
            {  
                if ( editableTR.getControlKind(editableTR.curInput) != 'WCombo76' )
                {
                     editableTR.processInputBlur = false;
                     if (editableTR.valuesChanged() &&  (!editableTR.confirmChanges ||window.confirm('Do you want save this record?'))) 
                         editableTR.saveValues();
                     else
                         editableTR.endEdit('oldValue');
                     editableTR.processInputBlur = true;
                 }
                  if (event.preventDefault) event.preventDefault();
                 event.cancelBubble = true;
            
            } break;
            case 37: /*left*/ case 39: /*right*/
            {               
                if (event.preventDefault) event.preventDefault();
                event.cancelBubble = true;
            } break;
            case 13: //enter
            {
                if ( editableTR.getControlKind(editableTR.curInput) != 'WCombo76'  || !editableTR.curInput.beforeKeyDown_popupIsOpen )
                {
                    if (editableTR.valuesChanged()) editableTR.saveValues();
                    else editableTR.endEdit('input');
                    editableTR.parentGrid.scrollToCurTR(editableTR.tr);
                    event.cancelBubble = true;
                }
            } break;
            case 27: //escape
            {
                if ( editableTR.getControlKind(editableTR.curInput) != 'WCombo76'  || !editableTR.curInput.beforeKeyDown_popupIsOpen )
                {
                    editableTR.endEdit('oldValue');
                    editableTR.parentGrid.scrollToCurTR(editableTR.tr);
                }
            } break;
            case 9: //tab
            {
                editableTR.DirectNextEditTR = event.shiftKey ? -1 : 1;
                if (editableTR.getControlKind(editableTR.curInput) == 'WCalendar76' &&  event.returnValue == false) return; 
                if (!event.shiftKey)
                {
                    var nextIndex = editableTR.curInput.inputIndex + 1;
                    while (nextIndex < editableTR.inputs.length)
                    {
                        if (  !(new columnParam(editableTR.parentGrid.paramsNode, nextIndex)).readOnly()  )
                        {
                            editableTR.processInputBlur = false;
                            editableTR.inputs[nextIndex].focus();
                            if (editableTR.inputs[nextIndex].select) editableTR.inputs[nextIndex].select();
                            editableTR.processInputBlur = true;
                            if (event.preventDefault) event.preventDefault();
                            return event.returnValue = false;
                            
                        }
                        nextIndex++;
                    }
                    editableTR.processInputBlur = false;
                    if (editableTR.valuesChanged()  &&  (!editableTR.confirmChanges || window.confirm('Do you want save this record?')))  
                        editableTR.saveValues();
                    else 
                        editableTR.endEdit('oldValue');
                    editableTR.processInputBlur = true;                        
                    if (event.preventDefault) event.preventDefault();                        
                    return event.returnValue = false;
                }
                else 
                {
                    var nextIndex = editableTR.curInput.inputIndex - 1;
                    while (nextIndex >= 0 )
                    {
                        if (  !(new columnParam(editableTR.parentGrid.paramsNode, nextIndex)).readOnly()  )
                        {
                            editableTR.processInputBlur = false;
                            editableTR.inputs[nextIndex].focus();
                            if (editableTR.inputs[nextIndex].select) editableTR.inputs[nextIndex].select();
                            editableTR.processInputBlur = true;
                            {
                                if (event.preventDefault) event.preventDefault();
                                return event.returnValue = false;
                            }
                        }
                        nextIndex--;
                    }
                    editableTR.processInputBlur = false;
                    if (editableTR.valuesChanged()  &&  (!editableTR.confirmChanges || window.confirm('Do you want save this record?')))
                        editableTR.saveValues();
                    else 
                        editableTR.endEdit('oldValue');
                    editableTR.processInputBlur = true;                        
                        
                    if (event.preventDefault) event.preventDefault();
                    return event.returnValue = false;
                } 
            }break;
        }
    }
    
    this.saveValues = function()
    {
        var argsDOM = this.parentGrid.newXMLDOM();
        var methodNode = argsDOM.createElement('method');
        this.parentGrid.dom_appendAttr(methodNode, 'name', 'ModifyRecord')
        
        this.parentGrid.dom_appendNode(methodNode, 'ID', this.getTRID(this.tr));
        for (var i = 0; i < this.inputs.length; i++)
            if ( !(new columnParam(this.parentGrid.paramsNode, i)).readOnly()  )
                this.parentGrid.dom_appendNode( methodNode, 'val', this.getControlValue(this.inputs[i], i));
            else 
                this.parentGrid.dom_appendNode( methodNode, 'val', this.tr.cells.item(i).innerText);
            
        argsDOM.appendChild(methodNode);
   
        if (this.parentGrid.stateDOM)
            methodNode.appendChild(this.parentGrid.stateDOM.documentElement.cloneNode(true));

        this.readyState = 'loading';
        this.parentGrid.doCallback(argsDOM, this.callbackSaveValues);
    }
    
    this.valuesChanged = function()
    {
        for (var i = 0; i < this.inputs.length; i++)
        {
            var oldValue = this.oldValues[i];
            if (typeof(oldValue) ==  'object' && oldValue) oldValue = oldValue.value;
            
            if ( !(new columnParam(this.parentGrid.paramsNode, i)).readOnly() &&  this.getControlValue(this.inputs[i], i) != oldValue) 
                return true;
        }                
        return false;            
    }
}

//// class columnParam
function columnParam(paramsNode, colIndex)
{
    this.colIndex = typeof colIndex == 'string' ? parseInt(colIndex) : colIndex;
    this.colParamNode = paramsNode.selectNodes('Cols/Col')[this.colIndex];
    
        
    //this.colParamNode = paramsNode.selectSingleNode('Cols/Col[position()=' + (this.colIndex + 1) + ']');
        
    this.attrValue = function(attrName)
    {
        return this.colParamNode.getAttribute(attrName);
    }

    this.readOnly = function()
    {
         return this.editKind() == 'None';
    } 
    
    this.kind = function()
    {
        return this.attrValue('Kind');
    }
    
    this.editKind = function()
    {
        return this.attrValue('EditKind');
    }
    
    this.trueText = function()
    {
        return this.attrValue('TrueText');
    }
    
    this.falseText = function()
    {
        return this.attrValue('FalseText');
    }
    
    this.EditControlID = function()
    {
        return this.attrValue('EditControlID');
    }
    
    this.behavior = function()
    {
        return this.attrValue('Behavior');
    }
}

// class WGridSelectedRows76
function WGridSelectedRows76(ownerGrid)
{
    this.ownerGrid = ownerGrid;
    
    //private
    var selectedRowsNode = ownerGrid.getStateChildNode('selectedRows');
    var allowEmptySelection = ownerGrid.allowEmptySelection;
    var multiSelect = ownerGrid.multiSelect;
    var lastSelectedRowsNode = null;
    var sortXSL = null;

    this.unselectAllTR = function(checkAllowNull)
	{
	    var endCount = checkAllowNull && !allowEmptySelection ? 1 : 0;
        while (selectedRowsNode.childNodes.length > endCount)
        {
            var rNode = selectedRowsNode.firstChild;
            var tr = this.ownerGrid.findTR(rNode.getAttributeNode('kind').value, rNode.text);
            rNode.parentNode.removeChild(rNode);
            if (tr) this.unselectTR(tr, true);
        }
    }
	
	this.unselectTR = function(tr, notRemoveFromState)
	{
	     var id = this.ownerGrid.getTRID(tr);
		 
		 var xmlNode = this.ownerGrid.getNodeByTr(tr);
		 if (xmlNode) xmlNode.removeAttribute('Selected');
		 
		 if (!notRemoveFromState)
		 {
		    var rNode = this.isSelectedTR(tr);
		    if (rNode) rNode.parentNode.removeChild(rNode);
        }
        tr.className = this.isCurrentTR(tr) && multiSelect ? this.ownerGrid.getCurrentClassName(tr) : this.ownerGrid.getClassName(tr);
        if (this.ownerGrid.isGroupTR(tr)) this.ownerGrid.changeClassForGroup(this.ownerGrid.getTRID(tr), false);
	}
	
	this.selectTR = function(tr, notSaveToState)
	{
	    tr.style.backgroundColor = '';
        var xmlNode = this.ownerGrid.getNodeByTr(tr);
	    if (xmlNode) xmlNode.attributes.setNamedItem( xmlNode.ownerDocument.createAttribute('Selected') );
		
		var res = !this.isSelectedTR(tr);
	    if (!notSaveToState && !this.isSelectedTR(tr))
	    {
	        var rNode = selectedRowsNode.appendChild( selectedRowsNode.ownerDocument.createElement('r') );
	        rNode.text = this.ownerGrid.getTRID(tr);
	        var kindAttr = selectedRowsNode.ownerDocument.createAttribute('kind');
	        kindAttr.value = this.ownerGrid.isGroupTR(tr) ? 'Group' : 'Data';
	        rNode.setAttributeNode(kindAttr);
        }
        tr.className = this.isCurrentTR(tr) ? this.ownerGrid.getCurrentClassName(tr) : this.ownerGrid.getClassName(tr);
        if (this.ownerGrid.isGroupTR(tr)) this.ownerGrid.changeClassForGroup(this.ownerGrid.getTRID(tr), true);
        
        return res;
	}
	
	this.selectAllTR = function(groupNode)
	{
	    var res = false;
        if (!groupNode) groupNode = this.ownerGrid.xmlDOM.documentElement;
        var childNode = groupNode.firstChild;
        while (childNode)
        {
            if (childNode.nodeName == 'Row')
            {
                var tr = this.ownerGrid.findTR('Data', childNode.firstChild.text);
                if (tr) res = this.selectTR(tr) || res;
            }
            else if (childNode.nodeName == 'Group')
            {
                var tr = this.ownerGrid.findTR('Group', childNode.getAttribute('ID'));
                if (tr) 
                {
                    if (this.ownerGrid.getParamFromXML('RowSelectionMethod') != 'ItselfOnlyWithoutGroups')
                        res = this.selectTR(tr) || res;
                    res = this.selectAllTR(childNode) || res;
                }                    
            }
            childNode = childNode.nextSibling;                    
        }
        return res;
    }
    
    this.unSelectGroup = function(groupNode)
	{
	    var res = false;
        if (!groupNode) groupNode = this.ownerGrid.xmlDOM.documentElement;
        var childNode = groupNode.firstChild;
        while (childNode)
        {
            if (childNode.nodeName == 'Row')
            {
                var tr = this.ownerGrid.findTR('Data', childNode.firstChild.text);
                if (tr && (allowEmptySelection || this.count() > 1)) res = this.unselectTR(tr) || res;
            }
            else if (childNode.nodeName == 'Group')
            {
                var tr = this.ownerGrid.findTR('Group', childNode.getAttribute('ID'));
                if (tr) 
                {
                    if (this.ownerGrid.getParamFromXML('RowSelectionMethod') != 'ItselfOnlyWithoutGroups')
                        res = this.unselectTR(tr) || res;
                    res = this.unSelectGroup(childNode) || res;
                }                    
            }
            childNode = childNode.nextSibling;                    
        }
        return res;
    }


    this.isSelectedTR = function(tr)
    {
        var kind = this.ownerGrid.isGroupTR(tr) ? 'Group' : 'Data';
        var id = this.ownerGrid.getTRID(tr);
        return selectedRowsNode.selectSingleNode('r[@kind=\'' +  kind +  '\' and . = \'' + id.ReplaceAll('\'', '&apos;') +  '\']');
    }
    
    this.isCurrentTR = function(tr)
    {
        return this.ownerGrid.CurTR && tr && this.ownerGrid.CurTR.id == tr.id;
    }
    
    this.isSelectedAll = function()
    {
        return !this.ownerGrid.xmlDOM.selectSingleNode('//Row[not(@Selected)]') && !this.ownerGrid.xmlDOM.selectSingleNode('//Group[not(@Selected)]');
    }
    
    this.isSelectedNone = function()
    {
        return !selectedRowsNode.hasChildNodes();
    }
    
    this.count = function()
    {
        return selectedRowsNode ? selectedRowsNode.childNodes.length : 0;
    }
    
    this.toString = function(dataTextFieldIndex, separator)
    {
        var text = '';
        var rNode = selectedRowsNode.firstChild;
        while (rNode)
        {
            var rowNode = this.ownerGrid.rowNodeFromXmlDOM(rNode.text);
            if (rowNode)
            {
                var cNL = rowNode.selectNodes('c');
                if (cNL.length > dataTextFieldIndex) text += cNL[dataTextFieldIndex].text + separator;
            }
            rNode = rNode.nextSibling;
        }
        return text.length ? text.substr(0, text.length - separator.length) : '';
    }
    
    this.refreshSelectedRows = function(newSelectedRowsNode)
	{
        var isNew = newSelectedRowsNode != null;
        if (newSelectedRowsNode) this.unselectAllTR();
        else  newSelectedRowsNode = this.ownerGrid.getStateChildNode('selectedRows');
        
        var tr = null;             
        if (newSelectedRowsNode)
        {
            var rNode = newSelectedRowsNode.firstChild;
            while (rNode)
            {
                tr = this.ownerGrid.findTR(rNode.getAttributeNode('kind').value, rNode.text);
                if (tr) this.selectTR(tr, !isNew);
                rNode = rNode.nextSibling;
            }
        }
        
        if (tr)
        {
            this.ownerGrid.Curr_RowKind = this.ownerGrid.isGroupTR(tr) ? 'Group' : 'Data';
	        this.ownerGrid.Curr_ID = this.ownerGrid.getTRID(tr);
	        this.ownerGrid.CurTR = tr;
        }
	}
	
	this.selectRangeBeforeTR = function(tr)
	{
	    var res = false;
	    if (tr)
	    {
	        if (this.isSelectedNone())
	            res = this.selectTR(tr);
            else
            {
                var from_rNode = selectedRowsNode.lastChild;
                var from_tr = this.ownerGrid.findTR(this.isDataRow(from_rNode) ? 'Data' : 'Group', from_rNode.text);
                
                if (from_tr)
                {
                    var ei = Math.max(from_tr.rowIndex, tr.rowIndex);
                    for (var i = Math.min(from_tr.rowIndex, tr.rowIndex); i <= ei; i++ )
                        if (!(this.ownerGrid.getParamFromXML('RowSelectionMethod') == 'ItselfOnlyWithoutGroups' && 
                            this.ownerGrid.isGroupTR(this.ownerGrid.tblMain.rows.item(i))))
                            res = this.selectTR(this.ownerGrid.tblMain.rows.item(i)) || res; //note: for embedded grids need exclude expanded row
                }                        
            }
	    }
	    return res;
	}
	
	this.isDataRow = function(rNode)
	{
	    return  rNode && rNode.getAttributeNode('kind').value == 'Data';
	}
	
	this.isSelectedAllRowsInGroup = function(groupNode)
	{
	    return !groupNode.selectSingleNode('.//Row[not(@Selected)]');
	}
	
	this.isSelectedNoneRowsInGroup = function(groupNode)
    {
        return !groupNode.selectSingleNode('.//Row[@Selected]');
    }
	
	this.getSortXSL = function()
    {
        if (!sortXSL)
        {
            var sort_txt =  
	            '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' + 
	            '   <xsl:template match="selectedRows">' + 
		        '        <xsl:copy>' + 
		        '	        <xsl:for-each select="r">' + 
		        '		        <xsl:sort select="@kind"/>' + 
		        '		        <xsl:sort select="text()" order="ascending"/>' + 
		        '		        <xsl:copy>' + 
		        '			        <xsl:attribute name="kind"><xsl:value-of select="@kind"/></xsl:attribute>' + 
		        '			        <xsl:value-of select="text()"/>' + 
		        '		        </xsl:copy>' + 
		        '	        </xsl:for-each>' + 
		        '        </xsl:copy>		' + 
	            '    </xsl:template>' + 
                '</xsl:stylesheet>';
                   
            sortXSL = this.ownerGrid.newXMLDOM();
            sortXSL.loadXML(sort_txt);
        }
        return sortXSL;
    }        
	
	this.isChanged = function()
	{
        return !lastSelectedRowsNode ||  lastSelectedRowsNode.transformNode(this.getSortXSL()) != selectedRowsNode.transformNode(this.getSortXSL());
	}
	
	this.beginTransaction = function()
	{
	    lastSelectedRowsNode = this.ownerGrid.newXMLDOM();
	    lastSelectedRowsNode.loadXML(selectedRowsNode.xml);   
	}
	
	this.commit = function()
	{
	    lastSelectedRowsNode = null;
	}
	
	this.rollback = function()
	{
	    lastSelectedRowsNode = null;
	}
}

// class WEmbeddedGrids76
function WEmbeddedGrids76(ownerGrid)
{
    this.ownerGrid = ownerGrid;
    
    //private
    this.rows = new Array();
    
    this.add = function(masterId, grid)
    {
        if (!this.rows[masterId])
            this.rows[masterId] = new Array();
    
        this.rows[masterId][this.rows[masterId].length] = grid;
    }
    
    this.clear = function(masterId)
    {
        if (this.rows[masterId])
            this.rows[masterId] = new Array();
    }
    
    this.count = function()
    {
        return this.rows.length;
    }
    
    this.forEachGrid = function(rowId, method)
    {
        if (!rowId)
        {
            for (rowId in this.rows)
                if (typeof this.rows[rowId] != 'function')
                    for (var i = 0; i <  this.rows[rowId].length; i++)
                        method.apply(this.rows[rowId][i], arguments)
        }
        else
            for (var i = 0; i <  this.rows[rowId].length; i++)
                    method.apply(this.rows[rowId][i], arguments)
                                
    }
    
    this.lastDownloadedGrid = function(row_id)
    {
        var res = null;
        this.forEachGrid(row_id,
            function()
            {
                if (!this.isDataLoaded && (!this.allowCollapse || this.gridExpanded()))
                    res = this;
            }
        );
        return res;
    }        	        
}

function Controls76_WGrid76_Builder(name, obj_id)
{
    this.name = name;
    try { this.obj = eval(obj_id); }
    catch (ex) { this.obj = null; }
    
    this.properties = new Array('DataChanged');
    
    this.get_prop = function(prop_name)
    {
        if (this.obj != null)
            switch(prop_name) 
            {
                case 'DataChanged': return false;
                default: return eval('if (this.obj.get' + prop_name + ') this.obj.get' + prop_name + '()');
            }
            
        return '';
    }
    
    this.set_prop = function(prop_name, prop_value)
    {
        if (this.obj != null)
            switch(prop_name)
            {
                default: eval('if (this.obj.set' + prop_name + ') this.obj.set' + prop_name + '(prop_value)');
            }
    }
}


// class
function WResultNavigator76(Prefix)
{
    this.uniqueId = '';
    this.container = null;
    this.Prefix = Prefix;
    this.hdnState = $(Prefix + 'hdnState');
    this.ul = $(Prefix+ 'ul');
    
    this.doCallback = function(args, callbackMethod)
	{
        if (!this.container)
	        __doPostBack(this.uniqueId, args);
        else	        
        {
	        this.container.CallServer(this.uniqueId, '', args, this, callbackMethod, this.onCalbackError)
	    }
	}
	
	this.onCalbackError = function()
	{
	}
	
    this.change = function(start)
    {
        if (this.hdnState)
            this.hdnState.value = start;
            
        this.doCallback(start);
    }

    this.RestoreState = function(changesNode)
    {
        1;
        if (changesNode)
        {
            var curNode = changesNode.firstChild;
            while (curNode)
            {
                switch (curNode.nodeName)
                {
                    case 'html':
                    {
                        this.ul.innerHTML =  curNode.text;            
                    }return;
                }
                
                curNode = curNode.nextSibling;
            }
            
        }            
    }
}