// jPopup and jMessage, v1.0
// Pretty ways to alert the user to stuff that's going on
// Jeff Rowberg <jeff@rowberg.net> - April 6, 2008
// http://www.sectorfej.net/jpopup

// Use it, have fun with it, modify it...just don't say you
// wrote it unless you actually totally do rewrite it.

// NOTE: Requires jQuery >= 1.2 (built around 1.2.1)
// http://www.jquery.com/

// ********************************************************

// Behavioral settings located at bottom of file

// ============-------------------
// CONSTANTS - DON'T CHANGE THESE!
// ============-------------------
var JPOPUP_BTN_OK = 0, JPOPUP_BTN_OKCANCEL = 1, JPOPUP_BTN_YESNO = 2, JPOPUP_BTN_YESNOCANCEL = 3, JPOPUP_BTN_CUSTOM = 10;
var JPOPUP_ICON_QUESTION = 0, JPOPUP_ICON_ALERT = 1, JPOPUP_ICON_ERROR = 2, JPOPUP_ICON_INFO = 3;
var JPOPUP_RESPONSE_OK = 0, JPOPUP_RESPONSE_CANCEL = 1, JPOPUP_RESPONSE_YES = 2, JPOPUP_RESPONSE_NO = 3;
var JMESSAGE_UPDATE = 0, JMESSAGE_ERROR = 1, JMESSAGE_SUCCESS = 2, JMESSAGE_NOTICE = 3;
var JMESSAGE_POS_TOPLEFT = 0, JMESSAGE_POS_TOPRIGHT = 1, JMESSAGE_POS_BOTTOMLEFT = 2, JMESSAGE_POS_BOTTOMRIGHT = 3;

// ====================
// ON TO THE GOOD STUFF
// ====================
var jPopupZIndex = 1000;
var jPopupRef = new Array();
var jMessageOffset = 0;
var jMessageRef = new Array();

jQuery(window).scroll(function() {
    if (jPopupRef.length > 0)
        for (var i = 0; i < jPopupRef.length; i++)
            if (!jPopupRef[i].left && !jPopupRef[i].top) jPosition.windowCenter(jQuery("#" + jPopupRef[i].id), jPopupScrollSpeed);
    if (jMessageRef.length > 0)
        for (var i = 0; i < jMessageRef.length; i++)
            jMessagePositionFunction(jQuery("#" + jMessageRef[i].id), jMessagePadHoriz, jMessageRef[i].top, jMessageScrollSpeed);
});

jQuery(window).resize(function() {
    if (jPopupRef.length > 0)
        for (var i = 0; i < jPopupRef.length; i++) {
            if (!jPopupRef[i].left && !jPopupRef[i].top)
                jPosition.windowCenter(jQuery("#" + jPopupRef[i].id), jPopupScrollSpeed);
            var fullWidth = jQuery(document).width();
            var fullHeight = jQuery(document).height();
            if (jQuery(window).width() > fullWidth) fullWidth = jQuery(window).width();
            if (jQuery(window).height() > fullHeight) fullHeight = jQuery(window).height();
            jQuery("#" + jPopupRef[i].id + "_fade").width(fullWidth).height(fullHeight);
        }
    if (jMessageRef.length > 0)
        for (var i = 0; i < jMessageRef.length; i++)
            jMessagePositionFunction(jQuery("#" + jMessageRef[i].id), jMessagePadHoriz, jMessageRef[i].top, jMessageScrollSpeed);
});

function jPopup(body, title, type, callback, width, left, top) {
    d = new Date();
    var id = "jpopup" + Math.floor(Math.random(10000)) + "" + d.getTime();

    if (!title) title = jPopupDefaultTitle;
    if (!type) type = jPopupDefaultType;
    if (!callback) callback = jPopupDefaultCallback;
    if (!width) width = jPopupDefaultWidth;
    
    jQuery("body").append("<div id=\"" + id + "\" class=\"jPopupDiv\" style=\"display: none;\"></div>");
    jQuery("body").append("<div id=\"" + id + "_fade\" class=\"jPopupFade\" style=\"display: none;\"></div>");

    var p = jQuery("#" + id).css("z-index", jPopupZIndex + 2).css("opacity", 0).show(); // show required for auto-width

    p.append("<div id=\"" + id + "_title\" class=\"jPopupTitle\">" + title + "</div>");
    p.append("<div id=\"" + id + "_body\" class=\"jPopupBody\"><span id=\"" + id + "_bodyspan\">" + body + "</span></div>");

    var b = jQuery("#" + id + "_body");
    var s = jQuery("#" + id + "_bodyspan");
    
    // use 75% of window if 0 passed
    if (width == 0) width = -Math.floor(parseInt(jPosition.o().innerWidth) * .75);
    
    if (width < 0) { // autosize up to maximum -width
        if (s.paddedWidth() + 40 < -width) width = s.paddedWidth() + 40;
        else width = -width;
    }
    p.width(width);

    if (!left && !top) {
        jPosition.windowCenter(p);
    } else {
        if (!top) top = 30;
        if (!left) left = 40;
        p.css("left", left).css("top", top);
    }

    jPopupRef.push({ id: id, left: left, top: top });

    var btnDiv = '<div class="jPopupButtonContainer">';
    switch (type) {
        case JPOPUP_BTN_OK:
            btnDiv += '<input id="' + id + '_btnOK" type="button" class="jPopupButton" value="OK" />';
            break;
        case JPOPUP_BTN_OKCANCEL:
            btnDiv += '<input id="' + id + '_btnOK" type="button" class="jPopupButton" value="OK" />';
            btnDiv += '<input id="' + id + '_btnCancel" type="button" class="jPopupButton" value="Cancel" />';
            break;
        case JPOPUP_BTN_YESNO:
            btnDiv += '<input id="' + id + '_btnYes" type="button" class="jPopupButton" value="Yes" />';
            btnDiv += '<input id="' + id + '_btnNo" type="button" class="jPopupButton" value="No" />';
            break;
        case JPOPUP_BTN_YESNOCANCEL:
            btnDiv += '<input id="' + id + '_btnYes" type="button" class="jPopupButton" value="Yes" />';
            btnDiv += '<input id="' + id + '_btnNo" type="button" class="jPopupButton" value="No" />';
            btnDiv += '<input id="' + id + '_btnCancel" type="button" class="jPopupButton" value="Cancel" />';
            break;
        case JPOPUP_BTN_CUSTOM:
            if (options.customButtons) {
                for (var item in options.customButtons) {
                    alert(item + "=" + fieldData[item]);
                }
            } else {
                // failsafe
                btnDiv += '<input id="' + id + '_btnOK" type="button" class="jPopupButton" value="OK" />';
            }
            break;
    }
    btnDiv += '</div>';
    b.append(btnDiv);

    if (jPopupEnableSmooth) {
        jQuery("#" +  id + "_btnOK").click(function() { if (callback(JPOPUP_RESPONSE_OK)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
        jQuery("#" +  id + "_btnCancel").click(function() { if (callback(JPOPUP_RESPONSE_CANCEL)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
        jQuery("#" +  id + "_btnYes").click(function() { if (callback(JPOPUP_RESPONSE_YES)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
        jQuery("#" +  id + "_btnNo").click(function() { if (callback(JPOPUP_RESPONSE_NO)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
    } else {
        jQuery("#" +  id + "_btnOK").click(function() { if (callback(JPOPUP_RESPONSE_OK)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
        jQuery("#" +  id + "_btnCancel").click(function() { if (callback(JPOPUP_RESPONSE_CANCEL)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
        jQuery("#" +  id + "_btnYes").click(function() { if (callback(JPOPUP_RESPONSE_YES)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
        jQuery("#" +  id + "_btnNo").click(function() { if (callback(JPOPUP_RESPONSE_NO)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); });
    }

    var fullWidth = jQuery(document).width();
    var fullHeight = jQuery(document).height();
    if (jQuery(window).width() > fullWidth) fullWidth = jQuery(window).width();
    if (jQuery(window).height() > fullHeight) fullHeight = jQuery(window).height();
    var c = jQuery("#" + id + "_fade").width(fullWidth).height(fullHeight).css("z-index", jPopupZIndex + 1).css("opacity", 0).show();

    jPopupZIndex += 10;
    if (jPopupEnableSmooth) {
        c.fadeTo(jPopupFadeInSpeed, 0.5);
        p.fadeTo(jPopupFadeInSpeed, 1);
    } else {
        c.css("opacity", 0.5);
        p.css("opacity", 1);
    }
    return p;
}

function jMessage(message, type, duration, width) {
    d = new Date();
    var id = "jmessage" + Math.floor(Math.random(10000)) + "" + d.getTime();
    if (!type) type = jMessageDefaultType;
    if (!duration && duration !== 0) duration = jMessageDefaultDuration;
    if (!width) width = jMessageDefaultWidth;
    var cssClass = "";
    switch (type) {
        case JMESSAGE_UPDATE:  cssClass = "jMessageUpdate"; break;
        case JMESSAGE_ERROR:   cssClass = "jMessageError"; break;
        case JMESSAGE_SUCCESS: cssClass = "jMessageSuccess"; break;
        case JMESSAGE_NOTICE:  cssClass = "jMessageNotice"; break;
    }
    jQuery("body").append("<div id=\"" + id + "\" class=\"jMessageDiv " + cssClass + "\" style=\"display: none;\"></div>");
    var m = jQuery("#" + id).css("opacity", 0).show(); // to make auto-width work correctly
    m.append('<span id="' + id + '_closespan" class="jMessageCloseSpan"><a class="jMessageCloseLink" href="javascript:void();" onClick="jMessageOffset -= jQuery(\'#' + id + '\').paddedHeight(); jQuery(\'#' + id + '\').remove(); jMessageShiftUp(\'' + id + '\'); return false;">[X]</a></span>');
    m.append('<span id="' + id + '_span" class="jMessageSpan">' + message + '</span>');
    var cs = jQuery("#" + id + "_closespan");
    var s = jQuery("#" + id + "_span");
    if (width < 0) { // autosize up to maximum -width
        if (s.width() + cs.width() + 16 < -width) width = s.width() + cs.width() + 16;
        else width = -width;
    }
    m.width(width);
    jMessagePositionFunction(m, jMessagePadHoriz, jMessagePadVert + jMessageOffset);
    jMessageRef.push({ id: id, top: parseInt(m.css("top")) });
    jMessageOffset += m.paddedHeight();
    if (duration == 0) {
        if (jMessageEnableSmooth)
            m.fadeTo(jMessageFadeSpeed, jMessageOpacity);
        else
            m.css("opacity", jMessageOpacity);
    } else {
        if (jMessageEnableSmooth)
            m.fadeTo(jMessageFadeSpeed, jMessageOpacity, function() { setTimeout('jQuery("#' + id + '").fadeOut(jMessageFadeSpeed, function() { jMessageOffset -= jQuery(this).paddedHeight(); jQuery(this).remove(); jMessageShiftUp("' + id + '"); });', duration); });
        else {
            m.css("opacity", jMessageOpacity);
            setTimeout('jMessageOffset -= jQuery("#' + id + '").paddedHeight(); jQuery("#' + id + '").remove(); jMessageShiftUp("' + id + '");', duration);
        }
    }
    return m;
}

// removes a given message (or the top one if not specified) and slides the rest to fit
function jMessageShiftUp(id) {
    if (jMessageRef.length > 1) {
        var old = false, num;
        if (id) {
            for (var i = 0; i < jMessageRef.length; i++) if (jMessageRef[i].id == id) { old = jMessageRef.splice(i, 1); old = old[0]; num = i; break; }
        } else {
            old = jMessageRef.shift(); // take the top one
            num = 0;
        }
        if (num >= jMessageRef.length) return; // no shifting necessary
        var dist = jMessageRef[num].top - old.top;
        for (var i = num; i < jMessageRef.length; i++) {
            jMessageRef[i].top -= dist;
            jMessagePositionFunction(jQuery("#" + jMessageRef[i].id), jMessagePadHoriz, jMessageRef[i].top, jMessageSlideSpeed);
        }
    } else if (jMessageRef.length == 1) {
        jMessageRef.shift(); // just disappear, since it's the last one
    }
}

// returns full width, including padding
jQuery.fn.paddedWidth = function() {
    return jQuery(this).width() + parseInt(jQuery(this).css("padding-left")) + parseInt(jQuery(this).css("padding-right"));
};

// returns full height, including padding
jQuery.fn.paddedHeight = function() {
    return jQuery(this).height() + parseInt(jQuery(this).css("padding-top")) + parseInt(jQuery(this).css("padding-bottom"));
};

// modified and extended from "viewport" object of unknown origin--email me for credit
var jPosition = {
    o: function() {
        if (self.innerHeight) {
            this.pageYOffset = self.pageYOffset;
            this.pageXOffset = self.pageXOffset;
            this.innerHeight = self.innerHeight;
            this.innerWidth = self.innerWidth;
        } else if (document.documentElement && document.documentElement.clientHeight) {
            this.pageYOffset = document.documentElement.scrollTop;
            this.pageXOffset = document.documentElement.scrollLeft;
            this.innerHeight = document.documentElement.clientHeight;
            this.innerWidth = document.documentElement.clientWidth;
        } else if (document.body) {
            this.pageYOffset = document.body.scrollTop;
            this.pageXOffset = document.body.scrollLeft;
            this.innerHeight = document.body.clientHeight;
            this.innerWidth = document.body.clientWidth;
        }
        return this;
    },
    windowCenter: function(el, speed) {
        if (speed && speed !== 0) jQuery(el).animate({
            left: Math.round(jPosition.o().innerWidth / 2) + jPosition.o().pageXOffset - Math.round(jQuery(el).paddedWidth() / 2),
            top: Math.round(jPosition.o().innerHeight / 2) + jPosition.o().pageYOffset - Math.round(jQuery(el).paddedHeight() / 2)
            }, speed, "swing");
        else {
            jQuery(el).css("left", Math.round(jPosition.o().innerWidth / 2) + jPosition.o().pageXOffset - Math.round(jQuery(el).paddedWidth() / 2));
            jQuery(el).css("top", Math.round(jPosition.o().innerHeight / 2) + jPosition.o().pageYOffset - Math.round(jQuery(el).paddedHeight() / 2));
        }
    },
    windowTopLeft: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().pageXOffset + padHoriz,
            top: jPosition.o().pageYOffset + padVert
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().pageXOffset + padHoriz);
            jQuery(el).css("top", jPosition.o().pageYOffset + padVert);
        }
    },
    windowTopRight: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        //alert("padHoriz: " + padHoriz + "\npadVert: " + padVert + "\noldTop: " + jQuery(el).css("top") + "\noldLeft: " + jQuery(el).css("left") + "\nXOffset: " + jPosition.o().pageXOffset + "\nYOffset: " + jPosition.o().pageYOffset);
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz),
            top: jPosition.o().pageYOffset + padVert
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz));
            jQuery(el).css("top", jPosition.o().pageYOffset + padVert);
        }
    },
    windowBottomLeft: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().pageXOffset + padHoriz,
            top: jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert)
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().pageXOffset + padHoriz);
            jQuery(el).css("top", jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert));
        }
    },
    windowBottomRight: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz),
            top: jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert)
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz));
            jQuery(el).css("top", jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert));
        }
    }
};

// =================
// BEHAVIOR SETTINGS
// =================
var jPopupEnableSmooth = true;      // whether to animate or just show (disable for slower clients)
var jPopupFadeInSpeed = 600;        // ignored if jPopupEnableSmooth = false
var jPopupFadeOutSpeed = 300;       // ignored if jPopupEnableSmooth = false
var jPopupScrollSpeed = 300;        // ignored if jPopupEnableSmooth = false
var jPopupDefaultTitle = "Komunikat";
var jPopupDefaultType = JPOPUP_BTN_OK;
var jPopupDefaultCallback = function() { return true; };
var jPopupDefaultWidth = 0;

var jMessageEnableSmooth = true;    // whether to animate or just show (disable for slower clients)
var jMessageOpacity = 0.9;          // between 0 and 1
var jMessagePadHoriz = 28;          // safe for vertical scrollbars
var jMessagePadVert = 8;
var jMessagePosition = JMESSAGE_POS_TOPRIGHT;
var jMessageFadeSpeed = 600;        // ignored if jMessageEnableSmooth = false
var jMessageSlideSpeed = 600;       // ignored if jMessageEnableSmooth = false
var jMessageScrollSpeed = 100;      // ignored if jMessageEnableSmooth = false
var jMessageDefaultType = JMESSAGE_UPDATE;
var jMessageDefaultDuration = 5000; // time to show, in milliseconds (set 0 for indefinite)
var jMessageDefaultWidth = -320;

// ==================
// LAST MODIFICATIONS
// ==================

if (!jPopupEnableSmooth) {
    jPopupScrollSpeed = false;
}

if (!jMessageEnableSmooth) {
    jMessageFadeSpeed = false;
    jMessageSlideSpeed = false;
    jMessageScrollSpeed = false;
}

switch (jMessagePosition) {
    case JMESSAGE_POS_TOPLEFT: jMessagePositionFunction = jPosition.windowTopLeft; break;
    case JMESSAGE_POS_TOPRIGHT: jMessagePositionFunction = jPosition.windowTopRight; break;
    case JMESSAGE_POS_BOTTOMLEFT: jMessagePositionFunction = jPosition.windowBottomLeft; break;
    case JMESSAGE_POS_BOTTOMRIGHT: jMessagePositionFunction = jPosition.windowBottomRight; break;
}
