var __aspxTableColumnResizing = null;
var __aspxScrollerHelpers = null;

ASPxClientTableHelper = _aspxCreateClass(null, {
	constructor: function(control, contentTableName, headerTableName, footerTableName){
	    this.Control = control;
	    this.ContentTableName = contentTableName;
	    this.HeaderTableName = headerTableName;
	    this.FooterTableName = footerTableName;
    },
    GetContentTable: function() { return this.Control.GetChildElementById(this.ContentTableName); },
    GetHeaderTable: function() { return this.Control.GetChildElementById(this.HeaderTableName); },
    GetFooterTable: function() { return this.Control.GetChildElementById(this.FooterTableName); },
    getScrollBarWidth: function(table) {
        if(table.offsetParent.offsetHeight > table.offsetHeight) return 0;
        return this.getScrollBarWidthCore();
    },
    getScrollBarWidthCore: function() {
        if(this.scrollBarWidth > 0) return this.scrollBarWidth;
        var inner = document.createElement("p");
        inner.style.cssText = "width: 100%; height: 200px;";
        var outer = document.createElement("div");
        outer.appendChild(inner);
        outer.style.cssText = "position: absolute; visibility: hidden; width: 200px; height: 150px; overflow: hidden";
        document.body.appendChild(outer);
        var w1 = inner.offsetWidth;
        outer.style.overflow = "scroll";
        var w2 = inner.offsetWidth;
        if (w1 == w2) w2 = outer.clientWidth;                                 
        this.scrollBarWidth = (w1 - w2);
        document.body.removeChild(outer);
        return this.scrollBarWidth;
    },
    GetTableLastColGroup: function(table) {
        if(table == null) return null;
        var res = _aspxGetElementsByTagName(table, "COLGROUP");
        var res = res.length > 0 ? res[res.length - 1] : null;
        return res != null ? _aspxGetElementsByTagName(res, "COL") : null;
    },
    ChangeCellStyleWidth: function(cell, newColWidth) {
        if(_aspxIsExists(cell) && _aspxIsExists(cell.style)) {
            cell.style.width = newColWidth;   
        }
    },
    getWidthFromStyle: function(width) {
        if(!_aspxIsExists(width) || width == "" || width.indexOf("%") > -1) return -1;
        return width.indexOf("px") > -1 ? _aspxPxToInt(width) : parseInt(width);
    },
    GetCellBorders: function(cell) {
        var curStyle = _aspxGetCurrentStyle(cell);
        var res = _aspxPxToInt(curStyle.paddingLeft) + _aspxPxToInt(curStyle.paddingRight);
        res += _aspxPxToInt(curStyle.borderLeftWidth) + _aspxPxToInt(curStyle.borderRightWidth);
        return res;
    }
});

ASPxClientTableColumnResizing = _aspxCreateClass(ASPxClientTableHelper, {
	constructor: function(control, contentTableName, headerTableName, footerTableName){
		this.constructor.prototype.constructor.call(this, control, contentTableName, headerTableName, footerTableName);
	    this.groupCols = null;
	    this.colIndex = -1;
        this.contentWidthRow = -2;
	    this.column = null;
	    this.scrollerHelper = null;
	    this.maximumOffset = 5;
	    this.minimumWidth = 5;
	    this.cursors = new Object();
	    this.prevX = 0;
	    this.resizedInput = null;
	    this.resizableControl = null;
	    this.editorsList = null;
	    this.CanResizeLastColumn = true;
    },
    GetResizableTable: function() { return this.GetHeaderTable() != null ?  this.GetHeaderTable() : this.GetContentTable(); },
    StartResizing: function(column, evt, indentColumnCount) {
        this.groupCols = this.GetTableLastColGroup(this.GetResizableTable());
        this.column = column;
        this.colIndex = this._getColByCell(column, this.groupCols);
        __aspxTableColumnResizing = this;
        if(this.GetHeaderTable() != null) {
            this.scrollerHelper = new ASPxClientTableScrollerHelper(this.Control, this.ContentTableName, this.HeaderTableName, this.FooterTableName);
        }
    },
    CanStartResizing: function(column, evt, indentColumnCount) {
        var table = this.GetResizableTable();
        if(!_aspxIsExists(table)) return false;
        var columnType = this._getTableCellType(table, column, indentColumnCount);
        if(columnType < 0) return false;
        if(!this.CanResizeLastColumn && columnType == 1) return false;
        this.prevX = _aspxGetEventX(evt);
        var right = _aspxGetAbsoluteX(column) + column.offsetWidth;
        return (right > this.prevX) && (right - this.prevX < this.maximumOffset);
    },    
    SetResizedInput: function(input) {
        this.resizedInput = input;
    },
    IsResizing: function() { return __aspxTableColumnResizing == this; },
    GetCursor: function(element, evt, indentColumnCount) {
        var defaultCursor = this._getDefaultCursor(element);
        if(this.IsResizing() || this.CanStartResizing(element, evt, indentColumnCount)) return "W-resize";
        return defaultCursor;
    },
    SetResizableControl: function(resizableControl) {
        this.resizableControl = resizableControl;
    },
    SetEditorsList: function(list) {
        this.editorsList = list;
    },
    onmouseup: function(evt) {
        this.endResizing();
        this.CancelResizing(evt);
    },
    onmousemove: function(evt) {
        var newX = _aspxGetEventX(evt);
        var delta = newX - this.prevX;
        var newColWidth = this.getElementStyleOrigionalWidth(this.column) + delta;
        if(newColWidth < this.minimumWidth) return;
        if(!this.canApplyResizableElementsWidth(-delta)) return;
        if(this._changeColumnWidth(this.column, newColWidth)) {
            this.applyResizableElementsWidth(-delta);
            this.prevX = newX;
        }
    },
    CancelResizing: function(evt) {
        __aspxTableColumnResizing = null;
        this.contentWidthRow = -2;
	    this.groupCols = null;
	    this.column = null;
	    this.prevX = 0;
	    this.resizedInput = null;
	    this.resizableControl = null;
	    this.editorsList = null;
	    if(this.scrollerHelper != null) {
	        this.scrollerHelper.CorrectHeaderFooterColsWidth();
	    }
    },
    canApplyResizableElementsWidth: function(delta) {
        if(_aspxIsExists(this.resizableControl)) return true;
        var changedColumn = this._getNextChangedColumn(this.column, delta);
        if(changedColumn == null) return false;
        var oldWidth = this.getElementStyleOrigionalWidth(changedColumn);
        return oldWidth + delta >= this.minimumWidth;
    },
    applyResizableElementsWidth: function(delta) {
        if(_aspxIsExists(this.resizableControl)) {
            var curWidth = this.getElementStyleOrigionalWidth(this.resizableControl);
            this.resizableControl.style.width = (curWidth - delta) + "px";
            if(this.scrollerHelper != null) {
                this.scrollerHelper.SetHeaderFooterContainersWidth();
            }
        } 
        else {
            var changedColumn = this._getNextChangedColumn(this.column, delta);
            if(changedColumn == null) return;
            var oldWidth = this.getElementStyleOrigionalWidth(changedColumn);
            this._changeColumnWidth(changedColumn, oldWidth + delta);
        }
    },
    endResizing: function() {
        if(!_aspxIsExists(this.resizedInput) || !_aspxIsExists(this.column)) return;
        var cells = this.column.parentNode.cells;
        var res = "";
        for(var i = 0; i < cells.length; i ++) {
            width = this.getElementStyleOrigionalWidth(cells[i]);
            res += width + "|";
        }
        this.resizedInput.value = res;
        this.CorrectEditorsBounds();
    },
    CorrectEditorsBounds: function() {
        if(this.editorsList == null) return;
        for(var i = 0; i < this.editorsList.length; i ++)
            this.editorsList[i].AdjustControl(false);
    },
    _changeColumnWidth: function(column, newColWidth){
        var oldColWidth = this.getElementStyleOrigionalWidth(column);
        this._changeColumnWidthCore(this.GetResizableTable(), newColWidth, this.groupCols, column.cellIndex, 0);
        var result = oldColWidth != this.getElementStyleOrigionalWidth(column);
        if(result && this.GetHeaderTable() != null) {
            this._changeColumnWidthAnotherTable(this.GetContentTable(), column.cellIndex, newColWidth, this.GetContentWidthRow());
            this._changeColumnWidthAnotherTable(this.GetFooterTable(), column.cellIndex, newColWidth, 0);
        }
        return result;
    },
    _changeColumnWidthAnotherTable: function(table, columnIndex, newColWidth, rowIndex){
        if(table == null) return;
        this._changeColumnWidthCore(table, newColWidth, this.GetTableLastColGroup(table), columnIndex, rowIndex);
    },
    _changeColumnWidthCore: function(table, newColWidth, groupCols, colIndex, rowIndex){
        if(newColWidth < 0) return;
        var col =  groupCols[colIndex];
        col.width = newColWidth + "px";
        if(rowIndex > -1) {
            var row = table.rows[rowIndex];
            row.cells[colIndex].style.width = newColWidth + "px";
        }
    },
    _getColByCell: function(column, groupCols) {
        if(groupCols == null) return null;
        return groupCols[column.cellIndex];
    },
    _getNextChangedColumn: function(column, dWidth) {
        if(column.cellIndex == 0 && column.parentNode.cells.length == 1) return null;
        var cellIndex = column.cellIndex + 1 < column.parentNode.cells.length ? column.cellIndex + 1 : column.cellIndex - 1;
        return column.parentNode.cells[cellIndex];
    },
    _getDefaultCursor: function(element) {
        if(!_aspxIsExists(this.cursors[element.id]))
            this.cursors[element.id] = _aspxGetCurrentStyle(element).cursor;
        return this.cursors[element.id];
    },
    getElementStyleOrigionalWidth: function(element) {
        var col = this._getColByCell(element, this.groupCols);
        var res = -1;
        if(col != null) {
            res = this.getWidthFromStyle(col.width);
        } else {
            if(_aspxIsExists(element.style)) {
                res = this.getWidthFromStyle(element.style.width);
            }
        }
        if(res > 0) return res;
        return element.offsetWidth - this.GetCellBorders(element);
    },
    GetContentWidthRow: function() {
        if(this.contentWidthRow > -2) return this.contentWidthRow;
        this.contentWidthRow = -1;
        var colCount = this.groupCols.length;
        var table = this.GetContentTable();
        for(var i = 0; i < table.rows.length; i ++) {
            if(table.rows[i].cells.length == colCount) {
                this.contentWidthRow = i;
                break;
            }
        }
        return this.contentWidthRow;
    },
    //-1 - is not exists, 0 - exists, 1 - exists and it is last
    _getTableCellType: function(table, column, indentColumnCount) {
        for(var i = 0; i < table.rows.length; i ++) {
            var row = table.rows[i];
            for(var j = 0; j < row.cells.length; j ++) {
                if(row.cells[j] == column) {
                    if(column.cellIndex < indentColumnCount) return -1;
                    return j == row.cells.length - 1 ? 1 : 0;
                }
            }
        }
        return -1;
    }
});

ASPxClientTableScrollerHelper = _aspxCreateClass(ASPxClientTableHelper, {
	constructor: function(control, contentTableName, headerTableName, footerTableName){
		this.constructor.prototype.constructor.call(this, control, contentTableName, headerTableName, footerTableName);
	    this.scrollBarWidth = -1;
	    this.IsWidthTypePercent = false;
	    if(__aspxScrollerHelpers == null) {
	        __aspxScrollerHelpers = new Array();
	    }
	    __aspxScrollerHelpers.push(this);
    },
    CorrectHeaderFooterColsWidth : function() {
        this.SetHeaderFooterContainersWidth();
    },
    AfterWindowResize: function() {
        this.CorrectHeaderFooterColsWidth();
    },
    OnWindowResize: function(index) {
        if(!this.IsWidthTypePercent) return;
        _aspxSetTimeout("TableScrollerHelper_AfterWindowResize(" + index + ");", 0);
    },
    GetColsWidth: function(table) {
        if(table.rows.length < 2) return null;
        var widths = new Array();
        var row = table.rows[table.rows.length - 1];
        for(var i = 0; i < row.cells.length; i ++) {
            var width = row.cells[i].clientWidth;
            if(__aspxNS && (i == row.cells.length - 1)) {
                width += this.getScrollBarWidth(table);
            }
            widths.push(width);
        }
        return widths;
    },
    SetHeaderFooterContainersWidth: function() {
		if(!this.Control.IsVisible()) {
			this.Control.sizeCorrectedOnce = false;
			return;
		}
		var headerTable = this.GetHeaderTable();
		this.ResetContainerWidth(headerTable);
		this.ResetContainerWidth(this.GetContentTable());
		this.ResetContainerWidth(this.GetFooterTable());
    
		var mainEl = this.Control.GetMainElement();
		if(!mainEl) return;
		if(!_aspxIsExists(mainEl.dxgvOrigWidth))
			mainEl.dxgvOrigWidth = mainEl.style.width;
		else
			mainEl.style.width = mainEl.dxgvOrigWidth;
		var mainElWidth = mainEl.offsetWidth;
        if(headerTable && (__aspxOpera || __aspxFirefox)) {           
            // B131330, due to colgroups with fixed width
            var headerWidth = headerTable.offsetWidth;
            if(headerWidth > mainElWidth)
                mainElWidth = 2 + headerWidth + this.getScrollBarWidthCore();
        }				
		
		var width = mainElWidth - this.GetCellBorders(mainEl) - this.GetCellBorders(mainEl.rows[0].cells[0]);
        this.SetContainerWidth(headerTable, width, this.getScrollBarWidthCore());
        this.SetContainerWidth(this.GetContentTable(), width, 0);
		this.SetElementWidth(this.GetContentTable(), width, this.getScrollBarWidthCore(), 0);
        this.SetContainerWidth(this.GetFooterTable(), width, this.getScrollBarWidthCore());
        
        mainEl.style.width = mainElWidth + "px";
    },
    SetContainerWidth: function(table, width, margin) {
        if(table == null) return;
        var parent = table.parentNode;
        if(!_aspxIsExists(parent)) return;
        parent.align = "left";
        this.SetElementWidth(parent, width, margin, margin);
    },
    ResetContainerWidth: function(table) {
		if(table == null) return;
		var parent = table.parentNode;
		if(!_aspxIsExists(parent)) return;
		parent.style.width = 0;
    },
    SetElementWidth: function(element, width, margin, marginRight) {
        if(!_aspxIsExists(element)) return;
        if(width <= this.getScrollBarWidthCore()) return;
        if(marginRight > 0) {
            if(_aspxIsElementRigthToLeft(element) && !(__aspxOpera || __aspxSafariFamily)) {
                element.style.marginLeft = marginRight + "px";
                element.style.marginRight = "";
            }
            else {
            element.style.marginRight = marginRight + "px";
                element.style.marginLeft = "";
            }
        }
        element.style.width = (width - margin) + "px";
    }
});

function TableColumnResizing_onmouseup(e) {
    if(__aspxTableColumnResizing != null) {
        __aspxTableColumnResizing.onmouseup(e);
        return true;
    }
}
function TableColumnResizing_onmousemove(e) {
    if(__aspxTableColumnResizing != null) {
        __aspxTableColumnResizing.onmousemove(e);
        return true;
    }
}
function TableColumnResizing_onselectstart(e) {
    if(__aspxTableColumnResizing != null) {
        document.selection.empty();
        return false;
    }
}

function TableScrollerHelper_AfterWindowResize(index) {
    if(__aspxScrollerHelpers != null && index < __aspxScrollerHelpers.length) {
        __aspxScrollerHelpers[index].AfterWindowResize();
    }
}

function TableScrollerHelper_windowResize(e) {
    if(__aspxScrollerHelpers != null) {
        for(var i = 0; i < __aspxScrollerHelpers.length; i ++) {
            __aspxScrollerHelpers[i].OnWindowResize(i);
        }
    }
}

_aspxAttachEventToDocument("mouseup", TableColumnResizing_onmouseup);
_aspxAttachEventToDocument("mousemove", TableColumnResizing_onmousemove);
_aspxAttachEventToDocument("selectstart", TableColumnResizing_onselectstart);
_aspxAttachEventToElement(window, "resize", TableScrollerHelper_windowResize);