Ext.example = function(){
    var msgCt;

    function createBox(t, s){
        return ['<div class="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"><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('');
    }

    return {
        msg : function(title, format){
            if(!msgCt){
                msgCt = Ext.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
            }
            msgCt.alignTo(document, 't-t');
            var s = String.format.apply(String, Array.prototype.slice.call(arguments, 1));
            var m = Ext.DomHelper.append(msgCt, {html:createBox(title, '' + s)}, true);
            m.slideIn('t').pause(1).ghost("t", {remove:true});
        }
     };
}();
Ext.Ajax.timeout = 60000;


Ext.ValidateTip = Ext.extend(Ext.ToolTip, {
	firstLoad : true,
    initComponent : function(){
        Ext.ValidateTip.superclass.initComponent.call(this);
           this.on('beforeshow', this.onBeforeShow, this, {delay:10});
	},
    onBeforeShow : function(){
		if (this.rendered)
		{
			if (this.autoLoad)
			{
				this.autoLoad['params']['html'] = '';
				this.autoLoad['params']['value'] = this.target.dom.value;
				if (!this.firstLoad)
				{
					//Ext.example.msg('debug', 'validate');
					this.getUpdater().update(
						{
							url: this.autoLoad['url'], params: this.autoLoad['params'],
							callback: this.syncShadow.createDelegate(this)
						}
					);
					this.syncShadow();
				}
				this.firstLoad = false;
			}
		}
    },

    initTarget : function(){
        if(this.target){
            this.target = Ext.get(this.target);
            //this.target.on('mouseover', this.onTargetOver, this);
            //this.target.on('mouseout', this.onTargetOut, this);
            this.target.on('focus', this.onTargetOver, this);
            this.target.on('blur', this.onTargetOut, this);
            this.target.on('change', this.onBeforeShow, this);
            this.target.on('keyup', this.onKeyUp, this);
        }
    },

    onKeyUp : function(e){

    	if (this.onKeyUpTimer)
    	{
    		clearTimeout(this.onKeyUpTimer);
    	}
    	var _this = this;
    	this.onKeyUpTimer = setTimeout(function(){_this.fireEvent('beforeshow');}, 500);

    },
/*
    onTargetOut : function(e){

        if(this.disabled || e.within(this.target.dom, true)){
            return;
        }

        this.clearTimer('show');
        if(this.autoHide !== false){
            this.delayHide();
        }
    },
*/

	show : function(){
        if(!this.rendered){
            this.render(Ext.getBody());
        }
		this.el.dom.style.display = '';
        this.el.dom.style.visibility = 'hidden';
		this.el.alignTo(this.target, 'tl-tr', [0, -30]);
	    Ext.ToolTip.superclass.show.call(this);
		this.syncShadow();
    },

    onDocMouseDown : function(e){
        return;
    }

});

function convertFields(fields, config)
{
	var defaultConfig = {'exclude': [], 'options' : {}};
	var comboWidth = 212;
	Ext.apply(defaultConfig, config)
	config = defaultConfig;

	if (!(fields instanceof Array) && !fields.length)
	{
		fields = [fields];
	}

	var convertedInputs = {};
	var formId = config['formId'];
	var formEl = formId ? Ext.get(formId) : null;
	var formDom = formEl ? formEl.dom : null;

	for (var i = 0; i < fields.length; i++)
	{
		var fieldEl = Ext.get(fields[i]);
		if (!fieldEl)
		{
			continue;
		}
		var fieldDom = fieldEl.dom;
		var key = fieldDom.name;

		for (var j = 0; j < config.exclude.length; j++)
		{
			if (key == config.exclude[j])
			{
				break;
			}
		}

		if (j < config.exclude.length)
		{
			continue;
		}
		//alert(fieldDom);

		if (fieldDom && 'SELECT' == fieldDom.tagName)
		{
			var empty = false;

			//alert(fieldDom.innerHTML);

			if (0 > fieldDom.selectedIndex || !fieldDom.options[fieldDom.selectedIndex].getAttribute('selected')
			||

			(0 <= fieldDom.selectedIndex &&
			!fieldDom.options[fieldDom.selectedIndex].defaultSelected)

			)
			{
				empty = true;
			}
			/**changed d.shokel 05.11.2008
				block for install empty string in combos
			*/
			var fieldDom_name = fieldDom.name;
			var emptyString = Ext.comboEmptyString ? Ext.comboEmptyString : '';
			if (Ext.Options)
			{
				if (Ext.isArray(Ext.Options.comboEmptyStrings))
				{
					Ext.each(Ext.Options.comboEmptyStrings,function(obj,index,array){
						if(fieldDom_name == obj.name)
						{
							emptyString = obj.string;
						}
					});
				}
			}

			var conv = new Ext.form.ComboBox(Ext.apply({
				autocomplete:'off',
				emptyText: emptyString,
				triggerAction: 'all',
				transform: fieldDom,
				width: comboWidth,// Ext.get(fieldDom).getWidth(),
				//value: '',
				editable: true,
			 	selectOnFocus : true,
				typeAhead: true,
				forceSelection: !fieldEl.hasClass('edt'),
				cls: 'combo',
				ctCls: 'comboCt'
				//,allowBlank: false
				,validator: window[formId + '_gfieldsCheck'] ? function() {
					return window[formId + '_gfieldsCheck'](formDom, key);
				}.createDelegate(fieldDom) : Ext.empFn
				,disabled: fieldDom.disabled
				//,listeners: {'render': {fn: function () {alert('!')}}}
			}, config.options[fieldDom.name] || {}));

			if (fieldDom.onchange)
			{
				conv.addListener({
					'select' : fieldDom.onchange,
					scope: conv.el.dom
				});
			}

			if (fieldEl.hasClass('edt'))
			{
				//conv.on('blur', function() {this.setValue(this.el.dom.value);});
				conv.on('blur', function()
				{
					if (!this.store.getById(this.getValue()) || this.store.getById(this.getValue()).get('text') != this.getRawValue())
					{
						this.hiddenField.value = '';
					}
				});
				conv.el.dom.name = conv.getName() + '_new';
				if (config.options[fieldDom_name]['newvalue'])
				{
					conv.setRawValue(config.options[fieldDom_name]['newvalue']);
				}
			}
			if (Ext.getDom(key))
			{
				Ext.getDom(key).style.position = 'absolute';
				Ext.getDom(key).style.visibility = 'hidden';
	//			Ext.getDom(key).style.top = '0px';
				Ext.getDom(key).style.width = '0px';
				Ext.getDom(key).style.height = '0px';
				Ext.getDom(key).style.border = 'none';
			}
			//Ext.getDom(conv.getEl()).tabIndex = 1;

			if (conv.getResizeEl())
			{
				conv.getResizeEl().addClass(fieldDom.className);
			}

			if (empty && (!config || !config.options || !config.options[fieldDom_name] || !config.options[fieldDom_name]['value']))
			{
				conv.setValue('');
			}

			conv.clearInvalid();
			Ext.apply(conv, {
				markInvalid: function(str)
				{
					switch(this.msgTarget)
					{
						default:
						{
							Ext.form.ComboBox.superclass.markInvalid.call(this, str);
							break;
						}
						case 'qtip':
						{
							//Ext.form.ComboBox.superclass.markInvalid.call(this, str);
							break;
						}
					}
					//Ext.form.Field.markInvalid.call(this, str);
				}
			});

			conv.on('enable', function (){this.hiddenField.disabled = false;});

			convertedInputs[key] = conv;
			fieldDom = conv.hiddenField;
			if (fieldDom)
			{
				fieldDom.ext = conv;
			}
		}
	}
	return convertedInputs;
}

function convertForm(formId, config)
{
	var defaultConfig = {'exclude': []};
	Ext.apply(defaultConfig, config)
	config = defaultConfig;

	Ext.form.Field.prototype.msgTarget = 'qtip';
/*
	var frm = new Ext.form.BasicForm(formId, {
		onSubmit: Ext.emptyFn,
		submit: function() {
			this.getEl().dom.submit();
		}
	});
*/
	var formDom = Ext.getDom(formId);

	return convertFields(formDom.elements, config);
}

function createInlineComboBoxes(fields, config)
{
	var defaultConfig = {'exclude': [], 'options' : {}};
	Ext.apply(defaultConfig, config)
	config = defaultConfig;

	if (!(fields instanceof Array) && !fields.length)
	{
		fields = [fields];
	}

	var convertedInputs = {};
	var formId = config['formId'];
	var formEl = formId ? Ext.get(formId) : null;
	var formDom = formEl ? formEl.dom : null;

	for (var i = 0; i < fields.length; i++)
	{
		var fieldEl = Ext.get(fields[i]);
		if (!fieldEl)
		{
			continue;
		}
		var fieldDom = fieldEl.dom;
		var key = fieldDom.name;

		for (var j = 0; j < config.exclude.length; j++)
		{
			if (key == config.exclude[j])
			{
				break;
			}
		}

		if (j < config.exclude.length)
		{
			continue;
		}

		if (fieldDom)
		{
			config.options[fieldDom.name]['listeners'] = Ext.apply({
		    	'render' : {fn: function () {
			    	var elPar = this.el.parent('.x-form-field-wrap');
			    	//elPar.addClass('inline');
			    	//elPar.dom.style.width = 'auto';
					elPar.alignTo(this.renderTo, 'bl-bl');
					this._renderTo = this.renderTo;
			    	Ext.get(this.renderTo).on('click', this.onTriggerClick, this);
		    	}},
		    	'disable' : function (combo){
					Ext.get(combo._renderTo).addClass('x-hidden');
		    	},
		    	'enable' : function (combo){
					Ext.get(combo._renderTo).removeClass('x-hidden');
					Ext.get(combo._renderTo).child('a').dom.firstChild.data = combo.getRawValue() ? combo.getRawValue() : '...';
					combo.hiddenField.disabled = false;
		    	},
		    	'expand' : function (combo){
			        var elPar = combo.el.parent('.x-form-field-wrap');
			        elPar.alignTo(combo._renderTo, 'bl-bl');
			        //alert(1);
			        //return false;
				}
		    }, config.options[fieldDom.name]['listeners'] || {});

			var id = '' + fieldDom.id;
			fieldDom.id = id + '_ctr';

			convertedInputs[id] = new Ext.form.ComboBox(Ext.apply({
			    //store: config.options[fieldDom.name]['store'],
			    //displayField: 'state',

			    //typeAhead: true,
			    disableKeyFilter: true,

			    //mode: 'local',
			    triggerAction: 'all',
			    selectOnFocus: true,
			    listWidth: 100
				,hideTrigger: true
				//,cls: 'inlineCombo'
				,editable: true
			    ,renderTo: Ext.get(fieldDom).parent('span')
			    ,hiddenName: id
			    ,value: fieldDom.href.replace(/[^\d]/g, '')
			}, config.options[fieldDom.name] || {}));

			convertedInputs[id].addListener({
				'select' : function (combo) {
					Ext.get(combo._renderTo).child('a').dom.firstChild.data = combo.getRawValue();
				},
				scope: convertedInputs[id]
			});

			//convertedInputs[id].el.dom.onkeyup = function(){alert(1);};
			convertedInputs[id].hiddenField.ext = convertedInputs[id];
		}
	}
	return convertedInputs;
}

Ext.form.ComboBox.prototype.restrictHeight = function ()
{
    this.innerList.dom.style.height = '';
    var inner = this.innerList.dom;
    var fw = this.list.getFrameWidth('tb');
    var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
    this.innerList.setHeight(h < this.maxHeight ? 'auto' : this.maxHeight);
    this.list.beginUpdate();
    this.list.setHeight(this.innerList.getHeight()+fw+(this.resizable?this.handleHeight:0)+this.assetHeight);
    this.list.alignTo(this.wrap, this.listAlign);
    this.list.endUpdate();
};


function buildExtraMatching(keys, dOptions)
{
	var result = dOptions || {};

	i = 0;
	while (i < keys.length)
	{
		var selection = document.getElementById(keys[i]).options;
		var storedata = [];
		var val=-1;
		j =0;
		while (j < selection.length)
		{
			storedata.push([selection[j].text,selection[j].value]);
			if (selection[j].selected)
			   val = selection[j].value;
			j++;
		}

		var store = new Ext.data.SimpleStore({
        'id': 0,
        fields: [
           {name: 'text'},
           {name: 'value', type: 'int'}
        ]
        ,data: storedata
    	});
    	store.createFilterFn = function(property, value, anyMatch, caseSensitive)
		{
	        if(Ext.isEmpty(value, false)){
	            return false;
	        }
	        var matcher = this.data.createValueMatcher(value, anyMatch, caseSensitive);
	        return function(r){
	            return value == parseInt(r.data[property], 10) || matcher.test(r.data[property]);
	        };
	    };

    	if (-1 != val)
    	{
			options  = {'store': store , 'mode': 'local', valueField: 'value', displayField: 'text', value: val};
    	}
		else
		{
			options  = {'store': store , 'mode': 'local', valueField: 'value', displayField: 'text'};
		}
		Ext.apply(result.options[keys[i]], options);

		i++;
	}
	return result;
}

function buildExtrataTask(convertedInputs,selectlist)
{
	i = 0;
	while (i < selectlist.length)
	{
		convertedInputs[selectlist[i]].taTask = new Ext.util.DelayedTask(function(){
	        if(this.store.getCount() > 0){
	            var r = this.store.getAt(0);
	            var newValue = r.data[this.displayField];
	            var len = newValue.length;

				var handValue = this.getRawValue();
				var handValueL = handValue.length;

				var selStart;
				var ex = newValue.indexOf(handValue);
				if (ex !== 0){
					selStart = handValueL + ex;
				} else {
					selStart = handValueL;
				}
          		if(selStart < len){
	                this.setRawValue(newValue);
	                this.selectText(selStart, newValue.length);
	            }
	        }
	    }, convertedInputs[selectlist[i]]);
	    i++;
    }
}

Ext.namespace('Ext.custom', 'Ext.custom.form');

Ext.custom.form.ComboBox = Ext.extend(Ext.form.ComboBox, {
	viewMode: 'basic',

	_wrapper: null,
	_trigger: null,

	onRender: function(ct, position) {
		Ext.custom.form.ComboBox.superclass.onRender.call(this, ct, position);

		if ('plain' == this.viewMode)
		{
			var record, text = (undefined !== this.valueNotFoundText) ? this.valueNotFoundText : null;

			if (this.value && this.valueField)
			{
	            if (record = this.findRecord(this.valueField, this.value))
	            {
					text = record.data[this.displayField];
	            }
			}

			this._trigger = Ext.get(this.renderTo).insertFirst({
				tag: 'a', href: '#', cls: 'hasSub'
			});

			this._trigger.on('click', function(event) {
				event.preventDefault();
				this.wrap.alignTo(this._trigger, 'bl-bl');
				this.onTriggerClick();
			}, this);

			this._trigger = this._trigger.createChild({tag: 'span', html: text});
		}
	},

	onDestroy: function() {
		Ext.custom.form.ComboBox.superclass.onDestroy.call(this);

		if (('plain' == this.viewMode))
		{
            this._trigger.removeAllListeners();
            this._trigger.remove();
		}
	},

	setValue: function(value) {
		Ext.custom.form.ComboBox.superclass.setValue.call(this, value);

       	if (('plain' == this.viewMode) && this._trigger)
       	{
	       	var text = value, record;

	        if (this.valueField)
	        {
	            if (record = this.findRecord(this.valueField, value))
	            {
					text = record.data[this.displayField];
	            }
	            else if (undefined !== this.valueNotFoundText)
	            {
					text = this.valueNotFoundText;
	            }
	        }

	        this._trigger.update(text);
        }
	}
});

/**
 * Checkbox selection model for grid, which allows to
 * disable/enable selected rows, also during initial rows loading.
 */
Ext.grid.CheckboxSelectionModelE = Ext.extend(Ext.grid.CheckboxSelectionModel, {
	disabled: {},

	constructor: function(config) {
		Ext.grid.CheckboxSelectionModelE.superclass.constructor.call(this, config);

		// For some reason renderer is called in unknown
		// scope, so it is necessary to set scope explicitly.
		this.renderer = this.renderer.createDelegate(this);

		this.on('beforerowselect', function(model, rowIndex) {
			return (!this.grid.disabled && (('undefined' == this.disabled[rowIndex]) || !this.disabled[rowIndex]));
		}.createDelegate(this));
	},

	renderer: function(row, prop, record, rowIndex) {
		this.disabled[rowIndex] = record.get('disabled');

		return '<div id="x-grid3-row-cb-'
				+ rowIndex + '" class="x-grid3-row-checker" '
				+ (this.disabled[rowIndex] ? 'style="display: none"' : '')
				+ '>&#160;</div>';
	},

	enableRow: function(rowIndex, enable) {
		Ext.each(
			('number' == typeof rowIndex) ? [rowIndex] : rowIndex,
			function(rowIndex, index, all, enable) {
				this.disabled[rowIndex] = false;

				Ext.get('x-grid3-row-cb-' + rowIndex)[
					(('undefined' == typeof enable) || (true == enable)) ? 'show' : 'hide'
				]();
			}.createDelegate(this, [enable], true)
		);
	}
});

/**
 * Set prereturn to true and changed function will retrun interceptor
 * result, if it is defined, and the result of origin function otherwise.
 */
Ext.override(Function, {
    createInterceptor : function(fcn, scope, prereturn) {
        if (typeof fcn != "function")
        {
            return this;
        }

        var method = this;

        return function() {
            fcn.target = this;
            fcn.method = method;

            var ret = fcn.apply(scope || this || window, arguments);

            if (prereturn && ('undefined' != typeof ret))
            {
				return ret;
            }
            else if (false === ret)
            {
                return;
            }

            return method.apply(this || window, arguments);
        };
    }
});

/**
 * Base object for simple page control.
 */
PageControl = Ext.extend(Ext.util.Observable, {
	config: {
		pageUrl: document.location.href,
		name: null,
		strings: {}
	},

	constructor: function(config) {
		PageControl.superclass.constructor.apply(this, arguments);

		// This trick is used for make add-ons
		// possibility to override control strings hash.
		var strings = this.config.strings;

		Ext.apply(this.config, config);
		Ext.apply(this.config.strings, strings);
	},

	/**
	 * Returns localization string.
	 *
	 * @protected
	 */
	getString: function(name) {
		return ('undefined' != typeof this.config.strings[name]) ? this.config.strings[name] : name;
	},

	/**
	 * Just composes control URL, using page url and control name.
	 *
	 * @protected
	 */
	getUrl: function() {
		return this.config.pageUrl + '?it:' + this.config.name;
	},

	/**
	 * Looks for X-Response-Type header and compares it value with specified type.
	 * It is useful to, fo example, to distinguish HTML from JSON response.
	 *
	 * @protected
	 * @param {object} response AJAX response object
	 */
	checkResponse: function(response, type) {
		return response.getResponseHeader['X-Response-Type'] && (
			-1 != response.getResponseHeader['X-Response-Type'].indexOf(type)
		);
	},

	/**
	 * Wrapper for form validating function.
	 *
	 * @protected
	 */
	validateForm: function(id) {
		return window[id + '_gCheck'](Ext.getDom(id));
	}
});

PaneledWindow = Ext.extend(PageControl, {
	wnd: null,
	viewCB: null,
	view: null,
	panels: {},
	initialized: {},
	configs: {},
	panelsTpl: [{
			region: 'north',
			border: false,
			collapsible: true
		}, {
			region: 'center',
			border: false,
			collapsed: true
	}],
	data: {},

	constructor: function(config) {
		PaneledWindow.superclass.constructor.apply(this, arguments);

		this.addEvents({
			'initializeview': true, 'viewinitialized': true
		});

		this.on('initializeview', this.onInitializeView, this);
		this.on('viewinitialized', this.onViewInitialized, this);
	},

	getUrl: function(view) {
		return PaneledWindow.superclass.getUrl.apply(this, arguments) + (view ? '&view=' + view : '');
	},

	changeView: function(combo, forced) {
		var panel = this.wnd.getComponent(1);

		// Hide previous selected view panels.
		if (this.panels[this.view])
		{
			Ext.each(this.panels[this.view], function(item) { item.hide(); });
		}

		if ((this.view != (this.view = combo.getValue())) || (true === forced))
		{
			if (!this.initialized[this.view])
			{
				this.fireEvent('initializeview', this.view, (
					('undefined' != typeof this.configs[this.view]) ? this.configs[this.view] : null
				));
			}

			if (this.panels[this.view])
			{
				Ext.each(
					this.panels[this.view],
					function(item, index, all, panel) {
						if (!this.initialized[this.view])
						{
							panel.add(item);
						}
						else
						{
							item.show();
						}
					}.createDelegate(this, [panel], true)
				);

				panel.doLayout(true);
				panel.expand();

				if (!this.initialized[this.view])
				{
					// HACK: height problems
					if (this.panels[this.view][0].height)
					{
						this.panels[this.view][0].body.setHeight(this.panels[this.view][0].height);
					}

					this.fireEvent('viewinitialized', this.view);

					this.initialized[this.view] = true;
				}
			}
		}
	},

	/**
	 * To be overridden with add-ons.
	 * @private
	 */
	onInitializeView: function(view) {},

	/**
	 * To be overridden with add-ons.
	 * @private
	 */
	onViewInitialized: function(view) {},

	show: function() {
		(this.wnd || (this.wnd = new Ext.Window({
		 	plain: true,
			width: 600,
			y: Ext.getBody().getScroll().top + 30,
			closeAction: 'hide',
			title: this.getString('wnd_title'),
			shadow: false,
			resizable: false,
			modal: true,
			layout: 'anchor',
			items: [{
					region: 'north',
					border: false,
					contentEl: 'pnl-view'
				}, {
					region: 'center',
					border: false,
					collapsed: true
			}]
		}))).show();

		if (!this.viewCB)
		{
			(this.viewCB = convertForm('view_form')['view']).on(
				'select', this.changeView.createDelegate(this)
			);
		}
		else
		{
			this.wnd.setPosition(
				 this.wnd.x, Ext.getBody().getScroll().top + 20
			);

			this.changeView(this.viewCB, true);
		}
	}
});
Ext.redirect = function(url)
{
	if (!url)
	return false;
	var container =  Ext.query('div.Container')[0];
	container = container ? container : Ext.getBody();
	new Ext.LoadMask(container).show();
	document.location.href = url;
	return true;
}

function onAutoLogout(conn, response, options)
{
	if (405 == response.status)
	{
		var divElement = Ext.query('div.basis')[0];
		new Ext.LoadMask(divElement).show();
		var href = document.location.href;
		if (document.location.hash)
		{
			href = document.baseURI;
		}
		document.location.href = href;
		//document.location.reload();
/*		var params = Ext.decode(response.responseText);
		Ext.Msg.show({
		   title: params.title,
		   msg: params.msg,
		   buttons: Ext.Msg.OK,
		   icon: Ext.MessageBox.WARRNING,
		   fn: function(btnId)
		   {
		   }
		});*/
	}
}
Ext.Ajax.on('requestexception',onAutoLogout);

function showElement(el)
{
	if (el.hasClass('x-hidden'))
	{
		el.removeClass('x-hidden');
		setTimeout(function(div){div.className = div.className;}.createCallback(el.dom), 1);
	}
}

