/* ===============================
| JQUERY.LIGHTBOXLIB.JS
| Copyright, Andy Croxall (mitya@mitya.co.uk)
| For documentation and demo see http://www.mitya.co.uk/scripts/Lightbox-and-lightbox-dialog-99
|
| USAGE
| This script may be used, distributed and modified freely but this header must remain in tact.
| For usage info and demo, including info on args and params, see www.mitya.co.uk/scripts
=============================== */


/* -------------------
 | CONFIG
 ------------------- */

lightboxConfig = {
    lbOpacity:	.6,
    lbBackground: '444',
    lbdialog_defaultHeight: 305, //default height of lightbox replcement dialog box (i.e. alert/confirm)
    lbdialog_allowCloseByClickingLightbox: false, //see notes at top
    lbdialog_css: {
        borderRadius: -10,
        width: 300,
        boxShadow: '0 0 32px #26a1ce'
    }
};


/* -------------------
 | PREP. Log whether IE6 and declare func used by lbdialog to allow closure via escsape key (need to declare as non-anonymouse
 | func so it can be unbound when lbdialog closes
 ------------------- */

var ie6 = navigator.appVersion.match(/MSIE 6\.0/);
var closeLBDialogOnEscapePress = function(e) {
    if (e.keyCode == 27) hidelightbox();
};


$(function() {

    /* -------------------
	| MAIN LIGHTBOX FUNC
	------------------- */

    jQuery.fn.lightbox = function(noFade, autoDisappear, noLightbox, noClose) {


        //prep

        var ac = arguments.callee;
        $(this).addClass('lightbox_centralElement');
        var centralElement = this.get(0);
        $(centralElement).children().hide();
        if (noLightbox) $('#lightbox').css({
            opacity: 0,
            filter: 'alpha(opacity=0)'
        })
        if (noClose) $('#lightbox').addClass('noClose');


        //utility functions

        ac.doHide = function(noFade, callback) { //called on hide request
            if (!noFade) {
                var numChildren;
                if ((numChildren = $(ac.centralElement).children().length) > 0) {
                    var childrenFaded = 0;
                    $(ac.centralElement).children().fadeOut('', function() {
                        childrenFaded++;
                        if (childrenFaded == numChildren) $(ac.centralElement).slideUp('fast', function() {
                            reinsertCentralElement();
                            $('#lightbox').fadeOut('fast', callback ? callback() : null);
                        });
                    });
                } else
                    $(ac.centralElement).slideUp('fast', function() {
                        $('#lightbox').fadeOut('fast', callback ? callback() : null);
                        reinsertCentralElement();
                    });
            } else {
                $(ac.centralElement).hide();
                $('#lightbox').hide();
                if (callback) callback();
                reinsertCentralElement();
            }

        };


        //request to show

        if (centralElement.id != 'lightbox') {


            //force central element to be child of body (lift it out of the DOM and re-insert). This ensures centering relative to body. After, put back where it was.

            var node_holder = $(centralElement).clone(true);
            var markerNodeForReinsertion = document.createElement('em');
            $(centralElement).before($(markerNodeForReinsertion));
            markerNodeForReinsertion.id = 'markerNodeForReinsertion';
            $(centralElement).remove();
            centralElement = document.body.insertBefore(node_holder.get(0), document.body.childNodes[0]);


            //assuming noClose not passed, close lighbox if any <button> or element with .close inside central element is clicked
            if (!noClose) $(centralElement).find('button, .close').not('.noLBClose, [rel=noLBClose]').click(function(e) {
                $('#lightbox').lightbox();
            });


            //force position absolute and z-index 10001 if not set

            if ($(centralElement).css('position') != 'absolute') $(centralElement).css('position', 'absolute');
            if ($(centralElement).css('zIndex') != 10001) $(centralElement).css('zIndex', 10001);


            //remember the central element so we can kill it on hide request
            ac.centralElement = centralElement


            //centre it and ensure that, if user scrolls while LB open, central element moves with it
            $(centralElement).centreElement();
            $(window).scroll(function() {
                $(centralElement).centreElement();
            });

        }


        //toggle show/hide lightbox

        if ($('#lightbox').is(":hidden")) { //hidden - so show pos as necessary)

            var callback = function() {
                $(centralElement).slideDown('fast', function() {
                    $(centralElement).children(':not(:visible)').fadeIn();
                });
            };
            if (!noFade) $('#lightbox').fadeIn('fast', callback);
            else {
                $('#lightbox').show();
                callback();
            }
            if (autoDisappear) setTimeout(hidelightbox, autoDisappear * 1000)

        } else //showing - so hide
            ac.doHide();

    }



    /* -------------------
	| UTILITY: centre central element
	------------------- */

    jQuery.fn.centreElement = function(horiz, vert, justReturnValues) {

        //prep
        if (horiz == undefined) horiz = true;
        if (vert == undefined) vert = true;
        var scrollX = (document.documentElement.scrollLeft || document.body.scrollLeft || 0) || window.pageXOffset;
        var scrollY = (document.documentElement.scrollTop || document.body.scrollTop || 0) || window.pageYOffset;
        if (scrollX == undefined) scrollX = 0;
        if (scrollY == undefined) scrollY = 0;
        var el = this.get(0);

        //calculate
        var temp_elWidth = parseInt(el.currentStyle ? el.currentStyle.width : getComputedStyle(el, null).width);
        if (isNaN(temp_elWidth)) {
            $(el).css('width', '300px');
            temp_elWidth = 300;
        } //force default width if none set
        var left = (self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth)) / 2 - (temp_elWidth / 2) + scrollX;

        var temp_elHeight = parseInt(el.currentStyle ? el.currentStyle.height : getComputedStyle(el, null).height);
        if (isNaN(temp_elHeight)) {
            $(el).css('height', '300px');
            temp_elHeight = 300;
        } // " " "
        var top = (self.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight)) / 2 - (temp_elHeight / 2) + scrollY;

        //account for padding
        top -= parseInt(el.currentStyle ? el.currentStyle.paddingTop : getComputedStyle(el, null).paddingTop);
        left -= parseInt(el.currentStyle ? el.currentStyle.paddingLeft : getComputedStyle(el, null).paddingLeft);

        //return/effect
        if (!justReturnValues) {
            if (horiz) el.style.left = left+"px";
            if (vert) el.style.top = top+"px";
        } else {
            if ((!horiz || horiz) && (!vert || vert))
                return [left, top];
            else if (!horiz || horiz)
                return left;
            else if (!vert || vert)
                return vert;
        }

    }


    /* -------------------
	| BUILD LIGHTBOX ONLOAD
	------------------- */

    //build
    var lightboxDiv = document.createElement('div');
    lightboxDiv.id = 'lightbox';
    $(lightboxDiv).click(function() {
        if (
            !$(this).hasClass('noClose')
            &&
            (
                jQuery.fn.lightbox.centralElement.id != 'lightboxdialog'
                ||
                lightboxConfig.lbdialog_allowCloseByClickingLightbox
                )
                )
            $(this).lightbox();
    });
    $(document.body).prepend(lightboxDiv);

    //style it (doing it here means the script is portable, don't need to tell users to add rules to their CSS sheets)
    $('#lightbox').css({
        opacity: lightboxConfig.lbOpacity,
        filter: 'alpha(opacity='+(lightboxConfig.lbOpacity * 100)+')',
        width: $(document).width(),
        height: $(document).height(),
        background: '#'+lightboxConfig.lbBackground,
        position: 'fixed',
        left: 0,
        top: 0,
        zIndex: 10000,
        display: 'none'
    });

});



/* -------------------
| UTILITY FUNC: supporting func - on lightbox close, reinsert central element into DOM at its original position
------------------- */

reinsertCentralElement = function() {
    var ce = jQuery.fn.lightbox.centralElement;
    try {
        markerNodeForReinsertion = $('#markerNodeForReinsertion').get(0);
        if (markerNodeForReinsertion.parentNode.tagName.toLowerCase() != "body") {
            var ceHolder = ce;
            ce.parentNode.removeChild(ce);
            markerNodeForReinsertion.parentNode.insertBefore(ceHolder, markerNodeForReinsertion);
            markerNodeForReinsertion.parentNode.removeChild(markerNodeForReinsertion);
        }
    } catch(e) {}
}



/* -------------------
| UTILITY FUNC: lightbox-utilising replacement for in-built alert/confirm methods. See usage notes at top of page.
------------------- */

lbdialog = function(params) {


    //checktype passed args before continuing

    if (
        typeof params.content != 'string'
        ||
        (params.okButton &&
            (typeof params.okButton.callback != 'function' && params.okButton.callback)
            )
        ||
        (params.cancelButton &&
            (typeof params.cancelButton.callback != 'function' && params.cancelButton.callback)
            )
            )
        return false;


    //clean up from any previous alert

    if ($('#lightboxdialog').length != 0) $('#lightboxdialog').remove();


    //create, style (with necessary CSS, params-passed CSS and config CSS at top of file) and append dialog box

    var box = document.createElement('div');
    with ($(box)) {
        attr('id', 'lightboxdialog');
        css({
            //background: '#fff',
            position: 'absolute',
            padding: 15,
            width: 320,
            height: lightboxConfig.lbdialog_defaultHeight,
            display: 'none',
            textAlign: 'left'
        });
        if (typeof params.css == 'object') $(box).css(params.css);
        if (lightboxConfig.lbdialog_css) css(lightboxConfig.lbdialog_css);
        }
    $('body').prepend(box);


    //add content

    var fs = lightboxConfig.lbdialog_css.fontSize+'';
    if (!fs.match(/^\d$/)) fs += 'px';
    var header;
    if (params.error) header = ['ERROR', 'b00'];
    else if (params.success) header = ['SUCCESS', '0b0'];
    var header = header == undefined ? '' : "<h4 style='margin: 0 0 10px 0; color: #"+header[1]+"'>"+header[0]+"</h4>";
    $(box).html(header+'<p'+(fs ? " style='margin-bottom: 10px; font-size: "+fs+"'" : '')+'>'+params.content+"</p><div style='clear: both'></div>");


    //add buttons, unless params stipulate the dialog should close itself after X seconds. right button will always be put out,
    //whereas left button is only put out if params.cancelButton object is passed, i.e. is confirm, not alert. onclick, along
    //with effecting any callbacks passed, they will also close the lightbox unless  you pass 'noLBClose' in their object

    if (!params.autoDisappear) {
        var buttons = ['OK', 'cancel'];
        for(var e in buttons) {
            if (buttons[e] == 'OK' || params.cancelButton) {
                var but = document.createElement('button');
                $(but).css({
                    'float': buttons[e] == 'OK' ? 'right' : 'left'
                    });
                if (params[buttons[e]+'Button']) {
                    if (params[buttons[e]+'Button'].noLBClose) $(but).addClass('noLBClose');
                    var butText = params[buttons[e]+'Button'].text ? params[buttons[e]+'Button'].text : buttons[e];
                    if (params[buttons[e]+'Button'].callback) $(but).click(params[buttons[e]+'Button'].callback);
                } else
                    var butText = buttons[e];
                $(but).text(butText);
                box.appendChild(but);
            }
        }
    }


    //centre and show
    $(box).lightbox(true, params.autoDisappear ? params.autoDisappear : null, params.noLightbox ? true : null);

    //lastly, close on keypress to <escape>
    $(document).bind('keypress', closeLBDialogOnEscapePress);

};


/* -------------------
| UTILITY FUNC: close lightbox and remove keypress bind to escape key
------------------- */

hidelightbox = function(noFade, callback) {
    jQuery.fn.lightbox.doHide(noFade, callback);
    $(document).unbind('keypress', closeLBDialogOnEscapePress);
};
