String.prototype.repeat = function(l){
	return new Array(l+1).join(this);
};
Array.prototype.inArray = function(value) {
	for (var i = 0; i < this.length; i++) {
	  if (this[i] == value) return true;
	}
	return false;
}
Array.prototype.unique = function() {
	var u = [];
	for (var i = 0; i < this.length; i++) {
	  if (!u.inArray(this[i])) u.push(this[i]);
	}
	return u;
}


function amount_out(v, decimals, thousand) {
	if (typeof v == 'undefined' || v === '') return '';
	if (typeof decimals != 'number') decimals = 2;
	var roundFactor = Math.pow(10, decimals);
  v = (Math.round((v-0)*roundFactor))/roundFactor;
  v = String(v);
  var ps = v.split('.');
  var whole = ps[0];
  var sub = decimals > 0 ? TGSystem.decSep+(ps[1] ? ps[1]+("0").repeat(decimals-ps[1].length) : ("0").repeat(decimals)): '';
  if (thousand !== false && TGSystem.thousandSep) {
	  var r = /(\d+)(\d{3})/;
  	while (r.test(whole)) {
    	  whole = whole.replace(r, '$1' + TGSystem.thousandSep + '$2');
	  }
	}
  v = whole + sub;
  return v;
}
function amount_in(amount) {
  amount = amount + '';
  var re = new RegExp('\\' + TGSystem.thousandSep, 'g');
  amount = amount.replace(re, '');
  var re = new RegExp('\\' + TGSystem.decSep, 'g');
  amount = amount.replace(re, '.');
  amount = amount * 1;
  return amount;
}


function bid_amount_out(amount) {
	return amount_out(amount, 0);
}
function bid_amount_in(amount) {
	return amount_in(amount);
}

formSetDefault = function(form) {
	var el;
	for (i = 0; i < form.elements.length; i++) {
		el = form.elements[i];
		if (el.tagName == 'INPUT') {
		  if (el.type == 'radio' || el.type == 'checkbox') {
		    el.defaultChecked = el.checked;
		  } else {
		    el.defaultValue = el.value;
		  }
		}
	}
}
formIsDirty = function(form) {
	var el;
	var dirty = false;
	for (i = 0; i < form.elements.length; i++) {
		el = form.elements[i];
		if (el.tagName == 'INPUT') {
		  if (el.type == 'radio' || el.type == 'checkbox') {
		    if (el.defaultChecked != el.checked) dirty = true;
		  } else {
		    if (el.defaultValue != el.value) dirty = true;
		  }
		}
	}
	return dirty;
}

handleJSONResponse = function(success, response, msgTitle) {
  if (success == false) {
		Ext.Msg.hide();
    //alert('A communication error occured.');
    return false;
  }
  try {
	  var json = response.responseText;
	  result = Ext.util.JSON.decode(json);
  } catch(e) {
		Ext.Msg.hide();
    alert('A communication error occured:\n\n'+response.responseText);
    return false;
  }
  if (result.success == false && result.errDesc) {
		Ext.Msg.hide();
    Ext.Msg.alert(msgTitle || '', result.errDesc);
    return false;
  }
  return result;
}

handleFormSubmitError = function(f, a, config) {
	config = config || {};
	Ext.Msg.hide();
	if (a && a.result && a.result.errDesc) Ext.Msg.alert(config.title || '', a.result.errDesc);
	if (config.debug === true) {
	  alert(a.response.responseText);
	}
}

function createCookie(name, value, days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  } else {
    var expires = "";
  }
  document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
  var ca = document.cookie.split(';');
  var nameEQ = name + "=";
  for(var i=0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1, c.length); //delete spaces
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
  }
  return null;
}

function eraseCookie(name) {
  createCookie(name, "", -1);
}

//EXT manipulation

Ext.BLANK_IMAGE_URL = TGSystem.baseDir+'js/ext-1.1/resources/images/default/s.gif';

Ext.WizardPanel = function(form, config, help) {
	config = config || {};
	Ext.apply(config, {fitToFrame: true});
	Ext.WizardPanel.superclass.constructor.call(this, Ext.id(), config);
	this.form = form;
	this.config = config;
	this.help = help;
	this.rendered = false;
	if (!config.delayRender) {
	  this.renderPanel();
	}
};
Ext.extend(Ext.WizardPanel, Ext.ContentPanel,{
	renderPanel: function() {
	  if (this.rendered) return;
	  var form = this.form;
		var config = this.config;
		var help = this.help;
		var width = config.dlgWidth-200;
		var height = config.dlgHeight-200;
		var html =	'<div id="{0}">'+
	              	'<div id="{1}" style="padding: 10px;">'+
	                	'<div id="{2}">'+
		                '</div>'+
	                '</div>'+
	              	'<div id="{3}" style="padding: 10px;">'+
	                '</div>'+
								'</div>';
		var template = new Ext.DomHelper.Template(html);
		var layoutId = Ext.id(), centerId = Ext.id(), formId = Ext.id(), eastId = Ext.id();
		template.append(this.getId(),[layoutId, centerId, formId, eastId]);
		layoutConfig = {
		    center: {
		        titlebar: true,
		        margins: {top: 1, right: 1, bottom: 1, left: 1}
		      }
			 };
		if (help) {
		  layoutConfig.east =  {
	        titlebar: true,
		      margins: {top: 1, right: 1, bottom: 1, left: 1},
		      initialSize: 400,
					collapsible: true,
					collapsed: true
		  	};
		}
		this.layout = new Ext.BorderLayout(layoutId, layoutConfig);
		this.layout.beginUpdate();
		var title = config.title
		this.layout.add('center', new Ext.ContentPanel(centerId, {
		    title: title, fitToFrame: true
		  }));
		if (help) {
			var helpPanel = this.layout.add('east', new Ext.ContentPanel(eastId, {
			    title: 'Help', fitToFrame: true, autoScroll: true
			  }));
			helpPanel.setContent(help);
		}
		this.layout.endUpdate();
		form.render(formId);
		form.items.each(function(item) {
				item.on('blur', this.validate, this);
			}, this);
		this.rendered = true;
	},
	onActivate: function() {
	  if (!this.rendered) this.renderPanel();
	},
	getForm: function(){
		return this.form;
	},
	validate: function() {
	  var errs = new Array();
	  this.form.items.each(function(item) {
	      if (item.el.hasClass(item.invalidClass)) {
					errs.push({fieldLabel: item.fieldLabel, qtip: item.errorIcon.dom.qtip, tab: this, field: item});
				}
	    }, this);
		var valid = errs.length == 0 ? true : false;
    if (valid && this.markedInvalid) {
			this.setTitle(this.originalTitle)
			this.markedInvalid = false;
		} else if(!valid && !this.markedInvalid) {
	    this.originalTitle = this.title;
	    this.setTitle('<span style="color: #ff0000;">' + this.title + '</div>');
			this.markedInvalid = true;
		}
		return errs;
	}
});

Ext.Wizard = function (el, dlgConfig, config){
	if (dlgConfig.center === undefined){
		dlgConfig.center = {
				autoScroll:true
			};
	}

	var addConfig = {
	    alwaysShowTabs: true
	  }
	Ext.apply(dlgConfig, addConfig);

  this.items = new Ext.util.MixedCollection(false, function(o){
      return o.id || (o.id = Ext.id());
  });

  Ext.Wizard.superclass.constructor.call(this, el, dlgConfig);
  this.events={
	"activate":true,
	"deactivate":true,
	"cancel":true,
	"finish":true
  };
  Ext.apply(this, config);
	this.init();
}
Ext.extend(Ext.Wizard , Ext.LayoutDialog, {
	cancelButtonText : "Cancel",
	nextButtonText : "Next",
	previousButtonText : "Previous",
	finishButtonText : "Finish",
	validationErrTitle : "Formularen indeholder fejl",
	validationErrLine1 : "Dine data blev ikke gemt, da formularen indeholder en eller flere fejl.",
	validationErrLine2 : "De faneblade der indeholder fejl er markeret med <span style=\"color: #ff0000;\">rød</span>.",

		init:function(){
		  this.getEl().addClass('x-wizard');
			this.addKeyListener(27, this.cancel, this);
			this.addButton(this.cancelButtonText, this.cancel, this);
			this.btnPrev = this.addButton(this.previousButtonText, this.previousStep, this);
			this.btnNext = this.addButton(this.nextButtonText, this.nextStep, this);
			this.btnFinish = this.addButton(this.finishButtonText, this.finish, this);
			this.initSteps();
			//this.on('beforeshow', this.beforeShow, this);
			this.tabs = this.getLayout().getRegion('center').getTabs();
			if (this.tabs) {
				this.tabs.activate(this.tabs.items[0].id);
				this.tabs.on("tabchange",this.tabChange, this);
				this.tabs.on("beforetabchange", this.beforeTabChange, this);
			}
			this.toggleButtons();
		},
		initSteps : function() {
			var layout = this.getLayout();
			layout.beginUpdate();
			Ext.each(this.steps, this.createStep.createDelegate(this, layout, true),this);
			var center = layout.getRegion('center');
			var centerSize = center.tabs.bodyEl.getSize(true);
			center.panels.each(function(panel) {
			    if (panel.rendered) {
				    if (panel.getEl()) panel.getEl().setSize(centerSize.width, centerSize.height-27);
				    panel.layout.layout();
				  }
			  });
			layout.endUpdate();
		},
		createStep : function(step, index, array, layout){
			Ext.apply(step.config, {autoCreate: true, delayRender:index >100});
			var panel = layout.add('center', new Ext.WizardPanel(step.form, step.config, step.help));
			panel.on('activate', panel.onActivate, panel);
			panel.form.items.each(function(item) {
			    this.items.add(Ext.id(), item);
				}, this);
		},
		updateSteps : function(steps) {
		  var center = this.layout.getRegion('center');
			center.panels.each(function(panel) {
		      center.remove(panel);
		    });
		  this.items = new Ext.util.MixedCollection(false, function(o){
		      return o.id || (o.id = Ext.id());
		  });
		  this.steps = steps;
		  this.initSteps();
			this.tabs = this.getLayout().getRegion('center').getTabs();
			this.tabs.on("tabchange",this.tabChange, this);
			this.tabs.on("beforetabchange", this.beforeTabChange, this);
			this.tabs.activate(this.tabs.items[0].id);
		},
		beforeShow: function() {
	    Ext.Wizard.superclass.beforeShow.call(this);
		  this.enableButtons();
		  if (this.requireStepThrough) {
				this.btnFinish.disable();
				this.tabs.items[this.requireStepThrough].on('activate', this.btnFinish.enable, this.btnFinish, {single: true});
		  }
		},
		beforeTabChange:function(panel, e, newtab){
			var lastForm = this.getLayout().getRegion('center').getActivePanel().getForm();
			if (!lastForm.isValid()) e.cancel = true;
		},
		tabChange:function(panel, tab){
		  this.validate();
			this.toggleButtons();
		},
		addElements:function(form,elements){
		   for(var el in elements){
				fel=  new Ext.form.TextField({
						name: el,
						value:elements[el],
						hidden:true
					})
				form.add(fel);
			}
		},
		getValues:function(){
			var params = {};
			this.items.each(function(item) {
					var name = item.getName(), v;
					if (name) {
						v = item.getValue();
						if (v instanceof Date) v = v.format('Y-m-d');
						params[name] = v;
					}
			  });
			return params;
		},
		toggleButtons:function(){
			var index = this.getTabIndex();
			var cnt;
			if (this.tabs) cnt = this.tabs.items.length;
			else cnt = 1;
			this.btnPrev.setDisabled(index == 0);
			this.btnNext.setDisabled(index == cnt - 1);
			return;
			if (index == cnt - 1)
				this.btnFinish.enable();
			else
				this.btnFinish.disable();
		},
		getTabIndex:function(tab){
		  if (!this.tabs) return 0;
			if (!tab) tab = this.tabs.getActiveTab();
			return this.tabs.items.indexOf(tab);
		},
		activateNextStep:function(next){
			var index = this.getTabIndex();
			if (next){
				index++;
			} else {
				index--;
			}
			if (this.tabs.items[index]) this.tabs.activate(this.tabs.items[index].id);
		},
		nextStep:function(){
			this.activateNextStep(true);
		},
		previousStep:function(){
			this.activateNextStep(false);
		},
		cancel:function(){
			this.fireEvent("cancel", this);
		},
		finish:function(){
			this.fireEvent("finish", this);
		},
		findField : function(id) {
        var field = this.items.get(id);
        if(!field){
            this.items.each(function(f){
                if(f.isFormField && (f.dataIndex == id || f.id == id || f.id == id || f.getName() == id)){
                    field = f;
                    return false;
                }
            });
        }
        return field || null;
		},
		setButtonsDisabled: function(bool) {
			Ext.each(this.buttons, function(btn) {
			    btn.setDisabled(bool);
				}, this);
		  this.toggleButtons();
		},
		disableButtons: function() {
		  this.setButtonsDisabled(true);
		},
		enableButtons: function() {
		  this.setButtonsDisabled(false);
		},
		submit : function(config) {
		  this.disableButtons();
	    this.layout.getRegion('center').panels.each(function(panel) {
	        panel.form.clearInvalid();
	      });
		  var params = this.getValues();
			var con = new Ext.data.Connection();
			con.request({
			    url: config.url,
			    method: 'post',
			    params: params,
					callback: function(options, success, response) {
					    var result = handleJSONResponse(success, response);
					    if (result && result.success) {
					      if (typeof config.success == 'function') config.success(result);
							} else {
							  if (typeof result.errors == 'object') {
							    this.layout.getRegion('center').panels.each(function(panel) {
							        panel.form.markInvalid(result.errors);
							      });
							  }
							  this.validate();
					      if (typeof config.failure == 'function') config.failure(result);
							  this.enableButtons();
							}
					  },
					scope: this
			  });
		},
		validate: function() {
		  var valid = true;
		  var allErrs = new Array();
		  this.layout.getRegion('center').panels.each(function(panel) {
		      var errs = panel.validate();
		      if (errs.length > 0) {
						valid = false;
						allErrs = allErrs.concat(errs);
					}
		    });
			if (!valid) {
			  var text = this.validationErrLine1+'<br><br>'+this.validationErrLine2+'<br><br>';
			  var labelId;
			  var gotoArray = new Array();
			  for (i = 0; i < allErrs.length && i < 3; i++) {
			    labelId = Ext.id();
			    gotoArray.push({labelId: labelId, tab: allErrs[i].tab, field: allErrs[i].field});
			    text += '<br><div style="cursor: pointer;" id="'+labelId+'"><b>'+allErrs[i].fieldLabel+':</b><br>'+allErrs[i].qtip+'</div>';
			  }
		    Ext.QuickTipsEdit.register({
		        target: this.layout.getRegion('center').getTabs().bodyEl,
		        title: this.validationErrTitle,
		        text: text,
		        position: 'br-br',
		        width: 200
		      });
				Ext.each(gotoArray, function(item) {
				    var el = Ext.get(item.labelId);
				    el.on('click', function() {
				        this.tabs.activate(item.tab.el.id);
				        item.field.focus();
				      }, this);
				  }, this);
		  }
		},
		isDirty: function() {
		  var dirty = false;
		  this.layout.getRegion('center').panels.each(function(panel) {
		      if (panel.form.isDirty()) {
						dirty = true;
						return false;
					}
		    });
			return dirty;
		},
		destroy: function() {
		  this.layout.getRegion('center').panels.each(function(panel) {
		      panel.destroy();
		    });
		  Ext.Wizard.superclass.destroy.call(this);
		}
});




Ext.QuickTipsEdit = function(){
    var el, tipBody, tipBodyText, tipTitle, tm, cfg, close, tagEls = {}, esc, removeCls = null, bdLeft, bdRight;
    var ce, bd, xy, dd;
    var visible = false, disabled = true, inited = false;
    var showProc = 1, hideProc = 1, dismissProc = 1, locks = [];

    var onOver = function(e){
        if(disabled){
            return;
        }
        var t = e.getTarget();
        if(!t || t.nodeType !== 1 || t == document || t == document.body){
            return;
        }
        if(ce && t == ce.el){
            clearTimeout(hideProc);
            return;
        }
        if(t && tagEls[t.id]){
            tagEls[t.id].el = t;
            showProc = show.defer(tm.showDelay, tm, [tagEls[t.id]]);
            return;
        }
        var ttp, et = Ext.fly(t);
        var ns = cfg.namespace;
        if(tm.interceptTitles && t.title){
            ttp = t.title;
            t.qtip = ttp;
            t.removeAttribute("title");
            e.preventDefault();
        }else{
            ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);
        }
        if(ttp){
            showProc = show.defer(tm.showDelay, tm, [{
                el: t,
                text: ttp,
                width: et.getAttributeNS(ns, cfg.width),
                autoHide: et.getAttributeNS(ns, cfg.hide) != "user",
                title: et.getAttributeNS(ns, cfg.title),
           	    cls: et.getAttributeNS(ns, cfg.cls)
            }]);
        }
    };

    var onOut = function(e){
        clearTimeout(showProc);
        var t = e.getTarget();
        if(t && ce && ce.el == t && (tm.autoHide && ce.autoHide !== false)){
            hideProc = setTimeout(hide, tm.hideDelay);
        }
    };

    var onMove = function(e){
        if(disabled){
            return;
        }
        xy = e.getXY();
        xy[1] += 18;
        if(tm.trackMouse && ce){
            el.setXY(xy);
        }
    };

    var onDown = function(e){
        clearTimeout(showProc);
        clearTimeout(hideProc);
        if(!e.within(el)){
            if(tm.hideOnClick){
                hide();
                tm.disable();
            }
        }
    };

    var onUp = function(e){
        tm.enable();
    };

    var getPad = function(){
        return bdLeft.getPadding('l')+bdRight.getPadding('r');
    };

    var show = function(o){
        if(disabled){
            return;
        }
        clearTimeout(dismissProc);
        ce = o;
        if(removeCls){
            el.removeClass(removeCls);
            removeCls = null;
        }
        if(ce.cls){
            el.addClass(ce.cls);
            removeCls = ce.cls;
        }
        if(ce.title){
            tipTitle.update(ce.title);
            tipTitle.show();
        }else{
            tipTitle.update('');
            tipTitle.hide();
        }
        el.dom.style.width  = tm.maxWidth+'px';

        tipBodyText.update(o.text);
        var p = getPad(), w = ce.width;
        if(!w){
            var td = tipBodyText.dom;
            var aw = Math.max(td.offsetWidth, td.clientWidth, td.scrollWidth);
            if(aw > tm.maxWidth){
                w = tm.maxWidth;
            }else if(aw < tm.minWidth){
                w = tm.minWidth;
            }else{
                w = aw;
            }
        }
        el.setWidth(parseInt(w, 10) + p);
        if(ce.autoHide === false){
            close.setDisplayed(true);
            if(dd){
                dd.unlock();
            }
        }else{
            close.setDisplayed(false);
            if(dd){
                dd.lock();
            }
        }
        if (ce.showAtLocation) {
          el.setLocation(ce.showAtLocation[0], ce.showAtLocation[1]);
        } else {
					if (!ce.position) ce.position = 'br';
  	      el.alignTo(ce.target, ce.position, [-7,-5]);
  	    }

        if(tm.animate){
            el.setOpacity(.1);
            el.setStyle("visibility", "visible");
            el.fadeIn({callback: afterShow});
        }else{
            afterShow();
        }
    };

    var afterShow = function(){
        if(ce){
            el.show();
            esc.enable();
            if(tm.autoDismiss && ce.autoHide !== false){
                dismissProc = setTimeout(hide, tm.autoDismissDelay);
            }
        }
    };

    var hide = function(noanim){
        clearTimeout(dismissProc);
        clearTimeout(hideProc);
        ce = null;
        if(el.isVisible()){
            esc.disable();
            if(noanim !== true && tm.animate){
                el.fadeOut({callback: afterHide});
            }else{
                afterHide();
            }
        }
    };

    var afterHide = function(){
        el.hide();
        if(removeCls){
            el.removeClass(removeCls);
            removeCls = null;
        }
    };

    return {

       minWidth : 40,

       maxWidth : 300,

       interceptTitles : false,

       trackMouse : false,

       hideOnClick : true,

       showDelay : 500,

       hideDelay : 200,

       autoHide : true,

       autoDismiss : true,

       autoDismissDelay : 10000,

       animate : false,







       init : function(){
          tm = Ext.QuickTipsEdit;
          cfg = tm.tagConfig;
          if(!inited){
              if(!Ext.isReady){
                  Ext.onReady(Ext.QuickTipsEdit.init, Ext.QuickTipsEdit);
                  return;
              }
              el = new Ext.Layer({cls:"x-tip", shadow:"drop", shim: true, constrain:true, shadowOffset:4});
              el.fxDefaults = {stopFx: true};

              el.update('<div class="x-tip-top-left"><div class="x-tip-top-right"><div class="x-tip-top"></div></div></div><div class="x-tip-bd-left"><div class="x-tip-bd-right"><div class="x-tip-bd"><div class="x-tip-close"></div><h3></h3><div class="x-tip-bd-inner"></div><div class="x-clear"></div></div></div></div><div class="x-tip-ft-left"><div class="x-tip-ft-right"><div class="x-tip-ft"></div></div></div>');
              tipTitle = el.child('h3');
              tipTitle.enableDisplayMode("block");
              tipBody = el.child('div.x-tip-bd');
              tipBodyText = el.child('div.x-tip-bd-inner');
              bdLeft = el.child('div.x-tip-bd-left');
              bdRight = el.child('div.x-tip-bd-right');
              close = el.child('div.x-tip-close');
              close.enableDisplayMode("block");
              close.on("click", hide);
              var d = Ext.get(document);
              d.on("mousedown", onDown);
              d.on("mouseup", onUp);
              /*
              d.on("mouseover", onOver);
              d.on("mouseout", onOut);
              d.on("mousemove", onMove);
              */
              esc = d.addKeyListener(27, hide);
              esc.disable();
              inited = true;
          }
          this.enable();
       },


       register : function(config){
          if(!inited){
            this.init();
          }
           var cs = config instanceof Array ? config : arguments;
           for(var i = 0, len = cs.length; i < len; i++) {
               var c = cs[i];
               var target = c.target;
               if(target){
                   if(target instanceof Array){
                       for(var j = 0, jlen = target.length; j < jlen; j++){
                           tagEls[target[j]] = c;
                       }
                   }else{
                       tagEls[typeof target == 'string' ? target : Ext.id(target)] = c;
		                   show(c);
                   }
               }
           }
       },


       unregister : function(el){
           delete tagEls[Ext.id(el)];
       },


       enable : function(){
           if(inited && disabled){
               locks.pop();
               if(locks.length < 1){
                   disabled = false;
               }
           }
       },


       disable : function(){
          disabled = true;
          clearTimeout(showProc);
          clearTimeout(hideProc);
          clearTimeout(dismissProc);
          if(ce){
              hide(true);
          }
          locks.push(1);
       },


       isEnabled : function(){
            return !disabled;
       },


       tagConfig : {
           namespace : "ext",
           attribute : "qtip",
           width : "width",
           target : "target",
           title : "qtitle",
           hide : "hide",
           cls : "qclass"
       }
   };
}();



Ext.grid.Grid.prototype.maskIfEmpty = function(text) {
	var el = this.getGridEl();
	var ds = this.dataSource;
	if (el.isMasked()) el.unmask(true);
	ds.on('load', function() {
			if (ds.getCount() == 0) {
			  if (!el.isMasked()) el.mask(text);
			} else {
			  if (el.isMasked()) el.unmask();
			}
		}, this);
}

Ext.grid.Grid.prototype.autoUpdateOnBeforeLoad = function(ds, options) {
	var view = this.getView();
  var ft = this.autoUpdateFooterEl;
  if (document.getElementById(this.getGridEl().id) == null) {
		return false;
  }
  if (ft) {
    ft.update(this.autoUpdateText);
    ft.addClass('x-grid-footer-loading');
	}
  //Save scrollTop
  var bd = view.mainBody.dom;
  options.gridBdScroll = bd.scrollTop;
}

Ext.grid.Grid.prototype.autoUpdateOnLoad = function(ds, records, options) {
	var view = this.getView();
  var ft = this.autoUpdateFooterEl;
  if (document.getElementById(this.getGridEl().id) == null) {
		return false;
  }
  if (ft) {
    ft.update('&nbsp;');
		ft.removeClass('x-grid-footer-loading');
	}
	//Set old scrollTop
  window.setTimeout(function() { view.scroller.dom.scrollTop = options.gridBdScroll; }, 1);
  //Initialize next Task
  if (!this.updateTask) {
		this.updateTask = new Ext.util.DelayedTask(this.autoUpdateLoad, this);
	}
	var interval = this.autoUpdateInterval;
	if (typeof interval == "function") {
	  interval = interval();
	}
	if (interval) this.updateTask.delay(interval);
}
Ext.grid.Grid.prototype.autoUpdateLoad = function(ds, records, options) {
	var params = {};
	/*
	if (this.pagingConfig) {
	  params = {
	      'start': 0,
	      limit: this.pagingConfig.pageSize
	    };
	}
	*/
	this.dataSource.load({params: params});
}

Ext.grid.Grid.prototype.autoUpdate = function(interval, text, pagingConfig) {
	if (text == undefined) text = "Opdaterer...";
	if (text === '') text = '&nbsp;';
	this.autoUpdateInterval = interval;
	this.autoUpdateText = text;
	var ds = this.dataSource;
	ds.on('beforeload', this.autoUpdateOnBeforeLoad, this);
	ds.on('load', this.autoUpdateOnLoad, this);
	var ft = this.getView().getFooterPanel(true), params;
	if (text !== false) {
	  ft.addClass('x-toolbar');
	  ft.setStyle('border-top', '1px solid #c3daf9');
	  ft = Ext.DomHelper.append(ft.id, '<div style="x-grid-footer-loading"></div>', true);
	  ft.setStyle('line-height', '16px');
	  ft.update('&nbsp;');
	  this.autoUpdateFooterEl = ft;
	  params = {};
	} else if (pagingConfig) {
	  /*
	  this.pagingConfig = pagingConfig;
	  this.autoUpdatePaging = new Ext.PagingToolbar(ft, ds, {
	      pageSize: pagingConfig.pageSize,
	      displayInfo: true,
	      displayMsg: 'Displaying topics {0} - {1} of {2}',
	      emptyMsg: "No topics to display"
	  });
	  */
	}
	this.destroy = this.destroy.createSequence(this.cancelAutoUpdate, this);
	this.autoUpdateLoad();
}

Ext.grid.Grid.prototype.cancelAutoUpdate = function() {
	this.updateTask.cancel();
	var ds = this.dataSource;
	ds.un('beforeload', this.autoUpdateOnBeforeLoad, this);
	ds.un('load', this.autoUpdateOnLoad, this);
  var ft = this.autoUpdateFooterEl;
  if (document.getElementById(this.getGridEl().id) == null) {
		return false;
  }
  if (ft) {
    ft.update('&nbsp;');
		ft.removeClass('x-grid-footer-loading');
	}
}

Ext.form.TextField.prototype.defaultAutoCreate = {tag: "input", type: "text", size: "20", autocomplete: "on"},

Ext.form.ComboBox.prototype.setValueToFirst = function() {
	var first = this.store.getAt(0);
	if (first) {
		this.setValue(first.get(this.store.fields.keys[0]));
	} else {
	  this.setValue('');
	}
}
Ext.form.Form.prototype.addComboBox = function(fieldLabel, name, data, value, addConfig) {
	if (!addConfig) addConfig = {};
	if (!addConfig.width) addConfig.width = 200;
	if (value == null) value = false;
	var store;
	if (typeof data == 'object') {
		store = new Ext.data.SimpleStore({
	      fields: ['value','label'],
	      data: data
	    });
	} else {
	  store = new Ext.data.JsonStore({
	      url: data,
	      root: 'records',
	      fields: ['value','label']
	    });
	  store.load();
	}
	config = {
	    fieldLabel: fieldLabel,
	    hiddenName: name,
	    store: store,
			valueField: 'value',
			displayField: 'label',
			triggerAction: 'all',
			mode: 'local',
			editable: false
	  };
	Ext.apply(config, addConfig);
  var cb = new Ext.form.ComboBox(config);
  if (typeof data == 'object') {
		if (value === false) {
			cb.setValueToFirst();
		} else {
		  cb.setValue(value);
		}
	} else {
	  store.on('load', function() {
				if (value === false) {
					cb.setValueToFirst();
				} else {
				  cb.setValue(value);
				}
		  }, this, {single: true});
	}
	this.add(cb);
	return cb;
}
Ext.form.Form.prototype.addTextField = function(fieldLabel, name, value, addConfig) {
	if (!addConfig) addConfig = {};
	if (!addConfig.width) addConfig.width = 200;
	if (!value) value = '';
	config = {
	    fieldLabel: fieldLabel,
	    name: name,
	    value: value
	  };
	Ext.apply(config, addConfig);
	var f = new Ext.form.TextField(config);
  this.add(f);
	return f;
}
Ext.form.Form.prototype.addTextArea = function(fieldLabel, name, value, addConfig) {
	if (!addConfig) addConfig = {};
	if (!addConfig.width) addConfig.width = 200;
	if (!addConfig.height) addConfig.height = 200;
	if (!value) value = '';
	config = {
	    fieldLabel: fieldLabel,
	    name: name,
	    value: value
	  };
	Ext.apply(config, addConfig);
	var f = new Ext.form.TextArea(config);
  this.add(f);
	return f;
}
Ext.form.Form.prototype.addDateField = function(fieldLabel, name, value, addConfig) {
	if (!addConfig) addConfig = {};
	if (!addConfig.width) addConfig.width = 200;
	if (!value) value = '';
	config = {
	    fieldLabel: fieldLabel,
	    name: name,
	    value: value,
	    validationDelay: 2000
	  };
	Ext.apply(config, addConfig);
	var f = new Ext.form.DateField(config);
  this.add(f);
	return f;
}
Ext.form.Form.prototype.addCheckbox = function(fieldLabel, name, checked, inputValue, addConfig) {
	if (!addConfig) addConfig = {};
	if (!inputValue) inputValue = '1';
	checked = checked && checked != '0' ? true : false;
	config = {
	    fieldLabel: fieldLabel,
	    name: name,
	    inputValue: inputValue,
	    checked: checked
	  };
	Ext.apply(config, addConfig);
	var f = new Ext.form.Checkbox(config);
  this.add(f);
	return f;
}

Ext.form.Form.prototype.emptyAllFields = function() {
	this.items.each(function(item) {
		  if (item.setValueToFirst) {
		    item.setValueToFirst();
		  } else {
		    item.setValue('');
		  }
		});
}
Ext.form.Form.prototype.clearAllFields = function() {
	this.items.each(function(item) {
	    item.setValue('');
		});
}

Ext.form.Form.prototype.setValuesDefault = function(force) {
	this.items.each(function(item) {
	    var v = item.getValue();
			item.originalValue = v;
		});
}

Ext.form.Action.Submit.prototype.handleResponse = function(response){
    if(this.form.errorReader){
        var rs = this.form.errorReader.read(response);
        var errors = [];
        if(rs.records){
            for(var i = 0, len = rs.records.length; i < len; i++) {
                var r = rs.records[i];
                errors[i] = r.data;
            }
        }
        if(errors.length < 1){
            errors = null;
        }
        return {
            success : rs.success,
            errors : errors
        };
    }
    var result = handleJSONResponse(true, response);
		return result;
}


Ext.form.FileSelector = function(config){
  Ext.form.FileSelector.superclass.constructor.call(this, config);
};
Ext.extend(Ext.form.FileSelector, Ext.form.Field,  {
	defaultAutoCreate: {tag: "input", type: 'hidden'},
	
  onRender : function(ct, position){
    topCls = this.isDir ? 'x-dirselector' : '';
    tplHTML = ''+
      '<div class="'+topCls+'">'+
        '<div id="{id}-file-ct" class="x-fileselector">'+
          '<div class="x-fileselector-left-ct">'+
	          '<div class="x-fileselector-icon">'+
  	          '<img id="{id}-icon" src="">'+
    	      '</div>'+
      	    '<div class="x-fileselector-filename-ct">'+
  	    	    '<span id="{id}-filename">'+
	        	  '</span>'+
        	  '</div>'+
      	  '</div>'+
          '<div class="x-fileselector-buttons">'+
  	        '<div id="{id}-choose-ct" class="x-fileselector-button">'+
	          '</div>';
		if (this.isDir !== true) tplHTML += ''+
  	        '<div id="{id}-view-ct" class="x-fileselector-button">'+
	          '</div>';
		tplHTML += ''+
  	        '<div id="{id}-remove-ct" class="x-fileselector-button">'+
	          '</div>'+
          '</div>'+
        '</div>'+
      '</div>';
    var tpl = new Ext.Template(tplHTML);
    tpl.append(this.container, {
        id: this.id
			});
		this.fileCt = Ext.get(this.id+'-file-ct');
		this.fileIcon = Ext.get(this.id+'-icon');
		this.filenameEl = Ext.get(this.id+'-filename');
		this.chooseButton = new Ext.Button(this.id+'-choose-ct', {
		    text: 'Vælg',
		    handler: this.fileChoose,
		    scope: this,
		    minWidth: 50
		  });
		if (this.isDir !== true) {
			this.viewButton = new Ext.Button(this.id+'-view-ct', {
			    text: 'Vis',
			    handler: this.fileView,
			    scope: this,
			    minWidth: 50
			  });
		}
		this.removeButton = new Ext.Button(this.id+'-remove-ct', {
		    text: 'Fjern',
		    handler: this.fileRemove,
		    scope: this,
		    minWidth: 50
		  });
    Ext.form.FileSelector.superclass.onRender.call(this, ct, position);
	},
	setValue: function(v, iconSrc) {
    Ext.form.FileSelector.superclass.setValue.call(this, v);
    var filename = v;
    if (!v) {
			filename = '<i>Intet valgt</i>';
			iconSrc = 'images/icons/blank.png';
    }
	  this.filenameEl.set({title: 'Komplet sti: '+filename});
	  this.filenameEl.update(filename);
	  this.optimizeFilenameEl();
	  if (!iconSrc) {
			iconSrc = 'images/loading.gif';
			this.loadFileIcon(v);
		}
	  this.setFileIcon(iconSrc);
	},
	fileChoose: function() {
	  var v = this.getValue();
	  FileBrowser.show({
	      src: this.chooseButton.getEl(),
	      actionText: 'Indsæt',
	      actionFn: this.fileUpdate,
	      actionScope: this,
	      filter: this.filter,
				file: v
	    });
	},
	fileView: function() {
	  var v = this.getValue();
		if (v) window.open(v, 'view_file');
	},
	fileRemove: function() {
	  this.setValue('');
	},
	fileUpdate: function(data) {
	  var iconSrc = false;
	  if (!data.isThumbnail) {
			iconSrc = data.icon;
		}
	  this.setValue(data.absFilename, iconSrc);
	},
	optimizeFilenameEl: function() {
	  var shortened = false;
		while (this.filenameEl.getWidth() > 110) {
		  this.filenameEl.update(this.filenameEl.dom.innerHTML.substring(1));
		  shortened = true;
		}
		if (shortened) this.filenameEl.update('...'+this.filenameEl.dom.innerHTML)
	},
	setFileIcon: function(iconSrc) {
	  this.fileIcon.dom.src = iconSrc;
	},
	loadFileIcon: function(file) {
	  if (this.loadingFileIcon === true) {
	    this.fileIconCon.abort();
	  }
	  this.loadingFileIcon = true;
	  this.fileIconCon = new Ext.data.Connection();
	  this.fileIconCon.request({
	      url: 'admin_modules.php?module=filebrowser&mode=get_file_icon',
	      params: {
	          file: file,
	          width: 100,
	          height: 50
	        },
	      callback: this.loadFileIconResponse,
	      scope: this
	    });
	},
	loadFileIconResponse: function(options, success, response) {
	  var result = handleJSONResponse(success, response);
	  if (result === false || result.success === false) {
	    iconSrc = 'images/icons/exclamation.png';
	  } else {
	    iconSrc = result.iconSrc;
	  }
	  this.setFileIcon(iconSrc);
	  this.loadingFileIcon === false;
	},
	alignErrorIcon : function(){
		this.errorIcon.alignTo(this.fileCt, 'tl-tr', [2, 0]);
	}
});

Ext.form.DirSelector = function(config){
  Ext.form.DirSelector.superclass.constructor.call(this, config);
};
Ext.extend(Ext.form.DirSelector, Ext.form.FileSelector,  {
  onRender : function(ct, position){
    this.isDir = true;
		Ext.form.DirSelector.superclass.onRender.call(this, ct, position);
	},
	fileChoose: function() {
	  var v = this.getValue();
	  FileBrowser.show({
	      src: this.chooseButton.getEl(),
	      actionText: 'Vælg mappe',
	      actionFn: this.fileUpdate,
	      actionScope: this,
				file: v,
				dirSelect: true
	    });
	}
});


Ext.form.TinyMCE = function(config){
  Ext.applyIf(config, {width: 600, height: 300});
	this.config = config;
  Ext.form.TinyMCE.superclass.constructor.call(this, config);
};
Ext.extend(Ext.form.TinyMCE, Ext.form.TextArea,  {
  onRender : function(ct, position){
    if(!this.el){
        this.defaultAutoCreate = {
            tag: "textarea",
            style:"width:"+this.config.width+"px;height:"+this.config.height+"px;",
            autocomplete: "off"
        };
    }
    Ext.form.TextArea.superclass.onRender.call(this, ct, position);
    this.addMCEControl();
	},
	addMCEControl: function() {
	  for (var n in tinyMCE.instances) {
			var inst = tinyMCE.instances[n];
	    if (tinyMCE.isInstance(inst) && inst.editorId == this.mceEditorId) return false;
	  }
	  tinyMCE.addMCEControl(this.el.dom, this.el.dom.id)
	  this.mceEditorId = "mce_editor_" + (tinyMCE.idCounter-1);
	  this.originalValue = this.value || '';
	},
	triggerSave: function() {
	  try {
		  if (tinyMCE.instances && tinyMCE.instances[this.mceEditorId]) tinyMCE.instances[this.mceEditorId].triggerSave();
	  } catch(e) {
	  }
	},
	updateContent: function() {
	  tinyMCE.updateContent(this.el.id);
	},
	setValue : function(v) {
	  this.value = v;
	  this.el.dom.value = v;
	  this.updateContent();
	},
	getValue : function() {
	  this.triggerSave();
	  return Ext.form.TinyMCE.superclass.getValue.call(this);
	},
	setRawValue : function(v) {
	  this.value = v;
	  this.el.dom.value = v;
	  Ext.form.TinyMCE.superclass.setRawValue.call(this, v);
	  this.updateContent();
	},
	getRawValue : function() {
	  this.triggerSave();
	  return Ext.form.TinyMCE.superclass.getRawValue.call(this);
	},
  afterRender : function(){
    Ext.form.Field.superclass.afterRender.call(this);
  },
	alignErrorIcon : function(){
		this.errorIcon.alignTo(this.mceEditorId, 'tl-tr', [2, 0]);
	}
});

Ext.form.Form.prototype.addMCEControls = function() {
	this.items.each(function(item) {
			if (item instanceof Ext.form.TinyMCE) item.addMCEControl();
	  }, this);
}


Ext.form.HTML = function(config){
    Ext.form.HTML.superclass.constructor.call(this, config);
};
Ext.extend(Ext.form.HTML, Ext.form.Field,  {
  defaultAutoCreate : {tag: "input", type: "hidden"},
  onRender : function(ct, position){
	  Ext.form.HTML.superclass.onRender.call(this, ct, position);
		this.HTMLSpan = this.container.createChild({tag: 'span'});
		this.HTMLSpan.addClass('x-form-html');
		this.HTMLSpan.update(this.html || this.value);
	},
	markInvalid : function(msg) {
	  return;
	},
	setValue : function(v) {
		Ext.form.HTML.superclass.setValue.call(this, v);
	  this.value = v;
	  if (this.HTMLSpan) this.HTMLSpan.update(v);
	},
	setRawValue : function(v) {
	  this.setValue(v);
	}
});
Ext.form.Form.prototype.addHTML = function(fieldLabel, html, name) {
	if (!html) html = '';
	if (!name) name = 0;
	var t = new Ext.form.HTML({
	    fieldLabel: fieldLabel,
	    name: name,
	    html: html,
	    value: html
	  });
  this.add(t);
	return t;
}

setFieldLabel = function(field, newLabel) {
	if (!field) return;
	field.fieldLabel = newLabel;
	field.container.dom.parentNode.firstChild.innerHTML = newLabel+':';
}

Ext.form.Field.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.TextField.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.DateField.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.ComboBox.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.HtmlEditor.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.Checkbox.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.Radio.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.NumberField.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}
Ext.form.TextArea.prototype.destroyEl = function() {
	this.el.up('div.x-form-item').remove();
	this.destroy();
}

Ext.form.ComboBox.prototype.initEvents = Ext.form.ComboBox.prototype.initEvents.createSequence(function() {
    if(!this.forceSelection && this.editable){
      this.el.on('blur', this.selectInputValue, this);
    }
	});
Ext.form.ComboBox.prototype.selectInputValue = function() {
	var v = this.el.dom.value;
	var r = this.findRecord(this.displayField, v);
  if(!r){
		this.setValue(v);
	}
}
Ext.form.ComboBox.prototype.onDisable = function() {
  Ext.form.ComboBox.superclass.onDisable.call(this);
  this.hiddenField.disabled = true;
}
Ext.form.ComboBox.prototype.onEnable = function() {
  Ext.form.ComboBox.superclass.onEnable.call(this);
  this.hiddenField.disabled = false;
}


Ext.form.Action.Submit.prototype.run = Ext.form.Action.Submit.prototype.run.createInterceptor(function() {
		this.form.items.each(function(item) {
				if (item.el.getValue() == item.emptyText) {
				  item.el.dom.value = '';
				}
		  });
	});
Ext.form.Action.Submit.prototype.run = Ext.form.Action.Submit.prototype.run.createSequence(function() {
		this.form.items.each(function(item) {
				if (item.el.getValue() == '' && item.emptyText) {
				  item.el.dom.value = item.emptyText;
				}
		  });
	});

Ext.form.Form.prototype.append = function(container) {
	var fieldsArray = Array.prototype.slice.call(arguments, 1);
  // Create a new layout object
  var layout = new Ext.form.Layout();
  // Keep track of added fields that are form fields (isFormField)
  var fields = [];
  // Add all the fields on to the layout stack
  layout.stack.push.apply(layout.stack, fieldsArray);

  // Add only those fields that are form fields to the 'fields' array
  for(var i = 0; i < fieldsArray.length; i++) {
    if(fieldsArray[i].isFormField) {
      fields.push(fieldsArray[i]);
    }
  }

	if (container) {
	  container.stack.push.apply(container.stack, fieldsArray);
	} else {
		container = this;
	}
  // Render the layout
  layout.render(container.el);

  // If we found form fields add them to the form's items collection and render the
  // fields into their containers created by the layout
  if(fields.length > 0) {
    this.items.addAll(fields);

    // Render each field
    for(var i = 0; i < fields.length; i++) {
      fields[i].render('x-form-el-' + fields[i].id);
    }
  }

  return this;
};

Ext.form.FieldSet.prototype.empty = function(form) {
	Ext.each(this.stack, function(field) {
			if (form) form.items.remove(field);
			field.destroyEl();
	  }, this);
	this.stack = [];
}
Ext.form.FieldSet.prototype.loadingText = function(text) {
	if (!this.loadingEl) {
	  this.loadingEl = this.getEl().createChild({tag: 'div'});
	}
	if (text) {
	  this.loadingEl.update('<img src="images/loading.gif"> '+text);
	  this.loadingEl.setDisplayed(true);
	} else {
	  this.loadingEl.setDisplayed(false);
	}
}
Ext.form.FieldSet.prototype.setText = function(text) {
	if (this.rendered !== true) {
	  this.setTextOnRender(text);
	  return;
	}
	if (!this.textEl) {
		this.textEl = Ext.DomHelper.insertAfter(this.getEl().down('legend'), {tag: 'div', style: 'margin-bottom: 10px;'}, true);
	}
	this.textEl.update(text || '');
}
Ext.form.FieldSet.prototype.setTextOnRender = function(text) {
	this.on('render', this.setText.createDelegate(this, [text]), this);
}

Ext.LayoutDialog.prototype.checkDirtyOnHide = function(config) {
	this.checkDirtyForm = config;
	this.checkDirtyAllowHide = false;
	this.on('beforehide', this.checkDirtyOnBeforeHide, this);
}
Ext.LayoutDialog.prototype.checkDirtyOnBeforeHide = function() {
	if (this.checkDirtyAllowHide) {
	  this.checkDirtyAllowHide = false;
		return true;
	}
  if (this.checkDirtyForm.isDirty()) {
    Ext.Msg.confirm(this.checkDirtyMsgTitle, this.checkDirtyMsg, function(btn) {
        if (btn == "yes") {
          this.checkDirtyAllowHide = true;
          this.hide();
				}
      }, this);
		return false;
	}
}
Ext.LayoutDialog.prototype.forceHide = function() {
	this.checkDirtyAllowHide = true;
	this.hide();
}
Ext.LayoutDialog.prototype.checkDirtyMsgTitle = "";
Ext.LayoutDialog.prototype.checkDirtyMsg = "Dine ændringer vil ikke blive gemt.<br><br>Er du sikker på du vil lukke dette vindue?";


Ext.Toolbar.prototype.menuize = function() {
	function mouseOver(item) {
	  var showMenu = false;
	  item.parentItem.items.each(function(sibling) {
	      if (sibling != item && sibling.menu && sibling.menu.hidden == false) {
	        sibling.menu.hide();
	        showMenu = true;
	        return false;
	      }
	    });
	  if (showMenu) {
	    if (item.menu) item.menu.show(item.getEl());
	  }
	}
	this.items.each(function(item) {
	    if (typeof item.on == 'function') {
		    item.parentItem = this;
		    item.on('mouseover', function() { mouseOver(item); });
			}
	  }, this);
}

Ext.form.TabPanel = function(config, form) {
	Ext.form.TabPanel.superclass.constructor.call(this, config);
	this.stack = [];
	this.isTabPanel = true;
	this.form = form;
	form.on('actionfailed', this.formOnActionFailed, this);
};
Ext.extend(Ext.form.TabPanel, Ext.form.Layout, {
	onRender: function(ct, position) {
	  tabsCt = ct.createChild({tagName: 'div', style: 'border: 1px solid #99BBE8; background: #DEECFD; padding: 1px;'});
		this.tabs = new Ext.TabPanel(tabsCt);
    if(this.width){
      tabsCt.setWidth(this.width);
    }
    if(this.height){
      tabsCt.setHeight(this.height);
    }
		Ext.form.TabPanel.superclass.onRender.call(this, ct, position);
		if(this.tabs.getActiveTab() == null) this.tabs.activate(0);
		this.tabs.bodyEl.setHeight(tabsCt.getHeight() - this.tabs.stripWrap.getHeight());
	},
	formOnActionFailed: function(form, action) {
		var errors = action.result.errors;
		if (!errors) return;
		Ext.each(this.stack, function(item) {
		    var activate = false;
				Ext.each(errors, function(err) {
				    if (this.fieldInStack(item.stack, err.id)) {
				      activate = true;
				      return false;
				    }
				  }, this);
				if (activate) {
					item.tabPanelItem.activate();
					return false;
				}
		  }, this);
	},
	fieldInStack: function(stack, name) {
		inStack = false;
		Ext.each(stack, function(item) {
		    if (item.isFormField) {
		      if (item.getName() == name) {
						inStack = true;
						return false;
		      }
		    } else if (item.stack) {
		      if (this.fieldInStack(item.stack, name) === true) {
						inStack = true;
						return false;
		      }
		    }
		  }, this);
		return inStack;
	},
	activateFirst: function() {
	  this.tabs.activate(0);
	}
});

Ext.form.TabPanelItem = function(config) {
	Ext.form.TabPanelItem.superclass.constructor.call(this, config);
	this.stack = [];
	this.isTabPanelItem = true;
};
Ext.extend(Ext.form.TabPanelItem, Ext.form.Layout, {
	onRender: function(ct, position) {
		var item = this.ownerCt.tabs.addTab(Ext.id(), this.title);
		this.tabPanelItem = item;
		item.bodyEl.setStyle('padding', '10px');
		item.bodyEl.setStyle('overflow', 'auto');
		this.el = item.bodyEl;
		Ext.form.TabPanelItem.superclass.onRender.call(this, ct, position);
		if (this.activated) item.activate();
	}
});

Ext.form.Form.prototype.tabPanel = function(c) {
	var tp = new Ext.form.TabPanel(c, this);
	this.start(tp);
	return tp;
}
Ext.form.Form.prototype.tabPanelItem = function(c) {
	var item = new Ext.form.TabPanelItem(c);
	this.start(item);
	return item;
}

Ext.tree.TreeNode.prototype.setIcon = function(src) {
	this.ui.iconNode.src = src;
}

Ext.MessageBox.ghostMsgCreateBox = function(t, s) {
  return ['<div class="x-ghost-msg">',
          '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
          '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc" style="position: relative;">',
	          '<div class="x-ghost-msg-close"></div>',
						'<h3>', t, '</h3>', s, '',
					'</div></div></div>',
          '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
          '</div>'].join('');
}
Ext.MessageBox.ghostMsg = function(s, title, target, config) {
	if (!this.ghostMsgEls) this.ghostMsgEls = [];
	if (!this.ghostMsgIdCounter) this.ghostMsgIdCounter = 1;
	var id = this.ghostMsgIdCounter;
	this.ghostMsgIdCounter++;
  title = title || '';
  config = config || {};
  if(!this.ghostMsgCt){
      this.ghostMsgCt = Ext.DomHelper.insertFirst(document.body, {id:'ghost-msg-div'}, true);
  }
  if (config.width) this.ghostMsgCt.setWidth(config.width);
  this.ghostMsgCt.alignTo(Ext.get(target || document.body), 'tr-tr', [-1, 1]);
  var m = Ext.DomHelper.append(this.ghostMsgCt, {html:this.ghostMsgCreateBox(title, s)}, true);
  var closeBtn = m.child('.x-ghost-msg-close');
  closeBtn.on('click', this.ghostMsgGhost.createDelegate(this, [id]), this);
  closeBtn.addClassOnOver('x-ghost-msg-close-over');
  m.slideIn('t');
  dTask = new Ext.util.DelayedTask(this.ghostMsgGhost.createDelegate(this, [id]), this);
  dTask.delay(5000);
  this.ghostMsgEls[id] = {dTask: dTask, el: m};
}
Ext.MessageBox.ghostMsgGhost = function(id){
  this.ghostMsgEls[id].dTask.cancel();
	this.ghostMsgEls[id].el.ghost("t", {remove:true});
  this.ghostMsgEls[id] = null;
}
Ext.MessageBox.ghostMsgHide = function(){
  this.ghostMsgEl.remove();
  this.ghostMsgEl = null;
}

Ext.form.DateField.prototype.parseDate = function(value){
    if(!value || value instanceof Date){
        return value;
    }
    var v = Date.parseDate(value, this.format);
    if(!v && this.altFormats){
        var parts = value.split(/\D/);
        for (i = 0; i < parts.length; i++) {
          if (parts[i].length == 1) parts[i] = '0'+parts[i];
          if (i >= 2 && parts[i].length == 2) parts[i] = '20'+parts[i];
        }
        value = parts.join("-");
        if(!this.altFormatsArray){
            this.altFormatsArray = this.altFormats.split("|");
        }
        for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
            v = Date.parseDate(value, this.altFormatsArray[i]);
        }
    }
    return v;
}

Ext.FormDialog = function(config, form){
	Ext.QuickTips.init();
	var elId = Ext.id(), centerElId = Ext.id(), centerTableId = Ext.id(), formElId = Ext.id();
	var tpl = new Ext.Template(
			'<div id="{elId}">'+
				'<div id="{centerElId}" style="padding: 10px;">'+
				  '<table id="{centerTableId}"><tr><td>'+
						'<div id="{formElId}">'+
						'</div>'+
					'</td></tr></table>'+
				'</div>'+
			'</div>'
		);
	tpl.append(document.body, {
	    elId: elId,
	    centerElId: centerElId,
	    formElId: formElId,
	    centerTableId: centerTableId
		});
	var el = Ext.get(elId);
	var centerEl = Ext.get(centerElId);
	var centerTableEl = Ext.get(centerTableId);
	var formEl = Ext.get(formElId);
	this.centerTableEl = centerTableEl;

	Ext.applyIf(config, {
      modal:true,
      shadow:true,
      draggable: false,
      fixedcenter: true,
      collapsible: false,
      resizable: false,
      shim: true,
      closable: true,
      center: {
			  }
	  });
  Ext.FormDialog.superclass.constructor.call(this, el, config);

	this.form = form;
	if (config.msgTarget !== false) this.form.applyToFields({msgTarget: config.msgTarget || 'side'});
	this.form.render(formEl);

	if (!config.width || !config.height) this.on('show', this.formOnShow, this);

	this.layout.beginUpdate();
	var center = this.layout.add('center', new Ext.ContentPanel(centerEl, {
			fitToFrame: true, autoScroll: false
	  }));
	this.layout.endUpdate();
	if (config.title) this.setTitle(config.title);

  this.checkDirtyOnHide(this.form);
  this.addKeyListener(27, this.hide, this);
  this.addButton(config.cancelBtnText || TXT.cancel, this.hide, this);
  this.addButton(config.saveBtnText || TXT.save, this.save, this);

  this.config = config;
  
};
Ext.extend(Ext.FormDialog, Ext.LayoutDialog, {
	save: function() {
	  this.form.submit({
	      success: this.config.saveSuccess,
	      failure: handleFormSubmitError,
	      scope: this.config.scope
	    });
	},
	formOnShow: function() {
		this.setContentSize(Ext.get(this.centerTableEl).getWidth()+20, Ext.get(this.centerTableEl).getHeight()+20);
	}
});


Ext.form.FileUpload = function(config){
	this.slotId = config.slotId;
	if (!config.width || config.width < 8) config.width = 200;
	if (!config.height || config.height < 60) config.height = 60;
	this.width = config.width;
	this.height = config.height;
  Ext.form.FileUpload.superclass.constructor.call(this, config);
};
Ext.extend(Ext.form.FileUpload, Ext.form.Field,  {
	defaultAutoCreate: {tag: "input", type: 'hidden'},

  onRender : function(ct, position){
    tplHTML = ''+
        '<div id="{id}-file-ct" class="x-fileupload">'+
          '<div id="{id}-left-ct" class="x-fileupload-left-ct">'+
	          '<div id="{id}-icon-ct" class="x-fileupload-icon"><table><tbody><tr><td>'+
  	          '<img id="{id}-icon" src="'+TGSystem.baseDir+'js/custom/images/blank.gif" style="display: none;">'+
    	      '</td></tr></tbody></table></div>'+
      	    '<div id="{id}-filename-ct" class="x-fileupload-filename-ct">'+
  	    	    '<span id="{id}-filename">'+
	        	  '</span>'+
        	  '</div>'+
      	    '<div id="{id}-filedesc-ct" class="x-fileupload-desc-ct">'+
  	    	    '<span id="{id}-filedesc">'+
	        	  '</span>'+
        	  '</div>'+
      	  '</div>'+
          '<div class="x-fileupload-buttons">'+
  	        '<div id="{id}-choose-ct" class="x-fileupload-choose">'+
	          '</div>'+
  	        '<div id="{id}-input-ct" class="x-fileupload-input">'+
	          '</div>'+
  	        '<div id="{id}-remove-ct" class="x-fileupload-remove">'+
	          '</div>'+
          '</div>'+
		    '</div>';
    var tpl = new Ext.Template(tplHTML);
    tpl.append(this.container, {
        id: this.id
			});
		this.uploadForm = Ext.DomHelper.insertAfter(ct.up('form'), {tag: 'form', id: this.id+'-uploadform', enctype: 'multipart/form-data'}, true);
		this.fileCt = Ext.get(this.id+'-file-ct');
		this.leftCt = Ext.get(this.id+'-left-ct');
		this.fileIcon = Ext.get(this.id+'-icon');
		this.fileIconCt = Ext.get(this.id+'-icon-ct');
		this.filenameEl = Ext.get(this.id+'-filename');
		this.filenameCt = Ext.get(this.id+'-filename-ct');
		this.filedescEl = Ext.get(this.id+'-filedesc');
		this.filedescCt = Ext.get(this.id+'-filedesc-ct');
		this.inputCt = Ext.get(this.id+'-input-ct');
		this.fileIcon.on('click', this.iconClick, this);
		//Set dimensions
		this.fileCt.setSize(this.width, this.height);
		var leftWidth = this.width - 80;
		this.leftCt.setWidth(leftWidth);
		var iconHeight = this.height - 40;
		this.fileIconCt.setSize(leftWidth, iconHeight);
		this.filenameCt.setWidth(leftWidth);
		this.filedescCt.setWidth(leftWidth);
		//Init buttons
		this.chooseButton = new Ext.Button(this.id+'-choose-ct', {
		    text: 'Upload',
		    scope: this,
		    minWidth: 60
		  });
		this.createUploadInput();
		this.removeButton = new Ext.Button(this.id+'-remove-ct', {
		    text: TXT.remove,
		    handler: this.fileRemove,
		    scope: this,
		    minWidth: 60
		  });
    Ext.form.FileUpload.superclass.onRender.call(this, ct, position);
    if (!this.value) this.setValue('');
	},
	createUploadInput: function() {
	  if (this.uploadInput) {
	    this.uploadInput.removeAllListeners();
	    this.uploadInput.remove();
	  }
		this.uploadInput = Ext.DomHelper.append(this.inputCt, {
			tag:'input',
			type:'file',
			size:1,
			id:this.id+'-input',
			name:'uploadfile'
		}, true);
		this.uploadInput.on('change', this.uploadFile, this);
	},
	setValue: function(v) {
	  if (v) {
			this.loadFile(v);
		} else {
	    this.fileIcon.hide();
		  this.updateFilename('-', '', true);
		}
	  this.fileId = v || '';
    Ext.form.FileUpload.superclass.setValue.call(this, v);
	},
	updateFileInfo: function(result) {
    this.fileIcon.dom.src = result.icon;
	  this.fileIcon.show();
	  this.updateFilename(result.uploadName, result.fileDesc);
	},
	updateFilename: function(filename, fileDesc, noTitles) {
	  filename = filename || '';
	  fileDesc = fileDesc || '';
	  this.filenameEl.update(filename);
	  this.filenameEl.set({title: noTitles === true ? '' : filename});
	  this.filedescEl.update(fileDesc);
	  this.filedescEl.set({title: noTitles === true ? '' : fileDesc});
	},
	uploadFile: function() {
	  this.startLoading('Uploading...');
	  this.uploadInput.addClass('x-fileupload-input-hidden');
	  this.uploadInput.appendTo(this.uploadForm);
	  var params = {
	      slot_id: this.slotId
	    };
	  this.uploadFrame = Ext.Ajax.request({
	      url: TGSystem.baseDir+'fileupload',
	      params: params,
	      form: this.id+'-uploadform',
	      isUpload: true,
				callback: this.uploadCallback,
				scope: this
	    });
	},
	uploadCallback: function(options, success, response) {
	  var result = handleJSONResponse(success, response);
	  this.resetUploadForm();
	  if (!result) {
	    this.stopLoading(true);
	    return;
	  }
	  this.fileId = result.fileId;
	  this.setValue(result.fileId);
	  this.updateFileInfo(result);
    this.stopLoading();
	},
	loadFile: function(fileId) {
	  if (fileId == this.fileId) return;
	  this.startLoading('Loading...');
	  this.loadRequest = Ext.Ajax.request({
	      url: TGSystem.baseDir+'fileupload?mode=load_field_info&slot_id='+this.slotId+'&file_id='+fileId,
	      callback: this.loadFileCallback,
	      scope: this
	    });
	},
	loadFileCallback: function(options, success, response) {
	  var result = handleJSONResponse(success, response);
	  if (!result) {
	    this.stopLoading(true);
			return;
		}
	  this.setValue(result.fileId);
	  this.updateFileInfo(result);
    this.stopLoading();
	},
	startLoading: function(text) {
	  if (this.isLoading == true) {
	    this.abortLoading();
	  }
	  this.isLoading = true;
	  this.fileIcon.show();
	  this.fileIcon.dom.src = TGSystem.baseDir+'js/custom/images/loading.gif';
	  this.updateFilename(text || '', 'Please wait...', true);
	},
	abortLoading: function() {
    if (this.uploadFrame) Ext.data.Connection.abortFormUpload(this.uploadFrame);
    if (this.loadRequest) Ext.Ajax.abort(this.loadRequest);
	},
	stopLoading: function(clear) {
    this.uploadFrame = null;
    this.loadRequest = null;
	  this.isLoading = false;
	  if (clear === true) this.setValue('');
	},
	resetUploadForm: function() {
		this.createUploadInput();
	},
	fileRemove: function() {
    this.abortLoading();
    this.stopLoading();
	  this.resetUploadForm();
	  this.setValue('');
	},
	iconClick: function() {
	  if (!this.value) return;
	  window.open(TGSystem.baseDir+'file?file_id='+this.value+'&mode=window', 'fileuploadview', 'resizable=yes,scrollbars=no');
	},
	alignErrorIcon : function(){
		this.errorIcon.alignTo(this.fileCt, 'tl-tr', [2, 0]);
	}
});

Ext.data.Connection.abortFormUpload = function(frame) {
  Ext.get(frame).removeAllListeners();
  if (Ext.isIE) {
	  frame.contentWindow.document.execCommand('stop');
  } else {
	  frame.contentWindow.stop();
	}
  setTimeout(function(){document.body.removeChild(frame);}, 100);
}
//This function has been rewritten to return the frame object to be able to abort uploads
//Only the return line has been added
Ext.data.Connection.prototype.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);
        form.target = id;
        form.method = 'POST';
        form.enctype = form.encoding = 'multipart/form-data';
        if(url){
            form.action = url;
        }

        var hiddens, hd;
        if(ps){
            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 = {
                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) {

            }

            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(){document.body.removeChild(frame);}, 100);
        }

        Ext.EventManager.on(frame, 'load', cb, this);
        form.submit();

        if(hiddens){
            for(var i = 0, len = hiddens.length; i < len; i++){
                form.removeChild(hiddens[i]);
            }
        }
        return frame;
    }