var PopUp = function (id, _o) {
	this._id = id;
	this.opts = jQuery.extend({}, PopUp.defaults, _o);
};
PopUp.create = function (id, opts) {
	if (typeof(this._register) != 'object') this._register = {};
	if (typeof(this._register[id]) == 'object') return this._register[id];
	else {
		this._register[id] = new PopUp(id, opts);
		this._register[id].init();
		return this._register[id];
	}
};
PopUp.exists = function (id) {
	if (typeof(this._register) != 'object') this._register = {};
	if (typeof(this._register[id]) == 'object') return true;
	else return false;
};
PopUp.get = function (id) {
	if (typeof(this._register) != 'object') this._register = {};
	if (typeof(this._register[id]) == 'object') return this._register[id];
	else return null;
};
PopUp.defaults = {
	fullscreen: false,
	width: 200,
	height: 130,
	offsetTop: 0,
	offsetLeft: 0,
	title: null,
	content: null,
	closable: true
};
PopUp.prototype = {
	Index: null,
	State: 'hidden',
	States: { hidden:'hidden', loading:'loading', visible:'visible' },
	init: function () {
		if (this.el().length > 0) this.el().remove();
		jQuery('body').append('<div class="site-popup" id="popup-window-' + this._id + '"><div class="popup-title"><div class="popup-close"></div><span></span></div><div class="popup-loading"></div><div class="popup-content"></div></div>');
		if (jQuery("#popup-overlay").length == 0) {
			jQuery('body').prepend('<div id="popup-overlay"></div>');
		}
	},
	el: function (selector) {
		if (typeof(selector) != 'undefined') return jQuery(selector, this.el());
		return jQuery('#popup-window-' + this._id);
	},
	isFullscreen: function () {
		return (this.State == 'loading')?(false):(this.opts.fullscreen);
	},
	isClosable: function () {
		return (this.State == 'loading')?(false):(this.opts.closable);
	},
	setTitle: function (title) {
		if (typeof(title) == 'undefined') title = null;
		this.opts.title = title;
		return this;
	},
	setContent: function (content) {
		if (typeof(content) == 'undefined') content = null;
		this.opts.content = content;
		return this;
	},
	setState: function (new_state) {
		if (new_state != 'undefined' && this.States[new_state] == new_state) this.State = new_state;
		return this;
	},
	startLoading: function () {
		this.State = 'loading';
		PopUp.Manager.display(this);
	},
	stopLoading: function () {
		if (this.State == 'loading') {
			PopUp.Manager.hide(this.Index);
		}
	},
	show: function () {
		if (this.State == 'visible') return false;
		if (this.State == 'loading') PopUp.Manager.hide(this.Index);
		if (this.opts.content == null) return false;
		if (this.opts.title != null) {
			this.el('.popup-title > span').html(this.opts.title);
		}
		this.el('.popup-content').html(this.opts.content);
		PopUp.Manager.display(this);
	},
	hide: function () {
		PopUp.Manager.hide(this.Index);
	},
	cssPosition: function (width, height) {
		var pos = this.getViewPort();
		if (typeof(width) == 'string') {
			if (width == 'auto') {
				this.el().css({width: 'auto'});
				width = this.el().outerWidth();
			} else if (width.indexOf('%') != -1) {
				width = parseInt(width.substring(0, width.indexOf('%')));
				if (width > 0 && width <= 100) {
					width = pos[0]* (width/100);
				} else width = 0;
			} else width = parseInt(width);
		}
		if (width < 1) width = 140;
		
		if (typeof(height) == 'string') {
			if (height == 'auto') {
				this.el().css({height: 'auto'});
				height = this.el().outerHeight();
			} else if (height.indexOf('%') != -1) {
				height = parseInt(height.substring(0, height.indexOf('%')));
				if (height > 0 && height <= 100) {
					height = pos[1]* (height/100);
				} else height = 0;
			} else height = parseInt(height);
		}
		
		if (width < 1) width = 140;
		if (height < 1) height = 60;
		var X = Math.round((pos[0]-width)/2) + pos[2];
		var Y = Math.round((pos[1]-height)/2) + pos[3];
		if (this.opts.offsetLeft > 0) X = X + this.opts.offsetLeft;
		if (this.opts.offsetTop > 0) Y = Y + this.opts.offsetTop;
		return {
			width: width + 'px',
			height: height + 'px',
			top: Y,
			left: X
		};
	},
	_show: function () {
		if (this.State == 'loading') {
			this.el('.popup-title, .popup-content').hide();
			this.el('.popup-loading').show();
			this.el().css(this.cssPosition(220, 20)).show();
		} else if (this.State == 'hidden') {
			this.State = 'visible';
			this.el('.popup-content').show();
			this.el('.popup-loading').hide();
			if (this.opts.title != null) {
				this.el('.popup-title').show().addClass('has-title');
			} else this.el('.popup-title').show().removeClass('has-title');
			this.el().css(this.cssPosition(this.opts.width, this.opts.height)).fadeIn(200);
		} else return false;
	},
	_hide: function () {
		if (this.State == 'loading') {
			this.el().hide();
			this.el('.popup-content').html('');
		} else if (this.State == 'visible') {
			this.el().fadeOut(200);
		} else return false;
		this.State = 'hidden';
	},
	getViewPort: function () {
		return [jQuery(window).width(), jQuery(window).height(), jQuery(document).scrollLeft(), jQuery(document).scrollTop() ];
	}
};

PopUp.mngr = function () {
	this._queue = new Queue();
	this._fullscreen = false;
};
PopUp.mngr.prototype = {
	zIndex: 500,
	_stack: [],
	display: function (pop) {
		this._queue.enqueue(pop);
		this.processQueue();
	},
	processQueue: function () {
		var the_popup = null;
		while (!this._fullscreen && !this._queue.isEmpty()) {
			the_popup = this._queue.dequeue();
			if (the_popup.isFullscreen()) {
				this._fullscreen = true;
				this.showOverlay();
			}
			this._stack.push(the_popup);
			var popIndex = (this._stack.length-1);
			the_popup.Index = popIndex;
			if (the_popup.isClosable()) {
				the_popup.el('.popup-close').show().bind('click', {mngr: this, index: popIndex}, function (e) {
					e.data.mngr.hide(e.data.index);
					return false;
				});
			} else the_popup.el('.popup-close').hide();
			the_popup.el().css({zIndex: this.zIndex + this._stack.length});
			the_popup._show.apply(the_popup);
		}
	},
	showOverlay: function () {
		jQuery("#popup-overlay").css('opacity', 0.3).show();
	},
	hideOverlay: function () {
		jQuery("#popup-overlay").fadeOut(200);
	},
	hide: function (index) {
		if (this._stack.length == 0 || typeof(this._stack[index]) != 'object') return;
		var the_popup = this._stack.splice(index, 1)[0];
		if (this._fullscreen && the_popup.isFullscreen()) {
			this.hideOverlay();
			this._fullscreen = false;
		}
		the_popup._hide.apply(the_popup);
		the_popup.Index = null;
		this.processQueue();
	}
};
PopUp.Manager = new PopUp.mngr;
myLib('popup-content').register();
