Ext.lib.Event.resolveTextNode = Ext.isGecko ? function(node){
	if(!node){
		return;
	}
	var s = HTMLElement.prototype.toString.call(node);
	if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
		return;
	}
	return node.nodeType == 3 ? node.parentNode : node;
} : function(node){
	return node && node.nodeType == 3 ? node.parentNode : node;
};

Ext.override(Ext.data.Connection, {
	    /*// private
    doFormUpload : function(o, ps, url){
		var id = Ext.id();
        var frame = document.createElement('iframe');
        frame.id = id;
        frame.name = id;
        frame.className = 'x-hidden';
        if(Ext.isIE){
            frame.src = Ext.SSL_SECURE_URL;
        }
        document.body.appendChild(frame);

        if(Ext.isIE){
           document.frames[id].name = id;
        }

        var form = Ext.getDom(o.form),
            buf = {
                target: form.target,
                method: form.method,
                encoding: form.encoding,
                enctype: form.enctype,
                action: form.action
            };
        form.target = id;
        form.method = 'POST';
        form.enctype = form.encoding = 'multipart/form-data';
        if(url){
            form.action = url;
        }

        var hiddens, hd;
        if(ps){ // add dynamic params
            hiddens = [];
            ps = Ext.urlDecode(ps, false);
            for(var k in ps){
                if(ps.hasOwnProperty(k)){
                    hd = document.createElement('input');
                    hd.type = 'hidden';
                    hd.name = k;
                    hd.value = ps[k];
                    form.appendChild(hd);
                    hiddens.push(hd);
                }
            }
        }

        function cb(){
            var r = {  // bogus response object
                responseText : '',
                responseXML : null
            };

            r.argument = o ? o.argument : null;

            try { //
                var doc;
                if(Ext.isIE){
                    doc = frame.contentWindow.document;
                }else {
                    doc = (frame.contentDocument || window.frames[id].document);
                }
                if(doc && doc.body){
                    r.responseText = doc.body.innerHTML;
                }
                if(doc && doc.XMLDocument){
                    r.responseXML = doc.XMLDocument;
                }else {
                    r.responseXML = doc;
                }
            }
            catch(e) {
                // ignore
            }

            Ext.EventManager.removeListener(frame, 'load', cb, this);

            this.fireEvent("requestcomplete", this, r, o);

            Ext.callback(o.success, o.scope, [r, o]);
            Ext.callback(o.callback, o.scope, [o, true, r]);

            setTimeout(function(){Ext.removeNode(frame);}, 100);
        }

        Ext.EventManager.on(frame, 'load', cb, this);
        form.submit();
		
        form.target = buf.target;
        form.method = buf.method;
        form.enctype = buf.enctype;
        form.encoding = buf.encoding;
        //form.action = buf.action;
        
        if(hiddens){ // remove dynamic params
            for(var i = 0, len = hiddens.length; i < len; i++){
                Ext.removeNode(hiddens[i]);
            }
        }
    }*/
});

Ext.override(Ext.menu.Menu, {
	onClick : function(e){
		var t = this.findTargetItem(e);
		if(t){
			if(t.menu){
				if (!t.menu.isVisible()) {
					t.expandMenu();
				}
			} else {
				if (t && t.onClick) {
					t.onClick(e);
				}
				this.fireEvent("click", this, t, e);
			}
		}
	}
});

Ext.override(Ext.DataView, {
	getStore : function(){
		return this.store;
	},
	
	selectRecord : function(r) {
		var index = this.store.indexOf(r);
		this.select(index);
	}
});

/*Ext.lib.Ajax.handleTransactionResponse = function(I, J, E) {
	if (!J) {
		this.releaseObject(I);
		return
	}
	var G, F;
	try {
		if (I.conn.status !== undefined && I.conn.status != 0) {
			G = I.conn.status
		} else {
			G = 13030
		}
	} catch(H) {
		G = 13030
	}
	if (G >= 200 && G < 300) {
		F = this.createResponseObject(I, J.argument);
		if (J.success) {
			
			// this lines are new -->
			if (I.conn.responseText) {
				// check if the response is in json format
				if (I.conn.responseText.substr(0, 1) === '{' && I.conn.responseText.substr(-1) === '}') {
					var json = Ext.decode(I.conn.responseText);
					// if it is one of my backend exceptions
					if (!json.success && json.data && json.data.isException) {
						// show the message
						Ext.Msg.alert('Backend-Error', json.data.message);
					}
				}
			}
			// <-- until here
			
			if (!J.scope) {
				J.success(F)
			} else {
				J.success.apply(J.scope, [F])
			}
		}
	} else {
		switch (G) {
		case 12002:
		case 12029:
		case 12030:
		case 12031:
		case 12152:
		case 13030:
			F = this.createExceptionObject(I.tId, J.argument, (E ? E: false));
			if (J.failure) {
				if (!J.scope) {
					J.failure(F)
				} else {
					J.failure.apply(J.scope, [F])
				}
			}
			break;
		default:
			F = this.createResponseObject(I, J.argument);
			if (J.failure) {
				if (!J.scope) {
					J.failure(F)
				} else {
					J.failure.apply(J.scope, [F])
				}
			}
		}
	}
	this.releaseObject(I);
	F = null
};*/

/* window createWindow functionality */
Ext.override(Ext.Window.DD, {
    startDrag : function(){
		var w = this.win;
		w.fireEvent('ghost', []);
		
		if (w && w.winMgr) {
			w.winMgr.each(function(win){
				win.hide();
			});
		}

		this.proxy = w.ghost();
        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])});
        }
		
		
		
		
    },
	
	endDrag : function(e) {
		var w = this.win;
		if (w && w.winMgr) {
			w.winMgr.each(function(win){
				if (win.hidden === true) {
					win.show();	
				}
			});
		}
		
        this.win.unghost();
        this.win.saveState();
	}
});

Ext.override(Ext.BoxComponent, {
    setPosition : function(x, y){
        var oldXY = [this.x, this.y];
		if(x && typeof x[1] == 'number'){
            y = x[1];
            x = x[0];
        }
        this.x = x;
        this.y = y;
        if(!this.boxReady){
            return this;
        }
        var adj = this.adjustPosition(x, y);
        var ax = adj.x, ay = adj.y;

        var el = this.getPositionEl();
        if(ax !== undefined || ay !== undefined){
            if(ax !== undefined && ay !== undefined){
                el.setLeftTop(ax, ay);
            }else if(ax !== undefined){
                el.setLeft(ax);
            }else if(ay !== undefined){
                el.setTop(ay);
            }
            this.onPosition(ax, ay);
            
			var mXY = [oldXY[0] - ax, oldXY[1] - ay];
	
			this.fireEvent('move', this, ax, ay, mXY[0], mXY[1]);
        }
        return this;
    }
});

Ext.override(Ext.Panel, {
	createWindow : function(config, c){
		var allowedCls = [
			'icon-save',
			'icon-add',
			'icon-delete',
			'icon-error',
			'icon-error-add',
			'icon-error-delete'
		];
		if (!c) {
			var cla = Ext.Window;	
		} else {
			var cla = c;	
		}
		// create a window manager and customize events on this panel
		if (!this.winMgr) {
			this.winMgr = new Ext.WindowGroup();
			
			this.on('beforehide', function() {
				this.winMgr.hideAll();
			}.createDelegate(this));
			
			this.on('beforeclose', function() {
				this.winMgr.each(function(win){
					win.close();
				});	
			}.createDelegate(this));

			this.on('activate', function() {
				this.winMgr.each(function(win){
					if (win._isHidden !== true) {
						win.show();
					}
				});	
			}.createDelegate(this));
			
			this.on('move', function(cmp, x, y, mx, my) {
				this.winMgr.each(function(win){
					if (win.fixToParent && win._isHidden !== true) {
						var xy = win.getPosition(true);
						xy[0] -= mx;
						xy[1] -= my;
						
						win.setPosition(xy[0], xy[1]);
						win.doConstrain();
					}
				});
			}.createDelegate(this));
			
		}
		// get loading mask class
		var maskCls = config.iconCls && allowedCls.contains(config.iconCls) ? config.iconCls : 'x-mask-loading';
		// check if modal and mask this panels body only
		modal = false;
		if (config.modal === true) {
			config.modal = false;
			this.body.mask(config.title + '...', maskCls);
			this.winMgr.each(function(win){
				if (!win.modal && !win.ignoreModal) {
					win.body.mask(config.title + '...', maskCls);
				}
			});	
			modal = true;
		}
		
		// check if win exists
		var win = this.winMgr.get(config.id);
		if (!win || !win.body) {
			//config.zIndex = this.zIndex + 1;
			// create a new window
			config.manager = this.winMgr;
			win = new cla(config);	
			win.show();
			
			
			// do unmask on body and panel windows if this was modal window
			win.on('close', function() {
				if (modal === true) {
					this.body.unmask();
					this.winMgr.each(function(win){
						if (!win.modal && !win.ignoreModal) {
							win.body.unmask();
						}
					});	
				}
				this.focus();
			}.createDelegate(this));
			
			win.on('show', function() {
				win.focus();
			}.createDelegate(this));
				
			
			if (config.minimizable) {
				if (this.header) {
					var pWin = this;
					var header = this.header;	
				} else if (this.win && this.win.header) {
					var pWin = this.win;
					var header = this.win.header;
					//var header = this.win.header.first('div.x-tool-minimize');	
				} else {
					var pWin = this;
					var header = this.body;	
				}
				win.on('minimize', function() {
					var btn = new Ext.Button({
						text: '&nbsp;&nbsp;&nbsp;',
						tooltip: win.title,
						iconAlign: 'left',
						iconCls: config.iconCls,
						applyTo: header,
						cls: 'minimized-create-window',
						handler: function() {
							win.show();
							win._isHidden = false;
							btn.destroy();
							pWin.syncShadow();
						}.createDelegate(this)
					});
					/*pWin.addTool({
						//text: config.title,
						id: 'down',
						tooltip: win.title,
						iconAlign: 'left',
						iconCls: config.iconCls,
						//applyTo: header,
						cls: 'minimized-create-window',
						handler: function() {
							win.show();
							win._isHidden = false;
							btn.destroy();
						}.createDelegate(this)
					});*/
					//btn.render(header, tit.id);
					
					win.hide();
					win._isHidden = true;
					
					//alert('min');	
				}.createDelegate(this));
			}
			
			
		} else {
			// show and highlight this existing window
			win.show();
			win.body.highlight();
		}
		
		
		return win;
	}
});

Ext.override(Ext.Window, {
    setZIndex : function(index){
		var newZIndex = index + 1;
		var active = this.manager.getActive();
		if (active === this && this.winMgr) {
			this.winMgr.each(function(win){
				win.hide();
			}.createDelegate(this));
		}
		
		if(this.modal){
            this.mask.setStyle("z-index", index);
        }
        this.el.setZIndex(++index);
        index += 5;

        if(this.resizer){
            this.resizer.proxy.setStyle("z-index", ++index);
        }

		if (newZIndex > this.lastZIndex) {
			this.fireEvent('tofront', this);
		}
		else {
			this.fireEvent('toback', this);
		}
        this.lastZIndex = index;
    }
});

/**
 * @version 0.4
 * @author nerdydude81
 */
Ext.override(Ext.Element, {
    /**
     * @cfg {string} printCSS The file path of a CSS file for printout.
     */
    printCSS: null
    /**
     * @cfg {Boolean} printStyle Copy the style attribute of this element to the print iframe.
     */
    , printStyle: false
    /**
     * @property {string} printTitle Page Title for printout. 
     */
    , printTitle: document.title
    /**
     * Prints this element.
     * 
     * @param config {object} (optional)
     */
    , print: function(config) {
        Ext.apply(this, config);
        
        var el = Ext.get(this.id).dom;
        var c = document.getElementById('printcontainer');
        var iFrame = document.getElementById('printframe');
        
        var strTemplate = '<HTML><HEAD>{0}<TITLE>{1}</TITLE></HEAD><BODY onload="{2}"><DIV {3}>{4}</DIV></BODY></HTML>';
        var strLinkTpl = '<link rel="stylesheet" type="text/css" href="{0}" media="print"/>'
        var strAttr = '';
        var strFormat;
        var strHTML;
        
        //Get rid of the old crap so we don't copy it
        //to our iframe
        if (iFrame != null) c.removeChild(iFrame);
        if (c != null) el.removeChild(c);
        
        //Copy attributes from this element.
        for (var i = 0; i < el.attributes.length; i++) {
            if (Ext.isEmpty(el.attributes[i].value) || el.attributes[i].value.toLowerCase() != 'null') {
                strFormat = Ext.isEmpty(el.attributes[i].value)? '{0}="true" ': '{0}="{1}" ';
                if (this.printStyle? this.printStyle: el.attributes[i].name.toLowerCase() != 'style')
                    strAttr += String.format(strFormat, el.attributes[i].name, el.attributes[i].value);
            }
        }
        
        var strLink ='';
        if(this.printCSS){
            if(!Ext.isArray(this.printCSS))
                this.printCSS = [this.printCSS];
            
            for(var i=0; i<this.printCSS.length; i++) {
				strLink += String.format(strLinkTpl, this.printCSS[i]);
            }
        }
        //Build our HTML document for the iframe
        strHTML = String.format(
                strTemplate
                , strLink
                , this.printTitle
                , Ext.isIE? 'document.execCommand(\'print\');': 'window.print();'
                , strAttr
                , el.innerHTML
        );
        
        //I coun't get FF to print a hidden iframe,
        //so I encapsulated it in a hidden div.
        c = document.createElement('div');
        c.setAttribute('style','width:0px !important;height:0px !important;visibility:hidden !important;');
        c.setAttribute('id', 'printcontainer');
        el.appendChild(c);
        
        //IE doesn't like style attributes anymore?
        if (Ext.isIE)
            c.style.display = 'none';
        
        iFrame = document.createElement('iframe');
        iFrame.setAttribute('id', 'printframe');
        iFrame.setAttribute('name', 'printframe');
        c.appendChild(iFrame);
        
        //Write our new document to the iframe
        iFrame.contentWindow.document.open();        
        iFrame.contentWindow.document.write(strHTML);
        iFrame.contentWindow.document.close();
    }
});

Ext.override(Ext.Component, {
    printEl: function(config) {
        this.el.print(Ext.isEmpty(config)? this.initialConfig: config);
    }
    , printBody: function(config) {
        this.body.print(Ext.isEmpty(config)? this.initialConfig: config);
    }
}); 

/**
 * JS Array extension
 */
Array.prototype.contains = function (elem) {
  var i;
  for (i = 0; i < this.length; i++) {
	if (this[i] == elem) {
	  return true;
	}
  }

  return false;
};

Array.prototype.removeByKey = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Ext.apply(Ext.form.VTypes, {
	password: function(val, field) {
		if (field.initialPassField) {
			var pwd = Ext.getCmp(field.initialPassField);
			return (val == pwd.getValue());
		}
		return true;
	},
	passwordText: 'Passwords do not match',
	
	
	phone: function(val, field) {
		if (Ext.isEmpty(val)) {
			return true;	
		}
		return val.match(/^[\d \+]{5,17}$/i);
	},
	phoneText: 'This phone number should only contain digits and spaces.'
});

Ext.override(Ext.menu.Menu, {
    showAt : function(xy, parentMenu, /* private: */_e){
		this.parentMenu = parentMenu;
        if(!this.el){
            this.render();
        }
        if(_e !== false){
            this.fireEvent("beforeshow", this);
            xy = this.el.adjustForConstraints(xy);
        }
        this.el.setXY(xy);
		
		// get max height from body height minus y cordinate from this.el
		var maxHeight = Ext.getBody().getHeight() - xy[1];
		// store orig element height
		if (!this.el.origHeight) {
			this.el.origHeight = this.el.getHeight();
		}
		// if orig height bigger than max height
		if (this.el.origHeight > maxHeight) {
			// set element with max height and apply scrollbar
			this.el.setHeight(maxHeight);
			this.el.applyStyles('overflow-y:auto;');
		} else {
			// set the orig height
			this.el.setHeight(this.el.origHeight);
		}

		this.el.show();
        this.hidden = false;
        this.focus();
        this.fireEvent("show", this);
    }
}); 

Ext.override(Ext.grid.HeaderDragZone, {
    getDragData : function(e){
        var t = Ext.lib.Event.getTarget(e);
        var h = this.view.findHeaderCell(t);
        if (h && (this.grid.colModel.config[this.view.getCellIndex(h)].dragable !== false)){
            return {ddel: h.firstChild, header:h};
        }
        return false;
    }
});

Ext.override(Ext.layout.CardLayout, {
    setActiveItem : function(item){
        item = this.container.getComponent(item);
        if(this.activeItem != item){
            if (item.rendered && this.animate) {

                Ext.Fx.syncFx();
                if (this.activeItem) {

//                  Correct top position of card because they have to occupy the same space
//                  during animation.
                    var n = item.getEl();
                    n.setStyle({
                        position: 'absolute',
                        top: this.container.getLayoutTarget().getPadding('t') + 'px'
                    });
                    this.activeItem.getEl().fadeOut({
								useDisplay: true,
                        callback: Ext.Component.prototype.hide,
                        scope: this.activeItem
                    });
                }
                this.activeItem = item;
                item.show();
                this.layout();
                n.fadeIn({
                    callback: function() {
                        n.setStyle({
                            position: 'relative'
                        });
                    }
                });
                Ext.Fx.sequenceFx();
            } else {
                if(this.activeItem){
                    this.activeItem.hide();
                }
                this.activeItem = item;
                item.show();
                this.layout();
            }
        }
    }
});

Ext.override(Ext.tree.TreeNode, {
    isChildOf : function(parentNode, childNode){
		// node to search
		var pn = parentNode;
		// search in this node parents
		var cn = childNode || this;
		//console.log(cn);
		//console.log(pn);
		// wemm child node schon gleich parent node, ist es ein Kind
		if (cn === pn) {
			return true;	
		} else {
			// den ersten Parent Node holen
			var npn = cn.parentNode;
			// falls keiner existiert
			if (!npn) {
				return false;	
			}
			// wenn der erste parent node dem gesuchten node entspricht
			if (npn === pn) {
				return true;	
			} else {
				// ansonsten die Funktion rekursiv mit dem nächsten Element aufrufen und Rückgabe durchreichen
				return this.isChildOf(pn, npn);
			}
		}
		return true;
	}
});

Ext.override(Ext.ProgressBar, {
	isPaused : false,
	pausedI : 0,
	
	pause : function(){
		this.isPaused = true;
	},
	
	play : function() {
		this.isPaused = false;
	},
	
    wait : function(o){
        if(!this.waitTimer){
            var scope = this;
            o = o || {};
            this.updateText(o.text);
            this.waitTimer = Ext.TaskMgr.start({
                run: function(i){
					i = i - this.pausedI;
					if (this.isPaused === false) {
						var inc = o.increment || 10;
						this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*.01);
					} else {
						this.pausedI++;
					}
                },
                interval: o.interval || 1000,
                duration: o.duration,
                onStop: function(){
                    if(o.fn){
                        o.fn.apply(o.scope || this);
                    }
                    this.reset();
                },
                scope: scope
            });
        }
        return this;
    }
});


Ext.override(Ext.form.HtmlEditor, {
	markInvalid: function(msg){
		if(!this.rendered || this.preventMark){
			return;
		}
		msg = msg || this.invalidText;
		switch(this.msgTarget){
			case 'qtip':
				this.iframe.qtip = msg;
				this.iframe.qclass = 'x-form-invalid-tip';
				Ext.get(this.iframe).addClass(this.invalidClass);
				
				break;
		}
		return Ext.form.TextArea.superclass.markInvalid.call(this, [msg]);
	},
	clearInvalid: function(){
		if(!this.rendered || this.preventMark){
			return;
		}
		switch(this.msgTarget){
			case 'qtip':
				this.iframe.qtip = '';
				Ext.get(this.iframe).removeClass(this.invalidClass);
				break;
		}
		return Ext.form.TextArea.superclass.clearInvalid.call(this);
	},
	validateValue:function(){
		if(this.allowBlank==false){

			var value =this.getRawValue();
			value = value.replace(/&nbsp;/gi,"");
			value = value.replace(/<br>/gi,"");
			value = value.trim();
			if(value != ''){
				this.clearInvalid();
				return true;
			 }
			else{
				this.markInvalid("This field is required.")
				return false;
				}
		}else{
			this.clearInvalid();
			return true;
		}


	}
});

Ext.form.HtmlEditor.prototype.listeners={ sync: function(t,html){
		t.validateValue();
	}
};
