function popupBase() {
    this.eventListeners = {};

}

popupBase.prototype = {
    active: null,
    secondLevelActive: null,
    reflectionType: {
        LEFT: 0,
        RIGHT: 1,
        TOP: 2,
        BOTTOM: 3
    },
    modal: false,
    openingDialogId: undefined,

    /*
    parameters: noFade, center, posX, posY, reflectionVert, reflectionHor, showBackgroundIframe, isSecondLevel, modal
    */
    show: function(divId, parameters) {
        if (this.openingDialogId)
            return;
        var dialog = dojo.byId(divId);
        if (!dialog) throw (Error("dialog not found! ('"+divId+"')"));
        this.openingDialogId = divId;
        var dialogShowTimeOut = setTimeout("popupDialog.openingDialogId=undefined;", 800);
        var active = parameters ? parameters : {};
        if (parameters && parameters.isSecondLevel && this.active != null) {
            this.secondLevelActive = active;
            dojo.html.addClass(dialog, "topLevelDialog");
            if (dojo.byId("modalSubstLayer") && !parameters.noLayer)
                dojo.html.addClass(dojo.byId("modalSubstLayer"), "topLevelLayer");
        } else {
            if (this.active && this.active.dialog != dialog) {
                this.hide();
            }
            this.active = active;
            active.isSecondLevel = false;
        }
        dialog.onmousedown = stopEvent;
        active.dialog = dialog;

        dialog.style.left = "-5000px";
        dialog.style.display = "block";
        var dialogWidth = dojo.style.getBorderBoxWidth(dialog);
        var dialogHeight = dojo.style.getBorderBoxHeight(dialog);

        var posX = panraven.mouse.posX;
        var posY = panraven.mouse.posY;

        if (active.center) {
            posX = (dojo.html.getViewportWidth() - dialogWidth ) / 2 + getBrowserLeftScrollPosition();
            posY = (dojo.html.getViewportHeight() - dialogHeight) / 2 + getBrowserTopScrollPosition();
        } else {
            if (!isUndefined(active.x)) {
                active.posX = active.x;
                if (hasConsole())
                    console.warn("showing " + dialog.id +": don't use 'popupDialog.show()' with parameter 'x'. Use 'posX' instead");
            }
            if (!isUndefined(active.y)) {
                active.posY = active.y;
                if (hasConsole())
                    console.warn("showing " + dialog.id +": don't use 'popupDialog.show()' with parameter 'y'. Use 'posY' instead");
            }
            posX = !isUndefined(active.posX) ? active.posX : panraven.mouse.posX;
            posY = !isUndefined(active.posY) ? active.posY : panraven.mouse.posY;

            if (active.posX && !active.reflectionHor) {
                active.reflectionHor = this.reflectionType.LEFT;
            }
            if (!active.posX) {
                if (active.reflectionHor == this.reflectionType.LEFT || posX + dialogWidth > dojo.html.getViewportWidth()) {
                    posX -= dialogWidth;
                    if (posX < 10) {
                        posX = (document.body.offsetWidth - dialog.offsetWidth) / 2;
                    }
                    active.reflectionHor = this.reflectionType.LEFT;
                } else {
                    active.reflectionHor = this.reflectionType.RIGHT;
                }
            }
            if (!active.posY || !active.reflectionVert) {
                if (active.reflectionVert == this.reflectionType.TOP || (posY + dialogHeight > dojo.html.getViewportHeight() && active.reflectionVert != this.reflectionType.BOTTOM)) {
                    posY -= dialogHeight;
                    if (posY < 10) {
                        posY = (document.body.offsetHeight - dialog.offsetHeight) / 2;
                    }
                    active.reflectionVert = this.reflectionType.TOP;
                } else {
                    active.reflectionVert = this.reflectionType.BOTTOM;
                }
            }
        }

        if ((panraven.isIE6minus || panraven.isMac) && active.showBackgroundIframe != false || active.showBackgroundIframe) {
            active.iframe = new panraven.backgroundIframe(dialog);
            this.resizeIFrame(dialog);
            active.iframe.show();
            var _this = this;
            dialog.onresize = function() {
                _this.resizeIFrame();
            };
        }

        dialog.style.visibility="hidden";
        dialog.style.top = posY + "px";
        dialog.style.left = posX + "px";
        this.onBeforeShow(active);
        if (this.getActiveTail() && active.isSecondLevel) {
            dojo.html.addClass (this.getActiveTail(), "topLevelTail");
        }
        clearTimeout(dialogShowTimeOut);
        if (!active.noFade) {
            dojo.style.setOpacity(dialog, 0);
            dialog.style.visibility = "visible";
            var _this = this;
            dojo.lfx.html.fadeShow(dialog, 200, true, function() {
                _this.onAfterShow(_this.getActive());
                _this.openingDialogId = undefined;
                if (_this.getActiveTail()) {
                    _this.getActiveTail().style.display = "block";
                }
                if (panraven.isMac) {
                    dialog.style.opacity="1";
                }
            }).play();
        } else {
            dialog.style.visibility = "visible";
            this.onAfterShow(active);
            this.openingDialogId = undefined;
        }
    },

    hide: function() {
        var active = this.getActive();
        if (!active || active && active.allowHidingDialog == false)
            return;
        if (this.secondLevelActive) {
            dojo.html.removeClass(active.dialog, "topLevelDialog");
            if (this.getActiveTail()) {
                dojo.html.removeClass(this.getActiveTail(), "topLevelTail");
            }
            if (dojo.byId("modalSubstLayer"))
                dojo.html.removeClass(dojo.byId("modalSubstLayer"), "topLevelLayer");
        }
        var dialog = active.dialog;
        var _this = this;
        this.onHide(active);
        if (!active.noFade) {
            var iframeNode = active.iframe;
            var pop = dialog;
            var parent = dialog.parentNode;
            if (active.tail) {
                active.tail.style.display = "none";
            }
            dojo.lfx.html.fadeHide(dialog, 300, null, function() {
                popupDialog.removeIFrame(parent, iframeNode);
                pop.style.display = "none";
                if (active.tail) {
                    active.tail.style.display = "none";
                }
            }).play();
        }
        else {
            if (active.tail) {
                active.tail.style.display = "none";
            }
            dialog.style.display = "none";
            if (panraven.isIE) {
                dialog.style.top = "-10000px";
                dialog.style.left = "-10000px";
            }
            this.removeIFrame(dialog.parentNode, active.iframe);
        }
        if (this.secondLevelActive) {
            this.secondLevelActive = null;
        } else {
            this.active = null;
        }
        if (!active.noFade) {
            var _active = active;
            setTimeout(function() {
                _this.onAfterHide(_active);
            }, 300);
        } else {
            this.onAfterHide(active);
        }
    },

    recalculatePosition: function() {
        var position = this.getActive().dialogPositionGetter();
        if (!position)
            throw Error ("recalculatePosition(): no position specified");
        var dialog = this.getActive().dialog;
        dialog.style.left = position.x + 'px';
        dialog.style.top = position.y + 'px';
        if (this.getActiveTail()) {
            if (position.tailX)
                this.getActiveTail().style.left = position.tailX + 'px';
            if (position.tailY)
                this.getActiveTail().style.top = position.tailY + 'px';
            this.getActiveTail().style.display = 'block';
        }
    },

    /*returns the top-level dialog object*/
    getActive : function() {
        return (this.secondLevelActive ? this.secondLevelActive : this.active);
    },

    getActiveDialogId : function() {
        if (this.getActive())
            return this.getActive().dialog.id;
        return undefined;
    },

    getActiveByDialogId : function(dialogId) { //returns active popupDialog object (second or first level)
        if(!this.getActive()) {
            return null;
        }
        if (this.getActive().dialog.id == dialogId) {
            return this.getActive();
        }
        return this.active;
    },

    /*returns the tail object of active dialog*/
    getActiveTail : function() {
        if (this.getActive())
            return this.getActive().tail;
    },

    showCentered : function(dialog) {
        this.show(dialog, {center: true, isSecondLevel: true});
    },

    resizeIFrame: function(dialog) {
        var active = this.getActive();
        if (active && active.iframe) {
            active.iframe.onResized();
            active.iframe.iframe.style.left = - dojo.style.getPixelValue(dialog ? dialog : active.dialog, "border-left-width", true) - 1 + "px";
            active.iframe.iframe.style.top = - dojo.style.getPixelValue(dialog ? dialog : active.dialog, "border-top-width", true) - 1 + "px";
        }
    },

    removeIFrame: function(parent, iframe) {
        if (iframe) {
            iframe.hide();
            iframe.remove();
        }
    },

    onBeforeShow : function(active) {
        this.fireEvent('onBeforeShow', active);
    },

    onAfterShow : function(active) {
        this.fireEvent('onAfterShow', active);
    },

    onHide : function(active) {
        this.fireEvent('onHide', active);
    },

    onAfterHide: function(active) {
        this.fireEvent('onAfterHide', active);
    },

    addListener: function(eventName, fnc, addBefore) {
        var listeners = this.eventListeners[eventName];
        if (!listeners) {
            listeners = new Array();
        }
        if (addBefore)
            listeners.splice(0, 0, fnc);
        else
            listeners.push(fnc);
        this.eventListeners[eventName] = listeners;
    },

    fireEvent: function(eventName, active, additionalParams) {
        var listeners = this.eventListeners[eventName];
        if (!listeners || !active)  return;

        for (var i = 0; i < listeners.length; i++) {
            if (additionalParams || additionalParams == 0) {
                listeners[i].apply(this, [active, additionalParams]);
            } else {
                listeners[i].apply(this, [active]);
            }
        }
    }
}

var popupDialog = new popupBase();
var infoDialog = new popupBase();
var advSelectDialog = new popupBase();
