Function.prototype.bind = function(scope, args){ 
	var _this = this;
	return function() { 
		return _this.apply(scope, args ? args : []); 
	}
};

var ITc = {
	is_debug: false,
	showDebug: function(msg){
		if(this.is_debug == true){
			alert(msg);
		}
	},
	apply: function(o, c, defaults){
		if(defaults){
			this.apply(o, defaults);
		}
		if(o && c && typeof c == 'object'){
			for(var p in c){
				o[p] = c[p];
			}
		}
		return o;
	},
	extendClass:function(NC, EC, over){
		if (typeof NC != 'function'){
			NC = function(){
//TODO check this!!
				NC.prototype.superclass.apply(this,arguments);
			};
		}
		NC.prototype = $.extend({}, EC.prototype);
		if (over){
			$.extend(NC.prototype,over);
		}
		NC.prototype.superclass = EC;
		return NC;
	},
	clone: function(o) {
		if(!o || 'object' !== typeof o) {
			return o;
		}
		if('function' === typeof o.clone) {
			return o.clone();
		}
		var c = '[object Array]' === Object.prototype.toString.call(o) ? [] : {};
		var p, v;
		for(p in o) {
			if(o.hasOwnProperty(p)) {
				v = o[p];
				if(v && 'object' === typeof v) {
					c[p] = ITc.clone(v);
				}else {
					c[p] = v;
				}
			}
		}
		return c;
	},
	getEl: function(id, jQuery){
		if (id) {
			if (typeof id == 'string') {
				if (jQuery) {
					return $('#'+id);
				} else {
					return document.getElementById(id);
				}
			} else {
				if (id.tagName) {
					if (jQuery) {
						return $(id);
					}
				} else {
					if (!jQuery && id[0]) {
						return id[0];
					} else {
						return null;
					}
				}
			}
		}
		return id;
	},
	CC:null,
	getCacheContainer:function(){
		if (!this.CC) {
			var cache_cont_id = '_mcchel';
			this.CC = $('#'+cache_cont_id);
			if (!this.CC[0]) {
				this.CC = $('<div id="'+cache_cont_id+'" style="display:none"></div>').appendTo('body');
			}
		}
		return this.CC;
	},
	callCallback: function(callback, scope, args) {
		if (callback) {
			var fn = null;
			var sc = null;
			if (typeof callback == 'function') {
				fn = callback;
			} else if (callback.fn) {
				fn = callback.fn;
				if (callback.scope) {
					scope = callback.scope;
				}
			}
			if (fn) {
				fn.apply(scope ? scope : window, args);
			}
		}
	},
	hideMask: function(el) {
		el = ITc.getEl(el);
		if(el && el.mask_element){
			var mel = el.mask_element;
			if (mel.parentNode) {
				mel.parentNode.removeChild(mel);
			}
			el.mask_element = null;
		}
	},
	showMask: function(el){
		el = ITc.getEl(el);
		if(!el) return;
		if(!el.mask_element) {
			var h = el.offsetHeight;
			var element_loader = $('<div class="itc-mask"><div class="loading-indicator" style="margin-top:'+(h/2-8)+'px;"></div></div>');
			if ($.browser.msie && $.browser.version < 7) {
				var w = el.offsetWidth;
				element_loader.css({
					'height':h+'px',
					'width':w+'px'
				});
			}
			if (el.style.position != 'relative') {
				el.style.position = 'relative';
			}
			element_loader.appendTo(el);
			el.mask_element = ITc.getEl(element_loader);
			//el.appendChild(el.mask_element);
		}
	},

	rList: [],
	onReady: function(fn, scope) {
		if (scope) {
			this.rList.push(fn.bind(scope));
		} else {
			this.rList.push(fn);
		};
	},
	_onPLoad: function() {
		for(var i=0; i<this.rList.length; i++) {
			this.rList[i]();
		}
	},
	/**
	 * allow perform AJAX requests
	 * @param srting url
	 * @param object options
	 * allowed options :
	 * 		- parameters - object with parameters that should be passed to the server 
	 * 		- onSuccess - function that will call on success (response from server contain 'success' property equal to true)
	 * 		- onFail - function that will be call on fail
	 * 		- scope - scope for onSuccess callback
	 * 		- fscope - scope for onFail callback (if not defined scope will be used)
	 * 		- requestType - {html,json}, 'json' is default
	 */
	/**
	 * exmple:
		ITc.request('/ajax/login.php',{
			parameters: {cmd:'login'},
			requestType: 'html',
			onSuccess: function() {
				//console.info('Success');
				//console.info(arguments);
			},
			onFail: function() {
				//console.info('Fail');
				//console.info(arguments);
			},
			scope: window,
			fscope: window
		});
	 * 
	 * 
	 */
	request: function(url, options){
		if(!url || url == ''){
			//ITc.alert.show('FATAL - URL not found');
			return false;
		}
		if (!options) {
			options = {};
		}
		function _onRequestComplete(response, is_success){
			var jsonObj;
			if (is_success == 'success') {
				if (options.requestType && options.requestType == 'html') {
					jsonObj = {
						success: true
					};
				} else {
					try{
						eval('jsonObj = ' + response);
					} catch(exep){
					}
				}
			}
			var action = {
				result: jsonObj,
				responseText: response,
				options: options
			};
			if (jsonObj) {
				var msg_text, msgs;
				if (jsonObj.success) {
					if (jsonObj.messages) {
						msgs = jsonObj.messages;
					}
				} else {
					if (jsonObj.errors) {
						msgs = jsonObj.errors;
					}
				}
				
				if (jsonObj.success) {
					if (jsonObj.messages) {
						msgs = jsonObj.messages;
					}
				} else {
					if (jsonObj.errors) {
						msgs = jsonObj.errors;
					}
				}
				if (msgs) {
					if (msgs instanceof Array) {
						msg_text = msgs.join('<br />');
					} else if (typeof msgs == 'object') {
						msg_text = '';
						for(var k in msgs) {
							msg_text += msgs[k];
						}
					} else {
						//typeof msgs == 'string'
						msg_text = msgs;
					}
				};
				if (msg_text) {
					if (jsonObj.success) {
						ITc.alert.show(msg_text, null,
							_internalOnSuccess.bind(this, [action])
						);
					} else {
						ITc.alert.show(msg_text, 'Error',
							_internalOnFail.bind(this, [action])
						);
					}
				}else{
					if (jsonObj.success) {
						_internalOnSuccess(action);
					} else {
						_internalOnFail(action);
					}
				}
			}else{
				var req_fail = 'This request has failed.  Please try later.';
				ITc.alert.show(req_fail, 'Error',
					_internalOnFail.bind(this, [action])
				);
			}
		};

		function _internalOnSuccess(action){
			if (!options['onSuccess']) return;
			var f = options['onSuccess'];
			if (typeof f == 'function') {
				var scope = options['scope'] ? options['scope'] : window;
				f.apply(scope, [action.result, action]);
			}
		};

		function _internalOnFail(action){
			if (!options['onFail']) return;
			var f = options['onFail'];
			if (typeof f == 'function') {
				var scope = options['fscope'] ? options['fscope'] : (options['scope'] ? options['scope'] : window);
				f.apply(scope, [action.result, action]);
			}
		};

		$.post(
			url,
			options.parameters ? options.parameters : null,
			_onRequestComplete
		);
	},
	getCookie: function(name){
		var prefix = name + '=';
		var cookieStartIndex = document.cookie.indexOf(prefix);
		if (cookieStartIndex == -1) {
			return null;
		}
		var cookieEndIndex = document.cookie.indexOf(';', cookieStartIndex + prefix.length);
		if (cookieEndIndex == -1) {
			cookieEndIndex = document.cookie.length;
		}
		return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex));
	},
	setCookie: function(name, value, expires, path, domain, secure){
		// set time, it's in milliseconds
		var today = new Date();
		today.setTime(today.getTime());

		/*
		if the expires variable is set, make the correct
		expires time, the current script below will set
		it for x number of days, to make it for hours,
		delete * 24, for minutes, delete * 60 * 24
		*/
		if (expires) {
			expires = expires * 1000 * 60 * 60 * 24;
		}
		var expires_date = new Date(today.getTime() + (expires));

		document.cookie = name + '=' +escape( value ) +
		( ( expires ) ? ';expires=' + expires_date.toGMTString() : '' ) +
		( ( path ) ? ';path=' + path : '' ) +
		( ( domain ) ? ';domain=' + domain : '' ) +
		( ( secure ) ? ';secure' : '' );
	}
};

ITc.Component = function(config){
	if (config) {
		//$.extend(true,this,config);
		ITc.apply(this, config);
		if (this.listeners){
			var i,
				scope = this.listeners.scope ? this.listeners.scope : window;
			for(i in this.listeners){
				if (i == 'scope') continue;
				this.on(i, this.listeners[i], scope);
			}
		}
	}
	this._initComponent();
};
ITc.Component.prototype = {
	fireEvent:function(eventName){
		var i,narg = [];
		for(i=1;i<arguments.length;i++){
			narg.push(arguments[i]);
		}
		$(this).trigger(eventName.toLowerCase(), narg);
	},
	on:function(eventName,callback,scope){
		$(this).bind(eventName.toLowerCase(), scope ? function(){
			callback.apply(scope, arguments);
		} : callback);
	},
	_initComponent:function(){
	}
};


ITc.alert = {
	dlg_id:0,
	show:function(msg, title, handler, scope){
		this.dlg_id++;
		var _dlg_id = 'mes_dialog_' + this.dlg_id,
			D = ITc.ut.lDialog.create($('<div id="'+_dlg_id+'">'+msg+'</div>'),{
				title: title ? title : 'Message',
				width: 400,
				close: this.close.bind(this, [_dlg_id]),
				buttons: {
					'Ok': function(){
						$(this).dialog('close');
					}
				}
			}),
			domEl = ITc.getEl(D);

		domEl._closeCallback = {
			handler: handler,
			scope: scope
		};
		D.dialog('open');
	},
	close: function(id){
		if (!id) return;
		var domEl = ITc.getEl(id);
		if (!domEl) return;
		if (domEl._closeCallback) {
			ITc.callCallback(domEl._closeCallback.handler, domEl._closeCallback.scope, []);
		}
		$(domEl).dialog('destroy');
	}
};

ITc.confirm = {
	dlg_id: 0,
	show: function(msg, title, okAction, scope, cancelAction, btns){
		if (!msg) return;
		
		if (btns) {
			if (typeof btns.ok == 'string') {
				btns.ok = {text:btns.ok};
			}
			if (typeof btns.cancel == 'string') {
				btns.cancel = {text:btns.cancel};
			}
		} else {
			btns = {};
		}
		this.dlg_id++;
		var _dlg_id = 'confirm_dialog_'+this.dlg_id,
			def_btns_conf = {
				ok:{
					text: 'Ok',
					cls:'rbutton right red',
					handler:function(){
						var dE = $('#'+_dlg_id);
						ITc.getEl(dE)._on_close_action = '_okCallback';
						dE.dialog('close');
					}
				},
				cancel:{
					text:'Cancel',
					cls:'rbutton right',
					handler:function(){
						var dE = $('#'+_dlg_id);
						ITc.getEl(dE)._on_close_action = '_cancelCallback';
						dE.dialog('close');
					}
				}
			},
		
			D = ITc.ut.lDialog.create($('<div id="'+_dlg_id+'">'+msg+'</div>'), {
				title: title ? title : 'Confirm',
				close: this.close.bind(this, [_dlg_id]),
				width: 400,
				buttons: [
					ITc.apply(def_btns_conf.cancel, btns.cancel ? btns.cancel : {}),
					ITc.apply(def_btns_conf.ok, btns.ok ? btns.ok : {})
				]
			}),
			domEl = ITc.getEl(D);
		
		domEl._okCallback = {
			handler: okAction,
			scope: scope
		};
		domEl._cancelCallback = {
			handler: cancelAction,
			scope: scope
		};
		D.dialog('open');
	},
	close: function(id){
		if (!id) return;
		var domEl = ITc.getEl(id);
		if (!domEl) return;
		var h = domEl._on_close_action && domEl[domEl._on_close_action] ? domEl[domEl._on_close_action] : domEl._cancelCallback;
		if (h) {
			ITc.callCallback(h.handler, h.scope, []);
		}
		$(domEl).dialog('destroy');
	}
};

ITc.pageConfig = {
	inited:false,
	active:false,
	c:null,
	init:function(){
		if (!this.inited) {
			try{
				if (PageConfig) {
					this.setConfig(PageConfig);
				}
			} catch (exp) {};
			this.active = this.c && typeof(this.c) == 'object';
		}
		return this.active;
	},
	
	setConfig:function(newPageConfig){
		if (this.inited) {
			this.inited = false;
		}
		this.c = newPageConfig;
	},
		
	getVal: function(key, path, def){
		var val = def;
		if (this.init()) {
			if (path instanceof Array && path.length > 0) {
				var sec = this.getVal(path.pop(), path, def);
			} else {
				var sec = this.c;
			}
		} else {
			var sec = this.c;
		}
		
		if (!key) {
			return sec;
		}
		
		if (sec && sec[key] != undefined) {
			return sec[key];
		} else {
			return def != undefined ? def : null;
		}
	},
		
	setVal: function(value, key, path, ns_creation){
		if (!key) {
			return;
		}
		if (!this.c) {this.c = {};};
		if (this.init()) {
			if (path instanceof Array && path.length > 0) {
//TODO finish this
				/*var nk = path.pop(),
					ts = this.getVal(nk,path),
					sec = ts && ts == 'object' ? ts : this.setVal({}, nk, path);*/
				var sec = this.setVal({}, path.pop(), path);
			} else {
				var sec = this.c;
			}
		}
		if (sec && typeof sec == 'object') {
			sec[key] = value;
			return sec[key];
		}
	}
};

ITc.resLoader = {
	load:function(type,src,callback,scope){
		if (!src)return;
		var el;
		switch(type){
		case 'js':
			el = document.createElement('script');
			el.type = 'text/javascript';
			el.src = src;

			if (callback){
				if (scope){
					callback = callback.bind(scope);
				}
//JQuery used - need to change
				if (!$.browser.msie){
					el.onload = callback;
				} else {
					el.onreadystatechange = function(){
						if (this.readyState == 'complete'){
							callback();
						}
					}
				}
			}
			break;

		case 'css':
			el = document.createElement('link');
			el.href = src;
			el.type = 'text/css';
			el.rel = 'stylesheet';
			break;
		}
		if (!el) {
			return false;
		}
		document.getElementsByTagName('head')[0].appendChild(el);
		return true;
	}
};

ITc.format = {
	usMoney: function(v){
		v = (Math.round((v-0)*100))/100;
		v = (v == Math.floor(v)) ? v + '.00' : ((v*10 == Math.floor(v*10)) ? v + '0' : v);
		v = String(v);
		var ps = v.split('.');
		var whole = ps[0];
		var sub = ps[1] ? '.'+ ps[1] : '.00';
		var r = /(\d+)(\d{3})/;
		while (r.test(whole)) {
			whole = whole.replace(r, '$1' + ',' + '$2');
		}
		v = whole + sub;
		/*if(v.charAt(0) == '-'){
			return '-' + v.substr(1);
		}*/
		return v;
	}
};

ITc.ajaxForm = function(config) {
	if (config) {
		if (typeof config == 'object' && config.tagName != 'form') {
			ITc.apply(this, config);
		} else {
			this.form = config;
		}
	}
	this.init();
};

ITc.ajaxForm.prototype = {
	//form HTML dom element
	form: null,

	inputErrorClass: 'field-invalid',

	invalidClass: '',

	divErrorClass: 'error',

	listeners: null,

	mask_element: null,
	
	resetTitles: false,
	
	use_error_flags: true,

	init: function() {
		var f = this.form = ITc.getEl(this.form);
		if (!f) {
			ITc.showDebug('FATAL - FORM element not found!!');
			return false;
		}
		if(!this.mask_element){
			this.mask_element = this.form;
		}
		f.onsubmit = this._onSubmit.bind(this);
	},
	_onSubmit: function() {
		ITc.showMask(this.mask_element);
		
		if (this.resetTitles) {
			var field,k,fm = this._getRealFieldSet();
			for(k in fm) {
				field = fm[k];
				if (field.title && (field.type == 'text' || field.type == 'textarea') && field.title == field.value) {
					field.value = '';
				}
			}
		}
		
		if (this.form.enctype == 'multipart/form-data') {
			this._onSendMultypartForm();
		} else {
			var data = $(this.form).serialize();
			var _this = this;
			$.post(this.form.action, data, function(){_this._onRequestComplete.apply(_this, arguments)});
		}
		
		if (this.resetTitles) {
			for(k in fm) {
				field = fm[k];
				if (field.title && (field.type == 'text' || field.type == 'textarea') && field.value == '') {
					field.value = field.title;
				}
			}
		}

		return false;
	},
	
	_onSendMultypartForm: function(){
		/*** iframe creation ***/
		var id = 'iframe_upload_files';
		if (!ITc.getEl(id)) {
			var frame = document.createElement('iframe');
			frame.id = id;
			frame.name = id;
			frame.style.display = 'none';
			var isIE = $.browser.msie;
			if(isIE){
				frame.src = 'javascript:false;';
			}
			document.body.appendChild(frame);
			if(isIE){
				document.frames[id].name = id;
			}
			
			var _onLoadCallback = function(){
				var responseText = null;
				try {
					var doc = frame.contentDocument ? frame.contentDocument : frame.contentWindow.document;
					if(isIE){
						var doc = frame.contentWindow.document;
					}else {
						var doc = (frame.contentDocument || window.frames[id].document);
					}
					if(doc && doc.body){
						responseText = doc.body.innerHTML;
					}
				} catch(e) {// ignore
				}
				this._onRequestComplete(responseText, responseText ? 'success' : 'fail');
			};
			
			var _this = this;
			$(frame).load(function() {
				setTimeout(_onLoadCallback.bind(_this), 200);
			});
			this.form.target = id;
		}
		this.form.submit();
	},
	
	_onRequestComplete: function(response, is_success) {
		var jsonObj;
		if (is_success == 'success') {
			try{
				eval('jsonObj = ' + response);
			} catch(exep){
			}
		}

		var action = {
			result: jsonObj,
			responseText: response
		};

		if (jsonObj) {
			var msg_text,msgs;
			if (jsonObj.success) {
				if (jsonObj.messages) {
					msgs = jsonObj.messages;
				}
				this.resetErrors();
			} else {
				if (jsonObj.errors) {
					if (jsonObj.errors instanceof Array) {
						msgs = jsonObj.errors;
					} else if (typeof jsonObj.errors == 'object') {
						msgs = this._setupErrors(jsonObj.errors);
					} else {
						msgs = jsonObj.errors;
					}
				}
			}
			
			if (msgs) {
				if (msgs instanceof Array) {
					msg_text = msgs.join('<br />');
				} else if (typeof msgs == 'object') {
					msg_text = '';
					for(var k in msgs) {
						if (msg_text) {
							msg_text += '<br />';
						}
						msg_text += msgs[k];
					}
				} else {
					//typeof msgs == 'string'
					msg_text = msgs;
				}
			};
			
			if (msg_text) {
				if (jsonObj.success) {
					ITc.alert.show(msg_text, null,
						this._internalOnSuccess.bind(this, [action])
					);
				} else {
					ITc.alert.show(msg_text, 'Error',
						this._internalOnFail.bind(this, [action])
					);
				}
			} else {
				if (jsonObj.success) {
					this._internalOnSuccess(action);
				} else {
					this._internalOnFail(action);
				}
			}
		} else {
			ITc.alert.show('Request has Failed. Please, try later.', 'Error',
				this._internalOnFail.bind(this, [action])
			);
		}
		ITc.hideMask(this.mask_element);
	},
	_internalOnSuccess: function(action) {
		if (!this.listeners) return false;
		var f = this.listeners['success'] ? this.listeners['success'] : null;
		if (f && typeof f == 'function') {
			if (this.listeners['scope']) {
				f.apply(this.listeners['scope'], [this, action]);
			} else {
				f(this, action);
			}
		}
	},
	_internalOnFail: function(action) {
		if (!this.listeners) return false;
		var f = this.listeners['failure'] ? this.listeners['failure'] : null;
		if (f && typeof f == 'function') {
			if (this.listeners['scope']) {
				f.apply(this.listeners['scope'], [this, action]);
			} else {
				f(this, action);
			}
		}
	},
	_setFieldState: function(field, is_valid, mes) {
		if (!is_valid) {
			if (!field.error_div) {
				var p = field.parentNode;
				var d = document.createElement('div');
				d.className = this.divErrorClass;
				p.appendChild(d);
				field.error_div = d;
			} else {
				field.error_div.style.display = '';
			}
			$(field.error_div).html(mes);
			//field.error_div.innerHTML = mes;
			if(!field.is_invalid){
				field.begining_class = field.className;
				field.className += ' '+this.inputErrorClass+this.invalidClass;
				field.is_invalid = true;
			}
			if (this.use_error_flags && field.error_flag_div) {
				field.error_flag_div.className = 'flag error';
			}
		} else if(field.is_invalid) {
			field.is_invalid = false;
			field.error_div.style.display = 'none';
			field.className = field.begining_class;
			if (this.use_error_flags && field.error_flag_div) {
				field.error_flag_div.className = 'flag ok';
			}
		}
	},
	_getFieldsMap: function() {
		if (!this.fieldsMap) {
			var m = this.form.elements;
			var map = {};
			var error_div_id, error_div, flag_div_id, flag_div;
			for(var i=0; i<m.length; i++) {
				//if (m[i].type == 'hidden' || m[i].type == 'button' || m[i].type == 'submit' || m[i].type == 'image') {
				if ( m[i].type == 'button' || m[i].type == 'submit' || m[i].type == 'image') {
					continue;
				}

				var data_key = this.getFieldDataKey(m[i]);
				if (data_key) {
					if (map[data_key]) {
						ITc.showDebug('already_set' + data_key);
					} else {
						map[data_key] = m[i];
						error_div_id = m[i].getAttribute('error_div_id');
						if (error_div_id) {
							error_div = document.getElementById(error_div_id);
							if (error_div) {
								m[i].error_div = error_div;
							}
						}
						//m[i].onfocus = this._setFieldState.bind(this, m[i], true);
						if (this.use_error_flags) {
							flag_div_id = m[i].getAttribute('error_flag_id');
							if (flag_div_id) {
								var flag_div = document.getElementById(flag_div_id);
								if (flag_div) {
									m[i].error_flag_div = flag_div;
								}
							}
						}
					}
				} else {
					ITc.showDebug('Cant get ' + m[i].name + m[i].type);
				}
			}
			this.fieldsMap = map;
		}
		return this.fieldsMap;
	},
	resetFieldsMap: function() {
		if (this.fieldsMap) {
			this.fieldsMap = null;
		}
	},
	_getRealFieldSet: function(){
		if (!this.realFieldsMap) {
			var m = this.form.elements;
			var map = {};
			for(var i=0; i<m.length; i++) {
				if (m[i].type == 'button' || m[i].type == 'submit' || m[i].type == 'image' || m[i].type == 'radio') {
					continue;
				}
				var data_key = this.getFieldDataKey(m[i]);
				if (data_key) {
					if (map[data_key]) {
						ITc.showDebug('already_set' + data_key);
					} else {
						map[data_key] = m[i];
						var error_div_id = m[i].getAttribute('error_div_id');
						if (error_div_id) {
							var error_div = document.getElementById(error_div_id);
							if (error_div) {
								m[i].error_div = error_div;
							}
						}
						//m[i].onfocus = this._setFieldState.bind(this, m[i], true);
					}
				} else {
					ITc.showDebug('Cant get ' + m[i].name + m[i].type);
				}
			}
			this.realFieldsMap = map;
		}
		return this.realFieldsMap;
	},

	getFieldDataKey: function(field) {
		var res = field.getAttribute('dataIndex');
		if (!res) {
			res = field.name.replace(/(?:.*\[)(.*)(?:\])/, '$1');
		}
		return res;
	},
	setValues: function(formValues){
		if (!formValues) return;
		var f,map = this._getRealFieldSet();
		for (var i in formValues){
			if (map[i]) {
				f = map[i];
				//special for jquery
				if (f.type == 'checkbox') {
					f.checked = formValues[i] ? true : false;
				} else {
					$(map[i]).val(formValues[i]);
				}
				
			}
		}
	},
	resetErrors: function() {
		this._setupErrors({});
	},
	reset: function() {
		this.form.reset();
		this._setupErrors({});
	},
	_setupErrors: function(messages){
		var m = this._getFieldsMap();
		for(var name in m) {
			if (messages[name]) {
				this._setFieldState(m[name], false, messages[name]);
				delete(messages[name]);
			} else {
				this._setFieldState(m[name], true);
			}
		}
		//check for left messages (field not found)
		for (var i in messages) {
			return messages;
		}
		return null;
	},
	submit: function() {
		this._onSubmit();
	}
};

ITc.ut = {
	//allow leave additional comments before some action
	additionalCommentDialog: {
		wrapper_id: 'add_comd_el_cont',
		def_options: {
			title: 'Please specify the reason',
			html: '<div><textarea class="comment" style="width:98%;height:80px;"></textarea></div>',
			width: 350,
			blockEmpty:false,
			callback: {
				fn: function(comment) {
					//alert('CO:' + comment);
				},
				scope: window
			}
		},
		
		show: function(options){
			options = ITc.apply(this.def_options, options);
			
			var w_cont = ITc.getEl(this.wrapper_id);
			if (!w_cont) {
				$('<div id="'+this.wrapper_id+'" style="display:none;"></div>').appendTo('body');
				w_cont = ITc.getEl(this.wrapper_id);
			}
			$(options.html).appendTo(w_cont);
			//need to fix this!
			var D = $(w_cont.firstChild);
			var DomEl = ITc.getEl(D);
			DomEl.callback = options.callback;
			DomEl.blockEmpty = options.blockEmpty;
			ITc.ut.lDialog.create(D, {
				title: options.title,
				width: options.width,
				buttons: {
					'Cancel': function(){
						$(this).dialog('close');
					},
					'OK': function(){
						var t = $(this).find('.comment');
						var val = t.val();
						if (!val && this.blockEmpty) {
							return;
						}
						
						var c = this.callback;
						if (c && c.fn) {
							ITc.callCallback(c.fn, c.scope ? c.scope : window, [t.val()]);
						} else {
							ITc.callCallback(c, window, [t.val()]);
						}
						
						$(this).dialog('close');
					}
				}
			});
			D.dialog('open');
		}
	},
	
	lDialog:{
		create: function(el, conf){
			if (!el || !el.length){
				return null;
			}
			
			var buttons = null;
			
			conf = ITc.apply({
				dialogClass:'light-dialog',
				resizable:false,
				modal:true,
				autoOpen:false,
				width:580
			}, conf ? conf : {});
			
			if (conf.buttons){
				buttons = conf.buttons;
				delete(conf.buttons);
			}
			el.dialog(conf);
			
			if (conf.title){
				this._renderTitle(el, conf.title);
			}
			if (buttons){
				this._renderButtons(el, buttons);
			}
			return el;
		},

		_renderTitle:function(el, title){
			$('<h2>'+title+'</h2>').insertBefore(el);
		},

		_renderButtons:function(el, buttons){
			var _cb, def_button_options = {
				cls: 'rbutton right'
			};
			if (buttons instanceof Array){
				_cb = buttons;
			}else if (buttons instanceof Object) {
				_cb = this._convertFromJqueryButtons(el, buttons, def_button_options);
			};
			
			if (_cb){
				var i,btn,B,
					Btnc = $('<div class="btn-cont"></div>').insertAfter(el);
				for(i = 0; i<_cb.length; i++){
					btn = _cb[i];
					B = $('<a class="'+btn.cls+'">'+btn.text+'</a>').appendTo(Btnc)
						.click(btn.handler);
					if (btn.style){
						B.css(btn.style);
					}
				}
				$('<div class="clear"></div>').appendTo(Btnc);
			} else {
				return false;
			}
			return true;
		},
		
		_convertFromJqueryButtons: function(el, buttons, def_button_options){
			var _cb = [], title, handler, org_el = el[0];
			
			for(title in buttons){
				handler = typeof buttons[title] == 'function' ?
						buttons[title].bind(org_el)
					:	function(){};
				_cb.push({
					text: title,
					handler: handler,
					cls: def_button_options.cls
				});
			}
			
			return _cb;
		}
	}
};

ITc.ut.charsCounter = ITc.extendClass(null, ITc.Component, {
	field: null,
	counter_box: null,
	max_chars: 1000,
	update_delay:300,
	_cctout: null,
	_c_len: 0,
	_initComponent: function() {
		this.counter_box = ITc.getEl(this.counter_box);
		this.field = ITc.getEl(this.field);
		
		if (!this.counter_box || !this.field) {
			return;
		}
		var self = this,
			listener = function(ev, el){
			if (!ev) {
				ev = event;
			}
			if (!el) {
				el = this;
			}
			var len = el.value.length;
			if(len == self.max_chars && ev.charCode > 0){
				return false;
			}
			self._c_len = len;
			clearTimeout(self._cctout);
			self._cctout = setTimeout(self._cUpdaterDelegate, self.update_delay);
			return true;
		};
		if (!this._cUpdaterDelegate) {
			this._cUpdaterDelegate = this.countUpdater.bind(this);
		}
		this.field.onkeyup = listener;
		this.field.onkeypress = listener;
		
		self._c_len = this.field.value.length;
		this.countUpdater(true);
	},
	countUpdater: function(block_substr){
		if (this._c_len > this.max_chars) {
			if (!block_substr) {
				this.field.value = this.field.value.substr(0, this.max_chars);
			}
			this.counter_box.innerHTML = '0';
		} else {
			this.counter_box.innerHTML = (this.max_chars - this._c_len);
		}
	}
});


jQuery(ITc._onPLoad.bind(ITc));