(function ($) {
/**
 * Component
 * @constructor jQuery
 */
$.widget('ui.Component', {
	/**
	 * Class name
	 */
	type: 'Component',
	/**
	 * Children components
	 */
	children: {},
	/**
	 * Whether component rendered as modal window
	 */
	_modal: false,
	/**
	 * masking style:
	 *  block - when component div is masked
	 *  global - cursor changes its style globally to notify user about progress
	 */
	_masking: 'block',
	/**
	 * Initialize component children
	 * @private
	 */
	_initChildren: function (children) {
		for (var c in children) {
			var child = $('#' + c);
			if (child) { // child element has been found
				this.children[c] = child.component({children: children[c]});
			}
		}
	},

	/**
	 * Initialize with content requested from server
	 */
	_load: function () {
		var self = this;

		$.post(location.langbase + 'ajax/' + this.type + '/' + (this.element.attr("id") || 'null') +'/1/', this.options.loadParams || {}, function (data) {
				var loaded = $(data.html.htmldecode());
				delete data.html;

				self.element.replaceWith(loaded);

				// preserve options
				$.extend(self.options, data);
				delete self.options.load;
				delete self.options.loadParams;

				loaded.component(self.options);

			}, 'json');
	},

	/**
	 * Initialize component
	 * NOTE: usually each component will require
	 * this method being extended, so make sure
	 * not to lose children initialization (you
	 * may perform the action by calling parent
	 * component `init` method)
	 */
	_init: function () {
		this._initChildren(this.options.children);

		var self = this;

		if (this.options.load) {
			// init from server
			this._load();
		} else if (this.options.modal && ! this._modal) {
			// transform component to modal window
			this.element.dialog($.extend({}, {
					modal: true,
					close: function () {
							self.element.dialog('destroy').remove();
						}
				}, this.options.modalConfig));
			this._modal = true;
		}

		if (this.options.isPost && this.options.post) { // and event configured to fire when component is posted successfully
			this.options.post.apply(this);
		}
	},

	/**
	 * Mask the component
	 */
	mask: function () {
		if (this._masking == 'block') {
			this.element.wrap('<div class="refresh" style="width:'+this.element.width()+'px;height:'+this.element.height()+'px;" />').before('<div class="overlay"  style="width:'+this.element.width()+'px;height:'+this.element.height()+'px;" />');
//			this.element/*.toggleClass("overlay_p")*/.wrap('<div class="refresh" />').before('<img style="position:absolute;left:'+ (this.element.width()/2-37) +'px;top:'+ (this.element.height()/2-37) +'px;" class="refresh_img" src="http://s.' + location.host + '/img/icon/wait-2.gif" />').wrap('<div class="overlay" />');
//			this.element.toggleClass("overlay_p").find('div, input, ul, li').css('background', 'none').css('border', '#aaaaaa').end().wrap('<div class="refresh" />').before('<img style="position:absolute;left:'+ (this.element.width()/2-25) +'px;top:'+ (this.element.height()/2-25) +'px;" class="refresh_img" src="http://s.' + location.host + '/img/icon/wait-2.gif" />').wrap('<div class="overlay" />');
			//this.element.find('div.box').css("height", this.element.height()-20).end().css("width", this.width());
			//$('div.outter_loading div.loading div.box').css("height", this.element.height()-20).css("width", this.width());
//			$('.overlay').click(function(ev){
//				ev.cancelBubble = true
//				ev.preventDefault()
//				alert("overlay")
//			})
//			$('.refresh').click(function(ev){
//				ev.cancelBubble = true
//				ev.preventDefault()
//				alert("refresh")
//			})
		} else if (this._masking == 'global') {
			$(document.body).addClass('waiting');
			$('.waiting').click(function(ev){
				ev.cancelBubble = true
				ev.preventDefault()
			})
		}
	},

	/**
	 * Unmask the component
	 */
	unmask: function () {
		if (this._masking == 'block') {
			this.element.parent('.refresh').before(this.element).remove();
//			this.element.toggleClass("overlay_p").parent('.overlay').parent('.refresh').before(this.element).remove();
			//this.element.show();
		} else if (this._masking == 'global'){
			$(document.body).removeClass('waiting');
		}
	},

	/**
	 * Reload component content requesting a new one
	 * from the server
	 * @param {object} params Request parameters or form to send
	 */
	reload: function (params, callback) {
		var self = this;

		this.mask();

		var url = location.langbase + 'ajax/' + this.type + '/' + this.element.attr("id") +'/?DM=0',
			handler = function (data) {
				self.element.html(data.html.htmldecode());
				delete data.html;
				self.unmask();
				$.extend(self.options, data);
				self._init();
				callback && callback();
			};

		if ($(params).is('form')) {
			(function () {
				$(params).ajaxSubmit({
						success: handler,
						url: url,
						type: 'POST',
						dataType: 'json'
					});
			}).require("http://s." + location.host + '/js/jquery/jquery.form.js', 'script', function (){return $.fn.selected != undefined && $.fn.ajaxForm != undefined})();
		} else {
			$.post(url, params || {}, handler, 'json');
		}
	},

	/**
	 * String representation
	 */
	toString: function () {
		return '[' + this.type +'] ' + this.element.attr("id");
	}
});

})(jQuery);
