if (typeof console == 'undefined') {
	console = {
		log: function() {}
	};
}
Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
//make components only save state when told to by stateful = true
Ext.override(Ext.Component, {
	saveState: function() {
		if (Ext.state.Manager && this.stateful !== false) {
			var state = this.getState();
			if (this.fireEvent('beforestatesave', this, state) !== false) {
				Ext.state.Manager.set(this.stateId || this.id, state);
				this.fireEvent('statesave', this, state);
			}
		}
	},
	stateful: false
});
//decodeValue erroneously decodes empty arrays and objects
//empty arrays return as [undefined]
//empty objects (untested) probably fail or return as {undefined: undefined}
//either way, a simple check for empty value portions alleviates this issue
Ext.override(Ext.state.Provider, {
	decodeValue: function(cookie) {
		var re = /^(a|n|d|b|s|o)\:(.*)$/;
		var matches = re.exec(unescape(cookie));
		if (!matches || !matches[1]) return; // non state cookie
		var type = matches[1];
		var v = matches[2];
		switch (type) {
		case "n":
			return parseFloat(v);
		case "d":
			return new Date(Date.parse(v));
		case "b":
			return (v == "1");
		case "a":
			var all = [];
			if (v) {
				var values = v.split("^");
				for (var i = 0, len = values.length; i < len; i++) {
					all.push(this.decodeValue(values[i]));
				}
			}
			return all;
		case "o":
			var all = {};
			if (v) {
				var values = v.split("^");
				for (var i = 0, len = values.length; i < len; i++) {
					var kv = values[i].split("=");
					all[kv[0]] = this.decodeValue(kv[1]);
				}
			}
			return all;
		default:
			return v;
		}
	}
});
/*******************************************************************************
 * Custom Time field for EditableGrids
 */
Ext.ns("Ext.ux");
Ext.ux.timeColumn = function(increment) {
	var times = [],
		lastDate = new Date();
	lastDate.setHours(0, 0, 0);
	while (lastDate.getDayOfYear() == new Date().getDayOfYear()) {
		times.push([lastDate.format('h:i A')]);
		lastDate = lastDate.add(Date.MINUTE, increment);
	}
	Ext.ux.timeColumn.superclass.constructor.call(this, {
		autoCreate: {
			tag: "input",
			type: "text",
			size: "8",
			autocomplete: "off"
		},
		store: new Ext.data.SimpleStore({
			fields: ['times'],
			data: times
		}),
		displayField: 'times',
		valueField: 'times',
		typeAhead: true,
		mode: 'local',
		triggerAction: 'all',
		emptyText: 'Time...',
		selectOnFocus: true,
		validator: function(value) {
			return isNaN(Date.parse('1/1/2007 ' + value)) ? 'Not a valid time' : true;
		},
		maskRe: /a|p|A|P|:|s|d/,
		value: new Date().format('h:i A'),
		listeners: {
			change: function() {
				var time = Date.parse('1/1/2007 ' + this.getValue());
				if (!isNaN(time)) this.setRawValue((new Date(time)).format('h:i A'));
			}
		}
	});
}
Ext.extend(Ext.ux.timeColumn, Ext.form.ComboBox);
function timeRenderer(combo) {
	return function(value) {
		if (!value) {
			return '';
		}
		var record = combo.findRecord(combo.valueField || combo.displayField, value);
		var time = (record ? record.get(combo.displayField) : (combo.valueNotFoundText ? combo.valueNotFoundText : value));
		if (isNaN(time)) time = Date.parse('1/1/2007 ' + time);
		return (new Date(time)).format('h:i A');
	}
}
/*******************************************
 * FROM: http://extjs.com/forum/showthread.php?t=17580
 */
Ext.grid.CheckColumn = function(config) {
	if (!this.id) {
		this.id = Ext.id();
	}
	this.addEvents({
		click: true
	});
	Ext.grid.CheckColumn.superclass.constructor.call(this);
	Ext.apply(this, config, {
		init: function(grid) {
			this.grid = grid;
			this.grid.on('render', function() {
				var view = this.grid.getView();
				view.mainBody.on('mousedown', this.onMouseDown, this);
			}, this);
		},
		onMouseDown: function(e, t, a, nextIndex, doClick) {
			if (nextIndex != undefined || t.className && t.className.indexOf('x-grid3-cc-' + this.id) != -1) {
				if (nextIndex == undefined) {
					e.stopEvent();
					var index = this.grid.getView().findRowIndex(t);
					var record = this.grid.store.getAt(index);
					doClick = !record.data[this.dataIndex];
					if (doClick) {
						Ext.get(t).removeClass('x-grid3-check-col');
						Ext.get(t).addClass('x-grid3-check-col-on');
					} else {
						Ext.get(t).removeClass('x-grid3-check-col-on');
						Ext.get(t).addClass('x-grid3-check-col');
					}
					//record.set(this.dataIndex, doClick);
					if (this.grid.view.viewType != undefined && this.grid.view.viewType == 'EditorTreeGrid') {
						record.data[this.dataIndex] = doClick;
					} else {
						record.set(this.dataIndex, doClick);
					}
					//this.grid.getView().refreshRow(record);     
					//this.fireEvent('click', this, e, record);
				} else {
					index = nextIndex;
				}
				record = this.grid.store.getAt(index);
				view = this.grid.getView();
				if (record.node != undefined) {
					for (i = 0; i < record.node.childNodes.length; i++) {
						index++;
						record = this.grid.store.getAt(index);
						if (this.grid.view.viewType != undefined && this.grid.view.viewType == 'EditorTreeGrid') {
							record.data[this.dataIndex] = doClick;
						} else {
							record.set(this.dataIndex, doClick);
						}
						col = view.cm.findColumnIndex(this.dataIndex);
						el = Ext.get(view.getCell(index, col)).last().last();
						if (doClick) {
							el.removeClass('x-grid3-check-col');
							el.addClass('x-grid3-check-col-on');
						} else {
							el.removeClass('x-grid3-check-col-on');
							el.addClass('x-grid3-check-col');
						}
						//this.grid.getView().refreshRow(record);
						this.onMouseDown(null, null, null, index, doClick);
					}
				}
			}
		},
		renderer: function(v, p, record) {
			p.css += ' x-grid3-check-col-td';
			return '<div style="margin:0 !important; padding:0 !important;" class="x-grid3-check-col' + (v ? '-on' : '') + ' x-grid3-cc-' + this.id + '">&#160;</div>';
		}
	});
	this.renderer = this.renderer.createDelegate(this);
};
Ext.extend(Ext.grid.CheckColumn, Ext.util.Observable);
Ext.grid.RadioColumn = function(config) {
	if (!this.id) {
		this.id = Ext.id();
	}
	this.addEvents({
		click: true
	});
	Ext.grid.RadioColumn.superclass.constructor.call(this);
	Ext.apply(this, config, {
		init: function(grid) {
			this.grid = grid;
			this.grid.on('render', function() {
				var view = this.grid.getView();
				view.mainBody.on('mousedown', this.onMouseDown, this);
			}, this);
		},
		onMouseDown: function(e, t) {
			e.stopEvent();
			var field = this.dataIndex;
			var index = this.grid.getView().findRowIndex(t);
			var record = this.grid.store.getAt(index);
			if (!record.data[field]) {
				var i = 0;
				Ext.each(this.grid.store.data.items, function(rec) {
					if (i != index) {
						record.data[this.dataIndex] = false;
					}
					i++;
				}, this);
				record.data[this.dataIndex] = true;
				Ext.get(t).removeClass('x-grid3-radio-col');
				Ext.get(t).addClass('x-grid3-radio-col-on');
				this.fireEvent('click', this, e, record);
			}
		},
		renderer: function(value, metadata, record, rowIndex, colIndex, store) {
			metadata.css += ' radioColCell'
			return '<input type="radio" value="value" class="x-grid3-radio-col' + (value ? '-on' : '') + ' x-grid3-rb-' + this.id + '" name="rb-' + this.id + '-' + colIndex + '" ' + (value ? ' checked="checked"' : '') + '>';
		}
	});
	this.renderer = this.renderer.createDelegate(this);
};
Ext.extend(Ext.grid.RadioColumn, Ext.util.Observable);
/*******************************************************************************
 * Support for Printing specified Ext.Element's with specified parameters
 * 
 * @version 0.4
 * @author nerdydude81
 */
Ext.override(Ext.Element, {
	// @cfg {string} css A string containing a css style text.
	css: ''
	// @cfg {string} printCSS The file path of a CSS file for printout.
	,
	printCSS: "css/print.css"
	//// @cfg {string} addHeader Additional HTML text to add a the top.
	//, addHeader: { tpl: '<h1><IMG src="http://www.schooldynamics.net/images/icon_infodirect_logo.png" /> INFO<span>DIRECT</span></h1>\n<h3>{schoolname}</h3>', store: schoolnamestore}
	//// @cfg {string} addFooter Additional HTML text to add a the bottom.
	//, addFooter: ''//<div id="footer"><h4><em>Powered by</em> InfoDirect</h4><div><h6>Copyright &copy; {year} School Dynamics<h6></div></div>
	// @cfg {Boolean} printStyle Copy the style attribute of this element to the print iframe.
	,
	printStyle: true
	// @property {string} printTitle Page Title for printout. 
	,
	printTitle: document.title
	// @cfg {Boolean} printLandscape Set the default orientation for this print job.
	,
	printLandscape: false
/* handles a messagebox for reports designed for landscape view before printing the report.
     * @param config {object} (optional)
     */
	,
	print: function(config) {
		Ext.apply(this, config);
		var el = this; // gives the alert's callback function access to the current "this" variable
		if (this.printLandscape == true) {
			Ext.MessageBox.show({
				title: "School Dynamics",
				msg: "This report prints best in Landscape view.",
				buttons: Ext.MessageBox.OK,
				fn: function(btn) {
					el._print(config);
				}
			});
		} else {
			this._print(config);
		}
	}
/* Prints this element.
     * @param config {object} (optional)
     */
	,
	_print: function(config) {
		Ext.apply(this, config);
		var el = Ext.get(this.id).dom;
		var c = document.getElementById('printcontainer');
		var iFrame = document.getElementById('printframe');
		var oRequest = new XMLHttpRequest();
		if (typeof oRequest == 'undefined') oRequest = new ActiveXObject("Msxml2.XMLHTTP"); //IE fix
		if (typeof oRequest == 'undefined') oRequest = new ActiveXObject("Microsoft.XMLHTTP"); //IE fix
		if (window.location.href.indexOf("schooldynamics") == -1) {
			oRequest.open("GET", "http://localhost/v3/print.html", false);
		} else {
			oRequest.open("GET", "https://www.schooldynamics.net/v3/print.html", false);
		}
		oRequest.setRequestHeader("User-Agent", navigator.userAgent);
		oRequest.send(null);
		if (oRequest.status != 200) {
			Ext.Msg.alert('Status', 'Error printing document!');
			return;
		}
		var strTemplate = oRequest.responseText;
		var strLinkTpl = '<link rel="stylesheet" type="text/css" href="{0}" media="print" />';
		var strAttr = '';
		var strFormat;
		var strHTML;
		//Get rid of the old crap so we don't copy it to our iframe
		//if (iFrame!=undefined)if (iFrame != null) c.removeChild(iFrame);
		//if (c != null) el.removeChild(c);
		//Copy attributes from this element.
		for (var i = 0; i < el.attributes.length; i++) {
			if (Ext.isEmpty(el.attributes[i].value) || el.attributes[i].value.toLowerCase() != 'null') {
				strFormat = Ext.isEmpty(el.attributes[i].value) ? '{0}="true" ' : '{0}="{1}" ';
				if (this.printStyle ? this.printStyle : el.attributes[i].name.toLowerCase() != 'style') strAttr += String.format(strFormat, el.attributes[i].name, el.attributes[i].value);
			}
		}
		var strLink = '';
		if (this.printCSS) {
			if (!Ext.isArray(this.printCSS)) this.printCSS = [this.printCSS];
			for (var i = 0; i < this.printCSS.length; i++) strLink += String.format(strLinkTpl, this.printCSS[i]);
		}
		strHTML = strTemplate;
		strHTML = strHTML.replace("{css}", strLink);
		strHTML = strHTML.replace("{title}", this.printTitle);
		strHTML = strHTML.replace("{title}", this.printTitle); //IE Fix
		strHTML = strHTML.replace("{schoolname}", SchoolDynamics.SchoolName);
		strHTML = strHTML.replace("{onload}", (Ext.isIE ? 'document.execCommand(\'print\');' : 'window.print();'));
		strHTML = strHTML.replace("{customizations}", strAttr);
		strHTML = strHTML.replace("{content}", (el.innerHTML ? el.innerHTML : (el.value ? el.value : "")));
		strHTML = strHTML.replace(' disabled="false" ', ''); //IE fix
		//I coun't get FF to print a hidden iframe, so I encapsulated it in a hidden div.
		c = document.createElement('div');
		c.setAttribute('style', 'width:0px;height:0px;' + (Ext.isSafari ? 'display:none;' : 'visibility:hidden;'));
		c.setAttribute('id', 'printcontainer');
		el.appendChild(c);
		//IE doesn't like style attributes anymore?
		if (Ext.isIE) c.style.display = 'none';
		iFrame = document.createElement('iframe');
		iFrame.setAttribute('id', 'printframe');
		iFrame.setAttribute('name', 'printframe');
		c.appendChild(iFrame);
		//Write our new document to the iframe
		iFrame.contentWindow.document.open();
		iFrame.contentWindow.document.write(strHTML);
		iFrame.contentWindow.document.close();
		//console.log(strHTML);
	}
});
Ext.override(Ext.Component, {
	printEl: function(config) {
		this.el.print(Ext.isEmpty(config) ? this.initialConfig : config);
	},
	printBody: function(config) {
		this.body.print(Ext.isEmpty(config) ? this.initialConfig : config);
	}
});
Ext.override(Ext.Panel, {
	printEl: function(config) {
		this.el.print(Ext.isEmpty(config) ? this.initialConfig : config);
	},
	printBody: function(config) {
		this.body.print(Ext.isEmpty(config) ? this.initialConfig : config);
	}
}); /******************************************************************************/
/*
Ext.override(Ext.form.DateField, {
    hide: function(datefield) {
         this.fireEvent('change',datefield, datefield.getValue() );
         this.fireEvent('hide',datefield );
    }
});
*/
Ext.form.DateField.prototype.onMenuHide = function() {
	this.fireEvent('change', this, this.getValue());
	this.fireEvent('blur', this);
};
Ext.link = Ext.extend(Ext.Button, {
	constructor: function(config) {
		this.cls = 'x-link';
		Ext.link.superclass.constructor.apply(this, arguments);
	}
});
Ext.ComponentMgr.registerType('link', Ext.link);
Ext.toolboxtext = Ext.extend(Ext.form.Label, {
	constructor: function(config) {
		this.cls = 'toolbartext ';
		Ext.toolboxtext.superclass.constructor.apply(this, arguments);
		this.cls = this.cls + this.iconCls;
	}
});
Ext.ComponentMgr.registerType('toolboxtext', Ext.toolboxtext);
//if a combo's store isn't loaded when combo.setValue() is called, load the store and select the value
Ext.override(Ext.form.ComboBox, {
	minChars: 1,
	allowBlank: true,
	valueNotFoundText: '',
	typeAhead: true,
	triggerAction: 'all',
	setValue: function(v, suppressEvent) {
		var oldValue = this.value;
		var text = v;
		if (this.valueField) {
			if (this.mode == 'remote' && !Ext.isDefined(this.store.totalLength)) {
				this.store.on('load', this.setValue.createDelegate(this, arguments), null, {
					single: true
				});
				if (this.store.lastOptions === null) {
					var params;
					if (this.valueParam) {
						params = {};
						params[this.valueParam] = v;
					} else {
						var q = this.allQuery;
						this.lastQuery = q;
						this.store.setBaseParam(this.queryParam, q);
						params = this.getParams(q);
					}
					this.store.load({
						params: params
					});
				}
				this.mode = 'local';
				this.firstLoad = true;
				return;
			}
			var r = this.findRecord(this.valueField, v);
			if (r) {
				text = r.data[this.displayField];
			} else if (this.valueNotFoundText !== undefined) {
				text = this.valueNotFoundText;
			}
		}
		this.lastSelectionText = text;
		if (this.hiddenField) {
			this.hiddenField.value = v;
		}
		Ext.form.ComboBox.superclass.setValue.call(this, text);
		this.value = v;
		if (this.firstLoad != undefined && this.firstLoad) {
			this.fireEvent('select', this, r, this.selectedIndex); //fire the select event, so there is an event to handle the value when it is first set
			this.firstLoad = false;
		}
		if (!suppressEvent) {
			if (this.value != oldValue) this.fireEvent('setValue', this, this.value, oldValue);
		}
		return this;
	},
	onViewClick: function() {
		var index = this.view.getSelectedIndexes()[0],
			s = this.store,
			r = s.getAt(index);
		if (r) {
			this.onSelect(r, index);
		} else {
			this.collapse();
		}
	},
	focus: function(selectText, delay) {
		if (delay) {
			this.focus.defer(Ext.isNumber(delay) ? delay : 10, this, [selectText, false]);
			return;
		}
		if (this.rendered) {
			this.el.focus();
			if (selectText === true) {
				this.el.dom.select();
			}
		}
		if (this.getValue() == '') {
			this.expand();
		}
		return this;
	},
	onTriggerClick: function() {
		if (this.disabled) {
			return;
		}
		if (this.isExpanded()) {
			this.collapse();
			this.el.focus();
		} else {
			this.onFocus({});
			if (this.triggerAction == 'all') {
				var tempmode = undefined;
				if (!(this.store.data.length < 1)) {
					tempmode = this.mode;
					this.mode = 'local';
				}
				this.doQuery(this.allQuery, true);
				if (tempmode != undefined) {
					this.mode = tempmode;
				}
			} else {
				this.doQuery(this.getRawValue());
			}
			this.el.focus();
		}
	},
	initEvents: function() {
		Ext.form.ComboBox.superclass.initEvents.call(this);
		this.keyNav = new Ext.KeyNav(this.el, {
			"up": function(e) {
				this.inKeyMode = true;
				this.selectPrev();
			},
			"down": function(e) {
				if (!this.isExpanded()) {
					this.onTriggerClick();
				} else {
					this.inKeyMode = true;
					this.selectNext();
				}
			},
			"enter": function(e) {
				this.onViewClick();
			},
			"esc": function(e) {
				this.collapse();
			},
			"tab": function(e) {
				this.collapse();
				return true;
			},
			scope: this,
			doRelay: function(e, h, hname) {
				if (hname == 'down' || this.scope.isExpanded()) {
					var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
					if (!Ext.isIE && Ext.EventManager.useKeydown) {
						this.scope.fireKey(e);
					}
					return relay;
				}
				return true;
			},
			forceKeyDown: true,
			defaultEventAction: 'stopEvent'
		});
		this.queryDelay = Math.max(this.queryDelay || 10, this.mode == 'local' ? 10 : 250);
		this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
		if (this.typeAhead) {
			this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
		}
		if (!this.enableKeyEvents) {
			this.mon(this.el, 'keyup', this.onKeyUp, this);
		}
		if (this.store != undefined) {
			if (this.store.combos == undefined) {
				this.store.combos = [];
			}
			this.store.combos.push(this);
		}
	},
	getValueRecord: function() {
		var value = this.getValue();
		var record = this.getRecordByValue(value);
		return record;
	},
	getRecordByValue: function(value) {
		var recIndex = this.store.find(this.valueField, value);
		var record = this.store.getAt(recIndex);
		return record;
	}
});
Ext.util.Observable.observeClass(Ext.data.Store);
Ext.data.Store.on('load', function(store, records) {
	if (records.length > 0 && store.combos != undefined) {
		for (i = 0; i < store.combos.length; i++) {
			store.combos[i].mode = 'local';
		}
	}
});
Ext.data.Store.on('beforeload', function(store) {
	if (SchoolDynamics.extendedAccessID !== undefined && SchoolDynamics.extendedAccessID !== '') {
		store.baseParams.extendedAccessID = SchoolDynamics.extendedAccessID;
	} else {
		delete store.baseParams.extendedAccessID;
	}
});
Ext.override(Ext.data.Store, {
	copyData: function(destStore) {
		var data = new Array();
		for (var i = 0, ilen = this.data.items.length; i < ilen; i++) {
			var rec = this.data.items[i];
			var fields = rec.fields.items;
			var record = new Array();
			for (var j = 0, jlen = fields.length; j < jlen; j++) {
				record.push(rec.data[fields[j].name]);
			}
			data.push(record);
		}
		destStore.loadData(data, false);
	},
	moveData: function(destStore) {
		this.copyData(destStore);
		this.removeAll();
	},
	addField: function(field) {
		field = new Ext.data.Field(field);
		this.recordType.prototype.fields.replace(field);
		if (typeof field.defaultValue != 'undefined') {
			this.each(function(r) {
				if (typeof r.data[field.name] == 'undefined') {
					r.data[field.name] = field.defaultValue;
				}
			});
		}
		delete this.reader.ef;
		this.reader.buildExtractors();
	},
	removeField: function(name) {
		this.recordType.prototype.fields.removeKey(name);
		this.each(function(r) {
			delete r.data[name];
			if (r.modified) {
				delete r.modified[name];
			}
		});
		delete this.reader.ef;
		this.reader.buildExtractors();
	},
	removeAllFields: function() {
		if (this.fields != undefined) {
			var fldnames = this.fields.keys;
			for (var i = 0, len = fldnames.length; i < len; len--) {
				this.removeField(fldnames[len]);
			}
		}
	}
});
Ext.override(Ext.grid.ColumnModel, {
	addColumn: function(column, colIndex) {
		if (typeof column == 'string') {
			column = {
				header: column,
				dataIndex: column
			};
		}
		var config = this.config;
		this.config = [];
		if (typeof colIndex == 'number') {
			config.splice(colIndex, 0, column);
		} else {
			colIndex = config.push(column);
		}
		this.setConfig(config);
		return colIndex;
	},
	removeColumn: function(colIndex) {
		var config = this.config;
		this.config = [config[colIndex]];
		config.splice(colIndex, 1);
		this.setConfig(config);
	}
});
Ext.override(Ext.grid.GridPanel, {
	configBuffer: [],
	addColumn: function(defaultValue, field, column, colIndex) {
		if (typeof field == 'string' || typeof field == 'number') {
			field = new Ext.data.Field({
				name: field.toString(),
				defaultValue: defaultValue
			});
		}
		if (!column) {
			if (field.dataIndex) {
				column = field;
				field = field.dataIndex;
			} else {
				column = field.name || field;
			}
		}
		this.store.addField(field);
		return this.colModel.addColumn(column, colIndex);
	},
	addToColumnBuffer: function(defaultValue, field, column, colIndex) {
		if (typeof field == 'string' || typeof field == 'number') {
			field = new Ext.data.Field({
				name: field.toString(),
				defaultValue: defaultValue
			});
		}
		if (!column) {
			if (field.dataIndex) {
				column = field;
				field = field.dataIndex;
			} else {
				column = field.name || field;
			}
		}
		this.store.addField(field);
		this.configBuffer.push(column);
	},
	removeColumn: function(name, colIndex) {
		this.store.removeField(name);
		if (typeof colIndex != 'number') {
			colIndex = this.colModel.findColumnIndex(name);
		}
		if (colIndex >= 0) {
			this.colModel.removeColumn(colIndex);
		}
	},
	removeAllColumns: function() {
		var fldnames = this.store.fields.keys;
		for (var i = 0, len = fldnames.length; i < len; len--) {
			this.removeColumn(fldnames[len]);
		}
	}
});
Ext.grid.CheckboxSelectionModel.override({
	initEvents: function() {
		Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
		this.grid.on('render', function() {
			var view = this.grid.getView();
			view.mainBody.on('mousedown', this.onMouseDown, this);
			Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
		}, this);
	}
});
Ext.grid.GridDragZone.override({
	handleMouseDown: function(e, t) {
		if (t.className == 'x-grid3-row-checker') return false;
		Ext.grid.GridDragZone.superclass.handleMouseDown.apply(this, arguments);
	}
});
/********************************************************************** 
 * add mouseclick focus() and blur() functionality to the Ext.Panel
 */
Ext.override(Ext.Panel, {
	hasFocus: false,
	handleDocMouseDown: function(e) {
		if (!e.within(this.getEl()) && this.hasFocus) {
			this.hasFocus = false;
			this.fireEvent('blur', this);
		} else if (e.within(this.getEl()) && !this.hasFocus) {
			this.hasFocus = true;
			this.fireEvent('focus', this);
		}
	}
});
Ext.util.Observable.observeClass(Ext.Panel);
Ext.Panel.on('beforerender', function(panel) {
	Ext.getDoc().on("mousedown", panel.handleDocMouseDown, panel);
	panel.addEvents({
		focus: true,
		blur: true
	});
}); /*********************************************************************/
Ext.grid.EditorGridPanel.override({
	clicksToEdit: 2
});
// CellSelectionModel override to move edited cell down/up on Shift+Enter key
Ext.grid.GridPanel.override({
	ltrTab: true
});
Ext.override(Ext.grid.CellSelectionModel, {
	handleKeyDown: function(e) {
		if (!e.isNavKeyPress()) {
			return;
		}
		var g = this.grid,
			s = this.selection;
		if (!s) {
			e.stopEvent();
			var cell = g.walkCells(0, 0, 1, this.isSelectable, this);
			if (cell) {
				this.select(cell[0], cell[1]);
			}
			return;
		}
		var sm = this;
		var walk = function(row, col, step, ltr) {
			if (!ltr) {
				var numrows = g.store.data.length;
				var numcols = g.colModel.columns.length;
				if (0 < step && row == numrows) { // down
					row = 0;
					col = (numcols - col != 1 ? col + 1 : 0);
				}
				if (step < 0 && row < 0) { // up
					row = numrows - (col != 0 ? 1 : 0);
					col--;
				}
			}
			return g.walkCells(row, col, step, sm.isSelectable, sm);
		};
		var k = e.getKey(),
			r = s.cell[0],
			c = s.cell[1];
		var newCell;
		switch (k) {
		case e.TAB:
			if (e.shiftKey) {
				newCell = walk(r - (g.ltrTab ? 0 : 1), c - (g.ltrTab ? 1 : 0), -1, g.ltrTab);
			} else {
				newCell = walk(r + (g.ltrTab ? 0 : 1), c + (g.ltrTab ? 1 : 0), 1, g.ltrTab);
			}
			break;
		case e.DOWN:
			newCell = walk(r + 1, c, 1, false);
			break;
		case e.UP:
			newCell = walk(r - 1, c, -1, false);
			break;
		case e.RIGHT:
			newCell = walk(r, c + 1, 1, true);
			break;
		case e.LEFT:
			newCell = walk(r, c - 1, -1, true);
			break;
		case e.ENTER:
			if (g.isEditor && !g.editing) {
				g.startEditing(r, c);
				e.stopEvent();
				return;
			}
			break;
		}
		if (newCell) {
			this.select(newCell[0], newCell[1]);
			if (g.isEditor && k == e.TAB) {
				g.stopEditing();
				g.startEditing(newCell[0], newCell[1]);
			}
			e.stopEvent();
		}
	}
});
Ext.override(Ext.tree.TreeNode, {
	findDescendant: function(attribute, value) {
		var children = this.childNodes;
		for (var i = 0, l = children.length; i < l; i++) {
			if (children[i].attributes[attribute] == value) {
				return children[i];
			} else if (node = children[i].findDescendant(attribute, value)) {
				return node;
			}
		}
		return null;
	}
});
Ext.util.Observable.observeClass(Ext.grid.CheckboxSelectionModel);
Ext.grid.CheckboxSelectionModel.on('rowselect', function(sm, rowIndex, record) {
	var i = 1;
	if (record.node != undefined) {
		Ext.each(record.node.childNodes, function(cnode) {
			sm.selectRow(rowIndex + i, true);
			i++;
		}, this);
	}
});
Ext.grid.CheckboxSelectionModel.on('rowdeselect', function(sm, rowIndex, record) {
	var i = 1;
	if (record.node != undefined) {
		Ext.each(record.node.childNodes, function(cnode) {
			sm.deselectRow(rowIndex + i);
			i++;
		}, this);
	}
});
Ext.grid.RadioSelectionModel = Ext.extend(Ext.grid.CheckboxSelectionModel, {
	singleSelect: true,
	header: '',
	constructor: function() {
		Ext.grid.RadioSelectionModel.superclass.constructor.apply(this, arguments);
	},
	renderer: function(v, p, record) {
		return '<div class="x-grid3-row-checker x-grid3-radio-checker">&#160;</div>';
	}
});
Ext.grid.GroupingView.override({
	toggleGroup: function(group, expanded) {
		var gel = Ext.get(group);
		expanded = Ext.isDefined(gel.selected) ? gel.selected : (Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed'));
		if (this.fireEvent('beforetoggleGroup', this, gel, expanded) === false) return false;
		if (this.state[gel.id] !== expanded) {
			this.grid.stopEditing(true);
			this.state[gel.id] = expanded;
			gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
			this.fireEvent('toggleGroup', this, gel, expanded);
		}
	}
});
Ext.form.Field.override({
	setValue: function(v) {
		var oldValue = this.value;
		this.value = v;
		if (this.rendered) {
			this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
			this.validate();
		}
		if (this.xtype != 'combo' && this.value != oldValue) {
			this.fireEvent('setValue', this, this.value, oldValue);
		}
		return this;
	},
	setReadOnly: function(readOnly) {
		if (readOnly == this.readOnly) {
			return;
		}
		this.readOnly = readOnly;
		if (readOnly) {
			this.el.dom.setAttribute('readOnly', true);
		} else {
			this.el.dom.removeAttribute('readOnly');
		}
	}
});
/***************************************
 * Custom mouse cursors for gripanels
 */
Ext.override(Ext.grid.GridView, {
	getColumnData: function() {
		var cs = [],
			cm = this.cm,
			colCount = cm.getColumnCount();
		for (var i = 0; i < colCount; i++) {
			var name = cm.getDataIndex(i);
			cs[i] = {
				name: (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),
				renderer: cm.getRenderer(i),
				scope: cm.getRendererScope(i),
				id: cm.getColumnId(i),
				cls: cm.config[i].cls || '',
				// ADDED
				style: this.getColumnStyle(i)
			};
		}
		return cs;
	},
	doRender: function(cs, rs, ds, startRow, colCount, stripe) {
		var ts = this.templates,
			ct = ts.cell,
			rt = ts.row,
			last = colCount - 1;
		var tstyle = 'width:' + this.getTotalWidth() + ';';
		var buf = [],
			cb, c, p = {},
			rp = {
				tstyle: tstyle
			},
			r;
		for (var j = 0, len = rs.length; j < len; j++) {
			r = rs[j];
			cb = [];
			var rowIndex = (j + startRow);
			for (var i = 0; i < colCount; i++) {
				c = cs[i];
				p.id = c.id;
				p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
				p.css += ' ' + c.cls || ''; // ADDED
				p.attr = p.cellAttr = '';
				p.value = c.renderer.call(c.scope, r.data[c.name], p, r, rowIndex, i, ds);
				p.style = c.style;
				if (Ext.isEmpty(p.value)) {
					p.value = ' ';
				}
				if (this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])) {
					p.css += ' x-grid3-dirty-cell';
				}
				cb[cb.length] = ct.apply(p);
			}
			var alt = [];
			if (stripe && ((rowIndex + 1) % 2 === 0)) {
				alt[0] = 'x-grid3-row-alt';
			}
			if (r.dirty) {
				alt[1] = ' x-grid3-dirty-row';
			}
			rp.cols = colCount;
			if (this.getRowClass) {
				alt[2] = this.getRowClass(r, rowIndex, rp, ds);
			}
			rp.alt = alt.join(' ');
			rp.cells = cb.join('');
			buf[buf.length] = rt.apply(rp);
		}
		return buf.join('');
	}
});
Ext.util.Observable.observeClass(Ext.grid.GridPanel);
Ext.grid.GridPanel.on('beforerender', function(grid) {
	if (grid.enableDragDrop) {
		grid.addClass('draggable_rows');
	}
	var columns = grid.colModel.config;
	for (var i = 0, len = columns.length; i < len; i++) {
		if (columns[i].editor != undefined) {
			if (columns[i].editor != null) {
				//column is editable
				columns[i].cls = 'editable';
			}
			//if the columns renderer is powered by a store in the editor, load the store.
			if (columns[i].editor.field != undefined && columns[i].editor.field.store != undefined && columns[i].editor.field.store.data.length < 1) {
				columns[i].editor.field.store.load({
					callback: function(records, options, success) {
						// the grid's view must be refreshed for the renderer to be re-called
						this.view.refresh();
					},
					scope: grid,
					add: false
				});
			}
		}
	}
}); /************************************************/
Ext.data.MotherStore = Ext.extend(Ext.data.Store, {
	childStores: [],
	constructor: function() {
		Ext.data.MotherStore.superclass.constructor.apply(this, arguments);
		this.on("load", this.onLoad, this);
	},
	createChildStore: function(filterProperty, filterValue) {
		var childStore = new Ext.data.Store({
			filterProperty: filterProperty,
			filterValue: filterValue,
			motherStore: this,
			reader: new Ext.data.ArrayReader({}, this.fields.items),
			load: function() {
				records = this.motherStore.query(this.filterProperty, this.filterValue);
				this.removeAll(false, true);
				if (records.length > 0) this.add(records.items, true);
			},
			removeAll: function(silent, blockDeletes) {
				var items = [];
				this.each(function(rec) {
					items.push(rec);
				});
				this.clearData();
				if (this.snapshot) {
					this.snapshot.clear();
				}
				if (this.pruneModifiedRecords) {
					this.modified = [];
				}
				if (silent !== true) { // <-- prevents write-actions when we just want to clear a store.
					this.fireEvent('clear', this, items, blockDeletes);
				}
			},
			add: function(records, isSilent) {
				records = [].concat(records);
				if (records.length < 1) {
					return;
				}
				for (var i = 0, len = records.length; i < len; i++) {
					records[i].join(this);
				}
				var index = this.data.length;
				this.data.addAll(records);
				if (this.snapshot) {
					this.snapshot.addAll(records);
				}
				this.fireEvent('add', this, records, index, isSilent);
			},
			setFilter: function(filterProperty, filterValue) {
				this.filterProperty = filterProperty;
				this.filterValue = filterValue;
			},
			listeners: {
				add: function(store, records, index, isSilent) {
					if (isSilent == undefined || !isSilent) {
						this.motherStore.add(records);
					}
				},
				remove: function(store, records, index) {
					this.motherStore.remove(records);
				},
				clear: function(store, records, blockDeletes) {
					if (blockDeletes == undefined || !blockDeletes) {
						this.motherStore.remove(records);
					}
				}
			},
			afterEdit: function(record) {
				if (this.modified.indexOf(record) == -1) {
					this.modified.push(record);
				}
				this.fireEvent('update', this, record, Ext.data.Record.EDIT);
				this.motherStore.afterEdit(record);
			},
			afterReject: function(record) {
				this.modified.remove(record);
				this.fireEvent('update', this, record, Ext.data.Record.REJECT);
				this.motherStore.afterReject(record);
			},
			afterCommit: function(record) {
				this.modified.remove(record);
				this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
				this.motherStore.afterCommit(record);
			}
		});
		this.childStores.push(childStore);
		childStore.load();
		return childStore;
	},
	loadChildren: function() {
		for (i = 0; i < this.childStores.length; i++) {
			this.childStores[i].load();
		}
	},
	onLoad: function() {
		this.loadChildren();
	}
});
//FROM: http://www.extjs.com/forum/showthread.php?21913-SOLVED-Grid-Drag-and-Drop-reorder-rows
Ext.namespace('Ext.ux.dd');
Ext.ux.dd.GridReorderDropTarget = function(grid, config) {
	this.target = new Ext.dd.DropTarget(grid.getEl(), {
		ddGroup: grid.ddGroup || 'GridDD',
		grid: grid,
		gridDropTarget: this,
		notifyDrop: function(dd, e, data) {
			// determine the row
			var t = Ext.lib.Event.getTarget(e);
			var rindex = this.grid.getView().findRowIndex(t);
			if (rindex === false) return false;
			if (rindex == data.rowIndex) return false;
			// fire the before move/copy event
			if (this.gridDropTarget.fireEvent(this.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections) === false) return false;
			// update the store
			var ds = this.grid.getStore();
			if (!this.copy) {
				for (i = 0; i < data.selections.length; i++) {
					ds.remove(ds.getById(data.selections[i].id));
				}
			}
			ds.insert(rindex, data.selections);
			// re-select the row(s)
			var sm = this.grid.getSelectionModel();
			if (sm) sm.selectRecords(data.selections);
			// fire the after move/copy event
			this.gridDropTarget.fireEvent(this.copy ? 'afterrowcopy' : 'afterrowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections);
			return true;
		},
		notifyOver: function(dd, e, data) {
			var t = Ext.lib.Event.getTarget(e);
			var rindex = this.grid.getView().findRowIndex(t);
			if (rindex == data.rowIndex) rindex = false;
			return (rindex === false) ? this.dropNotAllowed : this.dropAllowed;
		}
	});
	if (config) {
		Ext.apply(this.target, config);
		if (config.listeners) Ext.apply(this, {
			listeners: config.listeners
		});
	}
	this.addEvents({
		"beforerowmove": true,
		"afterrowmove": true,
		"beforerowcopy": true,
		"afterrowcopy": true
	});
	Ext.ux.dd.GridReorderDropTarget.superclass.constructor.call(this);
};
Ext.extend(Ext.ux.dd.GridReorderDropTarget, Ext.util.Observable, {
	getTarget: function() {
		return this.target;
	},
	getGrid: function() {
		return this.target.grid;
	},
	getCopy: function() {
		return this.target.copy ? true : false;
	},
	setCopy: function(b) {
		this.target.copy = b ? true : false;
	}
});
Ext.override(Ext.form.Field, {
	initEvents: function() {
		this.mon(this.el, Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.fireKey, this);
		this.mon(this.el, 'focus', this.onFocus, this);
		this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {
			buffer: 10
		} : null);
		if (this.label != undefined) {
			this.on({
				'hide': this.onHide2,
				'show': this.onShow2,
				scope: this
			});
			if (this.hidden) {
				this.hide();
			}
		}
	},
	onHide2: function() {
		this.label.hide();
	},
	onShow2: function() {
		this.label.show();
	}
});
Ext.override(Ext.data.GroupingStore, {
	getByGroupId: function(groupid) {
		var records = new Array();
		Ext.each(this.data.items, function(rec) {
			if (rec._groupId == groupid) records.push(rec);
		}, this);
		return records;
	},
	findInGroup: function(groupid, field, value) {
		var gRecs = this.getByGroupId(groupid),
			records = new Array();
		Ext.each(gRecs, function(rec) {
			if (in_array(value, rec.data)) records.push(rec);
		}, this);
		return records;
	}
});
Ext.override(Ext.chart.Chart, {
	refresh: function() {
		var styleChanged = false;
		// convert the store data into something YUI charts can understand
		var data = [],
			rs = this.store.data.items;
		for (var j = 0, len = rs.length; j < len; j++) {
			data[j] = rs[j].data;
		}
		//make a copy of the series definitions so that we aren't
		//editing them directly.
		var dataProvider = [];
		var seriesCount = 0;
		var currentSeries = null;
		var i = 0;
		if (this.series) {
			seriesCount = this.series.length;
			for (i = 0; i < seriesCount; i++) {
				currentSeries = this.series[i];
				var clonedSeries = {};
				for (var prop in currentSeries) {
					if (prop == "style" && currentSeries.style !== null) {
						clonedSeries.style = Ext.encode(currentSeries.style);
						styleChanged = true;
						//we don't want to modify the styles again next time
						//so null out the style property.
						// this causes issues
						// currentSeries.style = null;
					} else {
						clonedSeries[prop] = currentSeries[prop];
					}
				}
				dataProvider.push(clonedSeries);
			}
		}
		if (seriesCount > 0) {
			for (i = 0; i < seriesCount; i++) {
				currentSeries = dataProvider[i];
				if (!currentSeries.type) {
					currentSeries.type = this.type;
				}
				currentSeries.dataProvider = data;
			}
		} else {
			dataProvider.push({
				type: this.type,
				dataProvider: data
			});
		}
		//this.swf.setDataProvider(dataProvider);
		if (this.swf && this.swf.setDataProvider) { // fix
			this.swf.setDataProvider(dataProvider);
		}
	}
});
//**************************************************
// add observable properties to Ext.data.Connection
Ext.util.Observable.observeClass = function(c) {
	Ext.apply(c, new Ext.util.Observable());
	c.prototype.fireEvent = function() {
		return (c.fireEvent.apply(c, arguments) !== false) && (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false);
	};
};
Ext.override(Ext.util.Observable, {
	addListener: Ext.util.Observable.prototype.addListener.createInterceptor(function() {
		if (!this.events) {
			this.events = {};
		}
	})
});
Ext.util.Observable.prototype.on = Ext.util.Observable.prototype.addListener;
Ext.util.Observable.observeClass(Ext.data.Connection);
//**************************************************
var loadingstarted = 0,
	loadingfinished = 0,
	loadingprogress = 0;

function updateProgress() {
	loadingfinished++;
	loadingprogress = loadingfinished / loadingstarted;
	Ext.MessageBox.updateProgress((isNaN(loadingprogress) ? 1 : loadingprogress), (isNaN(Math.round(100 * loadingprogress)) ? '100' : Math.round(100 * loadingprogress)) + '% completed');
	if (loadingstarted <= loadingfinished) {
		loadingstarted = 0, loadingfinished = 0;
		Ext.MessageBox.hide();
	}
}
Ext.data.Connection.on('beforerequest', function(con, options) {
	if (options.scope === undefined || options.scope.writeWait === undefined || options.scope.writeWait || (options.params.xaction != 'create' && options.params.xaction != 'update')) {
		loadingstarted++;
		if (!Ext.MessageBox.isVisible()) Ext.MessageBox.show({
			title: 'Please Wait',
			/*msg: 'Loading...',*/
			progressText: 'Loading...',
			width: 300,
			progress: true,
			closable: false,
			modal: false
		});
	}
});
Ext.data.Connection.on('requestcomplete', function(con, response, options) {
	if (options.scope === undefined || options.scope.writeWait === undefined || options.scope.writeWait || (options.params.xaction != 'create' && options.params.xaction != 'update')) {
		updateProgress();
	}
});
Ext.data.Connection.on('requestexception', function(con, response, options) {
	if (options.scope === undefined || options.scope.writeWait === undefined || options.scope.writeWait || (options.params.xaction != 'create' && options.params.xaction != 'update')) {
		updateProgress();
	}
	if (response.status == 403) {
		Ext.MessageBox.alert('ERROR', 'You do not have permission to access this page');
	}
	if (response.status == 401) {
		window.location = response.responseText;
	}
});
Ext.lib.Ajax.request = Ext.lib.Ajax.request.createInterceptor(function(method, uri, cb, data, options) {
	//run universal code on "failure"
	if (options.scope === undefined || options.scope.writeWait === undefined || options.scope.writeWait || options.params.xaction != 'create') {
		cb.failure = cb.failure.createInterceptor(function(response) {
			updateProgress();
		});
	}
});
Ext.data.Connection.on('beforerequest', function(con, options) {
	if (options.method === undefined || options.method.toLowerCase() != 'post') {
		if (SchoolDynamics.extendedAccessID !== undefined && SchoolDynamics.extendedAccessID !== '') {
			if (options.params) {
				options.params.extendedAccessID = SchoolDynamics.extendedAccessID;
			} else {
				options.params = {
					extendedAccessID: SchoolDynamics.extendedAccessID
				};
			}
		} else {
			if (options.params !== undefined) {
				delete options.params.extendedAccessID;
			}
		}
	}
});
Ext.override(Ext.data.Store, {
	batchRemove: function(records) {
		if (this.autoSave) {
			this.autoSave = false;
			this.remove(records);
			this.autoSave = true;
			this.save();
		} else {
			this.remove(records);
		}
	}
});
Ext.override(Ext.tree.TreeNodeUI, {
	renderElements: function(n, a, targetNode, bulkRender) {
		// add some indent caching, this helps performance when rendering a large tree
		this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
		var cb = Ext.isBoolean(a.checked),
			nel, href = a.href ? a.href : Ext.isGecko ? "" : "#",
			buf = ['<li class="x-tree-node"><div ext:tree-node-id="', n.id, '" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls, '" unselectable="on">', '<span class="x-tree-node-indent">', this.indentMarkup, "</span>", '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />', cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '', '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon', (a.icon ? " x-tree-node-inline-icon" : ""), (a.iconCls ? " " + a.iconCls : ""), '" unselectable="on" />', '<a hidefocus="on" class="x-tree-node-anchor" href="', href, '" tabIndex="1" ', a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">', n.text, "</span></a></div>", '<ul class="x-tree-node-ct" style="display:none;"></ul>', "</li>"].join('');
		if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
			this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
		} else {
			this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
		}
		this.elNode = this.wrap.childNodes[0];
		this.ctNode = this.wrap.childNodes[1];
		var cs = this.elNode.childNodes;
		this.indentNode = cs[0];
		this.ecNode = cs[1];
		this.iconNode = cs[2];
		var index = 3;
		if (cb) {
			this.iconNode = cs[3];
			this.checkbox = cs[2];
			// fix for IE6
			this.checkbox.defaultChecked = this.checkbox.checked;
			index++;
			Ext.get(this.checkbox).addListener('click', function(e) {
				if (n.ownerTree.selModel.isSelected(n)) {
					n.ownerTree.selModel.unselect(n);
				} else {
					n.ownerTree.selModel.selectNode(n);
					if (e.shiftKey) {
						n.ownerTree.selModel.selectChildren(n);
					}
				}
			});
		}
		this.anchor = cs[index];
		this.textNode = cs[index].firstChild;
	}
});
Ext.override(Ext.form.BasicForm, {
	getExtFields: function() {
		elements = this.el.dom.elements;
		fields = [];
		Ext.each(elements, function(element) {
			field = Ext.getCmp(element.id);
			if (field !== undefined) {
				fields.push(field);
			}
		});
		return fields;
	}
});
Ext.override(Ext.grid.CheckboxSelectionModel, {
	selectAll: function() {
		if (this.isLocked()) {
			return;
		}
		this.selections.clear();
		for (var i = 0, len = this.grid.store.getCount(); i < len; i++) {
			this.selectRow(i, true);
		}
		if (this.grid.view.showGroupCheckBoxes) {
			var groups = this.grid.view.getGroups();
			for (i = 0; i < groups.length; i++) {
				Ext.get(this.grid.id + '-' + groups[i].id + '-checkbox').addClass('x-grid3-row-selected');
			}
		}
	},
	clearSelections: function(fast) {
		if (this.isLocked()) {
			return;
		}
		if (fast !== true) {
			var ds = this.grid.store;
			var s = this.selections;
			s.each(function(r) {
				this.deselectRow(ds.indexOfId(r.id));
			}, this);
			s.clear();
		} else {
			this.selections.clear();
		}
		this.last = false;
		if (this.grid.view.showGroupCheckBoxes) {
			var groups = this.grid.view.getGroups();
			for (i = 0; i < groups.length; i++) {
				Ext.get(this.grid.id + '-' + groups[i].id + '-checkbox').removeClass('x-grid3-row-selected');
			}
		}
	}
});
Ext.override(Ext.Window, {
	closable: true,
	createToolHandler: function(t, tc, overCls, panel) {
		if (tc.id == 'close' && panel.closable && panel.closeAction.toUpperCase() == 'HIDE' && panel.buttons != undefined) {
			for (h = 0; h < panel.buttons.length; h++) {
				btn = panel.buttons[h];
				if (btn.text != undefined && btn.handler != undefined && (btn.text.toUpperCase() == 'CLOSE' || btn.text.toUpperCase() == 'CANCEL')) {
					tc.handler = btn.handler.createDelegate(btn, [btn]);
				}
			}
		}
		return function(e) {
			t.removeClass(overCls);
			if (tc.stopEvent !== false) {
				e.stopEvent();
			}
			if (tc.handler) {
				tc.handler.call(tc.scope || t, e, t, panel, tc);
			}
		};
	}
});
/////////////////////////////Fix for Ext bug.  Used by setValues in schedule event. Try to remove after 3.3 update////////////////////////
// add type flag to RadioGroup
Ext.override(Ext.form.RadioGroup, {
	//private
	isRadioGroup: true
});
// add type flag to CheckboxGroup
Ext.override(Ext.form.CheckboxGroup, {
	//privates
	isCheckboxGroup: true
});
//Override for finding fields in checkboxgroups or radiogroups
Ext.override(Ext.BasicForm, {
	findField: function(id) {
		var field = this.items.get(id);
		if (!Ext.isObject(field)) {
			//searches for the field corresponding to the given id. Used recursively for composite fields
			var findMatchingField = function(f) {
				if (f.isFormField) {
					if (f.dataIndex == id || f.id == id || f.getName() == id) {
						field = f;
						return false;
					} else if (f.isComposite && f.rendered) {
						return f.items.each(findMatchingField);
					} else if (f.isRadioGroup && f.rendered) {
						return f.items.each(findMatchingField);
					} else if (f.isCheckboxGroup && f.rendered) {
						return f.items.each(findMatchingField);
					}
				}
			};
			this.items.each(findMatchingField);
		}
		return field || null;
	}
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

