function PopupWindow() {
    // Properties
    this.Container;
    this.Opacity;
    this.FadeSpeed;
    this.OnOpen;
    this.OnClose;
    this.ResizeIframe = true;
    this.IframeOnLoad;

    // Methods
    this.RenderDefaultStyles = function () {
        if ($("head > style.popupStyles").size() == 0) {
            var defaultStyles = "";
            defaultStyles += "<style id=\"popupStyles\" type=\"text/css\">";
            defaultStyles += "div.popupOverlay{position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 9990;}";
            defaultStyles += "div.popupContainer{position: absolute; z-index: 9991;}";
            defaultStyles += "</style>";

            $("head").append(defaultStyles);
        }
    };

    this.SetDefaultValues = function () {
        if (this.Opacity == null || parseInt(this.Opacity) < 0) {
            this.Opacity = 40;
        }

        if (this.FadeSpeed == null || parseInt(this.FadeSpeed) < 0) {
            this.FadeSpeed = 400;
        }
    };

    this.Open = function () {
        this.SetDefaultValues();

        if (this.Container != null) {
            if ($(this.Container).size() > 0) {
                if ($("div.popupOverlay").size() == 0) {
                    $("body").append("<div class=\"popupOverlay\" style=\"display: none;\"></div>");
                }

                var popupOverlay = $("div.popupOverlay");

                if ($("div.popupContainer").size() == 0) {
                    $("body").append("<div class=\"popupContainer\" style=\"display: none;\"></div>");
                }

                var popupContainer = $("div.popupContainer");

                popupOverlay.css("opacity", this.Opacity / 100);
                popupContainer.append($(this.Container).children());

                if (typeof (this.OnOpen) == "function") {
                    this.OnOpen();
                }

                if (this.ResizeIframe) {
                    popupContainer.find("iframe").bind("load", { "PopupWindow": this }, function (event) {
                        var popup = event.data.PopupWindow;
                        var iframe = this;
                        var iframeUrl = $(iframe).attr("src");

                        if (typeof (iframeUrl) == "string" && iframeUrl != "" && iframeUrl != "about:blank") {
                            if (typeof (popup.IframeOnLoad) == "function") {
                                popup.IframeOnLoad();
                            }

                            $(iframe).height("0px");
                            $(iframe).width("0px");

                            setTimeout(function () {
                                var iframeHeight = $(iframe).contents().height();
                                var iframeWidth = $(iframe).contents().width();

                                $(iframe).height(iframeHeight).width(iframeWidth);

                                popup.Center();
                            }, 100);
                        }
                    });
                }

                popupContainer.show();
                this.Center();
                popupOverlay.fadeIn(this.FadeSpeed);

                $(window).bind("resize", { "PopupWindow": this }, function (event) {
                    event.data.PopupWindow.Center();
                });

                popupContainer.find("a.popupClose").bind("click", { "PopupWindow": this }, function (event) {
                    event.data.PopupWindow.Close();
                });
            }
            else {
                throw "The specified Container is invalid";
            }
        }
        else {
            throw "You must specify the Container which holds the content to display in a popup window";
        }
    };

    this.Close = function () {
        if (this.Container != null) {
            if ($(this.Container).size() > 0) {
                if (typeof (this.OnClose) == "function") {
                    this.OnClose();
                }

                $("div.popupOverlay").fadeOut(this.FadeSpeed);

                var popupContainer = $("div.popupContainer");

                $(this.Container).append(popupContainer.children());

                popupContainer.hide();
                popupContainer.html("");
            }
            else {
                throw "The specified Container is invalid";
            }
        }
        else {
            throw "You must specify the Container which holds the content to display in a popup window";
        }
    };

    this.Center = function () {
        var popupContainer = $("div.popupContainer");

        var topPosition = (($(window).height() - popupContainer.height()) / 2);
        if (topPosition < 0) {
            topPosition = 0;
        }
        topPosition += $(window).scrollTop();

        var leftPosition = (($(window).width() - popupContainer.width()) / 2);
        if (leftPosition < 0) {
            leftPosition = 0;
        }
        leftPosition += $(window).scrollLeft();

        popupContainer.css({
            "top": topPosition + "px",
            "left": leftPosition + "px"
        });
    };

    this.RecalculateIframeDimensions = function () {
        var popup = this;

        var iframe = $("div.popupContainer iframe");
        var iframeUrl = $(iframe).attr("src");

        setTimeout(function () {
            var iframeHeight = $(iframe).contents().height();
            var iframeWidth = $(iframe).contents().width();

            $(iframe).height(iframeHeight).width(iframeWidth);

            popup.Center();
        }, 100);
    };

    this.RenderDefaultStyles();
}
