var Filters = {};

Ext.menu.FilterMenu = function(config){
    if(Ext.isArray(config)){
        config = {items:config};
    }
    Ext.apply(this, config);
    this.id = this.id || Ext.id();
    this.addEvents(

        'beforeshow',

        'beforehide',

        'show',

        'hide',

        'click',

        'mouseover',

        'mouseout',

        'itemclick'
    );
    Ext.menu.Menu.superclass.constructor.call(this);
    var mis = this.items;
    this.offset = (config['offset'])? config['offset'] : 0;

    this.on('click', function(menu, item, e){
        Ext.menu.MenuMgr.hideAll();
    });
    this.items = new Ext.util.MixedCollection();
    if(mis){
        this.add.apply(this, mis);
    }
};

Ext.extend(Ext.menu.FilterMenu, Ext.menu.Menu, {

    // private
    onMouseOut : function(e){
        var t;
        if(t = this.findTargetItem(e)){
            if(this.activeItem && t != this.activeItem){
                this.activeItem.deactivate();
                delete this.activeItem;
            }
        }
        this.over = false;
        this.fireEvent("mouseout", this, e, t);
    },

    createEl : function(){
        return new Ext.Layer({
            cls: "x-menu",
            shadow:this.shadow,
            shadowOffset : (Ext.isIE)? 3 : 4,
            constrain: false,
            parentEl: this.parentEl || document.body,
            zindex:15000
        });
    },
    
    initComponent : function(){
        Ext.menu.FilterMenu.superclass.initComponent.call(this);
    },

    onClick : function(e){
        var t;
        if(t = this.findTargetItem(e)){
            if(t.menu && this.ignoreParentClicks){
                if (t.menu.isVisible()) t.hideMenu();
                else t.expandMenu();
            }else{
                t.onClick(e);
                this.fireEvent("click", this, t, e);
            }
        }
    },
    
    show : function(el, pos, parentMenu){
        this.parentMenu = parentMenu;
        if(!this.el){
            this.render();
        }
        if (!this.notEvent) this.fireEvent("beforeshow", this);
        var dom_el = Ext.getDom(el);
        var f = dom_el;
        var x = 0;
        while (f.offsetParent){
            x += f.offsetLeft;
            f = f.offsetParent;
        }
        this.el.setWidth(this.minWidth);
        var offset = 0;
        if (!this.yOffset) this.yOffset = 0;
        //if (Ext.isIE) offset += 6;
        //if (Ext.isChrome) offset += 3;
        //if (Ext.isIE7) offset += 2;
//        if (this.offset > 0) this.el.setWidth(this.minWidth);
        x = Math.ceil(x + el.getWidth() - this.el.getWidth() + this.offset + offset);
        var y = el.getY() + el.getHeight() + this.yOffset;
        this.showAt([x, y], parentMenu, false);
    }
    
});

Ext.menu.FieldMenu = Ext.extend(Ext.menu.Menu, {
    show : function(el, pos, parentMenu){
        this.parentMenu = parentMenu;
        if(!this.el){
            this.render();
        }
        this.fireEvent("beforeshow", this);
        var xy = this.el.getAlignToXY(el, pos || this.defaultAlign);
        if (Ext.isGecko2) xy[0] += 1;
        if (Ext.isGecko3) xy[0] += 1;
        if (this.menuOffset){
            xy[0] += this.menuOffset[0];
            xy[1] += this.menuOffset[1];
        }
        this.showAt(xy, parentMenu, false);
    }
});

Ext.menu.FilterItem = function(config){
    Ext.menu.Item.superclass.constructor.call(this, config);
    this.alignElId = (config['alignId'])? config['alignId'] : null;
    if(this.menu){
        this.menu = Ext.menu.MenuMgr.get(this.menu);
    }
};

Ext.extend(Ext.menu.FilterItem, Ext.menu.Item, {

    initComponent : function(){
        Ext.menu.FilterItem.superclass.initComponent.call(this);
    },

    deactivate : function(){
        Ext.menu.Item.superclass.deactivate.apply(this, arguments);
    },

    onRender : function(container, position){
        var el = document.createElement("div");
        el.hideFocus = true;
        el.unselectable = "on";
        el.className = this.itemCls + (this.menu ?  " x-menu-item-arrow" : "") + (this.cls ?  " " + this.cls : "");
        el.innerHTML = String.format('{0}', this.itemText||this.text);
        this.el = el;
        Ext.menu.Item.superclass.onRender.call(this, container, position);
    },

    setText : function(text){
        this.text = text;
        if(this.rendered){
            this.el.update(String.format('{0}', this.text));
            this.parentMenu.autoWidth();
        }
    },
    
    deferExpand : function(autoActivate){
        delete this.showTimer;
        this.menu.show(this.container, this.parentMenu.subMenuAlign || "tl-tr?", this.parentMenu);
        var elem = Ext.get(this.alignElId);
        if (elem){
            var xy = this.menu.el.getAlignToXY(elem, this.parentMenu.subMenuAlign || "tl-tr?" || this.menu.defaultAlign,
                                                [0, 0]);
            this.menu.showAt(xy, this.parentMenu, false);
            if(autoActivate){
                this.menu.tryActivate(0, 1);
            }
        }
    }
});

Ext.FilterTip = Ext.extend(Ext.ToolTip, {

    // private
    initComponent: function(){
        Ext.FilterTip.superclass.initComponent.call(this);
    },

    show : function(){
        if(!this.rendered){
            this.render(Ext.getBody());
        }
        this.constrainPosition = false;
        this.showAt(this.el.getAlignToXY(this.showEl, this.defaultAlign, this.showOffset));
    }

});

Ext.GridTip = Ext.extend(Ext.ToolTip, {

    // private
    initComponent: function(){
        Ext.GridTip.superclass.initComponent.call(this);
        this.baseCls = 'grid_tooltip';
    },
/*
    // private
    initTarget : function(){
        if(this.target){
            this.target = Ext.get(this.target);
            this.target.on('click', this.onTargetClick, this);
            this.target.on('mouseout', this.onTargetOut, this);
            this.target.on('mouseover', this.onTargetOver, this);
        }
    },
    
    onTargetClick : function(e){
        if(this.disabled || e.within(this.target.dom, true)){
            return;
        }
        this.clearTimer('hide');
        this.targetXY = e.getXY();
        this.show();
    },

    onTargetOut : function(e){
        Ext.GridTip.superclass.onTargetOut.call(this, e);
        this.gridView.onTip = false;
    },

    onTargetOver : function(e){
        this.gridView.onTip = true;
    },
*/
    setSize : function(w, h){
        // support for standard size objects
        if(typeof w == 'object'){
            h = w.height;
        }
        // not rendered
        if(!this.boxReady){
            this.height = h;
            return this;
        }

        // prevent recalcs when not needed
        if(this.lastSize && this.lastSize.height == h){
            return this;
        }
        this.lastSize = {width: undefined, height: h};
        var adj = this.adjustSize(undefined, h);
        var ah = adj.height;
        if(ah !== undefined){ // this code is nasty but performs better with floaters
            var rz = this.getResizeEl();
            rz.setHeight(ah);
            this.onResize(undefined, ah, w, h);
            this.fireEvent('resize', this, undefined, ah, w, h);
        }
        return this;
    },
    
    show : function(){
        if(!this.rendered){
            this.render(Ext.getBody());
        }
        this.constrainPosition = false;
        this.showAt(this.el.getAlignToXY(this.showEl, this.defaultAlign, this.showOffset));
    }

});

Ext.DevxGridView = Ext.extend(Ext.grid.GridView, {

    // private
    initComponent: function(){
        Ext.DevxGridView.superclass.initComponent.call(this);
        this.lastRowOver = 0;
        this.tips = new Array();
        //this.onTip = false;
    },

    addTooltip : function(i){
        var tt = this.cm.getColumnTooltip(i);
        if (!this.tips) this.tips = new Array();
        if (this.tips[this.cm.getColumnId(i)]) this.tips[this.cm.getColumnId(i)].destroy();
        if(tt){
            //Ext.get(this.gridName + this.cm.getColumnId(i)).addClassOnOver('tip-icon');
            Ext.get(this.gridName + this.cm.getColumnId(i)).addClassOnOver('cursor-hand');
            this.tips[this.cm.getColumnId(i)] = new Ext.GridTip({
                //target : 'headerTip_'+i,
                target : this.gridName + this.cm.getColumnId(i),
                //gridView : this,
                hideDelay : 1000,
                dismissDelay : 0,
                showEl : Ext.get(this.gridName + this.cm.getColumnId(i)),
                showOffset : [0, 0],
                shadow : false,
                floating : true,
                defaultAlign : 'tl-bl?',
                html : '<div class="header"></div><div class="content2">'+tt+'</div>',
                listeners : {
                    render : function() {
                        if (!this.el || this.html.match(/<a/gi) == null) {
                            return;
                        }
                        var s = this;
                        this.el.on('mouseover', function(e) {
                            s.clearTimer('hide');
                        }, this);
                        this.el.on('mouseout',  function(e) {
                            s.clearTimer('show');
                            if(s.autoHide !== false){
                                s.delayHide();
                            }
                        }, this);
                    }
                }
            });
            Ext.QuickTips.init();
        }
    },
/*
    onHeaderClick : function(g, index){
        if (this.onTip) {
            return;
        }
        Ext.DevxGridView.superclass.onHeaderClick.call(this, g, index);
    },
*/
    initTemplates : function(){
        var ts = this.templates || {};
        var sortCls = 'x-grid3-sort-icon';
        if (Ext.isGecko) sortCls = 'x-grid3-sort-icon ff';
        ts.hcell = new Ext.Template(
                '<td id={hid} class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id} {alt}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
                '{value}',
//                '<img id="headerTip_{id}" class="grid-header-tip" src="../img/help_grid.gif" />',
                '<img class="'+sortCls+'" src="', Ext.BLANK_IMAGE_URL, '" />',
                '</div></td>'
                );
        ts.top_cell = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}"  id="x-grid3-top-cell-{id}" style="{style}" tabIndex="0" {cellAttr}>',
                '<div class="x-grid3-td-inner {alt}" unselectable="on">',
                '{value}',
                '</div>',
                '</td>'
                );
        ts.cell = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
                '<div class="x-grid3-cell-inner x-grid3-col-{id} {alt}" unselectable="on" {attr}>{value}</div>',
                "</td>"
                );
        this.templates = ts;
        if (this.withRangeFilter){
            ts.header = new Ext.Template(
                    '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                    '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
                    '<tr class="x-grid3-row custom_filter">{top_cells}</tr>',
                    "</table>"
                    );
            this.templates = ts;
        }
        Ext.DevxGridView.superclass.initTemplates.call(this);
    },
    
    initElements: function(){
        Ext.DevxGridView.superclass.initElements.call(this);
        if (this.hideVScroll) this.scroller.setStyle('overflow-y', 'hidden');
    },
    
    afterRender: function(){
        Ext.DevxGridView.superclass.afterRender.call(this);
        var len = this.cm.getColumnCount();
        for(var i = 0; i < len; i++){
            var col_id = this.cm.getColumnId(i);
            var f = gridArray[this.gridName].getStore().fields.get(col_id);
            if(!f || f.sortDir == 'ASC'){
                Ext.get(this.gridName + col_id).addClassOnOver('sort-asc-icon');
            } else {
                Ext.get(this.gridName + col_id).addClassOnOver('sort-desc-icon');
            }
            this.addTooltip(i);
            var el = document.getElementById('x-grid3-top-cell-'+ col_id);
            if (typeof(showTooltipIfNeed) != 'undefined' && el) {
                showTooltipIfNeed(el, true);
            }
        }
    },
    
    // private
    updateSortIcon : function(col, dir){
        var sc = this.sortClasses;
        var hds; 
        if (gridArray[this.gridName].getStore().getMultipleSortStatus()){
            hds = this.mainHd.select('td');
            hds.item(col).removeClass(sc);
        }else
            hds = this.mainHd.select('td').removeClass(sc);
        if (hds.item(col)) hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
    },
    
    // private
    updateHeaderSortState : function(){
        if (this.ds.getMultipleSortStatus()){
            var sc = this.sortClasses;
            this.mainHd.select('td').removeClass(sc);
            var states = this.ds.getMultipleSort();
            for (var i in states){
                var sortColumn = this.cm.findColumnIndex(i);
                if(sortColumn != -1){
                    var sortDir = states[i].dir;
                    this.updateSortIcon(sortColumn, sortDir);
                }
            }
        } else {
            Ext.DevxGridView.superclass.updateHeaderSortState.call(this);
        }
    },
    
    // private
    updateHeaders : function(){
        Ext.DevxGridView.superclass.updateHeaders.call(this);
        var len = this.cm.getColumnCount();
        for(var i = 0; i < len; i++)
            this.addTooltip(i);
    },

    // private
    onRowOver : function(e, t){
        Ext.DevxGridView.superclass.onRowOver.call(this, e, t);
        var row = this.findRowIndex(t)
        if (row !== false){
            if (this.withRanks) {
                var record = gridArray[this.gridName].getStore().getAt(row);
                var have_ranks = false;
                for (var k in record.data) {
                    var rank = 'rank_'+record.id+'_'+k;
                    if (Ext.get(rank)) {
                        have_ranks = true;
                        Ext.get(rank).show();
                        var mindata = 'mindata_'+record.id+'_'+k;
                        if (Ext.get(mindata)) {
                            Ext.get(mindata).hide();
                        }
                    }
                }
                if (Ext.get('overRankInfo'+this.rankSuffix) && have_ranks) {
                    var div = Ext.get('overRankInfo'+this.rankSuffix);
                    var el = Ext.get(this.getRow(row));
                    var first_cell = Ext.get(this.getCell(row, 0));
                    div.applyStyles({left : el.getLeft()+first_cell.getWidth()/2+(el.getWidth()-div.getWidth())/2+'px', top : el.getTop()-div.getHeight()+'px'});
                    div.show();
                }
                if (this.overFunction){
                    eval(this.overFunction+'(e, true, record, row, this);');
                }
            } else {
                if (row == this.lastRowOver) return;
                if (this.overFunction){
                    var eval_code = this.overFunction+'(';
                    var params = new Array();
                    for (var k in this.overParams){
                        if (parseInt(k) != 0) if (!parseInt(k)) continue;
                            params[k] = gridArray[this.gridName].getStore().getAt(row).get(this.overParams[k]);
                    }
                    eval_code += implode(', ', params)+');';
                    this.lastRowOver = row;
                    eval(eval_code);
                }
            }
        }
    },

    // private
    onRowOut : function(e, t){
        Ext.DevxGridView.superclass.onRowOut.call(this, e, t);
        var row = this.findRowIndex(t)
        if (row !== false && !e.within(this.getRow(row), true)){
            if (this.withRanks) {
                if (Ext.get('overRankInfo'+this.rankSuffix)) Ext.get('overRankInfo'+this.rankSuffix).hide();
                var record = gridArray[this.gridName].getStore().getAt(row);
                if (this.overFunction){
                    eval(this.overFunction+'(e, false, record, row, this);');
                }
                for (var k in record.data) {
                    var rank = 'rank_'+record.id+'_'+k;
                    if (Ext.get(rank)) {
                        Ext.get(rank).hide();
                        var mindata = 'mindata_'+record.id+'_'+k;
                        if (Ext.get(mindata)) {
                            Ext.get(mindata).show();
                        }
                    }
                }
            }
        }
    },

    updateColumnHidden : function(col, hidden){
        if (this.withRangeFilter){
            var display = hidden ? 'none' : '';
            var cm = this.grid.colModel;
                Ext.get('x-grid3-top-cell-'+cm.getColumnId(col)).setDisplayed(display);
        }
        Ext.DevxGridView.superclass.updateColumnHidden.call(this, col, hidden);
    },
    
    // private
    doRender : function(cs, rs, ds, startRow, colCount, stripe){
        var cm = this.cm;
        var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
        var tstyle = 'width:'+this.getTotalWidth()+';';
        // buffers
        var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
            for(var j = 0, len = rs.length; j < len; j++){
            r = rs[j]; cb = [];
            var rowIndex = (j+startRow);
            for(var i = 0; i < colCount; i++){
                c = cs[i];
                p.id = c.id;
                p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
                p.attr = p.cellAttr = "";
                p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
                p.style = c.style;
                var colType = cm.getColumnById(p.id).colType;
                p.alt = '';
                if (colType == 'min1border') {
                    p.alt = 'x-grid3-cell-min1border';
                } else if (colType == 'min2border') {
                    p.alt = 'x-grid3-cell-min2border';
                } else if (colType == 'double_ore') {
                    p.css += 'x-grid3-cell-oreborder';
                    p.alt += 'x-grid3-cell-oreborder';
                } else if (colType == 'double_ore_right') {
                    p.css += 'x-grid3-cell-oreborder-right';
                }
                if(p.value == undefined || p.value === "") p.value = "&#160;";
                if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
                    p.css += ' x-grid3-dirty-cell';
                }
                cb[cb.length] = ct.apply(p);
            }
            var alt = [];
            if(stripe && ((rowIndex+1) % 2 == 0)){
                alt[0] = "x-grid3-row-alt";
            }
            if(r.dirty){
                alt[1] = " x-grid3-dirty-row";
            }
            rp.cols = colCount;
            if(this.getRowClass){
                alt[2] = this.getRowClass(r, rowIndex, rp, ds);
            }
            rp.alt = alt.join(" ");
            rp.cells = cb.join("");
            buf[buf.length] =  rt.apply(rp);
        }
        return buf.join("");
    },

    // private
    fitColumns : function(preventRefresh, onlyExpand, omitColumn){
        var cm = this.cm, leftOver, dist, i;
        var tw = cm.getTotalWidth(false);
        var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;

        if(aw < 20){ // not initialized, so don't screw up the default widths
            return;
        }
        var extra = aw - tw;

        if(extra === 0){
            return false;
        }

        var vc = cm.getColumnCount(true);
        var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
        if(ac === 0){
            ac = 1;
            omitColumn = undefined;
        }
        var colCount = cm.getColumnCount();
        var cols = [];
        var extraCol = 0;
        var width = 0;
        var w;
        for (i = 0; i < colCount; i++){
            if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
                w = cm.getColumnWidth(i);
                cols.push(i);
                extraCol = i;
                cols.push(w);
                width += w;
            }
        }

        var frac = (aw - cm.getTotalWidth())/width;
        
        while (cols.length){
            w = cols.pop();
            i = cols.pop();
            cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
        }

        if((tw = cm.getTotalWidth(false)) > aw){
            var adjustCol = ac != vc ? omitColumn : extraCol;
             cm.setColumnWidth(adjustCol, Math.max(1,
                     cm.getColumnWidth(adjustCol)- (tw-aw)), true);
        } else if(tw < aw){
            var adjustCol = ac != vc ? omitColumn : extraCol;
             cm.setColumnWidth(adjustCol, Math.max(1,
                     cm.getColumnWidth(adjustCol)+ (aw-tw)), true);
        }

        if(preventRefresh !== true){
            this.updateAllColumnWidths();
        }


        return true;
    },

    renderHeaders : function(){
        var cm = this.cm, ts = this.templates;
        var ct = ts.hcell;
        var tc_tpl = ts.top_cell;

        var cb = [], sb = [], p = {}, tc = [];
        var len = cm.getColumnCount();
        var last = len - 1;
        for(var i = 0; i < len; i++){
            p = {};
            p.id = cm.getColumnId(i);
            p.hid = this.gridName + cm.getColumnId(i);
            p.value = cm.getColumnHeader(i) || "";
            p.style = this.getColumnStyle(i, true);
            p.tooltip = '';
            p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
            var colType = cm.getColumnById(p.id).colType;
            if (colType == 'min1border') {
                p.alt = 'x-grid3-title-cell-min1border';
            } else if (colType == 'min2border') {
                p.alt = 'x-grid3-title-cell-min2border';
            }
            if(cm.config[i].align == 'right'){
                p.istyle = 'padding-right:16px';
            } else {
                delete p.istyle;
            }
            cb[cb.length] = ct.apply(p);
            if (colType == 'min1border') {
                p.alt = 'x-grid3-top-cell-min1border';
            } else if (colType == 'min2border') {
                p.alt = 'x-grid3-top-cell-min2border';
            }
            p.value = '&nbsp;';
            if (this.withRangeFilter) {
                var fname = ((typeof(customFiltersData[p.id]) != 'undefined') && customFiltersData[p.id].used)? 'edit' : 'filter';
                p.value = (colType == 'double' || colType== 'hqc' || colType== 'double_ore' || colType== 'double_ore_right')? fname : '&nbsp;';
                if (p.value == 'edit' && (colType == 'double' || colType == 'double_ore' || colType== 'double_ore_right')) {
                    var minVal = ((customFiltersData[p.id].min.toString() == '') && (typeof(customFiltersMin[p.id]) != 'undefined'))? customFiltersMin[p.id] : customFiltersData[p.id].min;
                    var maxVal = ((customFiltersData[p.id].max.toString() == '') && (typeof(customFiltersMax[p.id]) != 'undefined'))? customFiltersMax[p.id] : customFiltersData[p.id].max;
                    p.value = minVal + ' - ' + maxVal;
                } else if (p.value == 'edit' && colType == 'hqc') {
                    var html = '';
                    for (var k = 0; k < customFiltersValues[p.id].length; k++) {
                        for (var j = 0; j < customFiltersData[p.id].values.length; j++) {
                            if (customFiltersData[p.id].values[j] == customFiltersValues[p.id][k]) {
                                html += customFiltersData[p.id].values[j] + ', ';
                                break;
                            }
                        }
                    }
                    html = html.substring(0, html.length - 2);
                    p.value = html;
                }
                if (p.value != '' && p.value != '&nbsp;') {
                    p.css += ' x-grid3-top-cell';
                    var onclick = 'onclick="showCustomFilter(\''+p.id+'\', this);"';
                    if (colType == 'hqc') {
                        onclick = 'onclick="showCustomHQCFilter(\''+p.id+'\', this);"';
                    }
                    p.cellAttr = 'onmouseover="Ext.get(this).addClass(\'top_cell_select\'); showTooltipIfNeed(this);" \n\
                                    onmouseout="Ext.get(this).removeClass(\'top_cell_select\');"\n\
                                    '+onclick;
                }
                tc[tc.length] = tc_tpl.apply(p);
            }
        }
        if (this.withRangeFilter) {
            return ts.header.apply({top_cells : tc.join(""), cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
        }
        return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
    }
    
});

Ext.Toolbar.DevxButton = Ext.extend(Ext.Toolbar.Button, {
    // private
    onClick : function(e){
        if(e){
            e.preventDefault();
        }
        if(e.button != 0){
            return;
        }
        if(!this.disabled){
            if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
                this.toggle();
            }
            if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick 
                && ((typeof(this.eventBeforeMenu) == 'undefined') || (!this.eventBeforeMenu)))
            {
                this.showMenu();
            }
            this.fireEvent("click", this, e);
            if(this.handler){
                //this.el.removeClass("x-btn-over");
                this.handler.call(this.scope || this, this, e);
            }
        }
    },
    // private
    onMouseOut : function(e){
        var internal = e.within(this.el) && e.target != this.el.dom;
        this.fireEvent('mouseout', this, e);
        if(this.isMenuTriggerOut(e, internal)){
            this.fireEvent('menutriggerout', this, this.menu, e);
        }
    }
});

Ext.data.DevxStore = function(config){
    Ext.data.DevxStore.superclass.constructor.call(this, config);
    this.multipleSortInfo = {};
    this.oldMultipleSortInfo = {};
    this.lastMultipleWeight = 0;
    this.cashRecords = Array();
    this.resetMulti = false;
};

Ext.extend(Ext.data.DevxStore, Ext.data.Store, {
    
    cashRecords : Array(),
    
    setMultipleSort : function(isMultipleSort){
        this.multipleSort = isMultipleSort;
        if (!isMultipleSort){
            this.oldMultipleSortInfo = this.multipleSortInfo ;
            this.multipleSortInfo = {};
            this.lastMultipleWeight = 0;
            /*
            if(!this.remoteSort){
                this.applySort();
                this.fireEvent("datachanged", this);
            }else{
                this.load(this.lastOptions);
            }
            */
/*        } else if (this.sortInfo){
            this.multipleSortInfo[this.sortInfo.field] = {dir : this.sortInfo.direction,
                                                        weight : this.lastMultipleWeight};
            this.lastMultipleWeight++;
*/
        }
    },

    getMultipleSortStatus : function(){
        if (!this.multipleSort) return false;
        return this.multipleSort;
    },

    getMultipleSort : function(){
        return this.multipleSortInfo;
    },

    setDefaultMultiSort : function(sort){
        this.multipleSort = true;
        this.lastMultipleWeight = 0;
        for(var i in sort){
            this.multipleSortInfo[i] = {dir : sort[i].dir, weight : this.lastMultipleWeight, colType : sort[i].colType};
            this.lastMultipleWeight ++;
            this.setDefaultSort(i, sort[i].dir);
        }
    },

    sort : function(fieldName, dir, resetMulti){
        this.resetMulti = (typeof(resetMulti) != 'undefined')? resetMulti : false;
        var f = this.fields.get(fieldName);
        if(!f){
            return false;
        }
        if (this.baseParams && this.multipleSort && !this.multipleSortInfo[f.name]) {
            var grid = gridArray[this.baseParams.grid_name];
            var colmodel = grid.getColumnModel();
            if (this.multiSortText) {
                var col = colmodel.getColumnById(fieldName);
                var old_col_type = 'text';
                var errorPopupId = this.errorSortPopupId;
                if (this.lastMultipleWeight != 0) {
                    for(var col_name in this.multipleSortInfo) {
                        if (typeof(this.multipleSortInfo[col_name].weight) != 'undefined' &&
                            this.multipleSortInfo[col_name].weight == this.lastMultipleWeight-1)
                        {
                            old_col_type = this.multipleSortInfo[col_name].colType;
                            errorPopupId = this.errorNextSortPopupId;
                            break;
                        }
                    }
                }
                var colType = col.colType;
                if ((col.colType == 'double' || col.colType == 'double_ore' || col.colType== 'double_ore_right')
                        && (old_col_type == 'double' || old_col_type == 'double_ore' || old_col_type== 'double_ore_right')
                ) {
                    var errorPopup = document.getElementById(errorPopupId);
                    if (errorPopup) {
                        errorPopup.style.position = 'absolute';
                        var top = grid.view.mainHd.select('td').item(colmodel.findColumnIndex(fieldName));
                        var el = Ext.get(top);
                        var dom_el = Ext.getDom(el);
                        var x = 0;
                        while (dom_el.offsetParent){
                            x += dom_el.offsetLeft;
                            dom_el = dom_el.offsetParent;
                        }
                        //x = Math.ceil(x + el.getWidth()) - 10;
                        var y = el.getY();
                        errorPopup.style.left = x + 'px';
                        errorPopup.style.top = y + 'px';
                        errorPopup.style.display = 'inline';
                    }
                    return false;
                }
            }
        }
        if(!dir){
            if (this.multipleSort && this.multipleSortInfo[f.name]){
                dir = (this.multipleSortInfo[f.name].dir || "ASC").toggle("ASC", "DESC");
            } else if (this.oldMultipleSortInfo[f.name]) {
                dir = (this.oldMultipleSortInfo[f.name].dir || "ASC").toggle("ASC", "DESC");
                this.oldMultipleSortInfo = {};
            }else if(this.sortInfo && this.sortInfo.field == f.name){ // toggle sort dir
                dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
            } else {
                dir = f.sortDir;
            }
        }
        var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
        var si = (this.sortInfo) ? this.sortInfo : null;
        if (this.multipleSort){
            if (this.multipleSortInfo[f.name]) this.multipleSortInfo[f.name].dir = dir;
            else{
                this.multipleSortInfo[f.name] = {dir : dir, weight : this.lastMultipleWeight, colType : colType};
                this.lastMultipleWeight++;
            }
        }

        this.sortToggle[f.name] = dir;
        this.sortInfo = {field: f.name, direction: dir};
        this.fireEvent("sort", this);
        if(!this.remoteSort){
            this.applySort();
            this.fireEvent("datachanged", this);
        }else{
            this.cashRecords = Array();
            if (!this.load(this.lastOptions)) {
                if (st) {
                    this.sortToggle[f.name] = st;
                }
                if (si) {
                    this.sortInfo = si;
                }
            }
        }
    },

    loadRecords : function(o, options, success){
        if(!o || success === false){
            if(success !== false){
                this.fireEvent("load", this, [], options);
            }
            if(options.callback){
                options.callback.call(options.scope || this, [], options, false);
            }
            return;
        }

        var r = o.records;
        var t = o.totalRecords;
        var totalVisible = (r.length < options.numVisibleRows ? r.length : options.numVisibleRows);
        if (totalVisible + options.params['scroll'] > t) options.params['scroll'] -= totalVisible + options.params['scroll'] - t;
        if (totalVisible >= t) options.params['scroll'] = 0;
        var showRecords = Array();
        
        for(var i = 0, len = r.length; i < len; i++){
            if(!options || options.add !== true){
                r[i].join(this);
                r[i]['start'] = options.params['start'];
                this.cashRecords[i + options.params['start']] = cloneObject(r[i]);
            }
        }
        for (var i = 0; i < totalVisible; i++) {
            showRecords[i] = this.cashRecords[i + options.params['scroll']];
            if (!showRecords[i]) {
                options.params.start = parseInt(i/options.numRowsPerPage) * options.numRowsPerPage;
                this.load(options);
                return;
            }
        }

        if ('undefined' != typeof(sg)) {
            slider.value = options.params['scroll'];
            var empty = true;
            for (var k = 0; k < r.length; k++) {
                empty = empty && (r[k].data.company_name == '<div style=\"overflow:hidden;white-space:nowrap\"><a sytle=\"display:none\">&nbsp;</a></div>');
            }
            if (t <= sg.data['rows_visible'] || empty) {
                slider.maxValue = t;
                slider.hide();
            } else {
                slider.maxValue = t - sg.data['rows_visible'];
                slider.show();
                slider.reDraw();
            }
            if (!this.loadedPages) this.loadedPages = {};
            this.loadedPages[options.params['start']] = true;
        }

        this.data.clear();
        this.data.addAll(showRecords);
        this.totalLength = t;
        this.applySort();
        this.fireEvent("datachanged", this);
        this.fireEvent("load", this, showRecords, options);
        if(options.callback){
            options.callback.call(options.scope || this, showRecords, options, true);
        }
        if (this.resetMulti) this.setMultipleSort(true);
    },
    
    load : function(options){
        options = options || {};
        //if (!options.numVisibleRows || !options.numRowsPerPage) return false;
        if (!options.params.scroll) options.params.scroll = 0;
        var o = Array();
        for (var i = options.params.scroll; i < (options.numVisibleRows + options.params.scroll) && this.cashRecords[i]; i++) {
            o[i - options.params.scroll] = this.cashRecords[i];
        }
        
        if (i < (options.numVisibleRows + options.params.scroll)) {
            
            options.params.start = parseInt(i/options.numRowsPerPage) * options.numRowsPerPage;
            
            if(this.fireEvent("beforeload", this, options) !== false){
                this.storeOptions(options);
                var p = Ext.apply(options.params || {}, this.baseParams);
                if(this.sortInfo && this.remoteSort){
                    var pn = this.paramNames;
                    p[pn["sort"]] = this.sortInfo.field;
                    p[pn["dir"]] = this.sortInfo.direction;
                }
                p = Ext.apply({}, options.params);
                if(this.sortInfo && this.remoteSort){
                    if (this.multipleSort && (this.lastMultipleWeight > 0)){
                        p['no_morder'] = 'N';
                        for (var k in this.multipleSortInfo){
                            p["morder["+this.multipleSortInfo[k].weight+"]"] = k;
                            p["morder_dir["+this.multipleSortInfo[k].weight+"]"] = this.multipleSortInfo[k].dir;
                        }
                    } else {
                        p['no_morder'] = 'Y';
                    }
                }
                this.proxy.load(p, this.reader, this.loadRecords, this, options);
                return true;
            } else {
                return false;
            }
        } else {
            options.add = true;
            this.loadRecords({records : o, totalRecords : this.totalLength}, options, true);
        }
    }
});

Ext.DevxMessageBox = function(){
    var dlg, opt, mask, waitTimer;
    var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
    var buttons, activeTextEl, bwidth, iconCls = '';

    // private
    var handleButton = function(button){
        if(dlg.isVisible()){
            Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 0);
            if (dlg.needHide)
                dlg.hide();
        }
    };

    // private
    var handleHide = function(){
        if(opt && opt.cls){
            dlg.el.removeClass(opt.cls);
        }
        progressBar.reset();
    };

    // private
    var handleEsc = function(d, k, e){
        if(opt && opt.closable !== false){
            dlg.hide();
        }
        if(e){
            e.stopEvent();
        }
    };

    // private
    var updateButtons = function(b){
        var width = 0;
        if(!b){
            buttons["ok"].hide();
            buttons["cancel"].hide();
            buttons["yes"].hide();
            buttons["no"].hide();
            return width;
        }
        dlg.footer.dom.style.display = '';
        for(var k in buttons){
            if(typeof buttons[k] != "function"){
                if(b[k]){
                    buttons[k].show();
                    buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
                    width += buttons[k].el.getWidth()+15;
                }else{
                    buttons[k].hide();
                }
            }
        }
        return width;
    };

    return {

        setToHide : function(hide){
            if (!dlg) return;
            dlg.needHide = hide;
        },

        getDialog : function(titleText){
           if(!dlg){
                Ext.WindowMgr.zseed = 200000;
                dlg = new Ext.Window({
                    autoCreate : true,
                    title:titleText,
                    resizable:false,
                    constrain:true,
                    constrainHeader:true,
                    minimizable : false,
                    maximizable : false,
                    stateful: false,
                    modal: true,
                    shim:true,
                    buttonAlign:"center",
                    width:550,
                    height:100,
                    minHeight: 80,
                    plain:true,
                    footer:true,
                    closable:true,
                    close : function(){
                        if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
                            handleButton("no");
                        }else{
                            handleButton("cancel");
                        }
                    }
                });
                dlg.needHide = true;
                buttons = {};
                var bt = this.buttonText;
                //TODO: refactor this block into a buttons config to pass into the Window constructor
                buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
                buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
                buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
                buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
                buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
                dlg.render(document.body);
                dlg.getEl().addClass('x-window-dlg');
                mask = dlg.mask;
                bodyEl = dlg.body.createChild({
                    html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
                });
                iconEl = Ext.get(bodyEl.dom.firstChild);
                var contentEl = bodyEl.dom.childNodes[1];
                msgEl = Ext.get(contentEl.firstChild);
                textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
                textboxEl.enableDisplayMode();
                textboxEl.addKeyListener([10,13], function(){
                    if(dlg.isVisible() && opt && opt.buttons){
                        if(opt.buttons.ok){
                            handleButton("ok");
                        }else if(opt.buttons.yes){
                            handleButton("yes");
                        }
                    }
                });
                textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
                textareaEl.enableDisplayMode();
                progressBar = new Ext.ProgressBar({
                    renderTo:bodyEl
                });
               bodyEl.createChild({cls:'x-clear'});
            }
            return dlg;
        },


        updateText : function(text){
            if(!dlg.isVisible() && !opt.width){
                dlg.setSize(this.maxWidth, 100); // resize first so content is never clipped from previous shows
            }
            msgEl.update(text || '&#160;');

            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
            var mw = msgEl.getWidth() + msgEl.getMargins('lr');
            var fw = dlg.getFrameWidth('lr');
            var bw = dlg.body.getFrameWidth('lr');
            if (Ext.isIE && iw > 0){
                //3 pixels get subtracted in the icon CSS for an IE margin issue,
                //so we have to add it back here for the overall width to be consistent
                iw += 3;
            }
            var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
                        Math.max(opt.minWidth || this.minWidth, bwidth || 0));

            if(opt.prompt === true){
                activeTextEl.setWidth(w-iw-fw-bw);
            }
            if(opt.progress === true || opt.wait === true){
                progressBar.setSize(w-iw-fw-bw);
            }
            if(Ext.isIE && w == bwidth){
                w += 4; //Add offset when the content width is smaller than the buttons.
            }
            dlg.setSize(this.width, 'auto').center();
            return this;
        },


        updateProgress : function(value, progressText, msg){
            progressBar.updateProgress(value, progressText);
            if(msg){
                this.updateText(msg);
            }
            return this;
        },


        isVisible : function(){
            return dlg && dlg.isVisible();
        },


        hide : function(){
            var proxy = dlg.activeGhost;
            if(this.isVisible() || proxy) {
                dlg.hide();
                handleHide();
                if (proxy) {
                    proxy.hide();
                }
            }
            return this;
        },


        show : function(options){
            if(this.isVisible()){
                this.hide();
            }
            opt = options;
            this.width = (options.width)? options.width : 550;
            var d = this.getDialog(opt.title || "&#160;");

            d.setTitle(opt.title || "&#160;");
            var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
            d.tools.close.setDisplayed(allowClose);
            activeTextEl = textboxEl;
            opt.prompt = opt.prompt || (opt.multiline ? true : false);
            if(opt.prompt){
                if(opt.multiline){
                    textboxEl.hide();
                    textareaEl.show();
                    textareaEl.setHeight(typeof opt.multiline == "number" ?
                        opt.multiline : this.defaultTextHeight);
                    activeTextEl = textareaEl;
                }else{
                    textboxEl.show();
                    textareaEl.hide();
                }
            }else{
                textboxEl.hide();
                textareaEl.hide();
            }
            activeTextEl.dom.value = opt.value || "";
            if(opt.prompt){
                d.focusEl = activeTextEl;
            }else{
                var bs = opt.buttons;
                var db = null;
                if(bs && bs.ok){
                    db = buttons["ok"];
                }else if(bs && bs.yes){
                    db = buttons["yes"];
                }
                if (db){
                    d.focusEl = db;
                }
            }
            if(opt.iconCls){
              d.setIconClass(opt.iconCls);
            }
            this.setIcon(opt.icon);
            bwidth = updateButtons(opt.buttons);
            progressBar.setVisible(opt.progress === true || opt.wait === true);
            this.updateProgress(0, opt.progressText);
            this.updateText(opt.msg);
            if(opt.cls){
                d.el.addClass(opt.cls);
            }
            d.proxyDrag = opt.proxyDrag === true;
            d.modal = opt.modal !== false;
            d.mask = opt.modal !== false ? mask : false;
            if(!d.isVisible()){
                // force it to the end of the z-index stack so it gets a cursor in FF
                document.body.appendChild(dlg.el.dom);
                d.setAnimateTarget(opt.animEl);
                d.show(opt.animEl);
            }
            //d.getEl().setStyle('z-index', '260000');
            
            //workaround for window internally enabling keymap in afterShow
            d.on('show', function(){
                if(allowClose === true){
                    d.keyMap.enable();
                }else{
                    d.keyMap.disable();
                }
            }, this, {single:true});

            if(opt.wait === true){
                progressBar.wait(opt.waitConfig);
            }
            return this;
        },


        setIcon : function(icon){
            if(icon && icon != ''){
                iconEl.removeClass('x-hidden');
                iconEl.replaceClass(iconCls, icon);
                iconCls = icon;
            }else{
                iconEl.replaceClass(iconCls, 'x-hidden');
                iconCls = '';
            }
            return this;
        },


        progress : function(title, msg, progressText){
            this.show({
                title : title,
                msg : msg,
                buttons: false,
                progress:true,
                closable:false,
                minWidth: this.minProgressWidth,
                progressText: progressText
            });
            return this;
        },


        wait : function(msg, title, config){
            this.show({
                title : title,
                msg : msg,
                buttons: false,
                closable:false,
                wait:true,
                modal:true,
                minWidth: this.minProgressWidth,
                waitConfig: config
            });
            return this;
        },


        alert : function(title, msg, fn, scope){
            this.show({
                title : title,
                msg : msg,
                buttons: this.OK,
                fn: fn,
                scope : scope
            });
            return this;
        },


        confirm : function(title, msg, fn, scope){
            this.show({
                title : title,
                msg : msg,
                buttons: this.YESNO,
                fn: fn,
                scope : scope,
                icon: this.QUESTION
            });
            return this;
        },


        prompt : function(title, msg, fn, scope, multiline, value){
            this.show({
                title : title,
                msg : msg,
                buttons: this.OKCANCEL,
                fn: fn,
                minWidth:250,
                scope : scope,
                prompt:true,
                multiline: multiline,
                value: value
            });
            return this;
        },


        OK : {ok:true},

        CANCEL : {cancel:true},

        OKCANCEL : {ok:true, cancel:true},

        YESNO : {yes:true, no:true},

        YESNOCANCEL : {yes:true, no:true, cancel:true},

        INFO : 'ext-mb-info',

        WARNING : 'ext-mb-warning',

        QUESTION : 'ext-mb-question',

        ERROR : 'ext-mb-error',


        defaultTextHeight : 75,

        maxWidth : 600,

        minWidth : 100,

        minProgressWidth : 250,

        buttonText : {
            ok : "OK",
            cancel : "Cancel",
            yes : "Yes",
            no : "No"
        }
    };
}();

Ext.PagingToolbarNoRefresh = Ext.extend(Ext.PagingToolbar, {
    // private
    onRender : function(ct, position){
        Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
        this.first = this.addButton({
            tooltip: this.firstText,
            iconCls: "x-tbar-page-first",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["first"])
        });
        this.prev = this.addButton({
            tooltip: this.prevText,
            iconCls: "x-tbar-page-prev",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["prev"])
        });
        this.addSeparator();
        this.add(this.beforePageText);
        this.field = Ext.get(this.addDom({
           tag: "input",
           type: "text",
           size: "3",
           value: "1",
           cls: "x-tbar-page-number"
        }).el);
        this.field.on("keydown", this.onPagingKeydown, this);
        this.field.on("focus", function(){this.dom.select();});
        this.field.on("blur", this.onPagingBlur, this);
        this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
        this.field.setHeight(18);
        this.addSeparator();
        this.next = this.addButton({
            tooltip: this.nextText,
            iconCls: "x-tbar-page-next",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["next"])
        });
        this.last = this.addButton({
            tooltip: this.lastText,
            iconCls: "x-tbar-page-last",
            disabled: true,
            handler: this.onClick.createDelegate(this, ["last"])
        });

        if(this.displayInfo){
            this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
        }
        if(this.dsLoaded){
            this.onLoad.apply(this, this.dsLoaded);
        }
    },
    // private
    onLoad : function(store, r, o){
        if(!this.rendered){
            this.dsLoaded = [store, r, o];
            return;
        }
       this.cursor = o.params ? o.params[this.paramNames.start] : 0;
       var d = this.getPageData(), ap = d.activePage, ps = d.pages;

        this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
        this.field.dom.value = ap;
        this.first.setDisabled(ap == 1);
        this.prev.setDisabled(ap == 1);
        this.next.setDisabled(ap == ps);
        this.last.setDisabled(ap == ps);
        this.updateInfo();
        this.fireEvent('change', this, d);
    },
    onLoadError : function(){},
    beforeLoad : function(){}
});

Ext.DevxLoadMask = Ext.extend(Ext.LoadMask, {
    onBeforeLoad : function(){
        if(!this.disabled){
            if(this.el.getStyle("position") == "static"){
                this.el.addClass("x-masked-relative");
            }
            if(this.el._maskMsg){
                this.el._maskMsg.remove();
            }
            if(this.el._mask){
                this.el._mask.remove();
            }

            this.el._mask = Ext.DomHelper.append(this.el.dom, {cls:""}, true);

            this.el.addClass("x-masked");
            this.el._mask.setDisplayed(true);
            if(typeof this.msg == 'string'){
                this.el._maskMsg = Ext.DomHelper.append(this.el.dom, {cls:"", cn:{tag:'div'}}, true);
                var mm = this.el._maskMsg;
                mm.dom.className = this.msgCls ? this.msgCls : "ext-el-mask-msg";
                mm.dom.firstChild.innerHTML = this.msg;
                mm.setDisplayed(true);
            }
            if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && this.el.getStyle('height') == 'auto'){ // ie will not expand full height automatically
                this.el._mask.setSize(this.el.getWidth(), this.el.getHeight());
            }
            return this.el._mask;
        }
    },
    onLoad : function(){
        this.el.unmask(this.removeMask);
    }
});

function moveOpenedFilters(){
    Ext.menu.MenuMgr.hideAll();
    if (Ext.isIE) return;
    for (var k in Filters){
        if (Filters[k].FilterMenu.isVisible()){
            Filters[k].FilterMenu.notEvent = true;
            Filters[k].MenuButton.showMenu();
            Filters[k].FilterMenu.notEvent = false;
            if ((Filters[k].SubFilterMenu) && (Filters[k].SubFilterMenu.isVisible())){
                Filters[k].SubFilterMenu.notEvent = true;
                Filters[k].SubMenuButton.showMenu();
                Filters[k].SubFilterMenu.notEvent = false;
            }
            if ((Filters[k].popupName)&&(Filters[k].selected_id >= 0)){
                if (Filters[k].selected_type == 1) Filters[k].openREMPopup(Filters[k].selected_id);
                else Filters[k].openPopup(Filters[k].selected_id);
            }
        }
    }
}

function implode( glue, pieces ) {
    return ( ( pieces instanceof Array ) ? pieces.join ( glue ) : '' );
}

function implodeWithBreak( glue, each, break_glue, pieces ) {
    if (!( pieces instanceof Array )) return '';
    if (pieces.length == 0) return '';
    var res = '';
    for (var i = 0; i < pieces.length-1; i++){
        res += pieces[i] + glue;
        if (i % each == each - 1) res += break_glue;
    }
    res += pieces[pieces.length - 1];
    return res;
}

function showCompanyInfo(id){
    if (!id) return; 
    var el = document.getElementById('companyInfo');
    if (!el) return;
    var mask = new Ext.LoadMask(el);
    var url = 'index.php?act=company&hdl=info&id='+id;
    mask.show();
    var form=new DEVXForm({'loader':loader});
    form.loadObj2ID(url, 'companyInfo', function () {
        switchBlankInfo(false);
        eval(form.jscode);
        mask.hide();
    });
    /*
    loader.data['onerror'] = function(){};
    loader.processGET(url, function(http){
        el.innerHTML = http.responseText;
        mask.hide();
    }, false, false);
    */
}

function switchBlankInfo(show){
    var el = document.getElementById('companyInfo');
    var blank_el = document.getElementById('companyInfoBlank');
    if (!el || !blank_el) return;
    if (show) {
        Ext.get(el).hide();
        Ext.get(blank_el).show();
        return;
    }
    Ext.get(blank_el).hide();
    Ext.get(el).show();
//    gridArray['grid'].getView().lastRowOver = 0;
}

initStatusIcons = function (grid) {
    var store = grid.getStore();
    var view = grid.getView();
    var rows = store.getCount();
    var cm = grid.getColumnModel();
    var compIndex = cm.findColumnIndex('company_name');

    for (var i = 0; i < rows; i++) {
        var r = store.getAt(i);
        var data = r.data;
        if (data.company_name && data.company_name != '') {
            var cell = view.getCell(i, compIndex);
            var img = 0;
            if ('C' == data.type_) {
                if ('Y' == data.conf_status) img = 3;
                else if ('N' == data.conf_status) img = 2;
            } else {
                if ('Y' == data.conf_status) img = 1;
            }
            if (img > 0) cell.style.background = 'url(img/stat'+img+'.gif) no-repeat center right';
            var div = cell.firstChild.firstChild;
            if (div && div.style) div.style.width = cell.offsetWidth - 15 + 'px';
        }
    }
}

Ext.DevxBodyMask = function(config){
    Ext.DevxBodyMask.superclass.constructor.call(this, Ext.getBody(), config);
}

Ext.extend(Ext.DevxBodyMask, Ext.LoadMask, {
    onBeforeLoad : function(){
            if(!this.disabled){
                var mask_el = this.el.mask(this.msg, this.msgCls);
                mask_el.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
            }
        }
});
