﻿/* 3.2.1 scrolling problem nexted panel in window */
Ext.Panel.override({
    setAutoScroll: function() {
        if (this.rendered && this.autoScroll) {
            var el = this.body || this.el;
            if (el) {
                el.setOverflow('auto');
                // Following line required to fix autoScroll
                el.dom.style.position = 'relative';
            }
        }
    }
});
/*fixing bug 22484 */

Ext.override(Ext.Window.DD, {
    startDrag: function() {

        var w = this.win;
        this.proxy = w.ghost();
        w.constrain = true;
        if (w.constrain !== false) {
            var so = w.el.shadowOffset;
            this.constrainTo(w.container, { right: so, left: so, bottom: so });
        } else if (w.constrainHeader !== false) {
            var s = this.proxy.getSize();
            this.constrainTo(w.container, { right: -(s.width - this.headerOffsets[0]), bottom: -(s.height - this.headerOffsets[1]) });
        }
    }

}
);


/**Fixing bug 22235
**/


Ext.override(Ext.grid.RowSelectionModel, {
    handleMouseDown: function(g, rowIndex, e) {
        if (e.button !== 0 || this.isLocked()) {
            return;
        }
        var view = this.grid.getView();
        if (e.shiftKey && !this.singleSelect && this.last !== false) {
            var last = this.last;
            this.selectRange(last, rowIndex, e.ctrlKey);
            this.last = last; // reset the last
            if (this.focusRow) view.focusRow(rowIndex);
        } else {
            var isSelected = this.isSelected(rowIndex);
            if (e.ctrlKey && isSelected) {
                this.deselectRow(rowIndex);
            } else if (!isSelected || this.getCount() > 1) {
                this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
                if (this.focusRow) view.focusRow(rowIndex);
            }
        }
    }

}
);

/**
fixing bug 19002
**/
Ext.dd.Registry = function() {
    var elements = {};
    var handles = {};
    var autoIdSeed = 0;

    var getId = function(el, autogen) {
        if (typeof el == "string") {
            return el;
        }
        var id = el.id;
        if (!id && autogen !== false) {
            id = "extdd-" + (++autoIdSeed);
            el.id = id;
        }
        return id;
    };

    return {

        register: function(el, data) {

            data = data || {};
            if (typeof el == "string") {
                el = document.getElementById(el);
            }
            data.ddel = el;
            elements[getId(el)] = data;
            if (data.isHandle !== false) {
                handles[data.ddel.id] = data;
            }
            if (data.handles) {
                var hs = data.handles;
                for (var i = 0, len = hs.length; i < len; i++) {
                    handles[getId(hs[i])] = data;
                }
            }
        },

        unregister: function(el) {
            var id = getId(el, false);
            var data = elements[id];
            if (data) {
                delete elements[id];
                if (data.handles) {
                    var hs = data.handles;
                    for (var i = 0, len = hs.length; i < len; i++) {
                        delete handles[getId(hs[i], false)];
                    }
                }
            }
        },

        getHandle: function(id) {
            if (typeof id != "string") { // must be element?
                id = id.id;
            }
            return handles[id];
        },

        getHandleFromEvent: function(e) {
            var t = Ext.lib.Event.getTarget(e);
            return t ? handles[t.id] : null;
        },

        getTarget: function(id) {
            if (typeof id != "string") { // must be element?
                id = id.id;
            }
            return elements[id];
        },

        getTargetFromEvent: function(e, checkMarkup) {

            var t = Ext.lib.Event.getTarget(e);
            if (t != null && t.id == "ext-ddMarkup" && checkMarkup)
                t = t.parentNode;

            return t ? elements[t.id] || handles[t.id] : null;
        }
    };
} ();

/* adding the function getSelection() to ext.grid.gridPanel after the migartin to extjs 3.1.1 */


Ext.override(Ext.grid.GridPanel, {
    getSelections: function() {
        return this.getSelectionModel().getSelections();
    }

});


/* Component Fix (ExtJS 3.2.1) */
Ext.override(Ext.PagingToolbar, {
	useJsonData:false,
	//	When a paging toolbar is listening to a store. It should provide start/limit values each time it loads
	beforeLoad : function(s,opts){
		if (!opts) return;
		var p = opts.params || (opts.params={}),
			pn = this.getParams();
		if (this.useJsonData) p = p.jsonData || (p.jsonData={});
		if (isNaN(p[pn.start])) p[pn.start] = 0;
		if (isNaN(p[pn.limit])) p[pn.limit] = this.pageSize;
        if(this.rendered && this.refresh){
            this.refresh.disable();
        }
    },
    doLoad : function(start){
        var o = {}, pn = this.getParams();
        o[pn.start] = start;
        o[pn.limit] = this.pageSize;
        if(this.fireEvent('beforechange', this, o) !== false){
			if (this.useJsonData) o = {jsonData:o};
            this.store.load({params:o});
        }
    },
	// private
    onLoad : function(store, r, o){
        if(!this.rendered){
            this.dsLoaded = [store, r, o];
            return;
        }
        var p = this.getParams();
		var pD = (o.params||{});
		if (this.useJsonData) pD = (pD.jsonData||{});
        this.cursor = pD[p.start] || 0;
        var d = this.getPageData(), ap = d.activePage, ps = d.pages;

        this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
        this.inputItem.setValue(ap);
        this.first.setDisabled(ap == 1);
        this.prev.setDisabled(ap == 1);
        this.next.setDisabled(ap == ps);
        this.last.setDisabled(ap == ps);
        this.refresh.enable();
        this.updateInfo();
        this.fireEvent('change', this, d);
    }
});


/* Bug: correct IE8 to use document.documentMode instead of just IE version (IE8 in Compatibility Mode using IE8 will state 7.00 as the browser version) */
/* Bug: IE9 not registrying correctly, setting it as IE9; */
if (Ext.isIE && (document.documentMode === 8) || /msie 9/.test(navigator.userAgent.toLowerCase())) {
    Ext.isIE6 = false;
    Ext.isIE7 = false;
    Ext.isIE8 = true;
}

/* Enhancement: Remove default stateful:true for all components (ExtJS 3.1.1) */
Ext.override(Ext.Component, { stateful: false });

Ext.override(Ext.Element, {
    /*	Bug: Avoid FF error on chrome elements (ExtJS 3.1.1) */
    contains: function(el) {
        if (!el) { return false; }
        try { return Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el); }
        catch (e) { return false; }
    },
    //	Fix for IE dom error
	getAttribute : Ext.isIE ? function(name, ns){
        var type, d = this.dom;
		try {
			type = typeof(d[ns + ":" + name]);
		} catch(e) {
			return null;
		}
        if(['undefined', 'unknown'].indexOf(type) == -1){
            return d[ns + ":" + name];
        }
        return d[name];
    } : function(name, ns){
        var d = this.dom;
        return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
    }
});


/*	Bug: getDom Override to avoid access denied bug (ExtJS 3.1.1) */
Ext.getDom = function(el, strict) {
    if (!el || !document) return null;
    if (el.dom) return el.dom;
    if (!Ext.isString(el)) return el;
    /* Change: Fix issue with back button and IFRAME (while unloading page, would get Access Denied otherwise) */
    var e;
    try {
        e = document.getElementById(el);
    } catch (ex) {
        e = null;
    }
    // IE returns elements with the 'name' and 'id' attribute.
    // we do a strict check to return the element with only the id attribute
    if (e && Ext.isIE && strict) return el == e.getAttribute('id') ? e : null;
    return e;
};
Ext.override(Ext.grid.CheckboxSelectionModel, {
    /* Enhancement: Full row checkbox selection */
    onMouseDown: function(e, t) {

        /* Change: for checksel even row select should keep the existing records */
        if (e.button === 0 || (!this.singleSelect && Ext.fly(t).hasClass('x-grid3-cell-inner'))) {

            e.stopEvent();
            var row = e.getTarget('.x-grid3-row');
            if (row) {
                var index = row.rowIndex;
                if (this.isSelected(index)) {
                    this.deselectRow(index);

                    /* Change:deselect checkbox header if selected */
                    var hd = Ext.DomQuery.selectNode('.x-grid3-hd-checker', this.grid.view.innerHd);
                    if (hd) Ext.fly(hd).removeClass('x-grid3-hd-checker-on');

                } else {
                    this.selectRow(index, true);

                    /* Change: Add */
                    if (this.getCount() == this.grid.store.getCount()) {
                        var hd = Ext.DomQuery.selectNode('.x-grid3-hd-checker', this.grid.view.innerHd);
                        if (hd) Ext.fly(hd).addClass('x-grid3-hd-checker-on');
                    }

                }
            }
        }
    }
});
Ext.override(Ext.tree.TreeNodeUI, {
	/* Enhancement: tree paging */
	showMoreText:'Show {0} More',
	
	
	//	Enhancement: Add Text Wraping to Tree Nodes (this.node.ownerTree.wrapText) (ExtJS 3.1.1)
	renderElements : function(n, a, targetNode, bulkRender){
        // add some indent caching, this helps performance when rendering a large tree
        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';

        /* Change: Add wrapText property so white-space:normal */
        var cb = Ext.isBoolean(a.checked),
            nel,
            href = a.href ? a.href : Ext.isGecko ? "" : "#",
            buf = ['<li class="x-tree-node"><div ext:tree-node-id="', n.id, '" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls, '" unselectable="on"', (this.node.ownerTree && this.node.ownerTree.wrapText) ? ' style="white-space:normal"' : '', '>',
            '<span class="x-tree-node-indent">', this.indentMarkup, "</span>",
            '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
            '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon', (a.icon ? " x-tree-node-inline-icon" : ""), (a.iconCls ? " " + a.iconCls : ""), '" unselectable="on" />',
            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
            '<a hidefocus="on" class="x-tree-node-anchor" href="', href, '" tabIndex="1" ',
             a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">', n.text, "</span></a></div>",
            '<ul class="x-tree-node-ct" style="display:none;"></ul>',
			
			/* Enhancement: tree paging */
			'<div class="x-tree-pager x-tree-node-el x-unselectable" ext:tree-node-id="',n.id,'" style="display:none;">',
				'<span class="x-tree-pager-indent"></span>',
				'<span class="x-tree-pager-more">',
				'<img src="', this.emptyIcon, '" class="x-tree-icon x-tree-pager-icon" />',
				'<span class="x-tree-pager-text"></span>',
				'</span>',
			'</div>',
			
            "</li>"].join('');


        if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
        } else {
            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
        }

        this.elNode = this.wrap.childNodes[0];
        this.ctNode = this.wrap.childNodes[1];
		
		/* Enhancement: tree paging */
		this.pgNode = this.wrap.childNodes[2];
		
        var cs = this.elNode.childNodes;
        this.indentNode = cs[0];
        this.ecNode = cs[1];
        this.iconNode = cs[2];
        var index = 3;
        if (cb) {
            this.checkbox = cs[3];
            // fix for IE6
            this.checkbox.defaultChecked = this.checkbox.checked;
            index++;
        }
        this.anchor = cs[index];
        this.textNode = cs[index].firstChild;
    },
	
	setHasMore : function(count) {
		if (!this.pgNode) return;
		if (count > 0) {
			var pager = Ext.fly(this.pgNode);
			pager.child('.x-tree-pager-text').update(String.format(this.showMoreText, count || ''));
			pager.child('.x-tree-pager-indent').update(this.getChildIndent());
			this.pgNode.style.display = '';
		} else {
			this.pgNode.style.display = 'none';
		}
	},
	onPage : function(){
		if (!this.pgNode) return;
		Ext.fly(this.pgNode).addClass('x-tree-pager-loading');
	},
	afterLoad : function(){
		if (this.pgNode) Ext.fly(this.pgNode).removeClass('x-tree-pager-loading');
		this.removeClass("x-tree-node-loading");
    }
});

Ext.override(Ext.tree.TreeEventModel, {
    delegateClick: function (e, t) {
        if (this.beforeEvent(e)) {
            if (e.getTarget('input[type=checkbox]', 1)) {
                this.onCheckboxClick(e, this.getNode(e));
            } else if (e.getTarget('.x-tree-ec-icon', 1)) {
                this.onIconClick(e, this.getNode(e));
            } else if (e.getTarget('.x-tree-pager', 3)) {
                this.onPageClick(e, this.getNode(e))
            } else if (this.getNodeTarget(e)) {
                if (this.tree.passOnNodeClick)
                 this.tree.onNodeClick(e, this.getNode(e));
                    else
                this.onNodeClick(e, this.getNode(e));
            } else {
                this.onContainerEvent(e, 'click');
            }
        }
    },

    onPageClick: function (e, node) {
        node.nextPage(e);
    }
});


Ext.override(Ext.tree.TreeNode, {

    /* Bug: If childNodes is destroyed, don't iterate (ExtJS 3.1.1) */
    renderChildren: function(suppressEvent) {
        if (suppressEvent !== false) {
            this.fireEvent("beforechildrenrendered", this);
        }

        /* Change: ensure cs is not null */
        var cs = this.childNodes || [];

        for (var i = 0, len = cs.length; i < len; i++) {
            cs[i].render(true);
        }
        this.childrenRendered = true;
    },


    /* Enhancement: overridden to provide emptyText feature for the ownerTree (ExtJS 3.1.1) */
    afterAdd: function(node, exists) {
  
        if (this.childrenRendered) {
            // bulk render if the node already exists
            node.render(exists);

            /* Change */
            if (this.ownerTree.emptyText			//	EmptyText enabled
			&& !(this.ownerTree.rootVisible)		//	Root is not visible
			&& this.childNodes.length == 1			//	A single child node
			&& this == this.ownerTree.root) {		//	This is the root node
                var bDom = this.ownerTree.body.dom;
                
                var child = Ext.get(bDom).child(".x-grid-empty");
                //var child = Ext.fly(bDom.childNodes[1]).hasClass("x-grid-empty") ? bDom.childNodes[1] :
                //			Ext.fly(bDom.childNodes[0]).hasClass("x-grid-empty") ? bDom.childNodes[0] : null;
                if (child) bDom.removeChild(child.dom); //	remove empty text cell
            }

        } else if (exists) {
            // make sure we update the indent
            node.renderIndent(true, true);
        }
    },
appendChild: function(n) {

        if (!n.render && !Ext.isArray(n)) {
            n = this.getLoader().createNode(n);
        }
        var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
        if (node && this.childrenRendered) {
            node.render();
          
            if (this.ownerTree.emptyText && !(this.ownerTree.rootVisible) && this.childNodes.length == 1 && this == this.ownerTree.root) {
               
               if(Ext.fly(this.ownerTree.body.dom.childNodes[1]).hasClass("x-grid-empty"))
                   this.ownerTree.body.dom.removeChild(this.ownerTree.body.dom.childNodes[1]);
                else
                if(Ext.fly(this.ownerTree.body.dom.childNodes[0]).hasClass("x-grid-empty"))
                    this.ownerTree.body.dom.removeChild(this.ownerTree.body.dom.childNodes[0]);
            }
        }
        this.ui.updateExpandIcon();
        return node;
    },
    /* Enhancement: overridden to support emptyText feature for the ownerTree (ExtJS 3.1.1) */
    removeChild: function(node, destroy) {
        this.ownerTree.getSelectionModel().unselect(node);
        Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
        // only update the ui if we're not destroying
        if (!destroy) {
            // if it's been rendered remove dom node
            if (node.ui.rendered) {
                node.ui.remove();
            }
            if (this.childNodes.length < 1) {

                /* Change */
                if (this.ownerTree.emptyText) this.ownerTree.applyEmptyText();

                this.collapse(false, false);
            } else {
                this.ui.updateExpandIcon();
            }
            if (!this.firstChild && !this.isHiddenRoot()) {
                this.childrenRendered = false;
            }
        }
        return node;
    },
	
	nextPage : Ext.emptyFn
});

Ext.override(Ext.tree.TreePanel, {

    /* Enhancement: To implement emptyText feature for Treepanel (3.1.1) */
    applyEmptyText: function() {
       
        if (this.emptyText && this.root.childNodes.length == 0 && (!this.rootVisible)) {
            this.body.createChild({ tag: 'div', cls: 'x-grid-empty', cn: { html: this.emptyText }, style: '' }, this.innerCt.dom);
        }
    },

    /* Enhancement: To implement emptyText feature for Treepanel (3.1.1) */
    renderRoot: function() {
        this.root.render();
        if (!this.rootVisible) {
            this.root.renderChildren();
        }

        /* Change */
        this.applyEmptyText();
    }
});

Ext.override(Ext.tree.AsyncTreeNode, {
    /* Enhancement: emptyText feature for the ownerTree (ExtJS 3.1.1) */
    loadComplete: function(deep, anim, callback, scope) {
        this.loading = false;
        this.loaded = true;
        this.ui.afterLoad(this);
        this.fireEvent("load", this);
        this.expand(deep, anim, callback, scope);

        /* Change */
        if (this.ownerTree != null
        && this.ownerTree.emptyText
        && !(this.ownerTree.rootVisible)
        && this == this.ownerTree.root) {
            this.ownerTree.body.dom.removeChild(this.ownerTree.body.dom.childNodes[1]);
        }
    },
	
	/* Enhancement: Allow paging child nodes */
	totalChildren:0,
	pageCursor:0,
    renderChildren: function(suppressEvent) {
		Ext.tree.AsyncTreeNode.superclass.renderChildren.call(this, suppressEvent);
		var nextPageSize = this.totalChildren - this.childNodes.length;
		var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
		if (loader) {
			nextPageSize = Math.min(loader.pageSize || 0, nextPageSize);
		}
		this.ui.setHasMore(Math.max(nextPageSize,0));
	},
	nextPage : function(e){
		var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
		if (loader) {
			var cl = loader.clearOnLoad;
			loader.clearOnLoad = false;
			this.pageCursor += loader.pageSize || 0;
			loader.load(this, this.loadComplete.createDelegate(this, [false, false, null, null]), this);
			loader.clearOnLoad = cl;
			this.ui.onPage();
		}
	}
});

/* TreeLoader that can load children in pages */
Ext.ns('Ext.ux.tree');
Ext.ux.tree.PagedTreeLoader = Ext.extend(Ext.tree.TreeLoader,{
	pageSize:250,
	keepPages:false,
	start:'start',
	limit:'limit',
	root:'list',
	total:'total',
	
	processResponse : function(response, node, callback, scope){
        var json = response.responseText;
        try {
            var list,total,o = response.responseData || Ext.decode(json);
			
			//	Backwards compatible
			if (this.root) {
				list = o[this.root] || [];
				total = o[this.total] || list.length;
			} else {
				list = o || [];
				total = list.length;
			}
			
            node.beginUpdate();
            for(var i = 0, len = list.length; i < len; i++){
                var n = this.createNode(list[i]);
                if(n){
                    node.appendChild(n);
                }
            }
			node.totalChildren = total;
            node.endUpdate();
			
            this.runCallback(callback, scope || node, [node]);
        }catch(e){
            this.handleFailure(response);
        }
    },
	
	getParams : function(node){
		var bp = Ext.ux.tree.PagedTreeLoader.superclass.getParams.call(this,node);
		if (this.directFn) {
			var po = this.paramOrder;
			if (po) {
				
				//	Stub: Figure this out later
				
			} else if (this.paramsAsHash) {
				bp[0][this.start] = node.pageCursor || 0;
				bp[0][this.limit] = this.pageSize;
			}
		} else {
			bp[this.start] = node.pageCursor || 0;
			bp[this.limit] = this.pageSize;
		}
		return bp;
	}
});



/* Resize Panel Component */
Ext.ResizePanel = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        Ext.ResizePanel.superclass.constructor.apply(this, arguments);
        var t = this;
        var up = function() { t.update(); };
        if (window.addEventListener) {
            window.addEventListener("resize", up, false);
            window.addEventListener("unload", function() { window.removeEventListener("resize", up, false); }, false);
        } else if (window.attachEvent) {
            window.attachEvent("onresize", up);
            window.detachEvent("onunload", function() { window.removeEventListener("onresize", up); });
        }
    },
    update: function() {
        this.doLayout(true);
    }
});

/* Row Expander (Ext 3.1.1) */
Ext.ns('Ext.ux.grid');
Ext.ux.grid.RowExpander = Ext.extend(Ext.util.Observable, {
    expandOnEnter: true,
    expandOnDblClick: true,
    header: '',
    width: 20,
    sortable: false,
    fixed: true,
    menuDisabled: true,
    dataIndex: '',
    id: 'expander',
    lazyRender: true,
    enableCaching: true,
    hideable: false,
    constructor: function(config) {
        Ext.apply(this, config);

        this.addEvents({
            beforeexpand: true,
            expand: true,
            beforecollapse: true,
            collapse: true
        });

        Ext.ux.grid.RowExpander.superclass.constructor.call(this);

        if (this.tpl) {
            if (typeof this.tpl == 'string') {
                this.tpl = new Ext.Template(this.tpl);
            }
            this.tpl.compile();
        }

        this.state = {};
        this.bodyContent = {};
    },

    getRowClass: function(record, rowIndex, p, ds) {
        p.cols = p.cols - 1;
        var content = this.bodyContent[record.id];
        if (!content && !this.lazyRender) {
            content = this.getBodyContent(record, rowIndex);
        }
        if (content) {
            p.body = content;
        }
        return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
    },

    init: function(grid) {
        this.grid = grid;

        var view = grid.getView();
        view.getRowClass = this.getRowClass.createDelegate(this);

        view.enableRowBody = true;


        grid.on('render', this.onRender, this);
        grid.on('destroy', this.onDestroy, this);
    },

    // @private
    onRender: function() {
        var grid = this.grid;
        var mainBody = grid.getView().mainBody;
        mainBody.on('mousedown', this.onMouseDown, this, { delegate: '.x-grid3-row-expander' });
        if (this.expandOnEnter) {
            this.keyNav = new Ext.KeyNav(this.grid.getGridEl(), {
                'enter': this.onEnter,
                scope: this
            });
        }
        if (this.expandOnDblClick) {
            grid.on('rowdblclick', this.onRowDblClick, this);
        }
    },

    // @private    
    onDestroy: function() {
        if (this.keyNav) {
            this.keyNav.disable();
            delete this.keyNav;
        }
        /*
        * A majority of the time, the plugin will be destroyed along with the grid,
        * which means the mainBody won't be available. On the off chance that the plugin
        * isn't destroyed with the grid, take care of removing the listener.
        */
        var mainBody = this.grid.getView().mainBody;
        if (mainBody) {
            mainBody.un('mousedown', this.onMouseDown, this);
        }
    },
    // @private
    onRowDblClick: function(grid, rowIdx, e) {
        this.toggleRow(rowIdx);
    },

    onEnter: function(e) {
        var g = this.grid;
        var sm = g.getSelectionModel();
        var sels = sm.getSelections();
        for (var i = 0, len = sels.length; i < len; i++) {
            var rowIdx = g.getStore().indexOf(sels[i]);
            this.toggleRow(rowIdx);
        }
    },

    getBodyContent: function(record, index) {
        if (!this.enableCaching) {
            return this.tpl.apply(record.data);
        }
        var content = this.bodyContent[record.id];
        if (!content) {
            content = this.tpl.apply(record.data);
            this.bodyContent[record.id] = content;
        }
        return content;
    },

    onMouseDown: function(e, t) {
        e.stopEvent();
        var row = e.getTarget('.x-grid3-row');
        this.toggleRow(row);
    },

    renderer: function(v, p, record) {
        p.cellAttr = 'rowspan="2"';
        return '<div class="x-grid3-row-expander">&#160;</div>';
    },

    beforeExpand: function(record, body, rowIndex) {
        if (this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false) {
            if (this.tpl && this.lazyRender) {
                body.innerHTML = this.getBodyContent(record, rowIndex);
            }
            return true;
        } else {
            return false;
        }
    },

    toggleRow: function(row) {
        if (typeof row == 'number') {
            row = this.grid.view.getRow(row);
        }
        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
    },

    expandRow: function(row) {
        if (typeof row == 'number') {
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
        if (this.beforeExpand(record, body, row.rowIndex)) {
            this.state[record.id] = true;
            Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
            this.fireEvent('expand', this, record, body, row.rowIndex);
        }
    },

    collapseRow: function(row) {
        if (typeof row == 'number') {
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
        if (this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false) {
            this.state[record.id] = false;
            Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
            this.fireEvent('collapse', this, record, body, row.rowIndex);
        }
    }
});
Ext.preg('rowexpander', Ext.ux.grid.RowExpander);

//backwards compat
Ext.grid.RowExpander = Ext.ux.grid.RowExpander;


Ext.ns('Ext.ux.form');

/* File Upload Field (Ext 3.1.1) */
Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField, {
    buttonText: 'Browse...',
    buttonOnly: false,
    buttonOffset: 3,

    // private
    readOnly: true,

    /**
    * @hide
    * @method autoSize
    */
    autoSize: Ext.emptyFn,

    // private
    initComponent: function() {
        Ext.ux.form.FileUploadField.superclass.initComponent.call(this);

        this.addEvents(
        /**
        * @event fileselected
        * Fires when the underlying file input field's value has changed from the user
        * selecting a new file from the system file selection dialog.
        * @param {Ext.ux.form.FileUploadField} this
        * @param {String} value The file value returned by the underlying file input field
        */
            'fileselected'
        );
    },

    // private
    onRender: function(ct, position) {
        Ext.ux.form.FileUploadField.superclass.onRender.call(this, ct, position);

        this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
        this.el.addClass('x-form-file-text');
        this.el.dom.removeAttribute('name');
        this.createFileInput();

        var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
            text: this.buttonText
        });
        this.button = new Ext.Button(Ext.apply(btnCfg, {
            renderTo: this.wrap,
            cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : '')
        }));

        if (this.buttonOnly) {
            this.el.hide();
            this.wrap.setWidth(this.button.getEl().getWidth());
        }

        this.bindListeners();
        this.resizeEl = this.positionEl = this.wrap;
    },

    bindListeners: function() {
        this.fileInput.on({
            scope: this,
            mouseenter: function() {
                this.button.addClass(['x-btn-over', 'x-btn-focus'])
            },
            mouseleave: function() {
                this.button.removeClass(['x-btn-over', 'x-btn-focus', 'x-btn-click'])
            },
            mousedown: function() {
                this.button.addClass('x-btn-click')
            },
            mouseup: function() {
                this.button.removeClass(['x-btn-over', 'x-btn-focus', 'x-btn-click'])
            },
            change: function() {
                var v = this.fileInput.dom.value;
                this.setValue(v);
                this.fireEvent('fileselected', this, v);
            }
        });
    },

    createFileInput: function() {
        this.fileInput = this.wrap.createChild({
            id: this.getFileInputId(),
            name: this.name || this.getId(),
            cls: 'x-form-file',
            tag: 'input',
            type: 'file',
            size: 1
        });
    },

    reset: function() {
        this.fileInput.remove();
        this.createFileInput();
        this.bindListeners();
        Ext.ux.form.FileUploadField.superclass.reset.call(this);
    },

    // private
    getFileInputId: function() {
        return this.id + '-file';
    },

    // private
    onResize: function(w, h) {
        Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h);

        this.wrap.setWidth(w);

        if (!this.buttonOnly) {
            var w = this.wrap.getWidth() - this.button.getEl().getWidth() - this.buttonOffset;
            this.el.setWidth(w);
        }
    },

    // private
    onDestroy: function() {
        Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);
        Ext.destroy(this.fileInput, this.button, this.wrap);
    },

    onDisable: function() {
        Ext.ux.form.FileUploadField.superclass.onDisable.call(this);
        this.doDisable(true);
    },

    onEnable: function() {
        Ext.ux.form.FileUploadField.superclass.onEnable.call(this);
        this.doDisable(false);

    },

    // private
    doDisable: function(disabled) {
        this.fileInput.dom.disabled = disabled;
        this.button.setDisabled(disabled);
    },


    // private
    preFocus: Ext.emptyFn,

    // private
    alignErrorIcon: function() {
        this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
    }

});

Ext.reg('fileuploadfield', Ext.ux.form.FileUploadField);

// backwards compat
Ext.form.FileUploadField = Ext.ux.form.FileUploadField;

/* SEARCH FIELD (ExtJS 3.1.1) */
Ext.ux.form.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
    initComponent: function() {
        Ext.app.SearchField.superclass.initComponent.call(this);
        this.on('specialkey', function(f, e) {
            if (e.getKey() == e.ENTER) {
                this.onTrigger2Click();
            }
        }, this);
    },

    validationEvent: false,
    validateOnBlur: false,
    trigger1Class: 'x-form-clear-trigger',
    trigger2Class: 'x-form-search-trigger',
    hideTrigger1: true,
    width: 180,
    hasSearch: false,
    paramName: 'query',
    defaultParams: { limit: 50 },

    getStore: function() {
        return this.store;
    },

    reconfigure: function(store) {
        this.store = store;
    },

    onTrigger1Click: function() {	//	Clear Results
        if (this.hasSearch) {
            this.el.dom.value = '';
            var o = this.store.lastOptions.params || this.defaultParams;
            o.start = 0;
            this.store.baseParams = this.store.baseParams || {};
            this.store.baseParams[this.paramName] = '';
            o[this.paramName] = '';
            this.fireEvent('onClear', this);
            this.store.reload({ params: o });
            this.triggers[0].hide();
            this.hasSearch = false;
        }
    },

    onTrigger2Click: function() {	//	Search
        var v = this.getRawValue();
        if (v.length < 1) {
            this.onTrigger1Click();
            return;
        }
        var o = this.store.lastOptions.params || this.defaultParams;
        o.start = 0;
        this.store.baseParams = this.store.baseParams || {};
        this.store.baseParams[this.paramName] = v;
        o[this.paramName] = v;
        this.fireEvent('onSearch', this, v);
        this.store.reload({ params: o });
        this.hasSearch = true;
        this.triggers[0].show();
    }
});
Ext.app.SearchField = Ext.ux.form.SearchField;

Ext.History = (function() {
    var iframe, hiddenField,
        ready = false,
        currentToken,
        ignoreNext = false;

    function getHash() {
        var href = top.location.href, i = href.indexOf("#");
        return i >= 0 ? href.substr(i + 1) : null;
    }

    function doSave() {
        hiddenField.value = currentToken;
    }

    function handleStateChange(token) {
        currentToken = token;
        if (!(token == ignoreNext)) {
            Ext.History.fireEvent('change', token);
        }
        ignoreNext = false;
    }

    function updateIFrame(token) {
        var html = ['<html><body><div id="state">', Ext.util.Format.htmlEncode(token), '</div></body></html>'].join('');
        try {
            var doc = iframe.contentWindow.document;
            doc.open();
            doc.write(html);
            doc.close();
            return true;
        } catch (e) {
            return false;
        }
    }

    function checkIFrame() {
        if (!iframe.contentWindow || !iframe.contentWindow.document) {
            setTimeout(checkIFrame, 10);
            return;
        }

        var doc = iframe.contentWindow.document,
            elem = doc.getElementById("state"),
            token = elem ? elem.innerText : null,
            hash = getHash();

        setInterval(function() {

            doc = iframe.contentWindow.document;
            elem = doc.getElementById("state");

            var newtoken = elem ? elem.innerText : null,
                newHash = getHash();

            if (newtoken !== token) {
                token = newtoken;
                handleStateChange(token);
                top.location.hash = token;
                hash = token;
                doSave();
            } else if (newHash !== hash) {
                hash = newHash;
                updateIFrame(newHash);
            }

        }, 50);

        ready = true;

        Ext.History.fireEvent('ready', Ext.History);
    }

    function startUp() {
        currentToken = hiddenField.value ? hiddenField.value : getHash();

        if (Ext.isIE && !Ext.isIE8) {
            checkIFrame();
        } else {
            var hash = getHash();
            setInterval(function() {
                var newHash = getHash();
                if (newHash !== hash) {
                    hash = newHash;
                    handleStateChange(hash);
                    doSave();
                }
            }, 50);
            ready = true;
            Ext.History.fireEvent('ready', Ext.History);
        }
    }

    return {

        /**
        * The id of the hidden field required for storing the current history token.
        * @type String
        * @property
        */
        fieldId: 'x-history-field',

        /**
        * The id of the iframe required by IE to manage the history stack.
        * @type String
        * @property
        */
        iframeId: 'x-history-frame',

        events: {},


        /**
        * Initialize the global History instance.
        * @param {Boolean} onReady (optional) A callback function that will be called once the history
        * component is fully initialized.
        * @param {Object} scope (optional) The scope (this reference) in which the callback is executed. Defaults to the browser window.
        */
        init: function(onReady, scope) {
            if (ready) {
                Ext.callback(onReady, scope, [this]);
                return;
            }
            if (!Ext.isReady) {
                Ext.onReady(function() {
                    Ext.History.init(onReady, scope);
                });
                return;
            }
            hiddenField = Ext.getDom(Ext.History.fieldId);
            if (Ext.isIE && !Ext.isIE8) {
                iframe = Ext.getDom(Ext.History.iframeId);
            }
            this.addEvents(

            /**
            * @event ready
            * Fires when the Ext.History singleton has been initialized and is ready for use.
            * @param {Ext.History} The Ext.History singleton.
            */
                'ready',

            /**
            * @event change
            * Fires when navigation back or forwards within the local page's history occurs.
            * @param {String} token An identifier associated with the page state at that point in its history.
            */
                'change'
            );
            if (onReady) {
                this.on('ready', onReady, scope, { single: true });
            }
            startUp();
        },


        /**
        * Add a new token to the history stack. This can be any arbitrary value, although it would
        * commonly be the concatenation of a component id and another id marking the specifc history
        * state of that component.  Example usage:
        * 

// Handle tab changes on a TabPanel
        tabPanel.on('tabchange', function(tabPanel, tab){
        Ext.History.add(tabPanel.id + ':' + tab.id);
        });

         * @param {String} token The value that defines a particular application-specific history state
        * @param {Boolean} preventDuplicates When true, if the passed token matches the current token
        * it will not save a new history step. Set to false if the same state can be saved more than once
        * at the same history stack location (defaults to true).
        */
        add: function(token, preventDup, suppressEvent) {
            if (preventDup !== false) {
                if (this.getToken() == token) {
                    return true;
                }
            }
            if (suppressEvent) {
                ignoreNext = token;
            }
            if (Ext.isIE && !Ext.isIE8) {
                return updateIFrame(token);
            } else {
                top.location.hash = token;
                return true;
            }
        },


        /**
        * Programmatically steps back one step in browser history (equivalent to the user pressing the Back button).
        */
        back: function() {
            history.go(-1);
        },


        /**
        * Programmatically steps forward one step in browser history (equivalent to the user pressing the Forward button).
        */
        forward: function() {
            history.go(1);
        },


        /**
        * Retrieves the currently-active history token.
        * @return {String} The token
        */
        getToken: function() {
            return ready ? currentToken : getHash();
        }
    };
})();
Ext.apply(Ext.History, new Ext.util.Observable());

Ext.override(Ext.data.Store, {
    sort: function(fieldName, dir) {
        var f = this.fields.get(fieldName);
        if (!f) {
            return false;
        }
        if (!dir) {
            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;

        this.sortToggle[f.name] = dir;
        this.sortInfo = { field: f.name, direction: dir };
        this.fireEvent('beforesort', this, this.sortInfo);
        if (!this.remoteSort) {
            this.applySort();
            this.fireEvent('datachanged', this);
        } else {
            if (!this.load(this.lastOptions)) {
                if (st) {
                    this.sortToggle[f.name] = st;
                }
                if (si) {
                    this.sortInfo = si;
                }
            }
        }
    }

});
/* Check Column: Grid Plugin (ExtJS 3.1.1) */
Ext.grid.CheckColumn = function(config) {
    Ext.apply(this, config);
    if (!this.id) this.id = Ext.id();
    this.renderer = this.renderer.createDelegate(this);
};
Ext.grid.CheckColumn.prototype = {
    init: function (grid) {
        this.grid = grid;
        this.grid.on('render', function () {
            var view = this.grid.getView();
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);
    },

    onMouseDown: function (e, t) {      
        if (t.className && t.className.indexOf('x-grid3-cc-' + this.id) != -1) {
            e.stopEvent();
            var index = this.grid.getView().findRowIndex(t);
            var record = this.grid.store.getAt(index);

            if (t.className.indexOf('disable') > -1) return;

            if (!this.readonly) {
                record.set(this.dataIndex, !record.data[this.dataIndex]);
            } else {
                record.reject(false);
            }
        }
    },

    renderer: function (v, p, record) {
        p.css += ' x-grid3-check-col-td';
        if (v != null) {
            return '<div class="x-grid3-check-col' + (v ? '-on' : '') + ' x-grid3-cc-' + this.id + '">&#160;</div>';
        }
        else return '<div>&#160;</div>';
    }
};

Ext.override(Ext.grid.GridView, {

    /* Enhancement: Allow Wrap Text (ExtJS 3.1.1) */
    initTemplates: function() {
        var ts = this.templates || {};
        if (!ts.master) {
            ts.master = new Ext.Template(
                    '<div class="x-grid3" hidefocus="true">',
                        '<div class="x-grid3-viewport">',
                            '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
                            '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
                        '</div>',
                        '<div class="x-grid3-resize-marker">&#160;</div>',
                        '<div class="x-grid3-resize-proxy">&#160;</div>',
                    '</div>'
                );
        }
        if (!ts.header) {
            ts.header = new Ext.Template(
                '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
                '</table>'
            );
        }

        if (!ts.hcell) {
            ts.hcell = new Ext.Template(
                '<td 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}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? this.grid.enableHdMenuBtn ? '<a style="HEIGHT: 22px;display:block" class="x-grid3-hd-btn" href="#"></a>' : '<a class="x-grid3-hd-btn" href="#"></a>' : '',
                '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
                '</div></td>'
            );
        }

        if (!ts.body) {
            ts.body = new Ext.Template('{rows}');
        }

        if (!ts.row) {
            ts.row = new Ext.Template(
                '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                '<tbody><tr>{cells}</tr>',
                (this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
                '</tbody></table></div>'
            );
        }
        if (!ts.cell) {

            /* Change */
            ts.cell = new Ext.Template(
				'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} ',
				this.selectable ? 'x-selectable' : '',
				' {css}" style="{style}" tabIndex="0" {cellAttr}>',
				this.wrapText ?
				'<div class="x-grid3-cell-inner x-grid3-col-{id}"  style="white-space:normal;"'
				: '<div class="x-grid3-cell-inner x-grid3-col-{id}" ',
				' unselectable="on" {attr}>{value}</div>',
				'</td>'
			);

        }
        for (var k in ts) {
            var t = ts[k];
            if (t && Ext.isFunction(t.compile) && !t.compiled) {
                t.disableFormats = true;
                t.compile();
            }
        }

        this.templates = ts;
        this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
    }
});

/* PANEL */
Ext.override(Ext.Panel, {

    /* Bug: Compatibility with PNGfix (firstChild returned VML tag instead of proper div) */
    getFrameWidth: function() {

        var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');

        if (this.frame) {
            /* Change: get elements by class name */
            var l = this.bwrap.first('.x-window-ml');
            if (l == null) {
                return w;
            }
            var r = l.first('.x-window-mr');




            w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(r).getFrameWidth('r'));
            w += this.mc.getFrameWidth('lr');
        }
        return w;
    },

    /* Enchancement 3.1.1: Add autoWidthToolbars (bool) property */
    autoWidthToolbars: true,
    onResize: function(w, h) {
        if (Ext.isDefined(w) || Ext.isDefined(h)) {
            if (!this.collapsed) {
                // First, set the the Panel's body width.
                // If we have auto-widthed it, get the resulting full offset width so we can size the Toolbars to match
                // The Toolbars must not buffer this resize operation because we need to know their heights.

                if (Ext.isNumber(w)) {
                    this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
                } else if (w == 'auto') {
                    w = this.body.setWidth('auto').dom.offsetWidth;
                } else {
                    w = this.body.dom.offsetWidth;
                }

                if (!this.autoWidthToolbars) { //	Edit

                    if (this.tbar) {
                        this.tbar.setWidth(w);
                        if (this.topToolbar) {
                            this.topToolbar.setSize(w);
                        }
                    }
                    if (this.bbar) {
                        this.bbar.setWidth(w);
                        if (this.bottomToolbar) {
                            this.bottomToolbar.setSize(w);
                            // The bbar does not move on resize without this.
                            if (Ext.isIE) {
                                this.bbar.setStyle('position', 'static');
                                this.bbar.setStyle('position', '');
                            }
                        }
                    }
                    if (this.footer) {
                        this.footer.setWidth(w);
                        if (this.fbar) {
                            this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
                        }
                    }
                } //	Edit

                // At this point, the Toolbars must be layed out for getFrameHeight to find a result.
                if (Ext.isNumber(h)) {
                    h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight()));
                    this.body.setHeight(h);
                } else if (h == 'auto') {
                    this.body.setHeight(h);
                }

                if (this.disabled && this.el._mask) {
                    this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
                }
            } else {
                // Adds an event to set the correct height afterExpand.  This accounts for the deferHeight flag in panel
                this.queuedBodySize = { width: w, height: h };
                if (!this.queuedExpand && this.allowQueuedExpand !== false) {
                    this.queuedExpand = true;
                    this.on('expand', function() {
                        delete this.queuedExpand;
                        this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
                    }, this, { single: true });
                }
            }
            this.onBodyResize(w, h);
        }
        this.syncShadow();
        Ext.Panel.superclass.onResize.call(this);
    }
});










/* CHECK BOX */ // Can we just use setValue? *Is this used?*
Ext.override(Ext.form.Checkbox, {
    /* Enhancement: adding a method to setChecked similar to Ext.menu.CheckItem */
    setChecked: function(state, suppressEvent) {
        //if (window.console) console.log('Ext-Extension::Ext.form.CheckBox::setChecked', arguments);
        var checked = this.checked;
        this.checked = (state === true || state === 'true' || state == '1' || String(state).toLowerCase() == 'on');
        if (this.rendered) {
            this.el.dom.checked = this.checked;
            this.el.dom.defaultChecked = this.checked;
            this.wrap[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
        }
        this.checked = state;
        if (suppressEvent !== true) {
            this.fireEvent("checkchange", this, state);
        }
    }
});

Ext.override(Ext.form.Action.Submit, {

    /* Enhancement: try catch to fix js error when decode syntax exception */
    handleResponse: function(response) {
        if (this.form.reader) {
            var rs = this.form.reader.read(response);
            var data = rs.records && rs.records[0] ? rs.records[0].data : null;
            return {
                success: rs.success,
                data: data
            };
        }
        var result;
        try {
            result = Ext.decode(response.responseText);
        } catch (e) {
            result = response.responseText;
        }

        return result;
    }
});

Ext.override(Ext.grid.GridView, {
    updateHeaderSortState: function() {
        var state = this.ds.getSortState();
        if (!state) {
            return;
        }
        if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
            this.grid.fireEvent('sortchange', this.grid, state);
        }
        this.sortState = state;
        var sortColumn = this.cm.findColumnIndex(state.field);
        if (sortColumn != -1) {
            var sortDir = state.direction;
            this.updateSortIcon(sortColumn, sortDir);
        }
    },

    updateSortIcon: function(col, dir) {
        var sc = this.sortClasses;
        var hds = this.mainHd.select('td').removeClass(sc);
        hds.item(col).addClass(sc[dir == 'DESC' ? 1 : 0]);
    }
});

Ext.override(Ext.form.HtmlEditor, {
    defaultLinkErrorMessage: 'The link is not valid.',

    createLink: function() {
        var url = prompt(this.createLinkText, this.defaultLinkValue);
        if (url && url != 'http:/' + '/' && url != 'https:/' + '/') {
            if (!this.urlCheck(url))
                url = 'http:/' + '/' + url;

            if (!this.urlCheck(url))
                alert(this.defaultLinkErrorMessage);
            else
                this.relayCmd('createlink', ("javascript:void%20window.open('" + url + "');"));
        }
    },

    urlCheck: function(str) {
        var v = new RegExp();
        v.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
        if (!v.test(str)) {
            return false;
        }

        return true;
    }
});

/* Bug (Ext 3.1): IE, getBoundingClientRect called on an orphan element throws an error.  */
(function() {
    var libFlyweight,
		doc = document,
        ROUND = Math.round,
		PARSEINT = parseInt;

    function fly(el) {
        if (!libFlyweight) {
            libFlyweight = new Ext.Element.Flyweight();
        }
        libFlyweight.dom = el;
        return libFlyweight;
    }

    Ext.lib.Dom.getXY = function(el) {
        var p,
        	pe,
        	b,
        	bt,
        	bl,
        	dbd,
        	x = 0,
        	y = 0,
        	scroll,
        	hasAbsolute,
        	bd = (doc.body || doc.documentElement),
        	ret = [0, 0];

        el = Ext.getDom(el);

        if (el != bd) {
            if (el.getBoundingClientRect) {
                //	Edit: use (0,0) if exception occurs
                try {
                    b = el.getBoundingClientRect();
                } catch (e) {
                    b = { left: 0, top: 0 };
                }
                //	End Edit
                scroll = fly(document).getScroll();
                ret = [ROUND(b.left + scroll.left), ROUND(b.top + scroll.top)];
            } else {
                p = el;
                hasAbsolute = fly(el).isStyle("position", "absolute");

                while (p) {
                    pe = fly(p);
                    x += p.offsetLeft;
                    y += p.offsetTop;

                    hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");

                    if (Ext.isGecko) {
                        y += bt = PARSEINT(pe.getStyle("borderTopWidth"), 10) || 0;
                        x += bl = PARSEINT(pe.getStyle("borderLeftWidth"), 10) || 0;

                        if (p != el && !pe.isStyle('overflow', 'visible')) {
                            x += bl;
                            y += bt;
                        }
                    }
                    p = p.offsetParent;
                }

                if (Ext.isSafari && hasAbsolute) {
                    x -= bd.offsetLeft;
                    y -= bd.offsetTop;
                }

                if (Ext.isGecko && !hasAbsolute) {
                    dbd = fly(bd);
                    x += PARSEINT(dbd.getStyle("borderLeftWidth"), 10) || 0;
                    y += PARSEINT(dbd.getStyle("borderTopWidth"), 10) || 0;
                }

                p = el.parentNode;
                while (p && p != bd) {
                    if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {
                        x -= p.scrollLeft;
                        y -= p.scrollTop;
                    }
                    p = p.parentNode;
                }
                ret = [x, y];
            }
        }
        return ret
    }
})();

/* Bug (ExtJS 2.2.1) */
Ext.menu.MenuMgr = function() {
    var menus, active, groups = {}, attached = false, lastShow = new Date();


    function init() {
        menus = {};
        active = new Ext.util.MixedCollection();
        Ext.getDoc().addKeyListener(27, function() {
            if (active.length > 0) {
                hideAll();
            }
        });
    }


    function hideAll() {
        if (active && active.length > 0) {
            var c = active.clone();
            c.each(function(m) {
                m.hide();
            });
            return true;
        }
        return false;
    }


    function onHide(m) {
        active.remove(m);
        if (active.length < 1) {
            Ext.getDoc().un("mousedown", onMouseDown);
            attached = false;
        }
    }


    function onShow(m) {
        var last = active.last();
        lastShow = new Date();
        active.add(m);
        if (!attached) {
            Ext.getDoc().on("mousedown", onMouseDown);
            attached = true;
        }
        if (m.parentMenu) {
            m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
            m.parentMenu.activeChild = m;
        } else if (last && !last.isDestroyed && last.isVisible()) {
            m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
        }
    }


    function onBeforeHide(m) {
        if (m.activeChild) {
            m.activeChild.hide();
        }
        if (m.autoHideTimer) {
            clearTimeout(m.autoHideTimer);
            delete m.autoHideTimer;
        }
    }


    function onBeforeShow(m) {
        var pm = m.parentMenu;
        if (!pm && !m.allowOtherMenus) {
            hideAll();
        } else if (pm && pm.activeChild) {
            pm.activeChild.hide();
        }
    }


    function onMouseDown(e) {
        // change 50 -> 500 to allow for ie being slow to render menu (jn)
        if (lastShow.getElapsed() > 500 && active.length > 0 && !e.getTarget(".x-menu")) {
            hideAll();
        }
    }


    function onBeforeCheck(mi, state) {
        if (state) {
            var g = groups[mi.group];
            for (var i = 0, l = g.length; i < l; i++) {
                if (g[i] != mi) {
                    g[i].setChecked(false);
                }
            }
        }
    }

    return {


        hideAll: function() {
            return hideAll();
        },


        register: function(menu) {
            if (!menus) {
                init();
            }
            menus[menu.id] = menu;
            menu.on({
                beforehide: onBeforeHide,
                hide: onHide,
                beforeshow: onBeforeShow,
                show: onShow
            });
        },


        get: function(menu) {
            if (typeof menu == "string") {
                if (!menus) {
                    return null;
                }
                return menus[menu];
            } else if (menu.events) {
                return menu;
            } else if (typeof menu.length == 'number') {
                return new Ext.menu.Menu({ items: menu });
            } else {
                return Ext.create(menu, 'menu');
            }
        },


        unregister: function(menu) {
            delete menus[menu.id];
            menu.un("beforehide", onBeforeHide);
            menu.un("hide", onHide);
            menu.un("beforeshow", onBeforeShow);
            menu.un("show", onShow);
        },


        registerCheckable: function(menuItem) {
            var g = menuItem.group;
            if (g) {
                if (!groups[g]) {
                    groups[g] = [];
                }
                groups[g].push(menuItem);
                menuItem.on("beforecheckchange", onBeforeCheck);
            }
        },


        unregisterCheckable: function(menuItem) {
            var g = menuItem.group;
            if (g) {
                groups[g].remove(menuItem);
                menuItem.un("beforecheckchange", onBeforeCheck);
            }
        },

        getCheckedItem: function(groupId) {
            var g = groups[groupId];
            if (g) {
                for (var i = 0, l = g.length; i < l; i++) {
                    if (g[i].checked) {
                        return g[i];
                    }
                }
            }
            return null;
        },

        setCheckedItem: function(groupId, itemId) {
            var g = groups[groupId];
            if (g) {
                for (var i = 0, l = g.length; i < l; i++) {
                    if (g[i].id == itemId) {
                        g[i].setChecked(true);
                    }
                }
            }
            return null;
        }
    };
} ();

Ext.override(Ext.form.ComboBox, {
    initList: function() {
        /* Bug (ExtJS 3.2.1) */
        if (!this.tpl) {
            this.tpl = new Ext.XTemplate('<tpl for="."><div class="x-combo-list-item">{', this.displayField, ':this.blank}</div></tpl>', {
                blank: function(value) {
                    return value === '' ? '&nbsp' : value;
                }
            });
        }
        /* Bug (ExtJS 3.3) */
        if (!this.list) {
            var cls = 'x-combo-list',
                listParent = Ext.getDom(this.getListParent() || Ext.getBody()),
                zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);

            if (!zindex) {
                zindex = this.getParentZIndex();
            }

            this.list = new Ext.Layer({
                parentEl: listParent,
                shadow: this.shadow,
                cls: [cls, this.listClass].join(' '),
                constrain: false,
                zindex: (zindex || 12000) + 5
            });

            var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
            this.list.setSize(lw, 0);
            this.list.swallowEvent('mousewheel');
            this.assetHeight = 0;
            if (this.syncFont !== false) {
                this.list.setStyle('font-size', this.el.getStyle('font-size'));
            }
            if (this.title) {
                this.header = this.list.createChild({ cls: cls + '-hd', html: this.title });
                this.assetHeight += this.header.getHeight();
            }

            this.innerList = this.list.createChild({ cls: cls + '-inner' });
            this.mon(this.innerList, 'mouseover', this.onViewOver, this);
            this.mon(this.innerList, 'mousemove', this.onViewMove, this);
            if (typeof lw != "string")
                this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));

            if (this.pageSize) {
                this.footer = this.list.createChild({ cls: cls + '-ft' });
                this.pageTb = new Ext.PagingToolbar({
                    store: this.store,
                    pageSize: this.pageSize,
                    renderTo: this.footer
                });
                this.assetHeight += this.footer.getHeight();
            }

            if (!this.tpl) {

                this.tpl = '<tpl for="."><div class="' + cls + '-item">{' + this.displayField + '}</div></tpl>';

            }


            this.view = new Ext.DataView({
                applyTo: this.innerList,
                tpl: this.tpl,
                singleSelect: true,
                selectedClass: this.selectedClass,
                itemSelector: this.itemSelector || '.' + cls + '-item',
                emptyText: this.listEmptyText,
                deferEmptyText: false
            });

            this.mon(this.view, {
                containerclick: this.onViewClick,
                click: this.onViewClick,
                scope: this
            });

            this.bindStore(this.store, true);

            if (this.resizable) {
                this.resizer = new Ext.Resizable(this.list, {
                    pinned: true, handles: 'se'
                });
                this.mon(this.resizer, 'resize', function(r, w, h) {
                    this.maxHeight = h - this.handleHeight - this.list.getFrameWidth('tb') - this.assetHeight;
                    this.listWidth = w;
                    this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
                    this.restrictHeight();
                }, this);

                this[this.pageSize ? 'footer' : 'innerList'].setStyle('margin-bottom', this.handleHeight + 'px');
            }
        }
    },
    initEvents: function() {
        Ext.form.ComboBox.superclass.initEvents.call(this);


        this.keyNav = new Ext.KeyNav(this.el, {
            "up": function(e) {
                this.inKeyMode = true;
                this.selectPrev();
            },

            "down": function(e) {
                if (!this.isExpanded()) {
                    this.onTriggerClick();
                } else {
                    this.inKeyMode = true;
                    this.selectNext();
                }
            },

            "enter": function(e) {
                this.onViewClick();
            },

            "esc": function(e) {
                this.collapse();
            },

            "tab": function(e) {
                 /* change JN */
                if (this.forceSelection === true && !this.view.getSelectionCount()) {
                    this.collapse();
                } else {
                    this.onViewClick(false);
                }
                return true;
            },

            scope: this,

            doRelay: function(e, h, hname) {
                if (hname == 'down' || this.scope.isExpanded()) {

                    var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
                    if (!Ext.isIE && Ext.EventManager.useKeydown) {

                        this.scope.fireKey(e);
                    }
                    return relay;
                }
                return true;
            },

            forceKeyDown: true,
            defaultEventAction: 'stopEvent'
        });
        this.queryDelay = Math.max(this.queryDelay || 10,
                this.mode == 'local' ? 10 : 250);
        this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
        if (this.typeAhead) {
            this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
        }
        if (!this.enableKeyEvents) {
            this.mon(this.el, 'keyup', this.onKeyUp, this);
        }
    },
    // custom function (jn)
    setRecordValue: function(value, display){
        getFieldMappingName = function(field, combo){
            var flds = combo.store.fields,
            i = flds.findIndex("name",field),
            m = flds.items[i].mapping;
            return m;
        }

        var rec = {};
        rec[getFieldMappingName(this.displayField, this)] = display;
        rec[getFieldMappingName(this.valueField, this)] = value;

        var data = {};
        data[this.store.root] = [rec]
        this.store.loadData(data)
        this.setValue(value);
    }
});
Ext.ns('Ext.ux.form');
Ext.ux.form.MaskPatterns = {
    '#': /\d/, 					//	Number
    '_': /[A-Z]|[\xC0-\xFF]/i, 	//	Letter/Accent
    '*': /[A-Z]|[\xC0-\xFF]|\d/i, //	Number/Letter/Accent
    '~': /./							//	Non-line break
}

Ext.override(Ext.form.TextField, {
    convertNumLock: function(code) {
        return code - 48; ;
    },
    enableKeyEvents: true,
    setCaret: function(start, end, input) {
        if (input.setSelectionRange) {
            input.selectionStart = start;
            input.selectionEnd = end;
        } else if (document.selection && document.selection.createRange) {
            var range = input.createTextRange();
            range.collapse(true);
            range.moveStart('character', start);
            range.moveEnd('character', end - start);
            range.select();

        }
    },
    checkCharacter: function(key, maskChar) {
        var patterns = Ext.ux.form.MaskPatterns
        var test = patterns[maskChar] ? patterns[maskChar] : maskChar;
        if (key.search(test) >= 0) {
            return true;
        } else {
            this.markInvalid("Invalid Charactor");
            return false;
        }

    },
    getSelectionRange: function(field) {
        if (!field) return;
        if (!isNaN(field.selectionStart)) {						//	w3c Compliant Browsers
            return { start: field.selectionStart, end: field.selectionEnd };
        } else if (document.selection) {						//	IE (The hard way)
            var r = document.selection.createRange(); 		//	Selection Range
            var a = field.createTextRange(); 				//	Input Text Range
            if (!a.inRange(r)) return null; 					//	Test Ranges
            var s = 0; 										//	Index
            while (a.compareEndPoints('StartToStart', r) < 0) {	//	Find Start Index (TODO: use bineary search)
                s++;
                a.moveStart("character", 1);
            }
            return { start: s, end: s + r.text.length }; 			//	Add Selection length to get end index
        }
        return null;
    },
    showMask: function(e, input) {
        if (input.value.length > 0) return;
        maskArray = this.mask.split("");
        for (var i = 0; i < maskArray.length; i++) {
            maskArray[i] = maskArray[i].replace("#", " ");
        }
        input.value = maskArray.join("");
        this.setCaret(0, 0, input);
    },
    setMaskedValue: function(input, key, e) {
        e.stopEvent();

        var value = input.value;
        var l = value.length;

        var range = this.getSelectionRange(input);
        if (range.start != range.end) range.end -= 1;

        var values = value.split("");
        var masks = this.mask.split("");
        var isDate = this.mask == "##/##/####";
        var valid = false;
        for (var i = 0; i < masks.length; i++) {
            var isValue = Ext.ux.form.MaskPatterns[this.mask.charAt(i)] != undefined;
            var v = values[i];
            if (isDate && i == range.start && key == "/" && false) {
                var array = this.checkDateMonth(key, value, range)
                value = array[0];
                range = array[1];
                values = value.split("");
                i++;
            } else if (isValue && i >= range.start && i <= range.end) {
                if (i == range.start) {
                    valid = this.checkCharacter(key, this.mask.charAt(range.start));
                    if (valid) v = key;
                } else {
                    v = " ";
                }
            } else if (!isValue) {
                v = masks[i];
                if (i == range.start) valid = key == this.mask[i];
            }
            values[i] = v;
        }
        while (range.start < input.value.length && Ext.ux.form.MaskPatterns[this.mask.charAt(range.start + 1)] == undefined) {
            range.start += 1;
            if (range.end <= range.start) range.end += 1;
        }
        if (valid) {
            input.value = values.join("");
            if (range.start == range.end) range.end += 1;
            range.start += 1;
            this.setCaret(range.start, range.end, input);
        } else {
            this.setCaret(range.start, range.end, input);
        }
    },
    removeWithMask: function(start, end, input, e) {
        e.stopEvent();
        var value = input.value;
        if (start == 0 && end == value.length) {
            input.value = "";
            this.showMask({}, input);
            return;
        }
        if ((e.getKey() == e.BACKSPACE || e.getKey() == e.DELETE) && end > start) {
            end -= 1;
        }
        if (e.getKey() == e.BACKSPACE && start == end) {
            start -= 1;
        }
        var values = value.split("");
        var masks = this.mask.split("");
        var isDate = this.mask == "##/##/####";
        var valid = false;
        for (var i = 0; i < masks.length; i++) {
            var isValue = Ext.ux.form.MaskPatterns[this.mask.charAt(i)] != undefined
            if (isValue && i >= start && i <= end) {
                values[i] = " ";
            }
        }
        input.value = values.join("");
        if (e.getKey() == e.DELETE) {
            end += 1;
            start = end;
        }
        this.setCaret(start, start, input);
    },
    filterMask: function(e, input) {
        var keyCode = e.getKey();
        if (keyCode >= 96 && keyCode <= 105) keyCode = this.convertNumLock(keyCode);
        var key = String.fromCharCode(keyCode);
        if (input.value.length == 0) {
            this.showMask({}, input)
        }
        if (keyCode == e.TAB || e.ctrlKey) {
            return;
        }
        if (e.keyCode == e.BACKSPACE || e.keyCode == e.DELETE) {
            var range = this.getSelectionRange(input);
            this.removeWithMask(range.start, range.end, input, e);
            return;
        }
        if (Ext.isGecko && (e.isNavKeyPress() || (key == e.DELETE && e.button == -1))) {
            return;
        }
        var cc = String.fromCharCode(e.getCharCode());
        if (!Ext.isGecko && e.isSpecialKey()) {
            return;
        }

        this.setMaskedValue(input, key, e)

    },
    handleMaskedBlur: function(e, input) {
        var removeEmptySpaces = true;
        var value = input.value;
        var values = value.split("");
        var masks = this.mask.split("");
        var empty = true;
        var lastMaskChar = 0;
        for (var i = 0; i < value.length; i++) {
            var isValue = Ext.ux.form.MaskPatterns[this.mask.charAt(i)] != undefined;
            if (isValue) {
                if (values[i].replace(" ", "").length > 0) empty = false;
                if (!empty) break;
            }
        }
        if (empty) input.value = "";
        else input.value = value.replace(/^\s+|\s+$/g, '');
        this.beforeBlur();
    },
    initEvents: function() {
        Ext.form.TextField.superclass.initEvents.call(this);
        if (this.validationEvent == 'keyup') {
            this.validationTask = new Ext.util.DelayedTask(this.validate, this);
            this.mon(this.el, 'keyup', this.filterValidation, this);
        }
        else if (this.validationEvent !== false && this.validationEvent != 'blur') {
            this.mon(this.el, this.validationEvent, this.validate, this, { buffer: this.validationDelay });
        }
        if (this.selectOnFocus || this.emptyText) {
            this.mon(this.el, 'mousedown', this.onMouseDown, this);

            if (this.emptyText) {
                this.applyEmptyText();
            }
        }
        if (this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype + 'Mask']))) {
            this.mon(this.el, 'keypress', this.filterKeys, this);
        }
        if (this.mask) {
            this.mon(this.el, 'keydown', this.filterMask, this);
            this.mon(this.el, 'focus', this.showMask, this);
            this.mon(this.el, 'blur', this.handleMaskedBlur, this);
        }
        if (this.grow) {
            this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, { buffer: 50 });
            this.mon(this.el, 'click', this.autoSize, this);
        }
        if (this.enableKeyEvents) {
            this.mon(this.el, {
                scope: this,
                keyup: this.onKeyUp,
                keydown: this.onKeyDown,
                keypress: this.onKeyPress
            });
        }
    }
})
Ext.override(Ext.form.DateField, {
    mask: '##/##/####',
    checkDateMonth: function(value) {
        var slashes = value.split("/");
        var added = false;
        for (var i = 0; i < slashes.length; i++) {
            var testvalue = slashes[i].replace(" ", "").replace(" ", "");
            switch (i + 1) {
                case 1:
                    if (testvalue.length == 1 && value != 0) {
                        slashes[i] = "0" + testvalue;
                        added = true;
                    }
                    break;
                case 2:
                    if (testvalue.length == 1 && value != 0) {
                        slashes[i] = "0" + testvalue;
                        added = true;
                    }
                    break;
                case 3:
                    break;
            }
        }
        if (added) {
            value = slashes.join("/");
        }
        return value;
    },
    invalidDateText: "Date doesn't exist.",
    validator: function(dtStr) {
        if (dtStr == "" && this.allowBlank || dtStr == "  /  /    " && this.allowBlank)
            return true;


        var reg = /(\d{1,2})[- \/.](\d{1,2})[- \/.]\d\d\d\d/;

        if (reg.test(dtStr)) {


            var dateValue = /(\d{1,2})[- \/.](\d{1,2})[- \/.](\d\d\d\d)/i.exec(dtStr);
            var intMonth = parseInt(dateValue[1], 10);
            var Month = dateValue[1];
            var Day = parseInt(dateValue[2]);
            var Year = parseInt(dateValue[3]);
            if (intMonth > 12 || intMonth <= 0)
                return String.format(this.invalidText, dtStr, this.format);


            if (Month == '2' || Month == '02') {


                if (Day > (((Year % 4 == 0) && ((!(Year % 100 == 0)) || (Year % 400 == 0))) ? 29 : 28))
                    return this.invalidDateText;
            }
            var DaysInMonth = [];
            for (var i = 1; i <= Month; i++) {
                DaysInMonth[i] = 31
                if (i == 4 || i == 6 || i == 9 || i == 11) { DaysInMonth[i] = 30 }
                if (i == 2) { DaysInMonth[i] = 29 }
            }

            if (Day > DaysInMonth[intMonth])

                return this.invalidDateText;

            return true;
        }
        else
            return String.format(this.invalidText, dtStr, this.format);
    },
    beforeBlur: function() {
        var v = this.checkDateMonth(this.getRawValue());
        v = this.parseDate(v);
        if (v) {
            this.setValue(v);
        }
    }

});
Ext.ux.form.HourTimeSecField = Ext.extend(Ext.form.TextField, {
    mask: '##:##:##'
})
Ext.apply(Ext.form.VTypes, {
    daterange: function(val, field) {
        var date = field.parseDate(val);
        if (!field.rendered) return true;
        if (!date) {
            if (field.startDateField) {
                var start = Ext.getCmp(field.startDateField);
                start.setMaxValue();
                start.validate();

            }
            if (field.endDateField) {
                var end = Ext.getCmp(field.endDateField);
                end.setMinValue();
                end.validate();
            }

            return false;
        }
        if (field.startDateField && (!this.dateRangeMax || (date.getTime() != this.dateRangeMax.getTime()))) {
            var start = Ext.getCmp(field.startDateField);
            start.setMaxValue(date);
            start.validate();
            this.dateRangeMax = date;
        }
        else if (field.endDateField && (!this.dateRangeMin || (date.getTime() != this.dateRangeMin.getTime()))) {
            var end = Ext.getCmp(field.endDateField);
            end.setMinValue(date);
            end.validate();
            this.dateRangeMin = date;
        }
        return true;
    }
});

Ext.ns('Ext.ux.helpers');
Ext.ux.helpers.RenderType = function (v, m, rec) {
    if (v.indexOf('organization')) {
        if (rec.data.orgUnitTypeId == 971) {
            v = 'orgUnitLocation';
        }
    }

    return '<span class="people-' + (v || "").replace(/\s/, '') + '"><span class="icon"></span></span>';
}
Ext.ux.helpers.RenderTypeSmall = function (v, m, rec) {
    if (v.indexOf('organization')) {
        if (rec.data.orgUnitTypeId == 971) {
            v = 'orgUnitLocation';
        }
    }

    return '<span class="people-' + (v || "").replace(/\s/, '') + '"><span class="icon-small"></span></span>';
}

//Sharath
Ext.override(Ext.data.Connection, {
    request: function(o){
            var me = this;
            if(me.fireEvent('BEFOREREQUEST', me, o)){
                if (o.el) {
                    if(!Ext.isEmpty(o.indicatorText)){
                        me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
                    }
                    if(me.indicatorText) {
                        Ext.getDom(o.el).innerHTML = me.indicatorText;
                    }
                    o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
                        Ext.getDom(o.el).innerHTML = response.responseText;
                    });
                }

                var p = o.params,
                    url = o.url || me.url,
                    method,
                    cb = {success: me.handleResponse,
                          failure: me.handleFailure,
                          scope: me,
                          argument: {options: o},
                          timeout : o.timeout || me.timeout
                    },
                    form,
                    serForm;


                if (Ext.isFunction(p)) {
                    p = p.call(o.scope||WINDOW, o);
                }

                if(o.cancelCallback){
                    cb = {}   
                }

                p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);

                if (Ext.isFunction(url)) {
                    url = url.call(o.scope || WINDOW, o);
                }

                if((form = Ext.getDom(o.form))){
                    url = url || form.action;
                     if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) {
                         return me.doFormUpload.call(me, o, p, url);
                     }
                    serForm = Ext.lib.Ajax.serializeForm(form);
                    p = p ? (p + '&' + serForm) : serForm;
                }

                method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? 'POST' : 'GET');

                if(method === 'GET' && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
                    var dcp = o.disableCachingParam || me.disableCachingParam;
                    url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
                }

                o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});

                if(o.autoAbort === true || me.autoAbort) {
                    me.abort();
                }

                if((method == 'GET' || o.xmlData || o.jsonData) && p){
                    url = Ext.urlAppend(url, p);
                    p = '';
                }
                if (o.scriptTag || this.scriptTag) {
                   this.transId = this.scriptRequest(method, url, cb, p, o);
                } else {
                   this.transId = Ext.lib.Ajax.request(method, url, cb, p, o);
                }
                return this.transId;
            }else{
                return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
            }
    },

    scriptRequest: function (method, url, cb, data, options) {
        var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
        var trans = {
            id: transId,
            cb: options.callbackName || "stcCallback" + transId,
            scriptId: "stcScript" + transId,
            options: options
        };

        url += (url.indexOf("?") != -1 ? "&" : "?") + data + String.format("&{0}={1}", options.callbackParam || 'callback', trans.cb);

        var conn = this;
        window[trans.cb] = function (o) {
            conn.handleScriptResponse(o, trans);
        };

        //Set up the timeout handler
        trans.timeoutId = this.handleScriptFailure.defer(cb.timeout, this, [trans]);

        var script = document.createElement("script");
        script.setAttribute("src", url);
        script.setAttribute("type", "text/javascript");
        script.setAttribute("id", trans.scriptId);
        document.getElementsByTagName("head")[0].appendChild(script);

        return trans;
    },

    handleScriptResponse: function (o, trans) {
        this.transId = false;
        this.destroyScriptTrans(trans, true);
        var options = trans.options;

        //Attempt to parse a string parameter as XML.
        var doc;
        if (typeof o == 'string') {
            if (window.ActiveXObject) {
                var doc = new ActiveXObject("Microsoft.XMLDOM");
                doc.async = "false";
                doc.loadXML(o);
            } else {
                var doc = new DOMParser().parseFromString(o, "text/xml");
            }
        }

        //Create the bogus XHR
        response = {
            responseObject: o,
            responseText: (typeof o == "object") ? Ext.util.JSON.encode(o) : String(o),
            responseXML: doc,
            argument: options.argument
        }
        this.fireEvent("requestcomplete", this, response, options);
        Ext.callback(options.success, options.scope, [response, options]);
        Ext.callback(options.callback, options.scope, [options, true, response]);
    },

    handleScriptFailure: function (trans) {
        this.trans = false;
        this.destroyScriptTrans(trans, false);
        var options = trans.options;
        response = {
            argument: options.argument
        };
        this.fireEvent("requestexception", this, response, options, new Error("Timeout"));
        Ext.callback(options.failure, options.scope, [response, options]);
        Ext.callback(options.callback, options.scope, [options, false, response]);
    },

    // private
    destroyScriptTrans: function (trans, isLoaded) {
        document.getElementsByTagName("head")[0].removeChild(document.getElementById(trans.scriptId));
        clearTimeout(trans.timeoutId);
        if (isLoaded) {
            window[trans.cb] = undefined;
            try {
                delete window[trans.cb];
            } catch (e) { }
        } else {
            // if hasn't been loaded, wait for load to remove it to prevent script error
            window[trans.cb] = function () {
                window[trans.cb] = undefined;
                try {
                    delete window[trans.cb];
                } catch (e) { }
            };
        }
    }
});


if (!window.setShadow) {
    window.setShadow = function () { };
}

if (!window.setHeaderShadow) {
    window.setHeaderShadow = function () { };
}
