(function($){ // secure $ jQuery alias
/*******************************************************************************************/
// jquery.window.js - rev 2
// Copyright (c) 2011, Larry (http://larionov.biz)
// Liscensed under the BSD License (BSD-LICENSE.txt)
// http://www.opensource.org/licenses/bsd-license.php
// Created: 2011-02-02
/*******************************************************************************************/

	// TODO: Close dialog on ESC key and press default key on Enter (maybe) and drop down
	/**
	 * @requires $.__Event
	 * @param {DOMElement|jQuery} toggle
	 * @param {Object} config
	 */
	$.Window = function(toggle, config) {
		var self = this;
		this.config = $.Window.Helper.extend(this.defaultConfig, config || {});

		this.toggle = null;
		if (toggle) {
			this.toggle = $(toggle).click(function() {
				self.open();
				return false;
			});
			this.toggle.data('window', this);
		}

		this.events = {};
		$.each(this.config.events, function(eventName, handler) {
			self.bind(eventName, handler);
		});

		this.overlay = $(this.config.tplOverlay).hide().css('z-index', 900).appendTo('body');
		this.content = $($.Window.Helper.replaceVars(this.config.tplMain, {
			content: this.getContent(),
			title: this.getTitle()
		})).css('z-index', 920).hide().appendTo('body');
		this.content.find('.window-close').click(function() {
			self.close();
			return false;
		});
		this.attachButtons();

		if (this.config.autoclose !== null) {
			this.bind('init', function() {
				var self = this;
				setTimeout(function() {
					self.close();
				}, this.config.autoclose);
			});
		}

		this.trigger('init');
	};
	$.__Event.inherit($.Window, $.__Event);
	$.Window.prototype.defaultConfig = {
		/* Содержимое попапа. Если не указано, то ищется объекст с @id указанным в @rel или @data-rel. Если такого нет, то попап не показывается */
		content: null,
		title: null,
		titleDefault: 'Message',

		tplMain: '<div class="window"><div class="window-title">{title}<span class="window-close">&times;</span></div><div class="window-content">{content}</div><div class="window-buttons-replacer"></div></div>',
		tplOverlay: '<div style="position: fixed; width: 100%; height: 100%; top: 0; left: 0; background-color: black; opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.3; filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30);"/>',
		tplButtonsWrap: '<div class="window-buttons"></div>',
		tplButton: '<a class="window-button f-button-09 {classes}"><span class="in">{title}</span></a> ',

		buttons: {},
		events: {},

		/**
		 * Автоматически скрыть через X милисекунд
		 * @var {int}
		 */
		autoclose: null,
		autocentre: false
	};
	$.Window.prototype.open = function() {
		this.overlay.show();
		this.content.show();
		if (this.config.autocentre) {
			this.content.css({
				'top': '50%',
				'margin-top': (-this.content.height() / 2) + 'px'
			});
		}
		this.trigger('open');
		return this;
	};
	$.Window.prototype.close = function() {
		if (this.trigger('close', true) === false) {
			return this;
		}
		this.overlay.hide();
		this.content.hide();
		return this;
	};
	$.Window.prototype.destroy = function() {
		this.trigger('destroy');
		this.overlay.remove();
		this.content.remove();
		this.toggle = this.config = this.events = null;
		if (this.toggle) {
			this.toggle.removeData('window');
		}
		try {delete this;} catch(e) {}
	};
	$.Window.prototype.getContent = function() {
		var rel, content = null;
		if (this.config.content) {
			content = this.config.content;
		} else if (this.toggle && ((rel = this.toggle.attr('rel')) || (rel = this.toggle.data('rel')))) {
			content = $('#' + rel);
			if (content.size()) {
				content = content.first().html();
			} else {
				content = null;
			}
		}
		return content;
	};
	$.Window.prototype.getTitle = function() {
		var title = this.config.title;
		if (!title && this.toggle) {
			title = this.toggle.attr('title');
		}
		if (!title) {
			title = this.config.titleDefault;
		}
		return title;
	};
	$.Window.prototype.attachButtons = function() {
		var self = this, replacer = this.content.find('.window-buttons-replacer');
		if ($.isArray(this.config.buttons)) {
			var wrap = $(this.config.tplButtonsWrap), button;
			for (var i = 0, count = this.config.buttons.length; i < count; i++) {
				button = $($.Window.Helper.replaceVars(this.config.tplButton, {
					name: this.config.buttons[i].name || '',
					classes: this.config.buttons[i].classes || '',
					title: this.config.buttons[i].title
				}));
				if (this.config.buttons[i].handler instanceof Function) {
					button.click({window: self}, this.config.buttons[i].handler);
				}
				wrap.append(button);
			}
			return replacer.replaceWith(wrap);
		} else {
			replacer.remove();
		}
		return this;
	};
	$.Window.Helper = {
		/**
		 * @param {Mixed} value
		 * @return bool
		 */
		isObject: function(value) {
			if(value instanceof Array) {
				return false;
			} else {
				return (value !== null) && (typeof(value) == 'object');
			}
		},
		/**
		 * @param {String} where
		 * @param {Object} replace
		 * @return {String}
		 */
		replaceVars: function(where, replace) {
			var result = where.toString();
			if ($.Window.Helper.isObject(replace)) {
				for (var key in replace) {
					if (typeof replace[key] == 'string') {
						result = result.replace(new RegExp('{' + key + '}', 'g'), replace[key]);
					}
				}
			}
			return result;
		},
		extend: function(source, target) {
			return $.extend(true, target, $.extend(true, {}, source || {}, target || {}));
		}
	};

	$.Window.message = function(message, config) {
		return (new $.Window(null, $.Window.Helper.extend({
			content	: message,
			buttons	: [{title: 'Ок', classes: 'button', handler: function(e) {e.data.window.close();}}],
			events	: {close: function(e) {this.destroy();}}
		}, config || {}))).open();
	};

	$.fn.Window = function(config) {
		var w;
		if (this.size() == 1 && (w = this.data('window'))) {
			return w;
		} else {
			return this.each(function(i, toggle) {
				new $.Window(toggle, config);
			});
		}
	};
})(jQuery);

