﻿(function (jQuery) {
	jQuery.extend(jQuery.expr[':'], {
		zIdx: function (element, index, matches, set) {
			var param = matches[3], jObj = jQuery(element), zIdx = jObj.css("z-index"), hz = jQuery.inArray(jObj.css("position"), ["absolute", "relative", "fixed"]) > -1;
			return hz && (parseInt(zIdx) || -1) > -1;
		}
	});

	jQuery.fn.myModal = function (options) {
		function RandomRange(lowVal, highVal) {
			return Math.floor(Math.random() * (highVal - lowVal + 1)) + lowVal;
		}

		function SetModalID() {
			var res = [], i = 0;
			for (i = 0; i < 7; i++) {
				res.push(RandomRange(0, 15).toString(16));
			}
			return res.join('');
		}

		function MaxZ() {
			var zObjs = $(":zIdx"), mx = Math.max.apply(null, jQuery.map(zObjs, function (v, n) {
				return parseInt(zObjs.css("z-index"));
			}));
			return !isFinite(mx) ? 0 : mx;
		}

		function dsInfo(object) {
			var d = $(document), w = $(window), oOW = object.outerWidth(true), oH = object.height(), oOH = object.outerHeight(true), dSt = d.scrollTop(), dSl = d.scrollLeft(), mz = MaxZ();
			this.CenterEdgeX = Math.floor((w.width() / 2) - (oOW > 0 ? oOW / 2 : 0)) + dSl;
			this.TopEdgeY = (w.height() / 2) - ((oOH + (oOH - oH)) * .75);
			this.DocWidth = w.width();
			this.DocHeight = w.height();
			this.LayerZIndex = mz + 1;
			this.MyObjectZIndex = mz + 2;
			//			$("#dbg").html(this.TopEdgeY + ' ' + (w.height() / 2) + ' ' + oOH + ' ' + object.height() + ' ' + object.outerHeight());
		}

		this.PopIn = function (e) {
			var jqObj = $(this), pMOly = {}, mm = jqObj.data("jquery.myModal.id");
			if (mm != undefined) {
				pMOly = $("#" + mm);
				pMOly.css("background-color", "black").colorBlend([{ param: "opacity", alpha: [0, 75], strobe: false, cycles: 1, duration: 500, preCallBack: function () { setTimeout(function () { pMOly.show() }, 20) } }]);
				jqObj.fadeIn();
				$(window).resize(function () { redraw(jqObj); });
				$(window).scroll(function () { redraw(jqObj); });
			}
		}

		this.PopOut = function (e) {
			var jqObj = $(this), pMOly = {}, mm = jqObj.data("jquery.myModal.id");
			if (mm != undefined) {
				pMOly = $("#" + mm);
				jqObj.fadeOut();
				pMOly.colorBlend([{ param: "opacity", alpha: [75, 0], strobe: false, cycles: 1, duration: 500, cycleCallBack: function () {
					pMOly.hide();
					jqObj.css("z-index", -1);
					pMOly.css("z-index", -1);
				}
				}]);
			}
			$(window).unbind("resize").unbind("scroll");
		}

		function redraw(jqObj) {
			var di = new dsInfo(jqObj), moCss = {
				"top": "0px",
				"left": "0px",
				"width": di.DocWidth + "px",
				"height": di.DocHeight + "px",
				"position": "absolute",
				"z-index": di.LayerZIndex
			}, jCss = {
				"z-index": di.MyObjectZIndex,
				"top": di.TopEdgeY + "px",
				"left": di.CenterEdgeX + "px",
				"position": "absolute"
			}, pMOly = {}, mm = jqObj.data("jquery.myModal.id");

			if (mm != undefined) {
				pMOly = $("#" + mm);
				jqObj.css(jCss);
				pMOly.css(moCss);
			}
		}

		function buildModal(jqObj) {
			var bgOly = $("#myModalBgOly"), pMOly = {}, bdy = $("body"), mm = jqObj.data("jquery.myModal.id");

			if (bgOly.size() == 0) {
				bdy.append("<div id='myModalBgOly' style='display:none;top:0px;left:0px;position:absolute;' />");
				bgOly = $("#myModalBgOly");
			}

			if (mm == undefined) {
				mm = SetModalID();
				jqObj.data("jquery.myModal.id", mm);
				pMOly = bgOly.clone();
				pMOly.attr("id", mm);
				bdy.append(pMOly);
				redraw(jqObj);
				jqObj.hide();
				pMOly.hide();
			} else {
				pMOly = $("#" + mm);
				redraw(jqObj);
			}


			//Check dimens 
			//center obj
			//show obj
			//close button
			//yes/no options
			//ability to add buttons and funtions?
			//array of functions?
			//bind to escape key
			//ability to provide validation
			//prompt? and alert? Hmm.
			//animate window
			//colorblend the background and opacity.
			return jqObj;
		}
		return buildModal(this);
	};

})(jQuery);

