/*global DGS, jQuery, window, console, document */
Reflow.widgets.popinManager = function(objParent, params) {
	var parent, id, selectors, defaultPopinOptions, popinList, templates, PopinObject, init, displayPopinList, setDefaultPopinOptions, open, closeAll, close, popin, visibilityFix, popinManagerOptions, getParam, toText, setSelectors, getSelector, defaultTemplates, setDefaultPopinOptions, setPopinManagerOptions, setTemplates, defaultTemplates, initialized, innerShiv, bgOpacity, isMobileDevice, documentMainWrapper;
	isMobileDevice = /iPhone|iPad|iPod|android|blackberry|palm/gi.test(navigator.userAgent);
	documentMainWrapper = jQuery("#main");
	initialized = false;
	parent = objParent;
	id = "popinManager";
	bgOpacity = 0.8;
	selectors = {
		linkPopin : ".open-popin",
		linkAjaxPopin : ".open-ajax-popin",
		linkClosePopin : ".close-popin",
		popin : ".rf-popin",
		elementsToResize : ".rf-popin-t, .rf-popin-b",
		wrapperElement : ".rf-popin-wrapper",
		hiddenClass : ".hidden",
		backgroundPopinId : "#rf-bg-popin",
		parameters : "popin-param",
		autoOpen : ".rf-popin[data-open-at-start]"
	};
	innerShiv = ( function() {
		var d, r;
		return function(h, u) {
			if(!d) {
				d = document.createElement('div');
				r = document.createDocumentFragment();
				/*@cc_on d.style.display = 'none';@*/
			}
			var e = d.cloneNode(true);
			/*@cc_on document.body.appendChild(e);@*/
			e.innerHTML = h;
			/*@cc_on document.body.removeChild(e);@*/
			if(u === false)
				return e.childNodes;
			var f = r.cloneNode(true), i = e.childNodes.length;
			while(i--)
			f.appendChild(e.firstChild);
			return f;
		};
	}());
	getSelector = function(args) {
		if( typeof args === "string") {
			return toText(selectors[args]);
		}
		return "";
	};
	setSelectors = function(args) {
		if( typeof args === "object") {
			selectors = parent.core.extend(selectors, args);
			if(initialized) { init(parent);
			}
		}
	};
	toText = function(str) {
		return str.replace(/[\.#]/, "");
	};
	css = function(el, prop) {
		return parseInt($.css(el[0], prop), 10) || 0;
	};
	defaultPopinOptions = {
		"width" : "auto",
		"css" : "",
		"style" : "",
		"modal" : false,
		"contentId" : "",
		"ajax" : false,
		"ajaxLink" : "",
		"allowAjaxCache" : true,
		"popinTemplate" : "light",
		"ajaxPHPFilter" : true
	};
	setDefaultPopinOptions = function(args) {
		if( typeof args === "object") {
			defaultPopinOptions = parent.core.extend(defaultPopinOptions, args);
			if(initialized) { init(parent);
			}
		}
	};
	popinManagerOptions = {
		"movePopin" : true,
		"ajaxPHPparam" : "ajax=true"
	};
	setPopinManagerOptions = function(args) {
		if( typeof args === "object") {
			popinManagerOptions = parent.core.extend(popinManagerOptions, args);
			if(initialized) { init(parent);
			}
		}
	};
	popinList = [];
	defaultTemplates = {
		"full" : (function() {
			return '<div id="{0}" class="rf-sizable-popin ' + toText(selectors.popin) + '"><div class="rf-popin-tl"></div><div class="rf-popin-t"></div><div class="rf-popin-tr"></div><div class="rf-popin-l"><div class="rf-popin-r"><div class="' + toText(selectors.wrapperElement) + '"></div></div></div><div class="rf-popin-bl"></div><div class="rf-popin-b"></div><div class="rf-popin-br"></div></div>'
		}),
		"light" : (function() {
			return '<div id="{0}" class="' + toText(selectors.popin) + '"><div class="' + toText(selectors.wrapperElement) + '"></div></div>'
		}),
		"video" : (function() {
			return '<div id="{0}" class="' + toText(selectors.popin) + ' ' + toText(selectors.hiddenClass) + '"><div class="' + toText(selectors.wrapperElement) + '"></div></div>'
		}),
		"loading" : Reflow.widgets.rsm.getText("popin.ajax.wait"),
		"errorLoading" : Reflow.widgets.rsm.getText("popin.ajax.error")
	};
	templates = {};
	setTemplates = function(args) {
		if( typeof args === "object") {
			templates = parent.core.extend(templates, args);
			if(initialized) { init(parent);
			}
		}
	};
	setTemplates(defaultTemplates);
	visibilityFix = function(state, selector) {
		if(state === "show") {
			jQuery(selector).each(function() {
				var select = jQuery(this);
				if(select.parents(selectors.popin).size() === 0) {
					if(this.RFlastState !== undefined && this.RFlastState !== null && this.RFlastState !== "") {
						select.css({
							"visibility" : this.RFlastState
						});
					}
				}
			});
		} else if(state === "hide") {
			jQuery(selector).each(function() {
				var select = jQuery(this);
				if(select.parents(selectors.popin).size() === 0) {
					this.RFlastState = select.css("visibility");
					select.css({
						"visibility" : "hidden"
					});
				}
			});
		}
	};
	getParam = function(link) {
		var returnObj = {};
		if( typeof (link) === "undefined" || typeof (link.className) === "undefined" || link.className === "" || !link.className.match(selectors.parameters)) {
			returnObj.width = null;
			returnObj.modal = false;
			if( typeof (link) !== "undefined" && typeof (link.rel) !== "undefined" && link.rel !== "") {
				returnObj.id = link.rel.replace(/[^a-zA-Z0-9_-]/g, "");
			}
		} else {
			var re, stringParam, params;
			re = /.*(rf-popin-param\()(.*)(\)).*/;
			stringParam = "(" + link.className.replace(re, "$2") + ")";
			params = eval(stringParam) || {};
			if(params.id !== undefined) {
				returnObj.id = params.id;
			} else if(link.rel !== "") {
				returnObj.id = link.rel.replace(/[^a-zA-Z0-9_-]/g, "");
			}
			if(params.width !== undefined) {
				returnObj.width = parseInt(params.width, 10);
			}
			if(params.modal !== undefined) {
				returnObj.modal = params.modal.toLowerCase() === "true";
			}
			if(params.css !== undefined) {
				returnObj.css = params.css;
			}
			if(params.style !== undefined) {
				returnObj.style = params.style;
			}
			if(params.contentId !== undefined) {
				returnObj.contentId = params.contentId;
			}
			if(params.allowAjaxCache !== undefined) {
				returnObj.allowAjaxCache = params.allowAjaxCache;
			}
			if(params.ajaxPHPFilter !== undefined) {
				returnObj.ajaxPHPFilter = params.ajaxPHPFilter;
			}
			if(params.popinTemplate !== undefined) {
				returnObj.popinTemplate = params.popinTemplate;
			}
		}
		return returnObj;
	};
	PopinObject = function(popinParam) {
		this.popin = null;
		this.id = popinParam.id;
		this.popinOptions = {};
		this.sizableElements = null;
		this.contentElement = null;
		this.storeOptions = function(args) {
			var tmpPopinOptions = {};
			tmpPopinOptions = parent.core.extend(tmpPopinOptions, defaultPopinOptions);
			this.popinOptions = parent.core.extend(tmpPopinOptions, args);
			id = this.popinOptions.id = args.id || this.popinOptions.id;
		};
		this.storeOptions(popinParam);
		if(this.popinOptions.ajax === false) {
			this.popin = jQuery("#" + this.popinOptions.id);
			this.sizableElements = this.popin.find(selectors.elementsToResize);
			this.contentElement = this.popin.find(selectors.wrapperElement);
		}
		this.callback = {
			closeCallback : null,
			closeCallbackArgs : {},
			openCallback : null,
			openCallbackArgs : {},
			beforeOpen : null,
			beforeOpenArgs : {},
			beforeClose : null,
			beforeCloseArgs : {}
		};
		this.getWrapper = function() {
			if(this.popin.hasClass(toText(selectors.wrapperElement)) === true) {
				return this.popin;
			} else {
				return this.popin.find(selectors.wrapperElement);
			}
		};
		this.centerPopin = function() {
			var jWindow, top, bg;
			jWindow = jQuery(window);
			if(!isMobileDevice) {
				this.popin.css('left', jWindow.width() / 2 - this.popin.width() / 2 + jWindow.scrollLeft());
				top = jWindow.height() / 2 - (this.popin.height() + css(this.popin, 'marginTop') + css(this.popin, 'marginBottom')) / 2 + jWindow.scrollTop();
				top = (top > 0 ? top : 0);
				this.popin.css('top', top);
				if(jQuery.browser.msie && jQuery.browser.version <= 6) {
					bg = jQuery(selectors.backgroundPopinId);
					bg.height(jWindow.height() + jWindow.scrollTop());
					bg.css({
						"position" : "absolute"
					});
				}
			} else {
				this.popin.css('left', documentMainWrapper.width() / 2 - this.popin.width() / 2);
				top = documentMainWrapper.height() / 2 - this.popin.height() / 2;
				top = (top > 0 ? top : 0);
				this.popin.css('top', top);
				bg = jQuery(selectors.backgroundPopinId);
				bg.height(documentMainWrapper.height());
				bg.width(jWindow.width());
			}
		};
		this.resizeScrollHandler = function(e) {
			if(!isMobileDevice) {
				e.data.popinObj.centerPopin();
			}
		};
		this.close = function(option) {
			var jWindow, bg;
			if(this.callback.beforeClose != null) {
				this.callback.beforeClose({
					"id" : this.id,
					"popin" : this.popin,
					"data" : this.callback.beforeCloseArgs,
					"popinObject" : this
				});
			}
			bg = jQuery(selectors.backgroundPopinId);
			if(this.popinOptions.modal === false) {
				bg.unbind("click", this.closeHandler);
			}
			this.popin.find(selectors.linkClosePopin).unbind();
			var _this = this;
			this.popin.stop().fadeOut(300, function() {
				$(this).css({
					left : -9999,
					top : -9999
				});
				_this.popin.addClass(toText(selectors.hiddenClass));
				if(_this.popinOptions.css !== "") {
					_this.popin.removeClass(_this.popinOptions.css);
				}
				_this.popin.attr("style", "");
				if(( typeof (option.bgOpen) !== "undefined" && option.bgOpen == false) || typeof (option.bgOpen) === "undefined") {
					bg.stop().fadeOut(300, function() {
						$(this).hide();
						if(jQuery.browser.msie && jQuery.browser.version <= 6) { visibilityFix("show", "select");
						}
					});
				}
			});
			jWindow = jQuery(window);
			jWindow.unbind("scroll", this.resizeScrollHandler);
			jWindow.unbind("resize", this.resizeScrollHandler);
			if(this.callback.closeCallback != null) {
				this.callback.closeCallback({
					"id" : this.id,
					"popin" : this.popin,
					"data" : this.callback.closeCallbackArgs,
					"popinObject" : this
				});
			}
		};
		this.closeHandler = function(e) {
			e.preventDefault();
			e.data.popinObj.close({});
		};
		this.open = function(options) {
			var jWindow, bg;
			if(jQuery.browser.msie && jQuery.browser.version <= 6) { visibilityFix("hide", "select");
			}
			if(options !== undefined) {
				this.storeOptions(options);
			}
			if(this.popinOptions.width !== null && this.popinOptions.width !== "" && this.popinOptions.width !== "auto") {
				this.popin.width(this.popinOptions.width);
				if(this.sizableElements.size() > 0) {
					var padding, width;
					padding = parseInt(this.contentElement.css("padding-left"), 10) + parseInt(this.contentElement.css("padding-right"), 10);
					width = this.contentElement.width() + padding;
					this.sizableElements.width(width);
				}
			}
			if(this.popinOptions.css !== "") {
				this.popin.addClass(this.popinOptions.css);
			}
			if(this.popinOptions.style !== "") {
				this.popin.css(this.popinOptions.style);
			}
			if(this.callback.beforeOpen != null) {
				this.callback.beforeOpen({
					"id" : this.id,
					"popin" : this.popin,
					"data" : this.callback.beforeOpenArgs,
					"popinObject" : this
				});
			}
			if(this.popin.hasClass(toText(selectors.hiddenClass))) {
				this.popin.removeClass(toText(selectors.hiddenClass)).hide();
			}
			this.centerPopin();
			jWindow = jQuery(window);
			jWindow.bind("scroll", {
				popinObj : this
			}, this.resizeScrollHandler);
			jWindow.bind("resize", {
				popinObj : this
			}, this.resizeScrollHandler);
			bg = jQuery(selectors.backgroundPopinId);
			if(this.popinOptions.modal === false) {
				bg.bind("click", {
					popinObj : this
				}, this.closeHandler);
			}
			this.popin.find(selectors.linkClosePopin).bind("click", {
				popinObj : this
			}, this.closeHandler);
			var _this = this;
			bg.stop().fadeTo(300, bgOpacity, function() {
				_this.popin.stop().fadeTo(300, 1, function() {
					if(_this.callback.openCallback != null) {
						_this.callback.openCallback({
							"id" : _this.id,
							"popin" : _this.popin,
							"data" : _this.callback.openCallbackArgs,
							"popinObject" : _this
						});
					}
				});
			});
		};
		this.openHandler = function(e) {
			var options;
			e.preventDefault();
			options = getParam(this);
			e.data.popinObj.open(options);
		};
		this.setContent = function(content) {
			this.contentElement = this.getWrapper();
			if(jQuery.browser.msie && jQuery.browser.version <= 8) {
				this.contentElement.html(innerShiv(content));
			} else {
				this.contentElement.html(content);
			}
		};
		this.writeTemplate = function() {
			if(this.popin == null || this.popin.size() === 0) {
				this.popin = jQuery("#" + this.popinOptions.id);
				if(this.popin.size() === 0) {
					var tpl = "";
					if(templates[this.popinOptions.popinTemplate] !== undefined) {
						tpl = templates[this.popinOptions.popinTemplate];
						if( typeof tpl === "function") {
							tpl = tpl();
						}
						tpl = tpl.replace("{0}", this.popinOptions.id);
					}
					jQuery("body").append(tpl);
					this.popin = jQuery("#" + this.popinOptions.id);
				}
			}
			this.sizableElements = this.popin.find(selectors.elementsToResize);
		};
		this.loadError = function(data, b, c) {
			this.popinObj.contentElement.html(templates.errorLoading);
		};
		this.loadSuccess = function(data) {
			if(this.popinObj.callback.dataLoaded != null) {
				data = this.popinObj.callback.dataLoaded({
					"id" : this.popinObj.id,
					"popin" : this.popinObj.popin,
					"data" : this.popinObj.callback.dataLoadedArgs,
					"loadedData" : data,
					"popinObject" : this
				}) || data;
			}
			if(jQuery.browser.msie && jQuery.browser.version <= 8) {
				this.popinObj.contentElement.empty();
				this.popinObj.contentElement.html(innerShiv(data));
			} else {
				this.popinObj.contentElement.html(data);
			}
			if(this.popinObj.callback.contentAdded != null) {
				this.popinObj.callback.contentAdded({
					"id" : this.popinObj.id,
					"popin" : this.popinObj.popin,
					"data" : this.popinObj.callback.contentAddedArgs,
					"popinObject" : this.popinObj
				});
			}
			this.popinObj.contentElement.find(selectors.linkClosePopin).bind("click", {
				popinObj : this.popinObj
			}, this.popinObj.closeHandler);
			this.popinObj.centerPopin();
		};
		this.load = function(url) {
			this.writeTemplate();
			this.setContent(templates.loading);
			this.open();
			jQuery.ajax({
				url : url,
				dataType : 'html',
				success : this.loadSuccess,
				error : this.loadError,
				cache : this.popinOptions.allowAjaxCache,
				popinObj : this
			});
		};
		this.loadForm = function(form) {
			this.writeTemplate();
			this.setContent(templates.loading);
			this.open();
			jQuery.ajax({
				url : form.action,
				dataType : 'html',
				type : form.method,
				data : jQuery(form).serialize(),
				success : this.loadSuccess,
				cache : false,
				error : this.loadError,
				cache : this.popinOptions.allowAjaxCache,
				popinObj : this
			});
		};
		this.loadHandler = function(e) {
			e.preventDefault();
			e.data.popinObj.ajaxLoad(this.href);
		};
		this.ajaxLoad = function(url) {
			this.load(url + (this.popinOptions.ajaxPHPFilter === true ? ((url.indexOf("?") != -1 || url.indexOf(".html") != -1) ? "&" + popinManagerOptions.ajaxPHPparam : "?" + popinManagerOptions.ajaxPHPparam) : ""));
		};
		this.addCallback = function(options) {
			if( typeof options !== "undefined") {
				if( typeof options.openCallback !== "undefined") {
					this.callback.openCallback = options.openCallback;
				}
				if( typeof options.openCallbackArgs !== "undefined") {
					this.callback.openCallbackArgs = options.openCallbackArgs;
				}
				if( typeof options.closeCallback !== "undefined") {
					this.callback.closeCallback = options.closeCallback;
				}
				if( typeof options.closeCallbackArgs !== "undefined") {
					this.callback.closeCallbackArgs = options.closeCallbackArgs;
				}
				if( typeof options.beforeOpen !== "undefined") {
					this.callback.beforeOpen = options.beforeOpen;
				}
				if( typeof options.beforeOpenArgs !== "undefined") {
					this.callback.beforeOpenArgs = options.beforeOpenArgs;
				}
				if( typeof options.beforeClose !== "undefined") {
					this.callback.beforeClose = options.beforeClose;
				}
				if( typeof options.beforeCloseArgs !== "undefined") {
					this.callback.beforeCloseArgs = options.beforeCloseArgs;
				}
				if( typeof options.contentAdded !== "undefined") {
					this.callback.contentAdded = options.contentAdded;
				}
				if( typeof options.contentAddedArgs !== "undefined") {
					this.callback.contentAddedArgs = options.contentAddedArgs;
				}
				if( typeof options.dataLoaded !== "undefined") {
					this.callback.dataLoaded = options.dataLoaded;
				}
				if( typeof options.dataLoadedArgs !== "undefined") {
					this.callback.dataLoadedArgs = options.dataLoadedArgs;
				}
			}
		};
		this.info = function() {
			console.log(this.popinOptions);
		};
		this.addOpenLink = function(link) {
			jQuery(link).bind("click", {
				popinObj : this
			}, this.loadHandler);
		};
		this.init = function(popinObject) {
			var links;
			_this = popinObject;
			if(popinManagerOptions.movePopin) {
				if(this.popin != null && this.popin.size() > 0) {
					if(this.popin.parent()[0].tagName !== "BODY") {
						jQuery("body").append(this.popin);
					}
					this.popin.addClass(toText(selectors.hiddenClass));
				}
			}
			if(this.popinOptions.ajax === true) {
				jQuery(this.popinOptions.ajaxLink).bind("click", {
					popinObj : this
				}, this.loadHandler);
			} else {
				links = jQuery(selectors.linkPopin + "[href=#" + this.popinOptions.id + "]");
				links.bind("click", {
					popinObj : this
				}, this.openHandler);
				links = jQuery(selectors.linkPopin + "[rel=" + this.popinOptions.id + "]");
				links.bind("click", {
					popinObj : this
				}, this.openHandler);
				links = jQuery(selectors.linkPopin + '[class*="' + this.popinOptions.id + '"]');
				links.bind("click", {
					popinObj : this
				}, this.openHandler);
				this.popin.find(selectors.linkClosePopin).bind("click", {
					popinObj : this
				}, this.closeHandler);
			}
			this.initialized = true;
		};
		this.setOptions = function(options) {
			this.storeOptions(options);
		};
	};
	popin = function(args) {
		if( typeof args === "string") {
			var tmp = {};
			tmp.id = args;
			args = tmp;
		}
		return (popinList[args.id] || false);
	};
	close = function(args) {
		if( typeof args === "string") {
			var tmp = {};
			tmp.id = args;
			args = tmp;
		}
		popin(args).close(args);
	};
	closeAll = function() {
		for(var popId in popinList) { close({
				id : popId
			});
		}
	};
	open = function(args) {
		if( typeof args === "string") {
			var tmp = {};
			tmp.id = args;
			args = tmp;
		}
		popin(args).open(args);
	};
	setDefaultPopinOptions = function(options) {
		defaultPopinOptions.width = parseInt(options.width, 10) || defaultPopinOptions.width;
		defaultPopinOptions.modal = options.modal || defaultPopinOptions.modal;
		defaultPopinOptions.css = options.css || defaultPopinOptions.css;
		defaultPopinOptions.style = options.style || defaultPopinOptions.style;
	};
	setPopinManagerOptions = function(options) {
		popinManagerOptions.movePopin = options.movePopin || popinManagerOptions.movePopin;
	};
	displayPopinList = function() {
		for(var popId in popinList) {
			popin({
				"id" : popId
			}).info();
		}
	};
	create = function(args) {
		var tmpPop;
		tmpPop = new PopinObject(args);
		tmpPop.init(tmpPop);
		tmpPop.writeTemplate();
		popinList[args.id] = tmpPop;
	};
	init = function(args) {
		if(args !== undefined && args.parent !== undefined) {
			parent = args.parent;
		}
		if(args.defaultPopinOptions !== undefined) { setDefaultPopinOptions(args.defaultPopinOptions);
		}
		if(args.popinManagerOptions !== undefined) { setPopinManagerOptions(args.popinManagerOptions);
		}
		if(jQuery(selectors.backgroundPopinId).size() === 0) {
			jQuery("body").append('<div id="' + toText(selectors.backgroundPopinId) + '"></div>');
		}
		bgOpacity = jQuery(selectors.backgroundPopinId).css("opacity");
		Reflow.events.addDOMLoadEvent(function() {
			jQuery(selectors.popin).each(function(e, o) {
				var popId, tmpPop;
				popId = o.id;
				if(popId === undefined) {
					var popOption = getParam(o);
					popId = popOption.id;
				}
				tmpPop = new PopinObject({
					"id" : popId
				});
				tmpPop.init(tmpPop);
				popinList[popId] = tmpPop;
			});
			jQuery(selectors.linkAjaxPopin).each(function(e, o) {
				var popOption, tmpPop;
				popOption = getParam(o);
				if( typeof popinList[popOption.id] === "undefined") {
					popOption.ajax = true;
					popOption.ajaxLink = o;
					tmpPop = new PopinObject(popOption);
					tmpPop.init(tmpPop);
					popinList[popOption.id] = tmpPop;
				} else {
					popin(popOption.id).addOpenLink(o);
				}
			});
			jQuery(selectors.autoOpen).each(function(e, o) {
				var idToOpen = jQuery(this).attr("id");
				if(idToOpen) {
					popin(idToOpen).open();
				}
			});
		});
	};
	return {
		id : id,
		init : init,
		open : open,
		close : close,
		popin : popin,
		closeAll : closeAll,
		info : displayPopinList,
		create : create,
		getSelector : getSelector,
		setSelectors : setSelectors,
		setDefaultPopinOptions : setDefaultPopinOptions,
		setPopinManagerOptions : setPopinManagerOptions,
		setTemplates : setTemplates
	};
};
Reflow.events.addDOMLoadEvent(function() {
	Reflow.widgets.popinManager = new Reflow.widgets.popinManager(Reflow, {});
	Reflow.widgets.popinManager.init(Reflow.widgets.popinManager);
});

