; (function($) {
    var 
		ks_wm_dv_wrapper,
		ks_wm_dv_overlay,
		ks_wm_dv_loading,
		ks_wm_panels = [],
		ks_wm_zindex = 9999,
		ks_wm_timer,
		ks_wm_return_value,

		_create_new_element = function(element, id, className, css) {
		    if (element != undefined) {
		        var el = $(document.createElement(element));
		        if (id != undefined)
		            el[0].id = id;
		        if (className != undefined)
		            el[0].className = className;
		        if (css != undefined)
		            el.css(css);
		        return el;
		    } else {
		        return null;
		    }
		},

		_start_window_manager = function() {
		    if (ks_wm_dv_wrapper != null) {
		        return;
		    }
		    ks_wm_dv_wrapper = _create_new_element("div", "ks_wm_dv_wrapper", null,
				{ "position": "fixed", "height": "100%", "width": "100%", "top": 0, "left": 0 });

		    ks_wm_dv_overlay = _create_new_element("div", "ks_wm_dv_overlay", null,
				{ "position": "absolute", "height": "100%", "width": "100%", "top": 0, "left": 0, "z-index": ks_wm_zindex + 1 });
		    ks_wm_dv_wrapper.append(ks_wm_dv_overlay);

		    ks_wm_dv_loading = _create_new_element("div", "ks_wm_dv_loading", null, { "z-index": 10100 });
		    ks_wm_dv_wrapper.append(ks_wm_dv_loading);

		    $("body").append(ks_wm_dv_wrapper);

		    $(window).bind("resize.ks", function() { clearTimeout(ks_wm_timer); ks_wm_timer = setTimeout($.ksWindowManager.centerTopPanel, 100); });
		},

		_create_new_panel = function(id) {
		    ks_wm_zindex += 2;

		    var panel = _create_new_element("div", "ks_wm_panel_wrapper_" + id, "ks_wm_panel_wrapper",
				{ "position": "absolute", "z-index": ks_wm_zindex });

		    var iframe = _create_new_element("iframe", "ks_wm_panel_iframe_" + id, "ks_wm_panel_iframe", null);
		    panel.append(iframe);

		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_n", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_ne", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_e", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_se", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_s", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_sw", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_w", null));
		    panel.append(_create_new_element("div", null, "ks_wm_panel_border_nw", null));

		    var titleSpan = _create_new_element("span", "ks_wm_panel_span_title_" + id, "ks_wm_panel_span_title", null);
		    panel.append(_create_new_element("div", null, "ks_wm_panel_title", null).append(titleSpan));

		    var closeButton = _create_new_element("a", null, "ks_wm_panel_close", null);
		    panel.append(closeButton);

		    return { panel: panel, panelElements: { iframe: iframe, title: titleSpan, close: closeButton} };
		},

		_start_new_panel = function(url, params) {
		    params.onStart();
		    _start_window_manager();

		    ks_wm_dv_loading.show();

		    var panelID = ks_wm_panels.length;

		    var panel = _create_new_panel(panelID, params);
		    var initialPosition = _get_viewport();
		    panel.panel.css({ "height": 0, "width": 0, top: (initialPosition[1] * 0.5), left: (initialPosition[0] * 0.5) });
		    panel.panelElements.iframe[0].src = url;
		    panel.panelElements.close.bind("click.ks", $.ksWindowManager.closeTopPanel);
		    panel.panelElements.title.text(params.title);

		    var completePanel = { url: url, panel: panel.panel, panelElements: panel.panelElements, params: params };

		    ks_wm_panels.push(completePanel);

		    _show_new_panel(completePanel);
		    return result;
		},

		_get_viewport = function() {
		    return [
				$(window).width(),
				$(window).height(),
				$(document).scrollLeft(),
				$(document).scrollTop()
			];
		},

		_show_new_panel = function(completePanel) {
		    ks_wm_dv_overlay.css("zIndex", completePanel.panel.css("zIndex") - 1);

		    completePanel.panel.hide();

		    completePanel.panelElements.iframe.bind("load.ks", function() {
		        ks_wm_dv_loading.hide();
		        var temp = _get_panel_center_position(completePanel);
		        completePanel.panel.css(temp);
		        completePanel.panel.fadeIn(
					"slow",
					function() {
					    completePanel.params.onComplete();
					}
				);
		        /*completePanel.panel.animate(
		        temp,
		        "fast",
		        function() {
		        completePanel.params.onComplete();
		        }
		        );*/
		    });
		    completePanel.panel.appendTo(ks_wm_dv_wrapper);

		},

		_get_panel_center_position = function(completePanel) {
		    var 
				view = _get_viewport(),
				to = {};

		    var panelParams = completePanel.params;

		    if (panelParams.height + panelParams.topMargin + panelParams.bottomMargin > view[1])
		        to.height = parseInt(view[1] - panelParams.topMargin - panelParams.bottomMargin);
		    else
		        to.height = panelParams.height;

		    if (panelParams.width + panelParams.leftMargin + panelParams.rightMargin > view[0])
		        to.width = parseInt(view[0] - panelParams.leftMargin - panelParams.rightMargin);
		    else
		        to.width = panelParams.width;

		    to.top = panelParams.topMargin + parseInt((view[1] - to.height - panelParams.topMargin - panelParams.bottomMargin) * 0.5);
		    to.left = panelParams.leftMargin + parseInt((view[0] - to.width - panelParams.leftMargin - panelParams.rightMargin) * 0.5);

		    return to;
		};

    $.fn.ksWindowManager = function(url, params) {
        if ($(this).length > 0) {
            $(this).bind("click.ks", function(e) {
                e.preventDefault();
                $.ksWindowManager(url, params);
            });
        } else {
            $(this.selector, $("iframe")[ks_wm_panels.length - 1].contentDocument).bind("click.ks", function(e) {
                e.preventDefault();
                $.ksWindowManager(url, params);
            });
        }
    };

    $.ksWindowManager = function(url, params) {
        params = $.extend([], $.ksWindowManager.params, params);
        _start_new_panel(url, params);
    };

    $.ksWindowManager.closeTopPanel = function(returnValue) {
        if (ks_wm_panels.length == 0) {
            return;
        }

        var completePanel = ks_wm_panels.pop();
        completePanel.params.onCleanup();

        ks_wm_return_value = returnValue;

        completePanel.panel.fadeOut(function() {
            ks_wm_zindex -= 2;
            ks_wm_dv_overlay.css("zIndex", ks_wm_zindex - 1);
            completePanel.params.onClosed(returnValue);
            completePanel.panel.remove();
            $.ksWindowManager.centerTopPanel();

            if (ks_wm_panels.length == 0) {
                ks_wm_dv_wrapper.fadeOut("fast", function() {
                    $(ks_wm_dv_wrapper).remove();
                    ks_wm_dv_wrapper = null;
                });
            } else {
                var completePanel2 = ks_wm_panels.pop();
                ks_wm_panels.push(completePanel2);
                completePanel2.params.onTopPanelClosed(returnValue);
            }
        });
    };

    $.ksWindowManager.closeTopPanelAndReturnValue = function(returnValue) {
        if (ks_wm_panels.length == 0) {
            return;
        }

        var completePanel = ks_wm_panels.pop();
        var callingFunctionName = completePanel.params.callBackFunction;
        completePanel.params.onCleanup();

        ks_wm_return_value = returnValue;

        completePanel.panel.fadeOut(function() {
            ks_wm_zindex -= 2;
            ks_wm_dv_overlay.css("zIndex", ks_wm_zindex - 1);
            completePanel.params.onClosed(returnValue);
            completePanel.panel.remove();
            $.ksWindowManager.centerTopPanel();

            if (ks_wm_panels.length == 0) {
                ks_wm_dv_wrapper.fadeOut("fast", function() {
                    $(ks_wm_dv_wrapper).remove();
                    ks_wm_dv_wrapper = null;
                });
            } else {
                var completePanel2 = ks_wm_panels.pop();
                ks_wm_panels.push(completePanel2);
                completePanel2.params.onTopPanelClosed(returnValue);
            }
        });

        var ifrmcount = (ks_wm_panels.length - 1)
        
        var callFun = "";
        if (ifrmcount >= 0) {
            var objifrm = "ks_wm_panel_iframe_" + ifrmcount;
            callFun = 'document.getElementById("' + objifrm + '").contentWindow.' + callingFunctionName + '("' + returnValue + '")';
        }
        else {
            callFun = callingFunctionName + '("' + returnValue + '")';
        }
        eval(callFun);
    };

    $.ksWindowManager.closeTopPanelAndRefresh = function(url, returnValue) {
        if (ks_wm_panels.length == 0) {
            return;
        }

        var completePanel = ks_wm_panels.pop();
        var callingFunctionName = completePanel.params.callBackFunction;
        completePanel.params.onCleanup();

        ks_wm_return_value = returnValue;

        completePanel.panel.fadeOut(function() {
            ks_wm_zindex -= 2;
            ks_wm_dv_overlay.css("zIndex", ks_wm_zindex - 1);
            completePanel.params.onClosed(returnValue);
            completePanel.panel.remove();
            $.ksWindowManager.centerTopPanel();

            if (ks_wm_panels.length == 0) {
                ks_wm_dv_wrapper.fadeOut("fast", function() {
                    $(ks_wm_dv_wrapper).remove();
                    ks_wm_dv_wrapper = null;
                });
            } else {
                var completePanel2 = ks_wm_panels.pop();
                ks_wm_panels.push(completePanel2);
                completePanel2.params.onTopPanelClosed(returnValue);
            }
        });

        var ifrmcount = (ks_wm_panels.length - 1)
        if (ifrmcount >= 0) {
            var objifrm = "ks_wm_panel_iframe_" + ifrmcount;
            if (url != '') {
                document.getElementById(objifrm).src = url;
            }
            else {
                url = document.getElementById(objifrm).src;
                document.getElementById(objifrm).src = url;
            }
        }
        else {
            if (url != null) {
                $.ksWindowManager.closeTopPanel(returnValue);
                window.location.href = url;
            } else {
                $.ksWindowManager.closeTopPanel(returnValue);
                location.reload();
            }
        }
    };

    $.ksWindowManager.resizeTopPanel = function(height, width) {
        if (ks_wm_panels.length == 0) {
            return;
        }

        var view = _get_viewport();
        var completePanel = ks_wm_panels.pop();
        ks_wm_panels.push(completePanel);

        completePanel.params.height = height;
        completePanel.params.width = width;

        var toPosition = _get_panel_center_position(completePanel);

        completePanel.panel
			.stop()
			.css(toPosition);
    };

    $.ksWindowManager.centerTopPanel = function() {
        if (ks_wm_panels.length == 0) {
            return;
        }

        var completePanel = ks_wm_panels.pop();
        ks_wm_panels.push(completePanel);

        $.ksWindowManager.resizeTopPanel(completePanel.params.height, completePanel.params.width);
    };

    $.ksWindowManager.params = {
        title: "",
        height: 300,
        width: 500,
        topMargin: 25,
        bottomMargin: 5,
        leftMargin: 5,
        rightMargin: 5,

        onStart: function() { },
        onComplete: function() { },
        onTopPanelClosed: function() { },
        onCleanup: function() { },
        onClosed: function() { },
        callBackFunction: ""
    };

})(jQuery);
