﻿/*Ext.override(Ext.form.ComboBox, {
	listeners: {
		afterrender: function(component) {
		  component.keyNav.tab = function() {
		    this.onViewClick(false);
		    return true;
		  };
		}
	}
})*/
Ext.form.TimeField.override({
	render: function() {
		this.on("blur", function() {
			var me = this, v = this.getValue();
			if(v != null) {
				switch(typeof v) {
					case "object"://just update the raw value
						this.setRawValue(Ext.Date.format(this.getValue(), "H:i"));
						break;
					case "string"://must parse value
						var values = v.replace(/[^(0-9:\.\,]/,"").split(/[(\.,)]/);
						switch(values[1].length) {
							case 0:
								values[1] = '00';
								break;
							case 1:
								values[1] = values[1] +'0';
								break;
						}
						this.setValue(Ext.String.leftPad(values[0],2,'0')+":"+values[1]);
						break;
				}
			}
		});
		this.callOverridden(arguments);
	}
});
Ext.form.Field.override({
	constructor: function() {
		arguments[0].name = arguments[0].id;
		this.callOverridden(arguments);
	}
});
Ext.form.Trigger.override({
	constructor: function() {
		//if(this.$className != "Ext.ux.form.field.BoxSelect") {
			if(arguments[0].triggerClass != undefined) {
				arguments[0].triggerCls = arguments[0].triggerClass;
				delete arguments[0].triggerClass;
			}
			if(arguments[0].hiddenName != undefined) {
				arguments[0].hiddenNameField = arguments[0].hiddenName;
				delete arguments[0].hiddenName;
			}
		//}
		this.callOverridden(arguments);
	},
	render: function() {
		//if(this.$className != "Ext.ux.form.field.BoxSelect") {
			if(this.initialConfig.hiddenNameField != undefined) {
				var hiddenEl = document.createElement("input");
				hiddenEl.setAttribute("type", "hidden");
				hiddenEl.setAttribute("name", this.initialConfig.hiddenNameField);
				hiddenEl.setAttribute("id", this.initialConfig.hiddenNameField);
				hiddenEl.setAttribute("value", this.initialConfig.value);
				if(!this.initialConfig.forceSelection && this.store.find(this.valueField,this.getValue()) == -1 && this.store.find(this.displayField, this.getRawValue()) == -1) {
					this.setRawValue(this.getValue());
				}
				if(this.initialConfig.rawValue != undefined) {
					this.setRawValue(this.initialConfig.rawValue);
				}
				Ext.get(arguments[0]).insertSibling(hiddenEl);
				this.on("change", function() {
					if(this.store.find(this.valueField,this.getValue()) == -1) {
						var pos = this.store.find(this.displayField, this.getRawValue())
						if(pos > -1) {
							Ext.get(this.initialConfig.hiddenNameField).dom.value = this.store.getAt(pos).get(this.valueField);
						} else {
							if(!this.initialConfig.forceSelection) {
								Ext.get(this.initialConfig.hiddenNameField).dom.value = this.getValue();
							}
						}
					} else {
						Ext.get(this.initialConfig.hiddenNameField).dom.value = this.getValue();
					}
				}, this);
			}
		//}
		this.callOverridden(arguments);
	}
});
Ext.data.ArrayStore.override({
	constructor: function() {
		if(arguments[0].fields != undefined && arguments[0].model == undefined) {
			var modelId = Ext.id();
			Ext.define(modelId, {
				extend: 'Ext.data.Model',
			    fields: arguments[0].fields
			});
			arguments[0].model = modelId;
		}
		this.callOverridden(arguments);
	}
})
Ext.form.ComboBox.override({
	constructor: function() {
		if(arguments[0].hiddenName != undefined) {
			arguments[0].hiddenNameField = arguments[0].hiddenName;
			delete arguments[0].hiddenName;
		}
		if(arguments[0].mode != undefined) {
			arguments[0].queryMode = arguments[0].mode;
			delete arguments[0].mode;
		}
		if(arguments[0].loadingText != undefined) {
			if(arguments[0].listConfig != undefined) {
				arguments[0].listConfig.loadingText = arguments[0].loadingText;
			} else {
				arguments[0].listConfig = {loadingText: arguments[0].loadingText};
			}
			delete arguments[0].loadingText;
		}
		if(arguments[0].maxHeight != undefined) {
			if(arguments[0].listConfig != undefined) {
				arguments[0].listConfig.maxHeight = arguments[0].maxHeight;
			} else {
				arguments[0].listConfig = {maxHeight: arguments[0].maxHeight};
			}
			delete arguments[0].maxHeight;
		}
		if(arguments[0].itemSelector != undefined) {
			if(arguments[0].listConfig != undefined) {
				arguments[0].listConfig.itemSelector = arguments[0].itemSelector;
			} else {
				arguments[0].listConfig = {itemSelector: arguments[0].itemSelector};
			}
			delete arguments[0].itemSelector;
		}
		if(arguments[0].resizable != undefined) {
			if(arguments[0].listConfig != undefined) {
				arguments[0].listConfig.resizable = arguments[0].resizable;
			} else {
				arguments[0].listConfig = {resizable: arguments[0].resizable};
			}
			delete arguments[0].resizable;
		}
		if(arguments[0].listWidth != undefined) {
			if(arguments[0].listConfig != undefined) {
				arguments[0].listConfig.listWidth = arguments[0].listWidth;
			} else {
				arguments[0].listConfig = {listWidth: arguments[0].listWidth};
			}
			arguments[0].matchFieldWidth = false;
			//delete arguments[0].listWidth;
		}
		if(arguments[0].tpl != undefined) {
			var tpl;
			switch(true) {
				case Ext.isArray(arguments[0].tpl):
					arguments[0].tpl.every(function(v,i,a){
						a[i] = v.replace("x-combo-list-item", "x-boundlist-item");
					});
					tpl = arguments[0].tpl;
					break;
				case typeof arguments[0].tpl == "string" && arguments[0].tpl.replace != undefined:
					tpl = arguments[0].tpl.replace("x-combo-list-item", "x-boundlist-item");
					break;
				case arguments[0].tpl.html != undefined:
					tpl = arguments[0].tpl.html.replace("x-combo-list-item", "x-boundlist-item");
					break;
				default:
					tpl = arguments[0].tpl;
					break;
			}
			
			if(arguments[0].listConfig != undefined) {
				arguments[0].listConfig.getInnerTpl = function() {
					console.log(this.listConfig);
					return this.listConfig.tpl;
				}
				arguments[0].listConfig.tpl = tpl;
			} else {
				arguments[0].listConfig = {
						getInnerTpl: function() {
							console.log(this.listConfig);
							return this.listConfig.tpl;
						},
						tpl: tpl
				}
			}
			delete arguments[0].tpl;
		}
		
		
		
		this.callOverridden(arguments);
	},
	doQuery: function(queryString, forceAll) {
        queryString = queryString || '';
        var me = this,
            qe = {
                query: queryString,
                forceAll: forceAll,
                combo: me,
                cancel: false
            },
            store = me.store,
            isLocalMode = me.queryMode === 'local';
        if (me.fireEvent('beforequery', qe) === false || qe.cancel) {
            return false;
        }
        queryString = qe.query;
        forceAll = qe.forceAll;
        if (forceAll || (queryString.length >= me.minChars)) {
            
            me.expand();

            
            if (!me.queryCaching || me.lastQuery !== queryString) {
                me.lastQuery = queryString;

                if (isLocalMode) {
                	if(store.filters.length == 0 || me.queryFilters) {
	                    if (forceAll) {
	                        store.clearFilter();
	                        me.queryFilters = false;
	                    } else {
	                        
	                        store.clearFilter(true);
	                        store.filter(me.displayField, queryString);
	                        me.queryFilters = true;
	                    }
                	}
                } else {
                    store.load({
                        params: me.getParams(queryString)
                    });
                }
            }

            
            if (me.getRawValue() !== me.getDisplayValue()) {
                me.ignoreSelection++;
                me.picker.getSelectionModel().deselectAll();
                me.ignoreSelection--;
            }

            if (isLocalMode) {
                me.doAutoSelect();
            }
            if (me.typeAhead) {
                me.doTypeAhead();
            }
        }
        return true;
	}
});


Ext.define('Ext.form.ColorPicker', {
	extend: 'Ext.form.field.Picker',
	getValue: function() {
		return this.value || "";
	},
	onExpand: function() {
        var me = this, value = me.getValue();
        if(me.picker.colors.indexOf(value) != -1) {
        	me.picker.select(value);
        }
        me.picker.getEl().dom.style.height = 'auto';
        me.picker.getEl().dom.style.backgroundColor = '#fff';
    },
    onBlur: function() {
    	var me = this;
		if(me.getValue() != me.getRawValue()) {
			me.setValue(me.getRawValue());
		}
    },
    createPicker: function() {
        var me = this, p;
        return Ext.create('Ext.picker.Color', {
            ownerCt: me.ownerCt,
            renderTo: document.body,
            floating: true,
            hidden: true,
            focusOnShow: true,
            listeners: {
                scope: me,
                select: me.onSelect
            },
            keyNavConfig: {
                esc: function() {
                    me.collapse();
                }
            }
        });
	},
	onSelect: function(f, v, o) {
		this.setValue('#'+v);
		return this.picker.hide();
	}
});

Ext.form.Checkbox.override({
	render: function() {
		if(this.initialConfig.id != undefined) {
			this.initialConfig.hiddenNameField = this.initialConfig.id;
			var hiddenEl = document.createElement("input");
			hiddenEl.setAttribute("type", "hidden");
			hiddenEl.setAttribute("name", this.initialConfig.id);
			hiddenEl.setAttribute("id", "_"+this.initialConfig.id);
			hiddenEl.setAttribute("value", this.getValue() ? this.initialConfig.value || "on" : "");
			Ext.get(arguments[0]).insertSibling(hiddenEl);
			this.on("change", function() {
				Ext.get("_"+this.initialConfig.hiddenNameField).dom.value = this.getValue() ? this.initialConfig.value || "on" : "";
			}, this);
		}
		this.callOverridden(arguments);
	}
});




Ext.override(Ext.form.TriggerField, {
	showPreview: false,
	showPreviewCalled: false,
	initComponent: function() {
		this.on("render", function() {
			this.getEl().on("mouseover",this.onShowPreview,this);
			this.getEl().on("mouseout",this.onHidePreview,this);
			this.getEl().on("mousemove",this.updateImagePreview,this);
		});
		Ext.form.TriggerField.superclass.initComponent.call(this, arguments);
	},
	onHidePreview: function() {
		this.showPreview = false;
		this.hideImagePreview.call(this);
	},
	onShowPreview: function(e,t,o) {
		if((typeof this.getValue() == "string" || typeof this.getValue() == "number") && this.getValue() != "" && this.getValue() != undefined && this.getValue() != null) {
			if(this.getValue().length >= 4) {
				switch(this.getValue().substr(-4)) {
					case '.gif':
					case '.jpg':
					case 'jpeg':
					case '.bmp':
					case '.png':
						if(!this.showPreviewCalled) {
							this.showPreviewCalled = true;
							Ext.defer(this.showImagePreview, 500, this,[e,t,o]);
						}
						break;
				}
			}
		}
	},
	showImagePreview: function(e,t,o) {
		if(this.showPreviewCalled) {
			this.showPreview = true;
			
			this.updateImagePreview.call(this,e,t,o);
		}
	},
	updateImagePreview: function(e,t,o) {
		var el = this.getPreviewEl();
		if(this.showPreview) {
			e.xy = this.triggerEl.elements[0].getXY();
			el.style.left = (e.xy[0]+10)+"px";
			el.style.top = (e.xy[1]+10)+"px";
			el.src = this.getValue();
			el.style.display = "";
		} else {
			el.style.display = "none";
		}
	},
	hideImagePreview: function() {
		this.showPreviewCalled = false;
		this.showPreview = false;
		this.updateImagePreview();
	},
	getPreviewEl: function() {
		var el = Ext.get("triggerFieldPreview");
		if(el == null) {
			el = document.createElement("img");
			el.setAttribute("id", "triggerFieldPreview");
			el.setAttribute("style","display:none;position:absolute;border:1px solid black;");
			document.body.appendChild(el);
		} else {
			el = el.dom;
		}
		return el;
	}
});

Ext.override(Ext.menu.Menu, {
    autoWidth : function(){
        var el = this.el, ul = this.ul;
        if(!el){
            return;
        }
        var w = this.width;
        if(w){
            el.setWidth(w);
        }else if(Ext.isIE && (Ext.isIE6 || Ext.isIE7)){
            el.setWidth(this.minWidth);
            var t = el.dom.offsetWidth; // force recalc
            el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));
        }
    }
});

Ext.override(Ext.form.ComboBox, {
	get: function(columnName) {
		var recIndex = this.store.find('ID', this.getValue());
		if(recIndex >= 0) {
			return this.store.getAt(recIndex).get(columnName);
		} else {
			return null;
		}
	}
});
Ext.override(Ext.grid.EditorGridPanel, {
	get: function(columns) {
		var col = columns.split(".");
		var cm = this.getColumnModel();
		var rec = this.getSelectionModel().getSelections();
		if(rec != null) {
			var colEditor = cm.getColumnById(col[0]);
			if(colEditor != null) {
				if(colEditor.editor.field.get != null) {
					var result = new Array();
					var y=0;
					for(var i=0;i<rec.length;i++) {
						var recIndex = colEditor.editor.field.store.find('ID', rec[i].get(col[0]));
						if(recIndex >= 0) {
							result[y] = colEditor.editor.field.store.getAt(recIndex).get(col[1]);
							y++;
						}
					}
					if(result.length == 1) {
						return result[0];
					} else {
						if(result.length > 1) {
							return result;
						}
					}
				}
			}
		}
		return null;
	},
	set: function(columnName, value) {
		var rec = this.getSelectionModel().getSelections();
		if(rec.length > 0) {
			rec[0].set(columnName, value);
			return rec[0];
		}
		return false;
	}
});
/*
Ext.override(Ext.tree.TreeDropZone, {
	completeDrop : function(de){
		var ns = de.dropNode, p = de.point, t = de.target;
		if(!Ext.isArray(ns)){
			ns = [ns];
		}
		var n, node, ins = false;
		if (p != 'append'){
			ins = true;
			node = (p == 'above') ? t : t.nextSibling;
		}
		for(var i = 0, len = ns.length; i < len; i++){
			n = ns[i];
			if (ins){
				t.parentNode.insertBefore(n, node);
			}else{
				t.appendChild(n);
			}
			if(Ext.enableFx && this.tree.hlDrop){
	   		n.ui.highlight();
			}
		}
		ns[0].ui.focus();
		t.ui.endDrop();
		this.tree.fireEvent("nodedrop", de);
	}
	
}); */
/* 
Ext.ux.FixedMultiSelectionModel = Ext.extend(Ext.tree.MultiSelectionModel, {
	// disabled tracking of mouse clicks because it doubles up drag selection...
	onNodeClick : function(node, e){
		if (e.shiftKey) e.preventDefault();
		// this.select(node);
	},

	// private
	// for comparing node order... (taken from quirksmode.org and googlecode)
	compareNodeOrder: document.compareDocumentPosition ?
		function(node1, node2) {
			// W3C DOM lvl 3 method (Gecko)
			return 3 - (node1.ui.elNode.compareDocumentPosition(node2.ui.elNode) & 6);
		} : 
		(typeof document.documentElement.sourceIndex !== "undefined" ? 
			function(node1, node2) {
				// IE source index method
				return node1.ui.elNode.sourceIndex - node2.ui.elNode.sourceIndex;	
			} :
			function(node1, node2) {
				if (node1 == node2) return 0;
				// Safari doesn't support compareDocumentPosition or sourceIndex
				// from http://code.google.com/p/doctype/wiki/ArticleNodeCompareDocumentOrder
				var range1 = document.createRange();
				range1.selectNode(a.ui.elNode);
				range1.collapse(true);

				var range2 = document.createRange();
				range2.selectNode(b.ui.elNode);
				range2.collapse(true);

				return range1.compareBoundaryPoints(Range.START_TO_END, range2);
			}		
		),

	// private
	sortSelNodes: function() {
		if (this.selNodes.length > 1) {
			if (!this.selNodes[0].ui.elNode) return;
			this.selNodes.sort(this.compareNodeOrder);
		}
	},

	// private single point for selectNode
	selectNode: function(node, push) {
		if (!this.isSelected(node)) {
			this.selNodes.push(node);
			this.selMap[node.id] = node;
			node.ui.onSelectedChange(true);
		}
	},

	// overwritten from MultiSelectionModel to fix unselecting...
	select : function(node, e, keepExisting){
		// Add in setting an array as selected... (for multi-selecting D&D nodes)
		if(node instanceof Array){
			for (var c=0;c<node.length;c++) {
				this.selectNode(node[c]);
			}
			this.sortSelNodes();
			this.fireEvent("selectionchange", this, this.selNodes, this.lastSelNode);
			return node;
		}
		// Shift Select to select a range
		// NOTE: Doesn't change lastSelNode
		// EEK has to be a prettier way to do this
		if (e && e.shiftKey && this.selNodes.length > 0) {
			this.lastSelNode = this.lastSelNode || this.selNodes[0];
			var before = this.compareNodeOrder(this.lastSelNode, node) > 0;
			// if (this.lastSelNode == node) {
			// check dom node ordering (from ppk of quirksmode.org)
			this.clearSelections(true);
			var cont = true;
			var inside = false;
			var parent = this.lastSelNode;
			// ummm... yeah don't read this bit...
			do {
				for (var next=parent;next!=null;next=(before?next.previousSibling:next.nextSibling)) {
					// hack to make cascade work the way I want it to
					inside = inside || (before && (next == node || next.contains(node)));
					if (next.isExpanded()) {
						next.cascade(function(n) {
							if (cont != inside) {
								this.selectNode(n);
							}
							cont = (cont && n != node);
							return true;
						}, this);
					} else {
						this.selectNode(next);
						cont = (next != node);
					}
					if (!cont) break;
				}
				if (!cont) break;
				while ((parent = parent.parentNode) != null) {
					if (before) {
						this.selectNode(parent);
					}
					cont = (cont && parent != node);
					if (before && parent.previousSibling) {
						parent = parent.previousSibling;
						break;
					}
					if (!before && parent.nextSibling) {
						parent = parent.nextSibling;
						break;
					}
				}
				if (!cont) break;
			} while (parent != null);
			this.selectNode(node);
			// sort the list
			this.sortSelNodes();
			this.fireEvent("selectionchange", this, this.selNodes, node);
			e.preventDefault();
			return node;
		} else if(keepExisting !== true) {
			this.clearSelections(true);
		}
		if(this.isSelected(node)) {
			// handle deselect of node...
			if (keepExisting === true) {
				this.unselect(node);
				if (this.lastSelNode === node) {
					this.lastSelNode = this.selNodes[0];
				}
				return node;
			}
			this.lastSelNode = node;
			return node;
		}
		// save a resort later on...
		this.selectNode(node);
		this.sortSelNodes();
		this.lastSelNode = node;
		this.fireEvent("selectionchange", this, this.selNodes, this.lastSelNode);
		return node;
	},
	// returns selected nodes precluding children of other selected nodes...
	// used for multi drag and drop...
	getUniqueSelectedNodes: function() {
		var ret = [];
		for (var c=0;c<this.selNodes.length;c++) {
			var parent = this.selNodes[c];
			ret.push(parent);
			// nodes are sorted(?) so skip over subsequent nodes inside this one..
			while ((c+1)<this.selNodes.length && parent.contains(this.selNodes[c+1])) c++;
		}
		return ret;
	},
	
	// check for descendents when nodes are removed...
	unselect: function(node, subnodes) {
		if (subnodes) {
			for (var c=this.selNodes.length-1;c>=0;c--) {
				if (this.selNodes[c].isAncestor(node)) {
					Ext.ux.FixedMultiSelectionModel.superclass.unselect.call(this, this.selNodes[c]);
				}
			}		
		}
		return Ext.ux.FixedMultiSelectionModel.superclass.unselect.call(this, node);
	},
	
    /**
     * Selects the node above the selected node in the tree, intelligently walking the nodes
     * @return TreeNode The new selection
     */
/*    selectPrevious : function(keepExisting){
        var s = this.selNodes[0];
        if(!s){
            return null;
        }
        var ps = s.previousSibling;
        if(ps){
            if(!ps.isExpanded() || ps.childNodes.length < 1){
                return this.select(ps, null, keepExisting);
            } else{
                var lc = ps.lastChild;
                while(lc && lc.isExpanded() && lc.childNodes.length > 0){
                    lc = lc.lastChild;
                }
                return this.select(lc, null, keepExisting);
            }
        } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
            return this.select(s.parentNode, null, keepExisting);
        }
        return null;
    },

    /**
     * Selects the node above the selected node in the tree, intelligently walking the nodes
     * @return TreeNode The new selection
     */
/*    selectNext : function(keepExisting){
        var s = this.selNodes[this.selNodes.length-1];
        if(!s){
            return null;
        }
        if(s.firstChild && s.isExpanded()){
             return this.select(s.firstChild, null, keepExisting);
         }else if(s.nextSibling){
             return this.select(s.nextSibling, null, keepExisting);
         }else if(s.parentNode){
            var newS = null;
            s.parentNode.bubble(function(){
                if(this.nextSibling){
                    newS = this.getOwnerTree().selModel.select(this.nextSibling, null, keepExisting);
                    return false;
                }
            });
            return newS;
         }
        return null;
    },

    onKeyDown : function(e){
        var s = this.selNode || this.lastSelNode;
        // undesirable, but required
        var sm = this;
        if(!s){
            return;
        }
        var k = e.getKey();
        switch(k){
             case e.DOWN:
                 e.stopEvent();
                 this.selectNext(e.shiftKey || e.ctrlKey);
             break;
             case e.UP:
                 e.stopEvent();
                 this.selectPrevious(e.shiftKey || e.ctrlKey);
             break;
             case e.RIGHT:
                 e.preventDefault();
                 if(s.hasChildNodes()){
                     if(!s.isExpanded()){
                         s.expand();
                     }else if(s.firstChild){
                         this.select(s.firstChild, e, e.shiftKey || e.ctrlKey);
                     }
                 }
             break;
             case e.LEFT:
                 e.preventDefault();
                 if(s.hasChildNodes() && s.isExpanded()){
                     s.collapse();
                 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
                     this.select(s.parentNode, e, e.shiftKey || e.ctrlKey);
                 }
             break;
        };
    }
    	
});*/
/*
	Enhanced to support dragging multiple nodes...
	
	for extension refer to data.nodes instead of data.node
	
*/
/*Ext.ux.MultiSelectTreeDragZone = Ext.extend(Ext.tree.TreeDragZone, {
	onBeforeDrag : function(data, e){
		if (data.nodes && data.nodes.length > 0) {
			for (var c=0;c<data.nodes.length;c++) {
				n = data.nodes[c];
				if (n.draggable === false || n.disabled) return false
			}
			return true;
		} else if (data.node) {
			if (data.node.draggable === false || data.node.disabled) return false			
		}
		return false;
		
	},
	// v1.0
	// fixed to handle multiSelectionModel
	// Data now calls SelectionModel.select instead of waiting for the click event
	// Creates Ghost inline rather than calling TreeNodeUI.
	//
	// v1.1
	// cleanup to have ghost generation slightly less hacky... still hacky though...
	// fixes problems with using extra tag nesting in a custom TreeNodeUI.
	getDragData : function(e) {
		// use tree selection model..
		var selModel = this.tree.getSelectionModel();
		// get event target
		var target = Ext.dd.Registry.getHandleFromEvent(e);
		// if no target (die)
		if (target == null) return;
		if (target.node.isSelected() && e.ctrlKey) {
			selModel.unselect(target.node);
			return;
		}
		var selNodes = [];
		if (!selModel.getSelectedNodes) {
			// if not multiSelectionModel.. just use the target...
			selNodes = [target.node];
		} else {
			// if target not selected select it...
			if (!target.node.isSelected() || e.shiftKey) {
				selModel.select(target.node, e, e.ctrlKey);
			}
			// get selected nodes - nested nodes...
			selNodes = selModel.getUniqueSelectedNodes();
		}
		// if no nodes selected stop now...
		if (!selNodes || selNodes.length < 1) return;
		var dragData = { nodes: selNodes };
		// create a container for the proxy...
		var div = document.createElement('ul'); // create the multi element drag "ghost"
		// add classes to keep is pretty...
		div.className = 'x-tree-node-ct x-tree-lines';
		// add actual dom nodes to div (instead of tree nodes)
		var height = 0;
		for(var i = 0, len = selNodes.length; i < len; i++) {
			// add entire node to proxy
			// normally this is done by TreeNodeUI.appendDDGhost(), but overriding that class requires
			// also overriding TreeLoader etc. Ext.extend() is an option though...
			var clonenode = selNodes[i].ui.wrap.cloneNode(true);
			// fix extra indenting by removing extra spacers
			// should really modify UI rendering code to render a duplicate subtree but this is simpler...
			// count current indent nodes from ui indentNode... (add 1 for elbow)
			var subtract = selNodes[i].ui.indentNode.childNodes.length + 1;
			// avoid indent alterations if possible..
			if (subtract > 0) {
				// relies on node ui using the same tag for all elems...
				var subNodes = Ext.query(selNodes[i].ui.indentNode.nodeName+".x-tree-node-indent", clonenode);
				for (var c=0,clen=subNodes.length;c<clen;c++) {
					var inode = subNodes[c];
					var current = inode.childNodes.length;
					if (current <= subtract) {
						inode.innerHTML = "";
						// remove elbow icon as well..
						if (current < subtract) inode.parentNode.removeChild(subNodes[c].nextSibling);
					} else {
						for (var r=0;r<subtract;r++) {
							subNodes[c].removeChild(subNodes[c].firstChild);
						}
					}
				}
			}
			div.appendChild(clonenode);
			Ext.fly(clonenode).removeClass(['x-tree-selected','x-tree-node-over']);
		}
		dragData.ddel = div;
		return dragData;
	},
	// fix from TreeDragZone (references dragData.node instead of dragData.nodes)
	onInitDrag : function(e){
		var data = this.dragData;
		this.tree.eventModel.disable();
		this.proxy.update("");
		this.proxy.ghost.dom.appendChild(data.ddel);
		this.tree.fireEvent("startdrag", this.tree, data.nodes, e);
	},
	// Called from TreeDropZone (looks like hack for handling multiple tree nodes)
	getTreeNode: function() {
		return this.dragData.nodes;
	},
	// fix from TreeDragZone (refers to data.node instead of data.nodes)
	// Don't know what this does, so leaving as first node.
	getRepairXY : function(e, data){
		return data.nodes[0].ui.getDDRepairXY();
	},

	// fix from TreeDragZone (refers to data.node instead of data.nodes)
	onEndDrag : function(data, e){
		this.tree.eventModel.enable.defer(100, this.tree.eventModel);
		this.tree.fireEvent("enddrag", this.tree, data.nodes || [data.node], e);
	},

	// fix from TreeDragZone (refers to dragData.node instead of dragData.nodes)
	onValidDrop : function(dd, e, id){
		this.tree.fireEvent("dragdrop", this.tree, this.dragData.nodes, dd, e);
		this.hideProxy();
	},

	// fix for invalid Drop
	beforeInvalidDrop : function(e, id){
		// this scrolls the original position back into view
		var sm = this.tree.getSelectionModel();
		// sm.clearSelections();
		// sm.select(this.dragData.nodes, e, true);
	}

});
*/
/*

MultiSelectTreeDropZone

Contains following fixups

- modified functions to handle multiple nodes in dd operation
	isValidDropPoint
	afterRepair
- modified getDropPoint such that isValidDropPoint can simulate leaf style below inserting.
	Overriding isValidDropPoint affects getDropPoint affects onNodeOver and onNodeDrop

Refer to data.nodes instead of data.node for events..

*/
/*Ext.ux.MultiSelectTreeDropZone = Ext.extend(Ext.tree.TreeDropZone, {

	// fix from TreeDropZone (referred to data.node instead of data.nodes)
	isValidDropPoint : function(n, pt, dd, e, data){
		if(!n || !data) { return false; }
		var targetNode = n.node;
		var dropNodes = data.nodes?data.nodes:[data.node];
		// default drop rules
		if(!(targetNode && targetNode.isTarget && pt)){
			return false;
		}
		if(pt == "append" && targetNode.allowChildren === false){
			return false;
		}
		if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
			return false;
		}
		// don't allow dropping a treenode inside itself...
		for (var c=0;c<dropNodes.length;c++) {
			if(dropNodes[c] && (targetNode == dropNodes[c] || dropNodes[c].contains(targetNode))){
				return false;
			}
		}
		// reuse the object
		var overEvent = this.dragOverData;
		overEvent.tree = this.tree;
		overEvent.target = targetNode;
		overEvent.data = data;
		overEvent.point = pt;
		overEvent.source = dd;
		overEvent.rawEvent = e;
		overEvent.dropNode = dropNodes;
		overEvent.cancel = false;
		var result = this.tree.fireEvent("nodedragover", overEvent);
		return overEvent.cancel === false && result !== false;
	},

	// override to allow insert "below" when leaf != true...
	getDropPoint : function(e, n, dd, data){
		var tn = n.node;
		if(tn.isRoot){
			return this.isValidDropPoint(n, "append", dd, e, data)? "append" : false;
		}
		var dragEl = n.ddel;
		var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
		var y = Ext.lib.Event.getPageY(e);
		var noAppend = tn.allowChildren === false || tn.isLeaf() || !this.isValidDropPoint(n, "append", dd, e, data);
		if(!this.appendOnly && tn.parentNode.allowChildren !== false){
			var noBelow = false;
			if(!this.allowParentInsert){
				noBelow = tn.hasChildNodes() && tn.isExpanded();
			}
			var q = (b - t) / (noAppend ? 2 : 3);
			if(y >= t && y < (t + q) && this.isValidDropPoint(n, "above", dd, e, data)){
				return "above";
			}else if(!noBelow && (noAppend || y >= b-q && y <= b) && this.isValidDropPoint(n, "below", dd, e, data)){
				return "below";
			}
		}
		return noAppend? false: "append";
	},

	// Override because it calls getDropPoint and isValidDropPoint
	onNodeOver : function(n, dd, e, data){
		var pt = this.getDropPoint(e, n, dd, data);
		var node = n.node;

		if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
			this.queueExpand(node);
		}else if(pt != "append"){
			this.cancelExpand();
		}

		var returnCls = this.dropNotAllowed;
		if(pt){
			var el = n.ddel;
			var cls;
			if(pt == "above"){
				returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
				cls = "x-tree-drag-insert-above";
			}else if(pt == "below"){
				returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
				cls = "x-tree-drag-insert-below";
			}else{
				returnCls = "x-tree-drop-ok-append";
				cls = "x-tree-drag-append";
			}
			if(this.lastInsertClass != cls){
				Ext.fly(el).replaceClass(this.lastInsertClass, cls);
				this.lastInsertClass = cls;
			}
		}
		return returnCls;
	},

	// Override because it calls getDropPoint and isValidDropPoint
	onNodeDrop : function(n, dd, e, data){
		var point = this.getDropPoint(e, n, dd, data);
		var targetNode = n.node;
		targetNode.ui.startDrop();
		if(point === false) {
			targetNode.ui.endDrop();
			return false;
		}

		var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
		var dropEvent = {
			tree : this.tree,
			target: targetNode,
			data: data,
			point: point,
			source: dd,
			rawEvent: e,
			dropNode: dropNode,
			cancel: !dropNode,
			dropStatus: false
		};
		var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
		if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
			targetNode.ui.endDrop();
			return dropEvent.dropStatus;
		}

		targetNode = dropEvent.target;
		if(point == "append" && !targetNode.isExpanded()){
			targetNode.expand(false, null, function(){
				this.completeDrop(dropEvent);
			}.createDelegate(this));
		}else{
			this.completeDrop(dropEvent);
		}
		return true;
	},

	// fix from TreeDropZone (referred to data.node instead of data.nodes)
	afterRepair : function(data){
		if(data && Ext.enableFx){
			var nl = data.nodes?data.nodes:[data.node];
			for (var c=0,len=nl.length;c<len;c++) {
				nl[c].ui.highlight();
			}
		}
		this.hideProxy();
	},

	// handle allowContainerDrop (appends nodes to the root node)
	onContainerDrop : function(dd, e, data) {
		if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
			var targetNode = this.tree.getRootNode();		
			targetNode.ui.startDrop();
			var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, "append", e) : null);
			var dropEvent = {
				tree : this.tree,
				target: targetNode,
				data: data,
				point: "append",
				source: dd,
				rawEvent: e,
				dropNode: dropNode,
				cancel: !dropNode,
				dropStatus: false
			};
			var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
			if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
				targetNode.ui.endDrop();
				return dropEvent.dropStatus;
			}
	
			targetNode = dropEvent.target;
			if(!targetNode.isExpanded()){
				targetNode.expand(false, null, function(){
					this.completeDrop(dropEvent);
				}.createDelegate(this));
			}else{
				this.completeDrop(dropEvent);
			}
			return true;
		}
		return false;
	},
	
	// handle allowContaineDrop (treat as a drop to the root node)
	onContainerOver : function(dd, e, data) {
		if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
			return this.dropAllowed;
		}
		return this.dropNotAllowed;
	}

});

/*

	MultiSelectTreePanel

	sets up using FixedMultiSelectionModel
	and initing with extended DragZone and DropZone by default

*/
/*
Ext.ux.MultiSelectTreePanel = Ext.extend(Ext.tree.TreePanel, {

	getSelectionModel : function(){
		if(!this.selModel){
			this.selModel = new Ext.ux.FixedMultiSelectionModel();
		}
		return this.selModel;
	},

	initEvents: function() {
		if((this.enableDD || this.enableDrop) && !this.dropZone){
			this.dropZone = new Ext.ux.MultiSelectTreeDropZone(this, this.dropConfig || {
								ddGroup: this.ddGroup || "TreeDD",
								appendOnly: this.ddAppendOnly === true
							});
		}
		if((this.enableDD || this.enableDrag) && !this.dragZone){
			this.dragZone = new Ext.ux.MultiSelectTreeDragZone(this, {
								ddGroup: this.ddGroup || "TreeDD",
								scroll: this.ddScroll
							});
		}
		Ext.ux.MultiSelectTreePanel.superclass.initEvents.apply(this, arguments);

		// This is temporary. Should really Ext.extend on TreeNode.removeChild()
		// and call getOwnerTree().removeNode(node) or similar...

		this.on("remove", function(tree, parent, node) {
			tree.getSelectionModel().unselect(node, true);
		});
	}
});

Ext.reg('multiselecttreepanel', Ext.ux.MultiSelectTreePanel);
*/

/*Ext.override(Ext.form.DateField, {
	initEvents: function() {
		Ext.form.NumberField.superclass.initEvents.call(this);
		this.menuListeners.select = function() {
			this.setValue(arguments[1]);
			if(this.events.select != null) { 
				if(this.events.select.listeners != null) {
					if(this.events.select.listeners[0] != null) {
						if(this.events.select.listeners[0].fireFn != null) {
							this.events.select.listeners[0].fireFn(); 
						}
					}
				}
			} 
		}
	}
});
*/
/*Ext.override(Ext.grid.CellSelectionModel, {
	onEditorKey : function(field, e){
		if(field.parseValue != null) {
			field.value = field.getValue();
			field.setRawValue(field.getValue());
			field.parseValue(field.getValue());
		}
		var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
		var shift = e.shiftKey;
		if(k == e.TAB){
			e.stopEvent();
			ed.completeEdit();
			if(shift){
				newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
			}else{
				newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
			}
		}else if(k == e.ENTER || k == e.UP || k == e.DOWN){
			e.stopEvent();
			ed.completeEdit();
			if(this.moveEditorOnEnter !== false){
				if(shift && k == e.ENTER || k == e.UP){
					newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
				}else{
					newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
				}
			}
		}else if(k == e.ESC){
			ed.cancelEdit();
		}
		if(newCell){
			g.startEditing(newCell[0], newCell[1]);
		}
	}
});*//*

Ext.grid.GroupSummary = function(config){
    Ext.apply(this, config);
};

Ext.extend(Ext.grid.GroupSummary, Ext.util.Observable, {
    init : function(grid){
        this.grid = grid;
        this.cm = grid.getColumnModel();
        this.view = grid.getView();

        var v = this.view;
        v.doGroupEnd = this.doGroupEnd.createDelegate(this);

        v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
        v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
        v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);
        v.afterMethod('onUpdate', this.doUpdate, this);
        v.afterMethod('onRemove', this.doRemove, this);

        if(!this.rowTpl){
            this.rowTpl = new Ext.Template(
                '<div class="x-grid3-summary-row" style="{tstyle}">',
                '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
                    '<tbody><tr>{cells}</tr></tbody>',
                '</table></div>'
            );
            this.rowTpl.disableFormats = true;
        }
        this.rowTpl.compile();

        if(!this.cellTpl){
            this.cellTpl = new Ext.Template(
                '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
                '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on">{value}</div>',
                "</td>"
            );
            this.cellTpl.disableFormats = true;
        }
        this.cellTpl.compile();
    },

    toggleSummaries : function(visible){
        var el = this.grid.getGridEl();
        if(el){
            if(visible === undefined){
                visible = el.hasClass('x-grid-hide-summary');
            }
            el[visible ? 'removeClass' : 'addClass']('x-grid-hide-summary');
        }
    },

    renderSummary : function(o, cs){
        cs = cs || this.view.getColumnData();
        var cfg = this.cm.config;

        var buf = [], c, p = {}, cf, last = cs.length-1;
        for(var i = 0, len = cs.length; i < len; i++){
            c = cs[i];
            cf = cfg[i];
            p.id = c.id;
            p.style = c.style;
            p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
            if(cf.summaryType || cf.summaryRenderer){
                p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
            }else{
                p.value = '';
            }
            if(p.value == undefined || p.value === "") p.value = "&#160;";
            buf[buf.length] = this.cellTpl.apply(p);
        }

        return this.rowTpl.apply({
            tstyle: 'width:'+this.view.getTotalWidth()+';',
            cells: buf.join('')
        });
    },

    calculate : function(rs, cs){
        var data = {}, r, c, cfg = this.cm.config, cf;
        for(var j = 0, jlen = rs.length; j < jlen; j++){
            r = rs[j];
            for(var i = 0, len = cs.length; i < len; i++){
                c = cs[i];
                cf = cfg[i];
                if(cf.summaryType){
                    data[c.name] = Ext.grid.GroupSummary.Calculations[cf.summaryType](data[c.name] || 0, r, c.name, data);
                }
            }
        }
        return data;
    },

    doGroupEnd : function(buf, g, cs, ds, colCount){
        var data = this.calculate(g.rs, cs);
        buf.push('</div>', this.renderSummary({data: data}, cs), '</div>');
    },

    doWidth : function(col, w, tw){
        var gs = this.view.getGroups(), s;
        for(var i = 0, len = gs.length; i < len; i++){
            s = gs[i].childNodes[2];
            s.style.width = tw;
            s.firstChild.style.width = tw;
            s.firstChild.rows[0].childNodes[col].style.width = w;
        }
    },

    doAllWidths : function(ws, tw){
        var gs = this.view.getGroups(), s, cells, wlen = ws.length;
        for(var i = 0, len = gs.length; i < len; i++){
            s = gs[i].childNodes[2];
            s.style.width = tw;
            s.firstChild.style.width = tw;
            cells = s.firstChild.rows[0].childNodes;
            for(var j = 0; j < wlen; j++){
                cells[j].style.width = ws[j];
            }
        }
    },

    doHidden : function(col, hidden, tw){
        var gs = this.view.getGroups(), s, display = hidden ? 'none' : '';
        for(var i = 0, len = gs.length; i < len; i++){
            s = gs[i].childNodes[2];
            s.style.width = tw;
            s.firstChild.style.width = tw;
            s.firstChild.rows[0].childNodes[col].style.display = display;
        }
    },

    // Note: requires that all (or the first) record in the 
    // group share the same group value. Returns false if the group
    // could not be found.
    refreshSummary : function(groupValue){
        return this.refreshSummaryById(this.view.getGroupId(groupValue));
    },

    getSummaryNode : function(gid){
        var g = Ext.fly(gid, '_gsummary');
        if(g){
            return g.down('.x-grid3-summary-row', true);
        }
        return null;
    },

    refreshSummaryById : function(gid){
        var g = document.getElementById(gid);
        if(!g){
            return false;
        }
        var rs = [];
        this.grid.store.each(function(r){
            if(r._groupId == gid){
                rs[rs.length] = r;
            }
        });
        var cs = this.view.getColumnData();
        var data = this.calculate(rs, cs);
        var markup = this.renderSummary({data: data}, cs);

        var existing = this.getSummaryNode(gid);
        if(existing){
            g.removeChild(existing);
        }
        Ext.DomHelper.append(g, markup);
        return true;
    },

    doUpdate : function(ds, record){
        this.refreshSummaryById(record._groupId);
    },

    doRemove : function(ds, record, index, isUpdate){
        if(!isUpdate){
            this.refreshSummaryById(record._groupId);
        }
    },

    showSummaryMsg : function(groupValue, msg){
        var gid = this.view.getGroupId(groupValue);
        var node = this.getSummaryNode(gid);
        if(node){
            node.innerHTML = '<div class="x-grid3-summary-msg">' + msg + '</div>';
        }
    }
});

Ext.grid.GroupSummary.Calculations = {
    'sum' : function(v, record, field){
        return v + (record.data[field]||0);
    },

    'count' : function(v, record, field, data){
        return data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
    },

    'max' : function(v, record, field, data){
        var v = record.data[field];
        var max = data[field+'max'] === undefined ? (data[field+'max'] = v) : data[field+'max'];
        return v > max ? (data[field+'max'] = v) : max;
    },

    'min' : function(v, record, field, data){
        var v = record.data[field];
        var min = data[field+'min'] === undefined ? (data[field+'min'] = v) : data[field+'min'];
        return v < min ? (data[field+'min'] = v) : min;
    },

    'average' : function(v, record, field, data){
        var c = data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
        var t = (data[field+'total'] = ((data[field+'total']||0) + (record.data[field]||0)));
        return t === 0 ? 0 : t / c;
    }
}

Ext.grid.HybridSummary = Ext.extend(Ext.grid.GroupSummary, {
    calculate : function(rs, cs){
        var gcol = this.view.getGroupField();
        var gvalue = rs[0].data[gcol];
        var gdata = this.getSummaryData(gvalue);
        return gdata || Ext.grid.HybridSummary.superclass.calculate.call(this, rs, cs);
    },

    updateSummaryData : function(groupValue, data, skipRefresh){
        var json = this.grid.store.reader.jsonData;
        if(!json.summaryData){
            json.summaryData = {};
        }
        json.summaryData[groupValue] = data;
        if(!skipRefresh){
            this.refreshSummary(groupValue);
        }
    },

    getSummaryData : function(groupValue){
        var json = this.grid.store.reader.jsonData;
        if(json && json.summaryData){
            return json.summaryData[groupValue];
        }
        return null;
    }
});

Ext.override(Ext.grid.GridPanel, { 
	GridUpdateStore : function(obj) {
		this.store.load({
			params: Ext.decode("{\"filter\": \""+obj.filter+"\",\"filterValue\": \""+obj.value+"\"," + Ext.encode(this.store.lastOptions.params).substr(1))
		});
	},	
	Criterias : {
		currentFilters : new Array(),
		add: function(pId, pColumn, pOperator, pValue) {
			this.currentFilters[this.currentFilters.length] = {id: pId, column: pColumn, operator: pOperator, value: pValue};
		},
		remove: function(pId) {
			for(x in this.currentFilters) {
				if(this.currentFilters[x].id == pId) {
					this.currentFilters[x] = this.currentFilters[this.currentFilters.length];
					this.currentFilters.length--;
				}
			}
		},
		clear: function() {
			this.currentFilters = new Array();
		},
		getById: function(pId) {
			for(x in this.currentFilters) {
				if(this.currentFilters[x].id == pId) {
					return this.currentFilters[x];
				}
			}
			return null;
		},
		update: function() {
			updateStore();
		}
	},
	getSum: function(colName) {
		var sum=0,value=null;
		for(var i=0;i<this.store.data.items.length;i++) {
			value = parseFloat(this.store.getAt(i).get(colName));
			if(!isNaN(value)) {
				sum+=value;
			}
		}
		return sum;
	},
	getAverage: function(colName) {
		var sum=0,value=null;
		for(var i=0;i<this.store.data.items.length;i++) {
			value = parseFloat(this.store.getAt(i).get(colName));
			if(!isNaN(value)) {
				sum+=value;
			}
		}
		return sum/this.store.data.items.length;
	},
	getMin: function(colName) {
		var minValue=null,newValue=null;
		for(var i=0;i<this.store.data.items.length;i++) {
			newValue = parseFloat(this.store.getAt(i).get(colName));
			if(!isNaN(newValue)) {
				if(minValue == null) {
					minValue = newValue;
				} else {
					if(minValue > newValue) {
						minValue = newValue;
					}
				}
			}
		}
		return minValue;
	},
	getMax: function(colName) {
		var maxValue=null,newValue=null;
		for(var i=0;i<this.store.data.items.length;i++) {
			newValue = parseFloat(this.store.getAt(i).get(colName));
			if(!isNaN(newValue)) {
				if(maxValue == null) {
					maxValue = newValue;
				} else {
					if(maxValue < newValue) {
						maxValue = newValue;
					}
				}
			}
		}
		return maxValue;
	},
	getCount: function() {
		return this.store.data.items.length;
	}
});

Ext.namespace('Ext.ux');

Ext.ux.FCKEditor = function(config) {
	Ext.apply(this, config);
	if(config.renderTo != null) {
		this.render(config.renderTo);
	}
}
Ext.override(Ext.ux.FCKEditor, {
	render: function(el) {
		var div = null;
		switch(typeof el) {
			case 'string':
				div = document.getElementById(el);
				break;
			case 'object':
				div = el;
				break;
			default:
				break;
		}
		if(div != null) {
			var fck = new FCKeditor((this.name || this.id));
			fck.BasePath = (this.BasePath || "http://shared.beezilla.com/libs/htmleditor/fckeditor/") ;
			fck.Height = (this.height || 450);
			fck.Width = (this.width || 450);
			fck.Config['ImageUpload'] = true;
			filepath = window.parent.location.href;
			locationpath = filepath.split('/');
			fck.Config['SkinPath'] = filepath.substring(0,filepath.lastIndexOf(locationpath[locationpath.length-1])) +'../../libs/htmleditor/fckeditor/editor/skins/office2003/';
			fck.Config['AutoDetectLanguage'] = true;
			fck.ToolbarSet = 'Backoffice';

			if(this.value != null) {
				fck.Value = this.value;
			} else {
				fck.Value = '';
			}
			div.innerHTML = fck.CreateHtml();
		}
	},
	setValue: function(v) {
		if(this.fck == null) {
			var fckEditor = FCKeditorAPI.GetInstance(this.id);
			Ext.apply(this, {fck: fckEditor});
		}
		this.fck.SetHTML(v);
	},
	getValue: function() {
		return this.fck.GetHTML();
	},
	setHeight: function() {
		
	},
	setWidth: function() {
		
	}
});



*/
Ext.ux.Toolbar = function(config) {
 
    // call parent constructor
    Ext.ux.Toolbar.superclass.constructor.call(this, config);
 
} // end of Ext.ux.Toolbar constructor

Ext.extend(Ext.ux.Toolbar, Ext.Toolbar, {
    toolbarView:null 
}); // end of extend


Ext.ux.Toolbar.Button = function(config){
    Ext.ux.Toolbar.Button.superclass.constructor.call(this, config);
};
/*
Ext.extend(Ext.ux.Toolbar.Button, Ext.Toolbar.Button, {
    toolbarView:null 
}); // end of extend
*/
/*Ext.ux.HourField = function(config) {
    Ext.ux.HourField.superclass.constructor.call(this, config);
};*/

Ext.ux.HourField = Ext.extend(Ext.form.NumberField, {
    hoursPerDay : 7.5 ,
    getNumberOfDays : function(){
        if (this.rendered) {
            return Math.round(parseFloat(parseFloat(this.getValue().toString().replace(",", ".")) / this.hoursPerDay) * 100) / 100;
        } else {
            return "";
        }
    }
}); // end of extend


Ext.override(Ext.form.NumberField, {
	initEvents : function() {
        Ext.form.NumberField.superclass.initEvents.call(this);
        var allowed = "\-0123456789";
        if(this.allowDecimals){
            allowed += ".,";
            //allowed += this.decimalSeparator;
        }
        if(this.allowNegative){
            allowed += "-";
        }
        this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
        var keyPress = function(e){
            var k = e.getKey();
            if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
                return;
            }
            var c = e.getCharCode();
            if(allowed.indexOf(String.fromCharCode(c)) === -1){
                e.stopEvent();
            }
        };
        this.el.on("keypress", keyPress, this);
		this.el.on("blur", function() {
			value = this.getValue().toString().replace(",", ".");
			value = String(value).replace(this.decimalSeparator, ".");
			value = parseFloat(value);
			
			value = parseFloat(String(value).replace(this.decimalSeparator, "."));
			this.setRawValue(isNaN(value) ? '' : value.toFixed(this.decimalPrecision));
		}, this);
	},
	parseValue : function(value){
        value = parseFloat((value == null || value == undefined ? "" : value.toString()).replace(",", ".").replace(this.decimalSeparator, "."));

		
        return isNaN(value) ? '' : value;
    }
});


Ext.override(Ext.ux.HourField, {
  initEvents : function(){
        Ext.form.NumberField.superclass.initEvents.call(this);
        var allowed = "0123456789jd";
        if(this.allowDecimals){
            allowed += ".,";
            //allowed += this.decimalSeparator;
        }
        if(this.allowNegative){
            allowed += "-";
        }
        this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
        var keyPress = function(e){
            var k = e.getKey();
            if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
                return;
            }
            var c = e.getCharCode();
            if(allowed.indexOf(String.fromCharCode(c)) === -1){
                e.stopEvent();
            }
        };
        this.el.on("keypress", keyPress, this);
    },
    parseValue : function(value){
        var s = value.toString();
        value = value.toString().replace(",", ".");
        value = String(value).replace(this.decimalSeparator, ".");
        value = String(value).replace("j", "");
        value = String(value).replace("d", "");
        value = parseFloat(value);
        
        if (s.charAt(s.length -1) == "j" || s.charAt(s.length -1) == "d") {
            value = value * this.hoursPerDay;          
        }
    
        value = parseFloat(String(value).replace(this.decimalSeparator, "."));
        return isNaN(value) ? '' : value;
    }
});


Ext.ux.TimeField = function(config) {
    Ext.ux.TimeField.superclass.constructor.call(this, config);
};

Ext.extend(Ext.ux.TimeField, Ext.form.TextField, {
    startTime : '8:00',
    endTime : '17:00',
    timeFormat: 'H:m',
	validationEvent: false,
	listeners: {'blur': function() {
		this.validate();
	}}
}); // end of extend

Ext.override(Ext.ux.TimeField, {

    initEvents : function(){
        Ext.form.TextField.superclass.initEvents.call(this);
        if(this.validationEvent == 'keyup'){
            this.validationTask = new Ext.util.DelayedTask(this.validate, this);
            this.el.on('keyup', this.filterValidation, this);
        }
        else if(this.validationEvent !== false){
            this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
        }
        if(this.selectOnFocus || this.emptyText){
            this.on("focus", this.preFocus, this);
            if(this.emptyText){
                this.on('blur', this.postBlur, this);
                this.applyEmptyText();
            }
        }
        if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
            this.el.on("keypress", this.filterKeys, this);
        }
        if(this.grow){
            this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
            this.el.on("click", this.autoSize,  this);
        }
        
        var allowed = "0123456789.,:";
        this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
        var keyPress = function(e){
            var k = e.getKey();
            if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
                return;
            }
            var c = e.getCharCode();
            if(allowed.indexOf(String.fromCharCode(c)) === -1){
                e.stopEvent();
            }
        };
        this.el.on("keypress", keyPress, this);
        
    },
    
    validateValue : function(value){    
        
        var s = value;
        s = String(s).replace(".", ":").replace(",", ":");
        if (s.indexOf(":") == -1 && s != "") {
            s += ":00"    
        }
      
        var a = s.split(":");
        if (a.length == 2) {
            if (a[1].toString().length == 1) {
                s += "0";
            } else if (a[1].toString().length == 0) {
                s += "00";
            }
        }
      
        value = s;
            
        if(value.length < 1 || value === this.emptyText){ // if it's blank
             if(this.allowBlank){
                 this.clearInvalid();
                 return true;
             }else{
                 this.markInvalid(this.blankText);
                 return false;
             }
        }
        if(value.length < this.minLength){
            this.markInvalid(String.format(this.minLengthText, this.minLength));
            return false;
        }
        if(value.length > this.maxLength){
            this.markInvalid(String.format(this.maxLengthText, this.maxLength));
            return false;
        }
        if(this.vtype){
            var vt = Ext.form.VTypes;
            if(!vt[this.vtype](value, this)){
                this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
                return false;
            }
        }
        if(typeof this.validator == "function"){
            var msg = this.validator(value);
            if(msg !== true){
                this.markInvalid(msg);
                return false;
            }
        }
        if(this.regex && !this.regex.test(value)){
            this.markInvalid(this.regexText);
            return false;
        }
        
        a = value.split(":");
        if (a.length == 2) {
            if (parseInt(a[0]) < 0 || parseInt(a[0]) > 23) {
                this.markInvalid('Invalid time, hours must be between 0 and 23');
                return false;
            }
            if (parseInt(a[1]) < 0 || parseInt(a[1]) > 59) {
                this.markInvalid('Invalid time, minutes must be between 0 and 59');
                return false;
            }
        }
        
        this.setRawValue(value);
        
        return true;
    }

});
Ext.override(Ext.form.TextField,
{
   selectText : function(start, end){
        var v = this.getRawValue();
        if(v.length > 0){
            start = start === undefined ? 0 : start;
            end = end === undefined ? v.length : end;
            var d = this.el.dom;
            if(d.setSelectionRange){
                d.setSelectionRange(start, end);
            }else if(d.createTextRange){
                var range = d.createTextRange();
                range.moveStart("character", start);
                range.moveEnd("character", end-v.length);
                range.select();
            }
			
			if(Ext.isGecko || Ext.isOpera){
				this.focus();
			}
        }
    }
}
);
Ext.override(Ext.form.DateField, {
  parseDate : function(value){
    //if user enters 0 returns current date (today), 
    //if user enters +7 returns current date + 7 days, 
    //if user enters -7 returns current date - 7 days
	if(value == null) {
		value = "";
	}
    var s = value.toString();
    if (s == "0") {
      value = Ext.Date.clearTime(new Date());
    } else if (s.charAt(0) == "+" && s.length > 1) { 
      value = Ext.Date.clearTime(new Date());
      value = Ext.Date.add(value, "d", parseInt(s.toString().substring(1))); 
    } else if (s.charAt(0) == "-" && s.length > 1) { 
      value = Ext.Date.clearTime(new Date());
      value = Ext.Date.add(value, "d", parseInt(s.toString().substring(1)) * -1);      
    }
     
    if(!value || value instanceof Date){
      return value;
    }
    var v = Ext.Date.parseDate(value, this.format);
    if(!v && this.altFormats){
      if(!this.altFormatsArray){
        this.altFormatsArray = this.altFormats.split("|");
      }
      for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
        v = Ext.Date.parseDate(value, this.altFormatsArray[i]);
      }
    }
    return v;
  }
});

/****
 * Ext.ux.form.TranslationField

 */
Ext.namespace("Ext.ux.form");
Ext.ux.form.TranslationField = function(config) {
    Ext.ux.form.TranslationField.superclass.constructor.apply(this, arguments);        
};

Ext.extend(Ext.ux.form.TranslationField, Ext.form.ComboBox, {
    
    /***
     * trigger classes.
     */
	translationKey: '',
    trigger1Class: '',            
    trigger2Class: 'x-form-translate-trigger',
	tmpVal : null,
	tmpLng : null,
    /***
     * initComponent
     */
    initComponent : function(){
        Ext.ux.form.TranslationField.superclass.initComponent.call(this);
		
        /***
         * @event translate
         * @param {field: Ext.ux.form.TranslationField, button: Ext.Element}
         * fires when 2nd trigger is clicked
         */
        this.addEvents({translate : true});
		this.addEvents({change: true});
		this.tpl = new Ext.XTemplate(
				'<tpl for=".">',
					'<div class="language" style="padding-5px;font-weight:bold; /*\*/height: 35px;/**/ min-height: 35px; overflow: auto;">{text:this.getLanguage}<br/><span style="font-weight:normal;">{text:this.getValue}</span></div>',
				'</tpl>',
				{	
					parentCmb: this,
					
					getLanguage: function(val) {
						switch(arguments[1].Value) {
							case 'fr': 
								return 'Francais';	
								break;
							case 'en':
								return 'English';
								break;
							case 'es':
								return 'Espanol';
								break;
							default:
								return arguments[1].Value;
						}
						
					},
					getLanguageCode: function(lng) {
						switch(lng) {
							case 'Francais': 
								return 'fr';	
								break;
							case 'English':
								return 'en';
								break;
							case 'Espanol':
								return 'es';
								break;
							default:
								return lng;
						}
					},
					getValue: function(val) {
						if(this.parentCmb.tmpLng != null) {
							this.parentCmb.tmpLng = this.parentCmb.getValue().substr(0,2);
							this.parentCmb.tmpVal = this.parentCmb.getRawValue();
							this.parentCmb.languageValues.setValue(this.parentCmb.tmpLng, this.parentCmb.tmpVal);
						}
						//setting tmp values
						this.parentCmb.tmpVal = this.parentCmb.getRawValue();
						this.parentCmb.tmpLng = this.parentCmb.getValue().substr(0,2);
						//inserting value in cmb
						this.parentCmb.setRawValue(this.parentCmb.languageValues.getValue(this.parentCmb.tmpLng));
						val = this.parentCmb.languageValues.getValue(this.getLanguageCode(arguments[1].Value));
						return val;
						//return this.parentCmb;
					}
				}
			);
		//creating up the store
		var vdata = Array();
		var i = 0;
		for(x in this.languageValues) {
			if(x.length == 2) {
				vdata[i] = [x, ''];
				i++;
			}
		}
		
		
		
		
		this.triggerAction = 'all';
		this.typeAhead = false;
		this.forceSelection = false;
		this.disableKeyFilter = true;
		this.mode = 'local';
		this.displayField = 'Name'; 
		this.valueField = 'Value';
		this.store = new Ext.data.SimpleStore({
						fields: ['Value', 'Name'],
						data : vdata
					});
		this.itemSelector = 'div.language';
//        this.addEvents({blur: true});
        // implement triggerConfig from Ext.form.TwinTriggerField
        this.triggerConfig = {
            tag:'span', cls:'x-form-twin-triggers', cn:[
            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
        ]};
		this.on('select', function() {
			this.tmpLng = this.getValue().substr(0,2);
			this.setRawValue(this.languageValues.getValue(this.tmpLng));
			this.setHiddenValue();
		});
		//	this.on('render', function getStore items... tableau object
		this.on('blur', function() { 
			this.tmpLng = this.getValue().substr(0,2);
			this.tmpVal = this.getRawValue();
			this.languageValues.setValue(this.tmpLng, this.tmpVal)
			this.setHiddenValue();
		});
		this.on('render', function() {
			this.setHiddenValue();
		});
		this.on('translate', function() {
			showTranslationDialog(this.translationKey, this.translationType, Ext.encode(this.languageValues));
		});
    },
	setHiddenValue : function() {
//		document.getElementById(this.hiddenName).value = Ext.encode({this.translationKey : this.languageValues});
		document.getElementById(this.hiddenName).value = Ext.encode({'translationkey': this.translationKey, 'values': this.languageValues});
	},
    
    /***
     * getTrigger
     * copied from Ext.form.TwinTriggerField
     * @param {Object} index
     */
    getTrigger : function(index){
        return this.triggers[index];
    },
	
	isEmpty : function() {
		for(x in this.languageValues) {
			if(x.length == 2) {
				if(this.languageValues.getValue(x) != "") {
					return false;
				}
			}
		}
		return true;
	},
    /***
     * initTrigger
     * copied from Ext.form.TwinTriggerField
     */
    initTrigger : function(){
        var ts = this.trigger.select('.x-form-trigger', true);
        this.wrap.setStyle('overflow', 'hidden');
        var triggerField = this;
        ts.each(function(t, all, index){
            t.hide = function(){
                var w = triggerField.wrap.getWidth();
                this.dom.style.display = 'none';
                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
            };
            t.show = function(){
                var w = triggerField.wrap.getWidth();
                this.dom.style.display = '';
                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
            };
            var triggerIndex = 'Trigger'+(index+1);

            if(this['hide'+triggerIndex]){
                t.dom.style.display = 'none';
            }
            t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
            t.addClassOnOver('x-form-trigger-over');
            t.addClassOnClick('x-form-trigger-click');
        }, this);
        this.triggers = ts.elements;
    },
    /***
     * onTrigger1Click
     * defer to std ComboBox trigger method
     */
    onTrigger1Click : function() {
		this.fireEvent('blur');
		this.setHiddenValue();
        this.onTriggerClick();    
    },
    /***
     * onTrigger2Click 
     * this is the "add" button handler.  fire 'add' event     
     */
	getValues : function (){
		return this.languageValues;
	},
    onTrigger2Click : function() {
		this.fireEvent('blur');
		showTranslationComboDialog(this.languageValues, this.translationType, this.updateValues, this);
		this.setHiddenValue();
        //this.fireEvent('translate', {field: this, button: this.triggers[1]});        
    },
	updateValues : function(pLanguageValues, scope) {
		//alert(pLanguageValues);
		pLanguageValues = Ext.decode(pLanguageValues);
		for(x in pLanguageValues) {
			scope.languageValues.setValue(x, eval('pLanguageValues.'+x));
		}
		scope.tmpLng = scope.getValue().substr(0,2);
		scope.setRawValue(scope.languageValues.getValue(scope.tmpLng));
		scope.tmpVal = scope.getRawValue();
		scope.setHiddenValue();
		
		//alert(Ext.encode(this.languageValues));
	},
    onChange : function() {
		this.fireEvents('change', {field: this});
	},
	/***
	 * insert
	 * provide a convenience method to insert ONE AND ONLY ONE record to the store.	 	 	 	 
	 * @param {Object} index
	 * @param {Object} data (
	 */
	insert : function(index, data) {
        this.reset();
        
        var rec = new this.store.recordType(data);                
        rec.id = rec.data.id; 
        this.store.insert(index, rec);
		this.setValue(rec.data.id);
		this.fireEvent('select', this, rec, index);        
	}
});
	 
	 
Ext.ux.MyDocumentGridEditor = function(config) {
 
    // call parent constructor
    Ext.ux.MyDocumentGridEditor.superclass.constructor.call(this, config);
 
} // end of Ext.ux.Toolbar constructor

Ext.extend(Ext.ux.MyDocumentGridEditor, Ext.form.TriggerField, {
   displayMode : 'image',
   windowWidth : 800,
   windowHeight : 600,
   onTriggerClick : function() {
		var w = screen.availWidth;
		var y = screen.availHeight;		
		var leftPos = (w - this.windowWidth)/2, topPos = (y - this.windowHeight)/2;
		window.open('/modules/mydocuments/index.php?mode=' + this.displayMode + '&templateid=0&act=link','selectpicture','width=' + this.windowWidth + ',height=' + this.windowHeight + ', top=' + topPos + ', left=' + leftPos);
	   
	}
}); // end of extend




Ext.ux.TranslationLabelEditor = function(config) {
    Ext.ux.TranslationLabelEditor.superclass.constructor.call(this, config);
}

Ext.ux.TranslationLabelEditor = Ext.extend(Ext.ux.TranslationLabelEditor, Ext.form.TriggerField, {
   translationKey: null,
   triggerClass:'x-form-translate-trigger',
   windowWidth : 800,
   windowHeight : 600,
   afterSave : Ext.emptyFn,/*function(trKey) {
	   this.setValue(trKey);
   },*/
   applicationId: null,
   onTriggerClick : function() {
	   if(this.applicationId != null && this.translationKey != null) {
		   window.top.Beezilla.Explorer.showDialog('/plugins/backoffice/modules/controlpanel/translation/edit.php?AppID='+this.applicationId+'&key=' + this.translationKey, 640, 480, 'Edit translation', this.afterSave);
	   }
   },
   setTranslationKey: function(tkey) {
	   this.translationKey = tkey;
   },
   setApplicationId: function(appid) {
	   this.applicationId = appid;
   }
}); // end of extend




Array.prototype.shuffle = function() {
	for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x);
	return this;
}
Ext.ux.TwinTriggerCombo = Ext.extend(Ext.form.ComboBox, {
    initComponent: function() {
        this.triggerConfig = {
            tag:'span', cls:'x-form-twin-triggers', cn:[
            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class},
            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class}
        ]};
        this.onTrigger2Click = this.onTrigger2Click.createInterceptor(function() {
            this.collapse();
        });
        Ext.ux.TwinTriggerCombo.superclass.initComponent.call(this);
    },
    getTrigger: Ext.form.TwinTriggerField.prototype.getTrigger,
    initTrigger: Ext.form.TwinTriggerField.prototype.initTrigger,
    onTrigger2Click: Ext.form.ComboBox.prototype.onTriggerClick,
    trigger1Class: Ext.form.ComboBox.prototype.triggerClass
});
Ext.ux.BrowseDocuments = Ext.extend(Ext.form.TriggerField, {
	initComponent: function() {
	    this.triggerConfig = {
	        tag:'span', cls:'x-form-twin-triggers', cn:[
	        {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class},
	        {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class}
	    ]};
	    this.onTrigger2Click = function() {//outside trigger
	      var div = document.getElementById("__myDocumentsFrame");
	      if(div == null) {
	        var div = document.createElement("div");
	        div.className = "x-hide-display";
	        div.innerHTML = "<iframe src=\"/modules/mydocuments/browser.php?mode=browser&type=attachment\" id=\"__myDocumentsFrame\" style=\"width: 100%; height: 100%;\" frameborder=\"0\"></iframe> ";
	        document.body.appendChild(div);
	      }
	      window['browseDocument'] = this;
	      if(window['myDocumentWindow'] == undefined || window['myDocumentWindow'] == null) {
	        window['myDocumentWindow'] = new Ext.Window({
	          width: 800, 
	          height: 600, 
	          closeAction: 'hide',
	          contentEl: '__myDocumentsFrame',
	          title: 'Mes documents'
	        });
	      }
	      window['myDocumentWindow'].show();
	      if(window['addAttachmentCallback'] == undefined) {
	        window['addAttachmentCallback'] = function(sFileID, sFilename, sFilePath) {
	          window['browseDocument'].setValue(sFilePath+'/'+sFilename);
	          window['myDocumentWindow'].hide();
	        }
	      }
	    };
	    this.onTrigger1Click = function() {//inside trigger
	      if(this.getValue() != "") {
	    	  window.open(this.getValue(), "UXBROWSEDOCUMENTPREVIEW", "width=800,height=600,status=0,resizable=1");
	      }
	    };
	    Ext.ux.BrowseDocuments.superclass.initComponent.call(this);
	},
	trigger1Class: 'triggerFieldDot',
	trigger2Class: 'x-form-search-trigger',
	getTrigger: Ext.form.TwinTriggerField.prototype.getTrigger,
	initTrigger: Ext.form.TwinTriggerField.prototype.initTrigger
});











Ext.ux.TotalHourField = Ext.extend(Ext.ux.HourField, {
    // Prototype Defaults, can be overridden by user's config object
    propA: 1,
    employeField: undefined,
    searchedEmployeField: false,
    totalDays: 0,
    hideTrigger: true,
    daysCountEl: null,
    daysLabel: 'jours',
    initComponent: function(){
        // Called during component initialization
 
        // Config object has already been applied to 'this' so properties can 
        // be overriden here or new properties (e.g. items, tools, buttons) 
        // can be added, eg:
        Ext.apply(this, {
            propA: 3
        });
        // Before parent code
        this.hideTrigger = true;
        // Call parent (required)
        Ext.ux.TotalHourField.superclass.initComponent.apply(this, arguments);
 
        // After parent code
        // e.g. install event handlers on rendered component
    },
    render: function() {
    	this.onRender(arguments[0]);
    },
    // Override other inherited methods 
    onRender: function(){
        // Before parent code
        var el = Ext.get(arguments[0]);
        el.dom.innerHTML = "<table cellpadding='0' cellspacing='0'><tr><td id='"+el.id+"_field'></td><td id='"+el.id+"_daysCount' style='padding-left:2px;'>0.00</td><td>&nbsp;"+this.daysLabel+"</td></tr></table>";
		arguments[0] = Ext.get(el.id+"_field");
		this.daysCountEl = el+"_daysCount";
        // Call parent (required)
        Ext.ux.TotalHourField.superclass.onRender.apply(this, arguments);
        if(this.hideTrigger) {
        	this.spinUpEl.dom.style.display = 'none';
        	this.spinDownEl.dom.style.display = 'none';
        }
 		
        // After parent code
    },
    setValue: function() {
    	Ext.ux.TotalHourField.superclass.setValue.apply(this, arguments);
    	this.updateTotalDaysCount();
    	
    },
    updateTotalDaysCount: function() {
    	nbrHoursPerDay = this.getHoursPerDayFromEmploye();
    	if(nbrHoursPerDay != null) {
    		var el = Ext.get(this.daysCountEl);
    		if(el != null) {
	    		if(nbrHoursPerDay > 0) {
	    			this.totalDays = this.getValue() / nbrHoursPerDay;
	    		} else {
	    			this.totalDays = 0;
	    		}
    			el.dom.innerHTML = this.totalDays.toFixed(2);
    		}
    	}
    },
    getHoursPerDayFromEmploye: function() {
    	if(this.employeField == undefined && !this.searchedEmployeField) {
	    	listOfPossibleEmployeFields = ['ctlEmployeID', 'ctlEmploye', 'cboEmploye', 'cboEmployeID'];
	    	for(var i=0;i<listOfPossibleEmployeFields.length && (this.employeField = Ext.getCmp(listOfPossibleEmployeFields[i])) == undefined;i++) {}
	    	this.searchedEmployeField = true;
	    }
	    if(this.searchedEmployeField && this.employeField != undefined) {
	    	var pos = this.employeField.store.find(this.employeField.valueField, this.employeField.getValue());
	    	if(pos >= 0) {
	    		var rec = this.employeField.store.getAt(pos);
	    		hoursPerDay = undefined;
	    		listOfPossibleEmployeHoursPerDayField = ['HoursPerDay', 'HourPerDay'];
	    		for(var i=0;i<listOfPossibleEmployeHoursPerDayField.length && hoursPerDay == undefined;i++) {
	    			if(rec.get(listOfPossibleEmployeHoursPerDayField[i]) != "") {
	    				hoursPerDay = rec.get(listOfPossibleEmployeHoursPerDayField[i]);
	    			}
	    		}
	    		return hoursPerDay == undefined ? null : hoursPerDay;
	    	}
	    }
	    
    },
    getDaysCount: function() {
    	return this.totalDays.toFixed(2);
    }
});
 
// register xtype to allow for lazy initialization
//Ext.define("Ext.ux.TotalHourField", Ext.ux.TotalHourField);
//Ext.define("totalhourfield", Ext.ux.TotalHourField);



Ext.ux.TreeCombobox = Ext.extend(Ext.form.ComboBox, {
	initComponent: function() {
		Ext.applyIf(this, {
			triggerAction: 'all',
			mode: 'local',
			listHeight: 200,
			multipleSelection: true,
			treePanelClicked: false,
			selectedItems: this.value != "" && this.value != undefined ? this.value.split(",") : [],
			selectedItemsText: [],
			hiddenId: this.hiddenName || '_'+this.id,
			selectNode: undefined
		});
		this.value = '';
		this.editable = false;
		this.tpl = '<tpl><div style="height:'+this.listHeight+'px" id="__tv_'+this.id+'"></div></tpl>';
		this.on('afterrender',function(){
			var onClickItem = function(node, checked) {
				if(this.multipleSelection === true) {
					if(typeof checked === "boolean") {//checkchange
						if(checked) {
							this.selectedItems[this.selectedItems.length] = node.attributes.value;
							this.selectedItemsText[this.selectedItemsText.length] = node.attributes.text;
						} else {
							var bFound = false;
							for(var i=0;i<this.selectedItems.length && !bFound;i++) {
								if(this.selectedItems[i] == node.attributes.value) {
									this.selectedItems.remove(this.selectedItems[i]);
									this.selectedItemsText.remove(this.selectedItemsText[i]);
									bFound = true;
								}
							}
						}
						
					}
				} else {
					this.selectedItems[0] = node.attributes.value;
					this.selectedItemsText[0] = node.attributes.text;
				}
				this.setHiddenValue(this.selectedItems.join(","));
				this.setRawValue(this.selectedItemsText.join(", "));
				this.treePanelClicked = true;
			}
			var onCancelCollapse = function() {
				this.treePanelClicked = true;
			}
			var getChildItem = function(parentId, parentNode) {
				if(parentId == '' && parentNode.attributes.rootNode !== true) {
					return;
				}
				for(var dataIndex = 0; dataIndex < this.store.data.length;dataIndex++) {
					var i = dataIndex;
					if(this.store.data.items[i].get(this.parentField) == parentId) {
						var selectNode = false;
						var treeNodeConfig = {
								id: 'tn_'+this.store.data.items[i].get(this.valueField),
								value: this.store.data.items[i].get(this.valueField), 
								text: this.store.data.items[i].get(this.displayField)
							};
						if(this.multipleSelection === true) {
							treeNodeConfig.checked = false;
							var bFound = false;
							for(var y=0;y<this.selectedItems.length && !bFound;y++) {
								if(this.selectedItems[y] == this.store.data.items[i].get(this.valueField)) {
									this.selectedItemsText[this.selectedItemsText.length] = this.store.data.items[i].get(this.displayField);
									treeNodeConfig.checked = true;
									bFound = true;
								}
							}
						} else {
							if(this.selectedItems[0] == this.store.data.items[i].get(this.valueField)) {
								selectNode = true;
								this.selectedItemsText[0] = this.store.data.items[i].get(this.displayField);
							}
						}
						Ext.applyIf(treeNodeConfig, this.store.data.items[i].data);
						var node = new Ext.tree.TreeNode(treeNodeConfig);
						if(selectNode) {this.selectNode = node;}
						parentNode.appendChild(node);
						getChildItem.call(this, this.store.data.items[i].get(this.valueField), node);
						node.on('beforeexpand', onCancelCollapse, this);
						node.on('beforecollapse', onCancelCollapse, this);
					}
				}
			}
			var rootNode = new Ext.tree.TreeNode({text: 'test', rootNode: true});
			var treePanel = new Ext.tree.TreePanel({
				id: 'tv_'+this.id,
				border: false,
				rootVisible: false,
				root: rootNode
			});
			treePanel.on('click', onClickItem, this);
			treePanel.on('checkchange', onClickItem, this);
			treePanel.on('beforeexpand', onCancelCollapse, this);
			treePanel.on('beforecollapse', onCancelCollapse, this);
			treePanel.on('expandnode',function(node) {this.treePanelClicked = false; if(this.selectNode !== undefined && node == this.selectNode) {this.selectNode.select();}},this);
			rootNode.on('beforeexpand', onCancelCollapse, this);
			rootNode.on('beforecollapse', onCancelCollapse, this);
			getChildItem.call(this,'',rootNode);
			this.setHiddenValue(this.selectedItems.join(","));
			this.setRawValue(this.selectedItemsText.join(", "));
			this.on('expand', function() {
				var treePanel = Ext.getCmp('tv_'+this.getId());
				if(!treePanel.rendered) {
					treePanel.render('__tv_'+this.getId());
					treePanel.expandAll();
				}
				//Ext.get("tv_"+this.getId()).dom.style.height = treePanel.getHeight();
			});
		});
		this.on('collapse', function() {
			if(this.treePanelClicked) {
				this.expand();
				this.treePanelClicked = false;
			}
		});
		Ext.ux.TreeCombobox.superclass.initComponent.call(this,arguments);
	}
	,onRender: function(a,b) {
		Ext.ux.TreeCombobox.superclass.onRender.call(this,a,b);
	}
	,getValue: function() {
		return this.selectedItems.join(',');
	}
	,setHiddenValue: function(v) {
		//console.log(v);
		Ext.get(this.hiddenId).dom.value = v;
	}
});

