BaseWindow.prototype.constructor = BaseWindow;

function BaseWindow() {

	// fields =====================================================================================
	/**
	 * @type Boolean
	 */	
	this._initDone = false;

	/**
	 * @type Boolean
	 */	
	this._initInProgress = false;
	
	/**
	 * @type jQuery
	 */
	this._container = null;
	
	/**
	 * @type jQuery
	 */
	this._closeButton = null;	
	
	/**
	 * @type String
	 */
	var _containerSelector = "";

	/**
	 * @type String
	 */	
	var _closeButtonSelector = "";
	
	// methods ====================================================================================
	
	/**
	 */
	this._postInitCallback = null;
	
	/**
	 * Initialize the base functionality of the window (container, close button etc.)
	 */
	this._doInit = function() {
		if (!this._initDone) {
			this._initInProgress = true;
			
			this._container = this._getContainer();
			if (!this._container instanceof jQuery) {
				this._container = $(containerSelector);
				if (!this._container instanceof jQuery) {
					throw ("container must be instance of jQuery!");
				}
			}

			var closeButtonSelector = this._getCloseButtonSelector();
			this._closeButton = $(closeButtonSelector, this._container);

			if (this._closeButton instanceof jQuery) {
				this._closeButton.unbind("click.baseWindow");
				this._closeButton.bind("click.baseWindow", $.proxy(function(event) {
					event.preventDefault();
					this.hide();
				}, this));			
			};
			
			this._initHook(this._postInitCallback);
		}
	};
	
	/**
	 * @param {jQuery} $triggerElement
	 */
	this._doShow = function($triggerElement) {
		this._preShowHook($triggerElement);

		this._container.fadeIn("normal", $.proxy(function() {
			this._postShowHook($triggerElement);			
		}, this));
	};
	
	/**
	 * Dynamically set the container
	 * @param {jQuery} $container
	 */
	this.setContainer = function($container) {
		_containerSelector = $container;
	};

	/**
	 * Dynamically set the close button selector
	 * @param {String} selector
	 */	
	this.setCloseButtonSelector = function(selector) {
		_closeButtonSelector = selector;
	};
	
	/**
	 * @type {jQuery} - the container object
	 */
	this.getContainer = function() {
		return this._container;
	};
	
	/**
	 * @type {jQuery} - the close button object
	 */
	this.getCloseButton = function() {
		return this._closeButton;
	};
	
	/**
	 * Override to define the window container selector
	 * @type {jQuery}
	 * @return the window container selector
	 */
	this._getContainer = function() {
		return _containerSelector;
	};
	
	/**
	 * Override to define the close button selector
	 * @type {String}
	 * @return the close button selector
	 */	
	this._getCloseButtonSelector = function() {
		return _closeButtonSelector;
	};

	/**
	 * Override to add functionality to initialization proccess
	 * @param {Function} callback
	 */
	this._initHook = function(callback) {
		if ($.isFunction(callback)) {
			callback();
		}
	};

	/**
	 * Override to add pre show functionality
	 * @param {jQuery} $triggerElement
	 */		
	this._preShowHook = function($triggerElement) {

	};
	
	/**
	 * Override to add post show functionality
	 * @param {jQuery} $triggerElement
	 */	
	this._postShowHook = function($triggerElement) {
		
	};
	
	/**
	 * Override to add pre hide functionality
	 */	
	this._preHideHook = function () {
		
	};
	
	/**
	 * Override to add post hide functionality
	 */	
	this._postHideHook = function() {
		
	};
	
	/**
	 * @param {jQuery} $triggerElement
	 */
	this.setTriggerElement = function($triggerElement) {
		if ($triggerElement instanceof jQuery) {
			var _this = this; 
			$triggerElement.unbind("click.baseWindow");
			$triggerElement.bind("click.baseWindow", function(event) {
				event.preventDefault();
				
				var $target = $(this);
				_this.show($target);
			});
		}		
	};
	
	this.init = function() {
		if (this._initInProgress || this._initDone) {
			return;
		}
		
		this._postInitCallback = $.proxy(function() {
			this._initDone = true;
			this._initInProgress = false;
			this._postInitCallback = null;
		}, this);		
		
		this._doInit();
	};
	
	/**
	 * @param {jQuery} $triggerElement
	 */
	this.show = function($triggerElement) {
		if (this._initInProgress) {
			this._postInitCallback = $.proxy(function() {
				this._initDone = true;
				this._initInProgress = false;
				this._doShow($triggerElement);
				this._postInitCallback = null;
			}, this);
		} else if (!this._initDone) {
			this._postInitCallback = $.proxy(function() {
				this._initDone = true;
				this._initInProgress = false;
				this._doShow($triggerElement);
				this._postInitCallback = null;
			}, this);
			
			this._doInit();
		} else {
			this._doShow($triggerElement);
		}
	};
	
	/**
	 * @param {Function} callback
	 */
	this.hide = function(callback) {
		this._preHideHook();
		this._container.fadeOut("normal", $.proxy(function() {
			 this._postHideHook();
			 if ($.isFunction(callback)) {
				 callback();
			 }
		}, this));
	};
}
