/*
* jQuery SuperBox! 0.9.2-dev
* Copyright (c) 2009 Pierre Bertet (pierrebertet.net)
* Licensed under the MIT (MIT-LICENSE.txt)
*
* TODO :
* - Document.load if init is before </body> against IE crash.
* - Animations
* - Image / Gallery mode : display a legend
*/
; (function($) {

    // Local variables
    var $curLink, $overlay, $wrapper, $container, $superbox, $closeBtn, $loading, $nextprev, $nextBtn, $prevBtn, settings,

    // Default settings
	defaultSettings = {
	    boxId: "superbox",
	    boxClasses: "",
	    overlayOpacity: .7,
	    boxWidth: "600",
	    boxHeight: "500",
	    loadTxt: "Cargando",
	    closeTxt: "",
	    prevTxt: "",
	    nextTxt: "",
	    beforeOpen: function() { },
	    afterOpen: function() { }
	},

	galleryGroups = {},
	galleryMode = false,
	hideElts = $([]),
	isWaiting = false;

    // Init dispatcher
    $.superbox = function() {

        // Settings
        settings = $.extend({}, defaultSettings, $.superbox.settings);

        // If IE6, select elements to hide
//        if ($.browser.msie && $.browser.version < 7) {
//            hideElts = hideElts.add("select");
//        }

        // Do not init SuperBox! twice
        if ($.superbox.mainInit !== true) {

            // Create base elements
            createElements();

            // Init global events (left / right, echap)
            initGlobalEvents();

            $.superbox.mainInit = true;
        }

        // Dispatch types
        dispatch();
    };

    // Dispatch types
    function dispatch() {

        // Match all superbox links
        $("a[rel^=superbox],area[rel^=superbox]").each(function() {

            // Optimisation
            var $this = $(this),
			relAttr = $this.attr("rel"),

            // Match first argument. Ex: superbox[gallery#my_id.my_class][my_gallery] > gallery#my_id.my_class
			firstArg = relAttr.match(/^superbox\[([^\]]+)\]/)[1],

            // Match type. Ex: superbox[gallery#my_id.my_class][my_gallery] > gallery
			type = firstArg.match(/^([^#\.]+)/)[1],

            // Match additionnal classes or IDs (#xxx.yyy.zzz)
			boxCurrentAttrs = firstArg.replace(type, "").match(/([#\.][^#\.\]]+)/g) || [],

            // Box ID and classes
			newBoxId = settings.boxId,
			newBoxClasses = settings.boxClasses;

            // Prevent multiple inits
            if ($this.data("superbox_init")) { return; }
            $this.data("superbox_init", true);

            // Additionnal rel settings
            this._relSettings = relAttr.replace("superbox[" + type + boxCurrentAttrs.join("") + "]", "");

            // Redefine settings
            $.each(boxCurrentAttrs, function(i, val) { // each class or id
                if (val.substr(0, 1) == "#") {
                    newBoxId = val.substr(1);

                } else if (val.substr(0, 1) == ".") {
                    newBoxClasses += " " + val.substr(1);
                }
            });

            // Call type method
            if (type.search(/^image|gallery|iframe|content|ajax$/) != -1) {
                $this.superbox(type, { boxId: newBoxId, boxClasses: newBoxClasses });
            }
        });
    };

    /*-- Superbox Method --*/
    $.fn.superbox = function(type, curSettings) {
        curSettings = $.extend({}, settings, curSettings);
        $.superbox[type](this, curSettings);

        this.click(function(e) {
            e.preventDefault();
            $curLink = this;
        });
    };

    /*-- Types --*/
    $.extend($.superbox, {

        // Wait... (loading)
        wait: function(callback) {

            isWaiting = true;

            prepareBox();

            // Loading anim
            initLoading(function() {

                // Execute callback after animation
                callback();
            });
        },

        // Custom SuperBox!
        open: function(content, curSettings) {

            curSettings = $.extend({}, settings, curSettings);

            // Launch load animation
            if (!isWaiting) {
                $.superbox.wait(function() {
                    $.superbox.open(content, curSettings);
                });
                return;
            }

            // Specified dimensions
            $superbox.width(curSettings.boxWidth + "px");
            $innerbox.height(curSettings.boxHeight + "px");

            // Set Id and Classes
            $superbox.attr("id", curSettings.boxId).attr("class", curSettings.boxClasses);

            // Append content
            $(content).appendTo($innerbox);

            // Show box
            showBox(curSettings);

            // Stop waiting
            isWaiting = false;
        },

        // Close SuperBox!
        close: function() {

            hideBox();
            $overlay.fadeOut(300, function() {

                // Show hidden elements for IE6
                hideElts.show();
            });
            galleryMode = false;
        },

        // Image
        image: function($elt, curSettings, isGallery) {

            // On click event
            $elt.click(function() {

                galleryMode = !!isGallery;

                $.superbox.wait(function() {

                    var relSettings = getRelSettings($elt.get(0)),
					dimensions = false;

                    // Extra settings
                    if (!!relSettings) {

                        var relDimensions;

                        if (galleryMode) {
                            relDimensions = relSettings[1];

                        } else {
                            relDimensions = relSettings[0];
                        }

                        if (!!relDimensions) {
                            dimensions = relDimensions.split("x");
                        }
                    }

                    // Image
                    var $curImg = $('<img src="' + $elt.attr("href") + '" title="' + ($elt.attr("title") || $elt.text()) + '" />');

                    // On image load
                    $curImg.load(function() {

                        // Image box dimensions
                        if (!!dimensions && dimensions[0] != "") {
                            var boxWidth = dimensions[0] - 0;
                        } else {
                            // image width + $innerbox padding
                            var boxWidth = $curImg.width() + ($innerbox.css("paddingLeft").slice(0, -2) - 0) + ($innerbox.css("paddingRight").slice(0, -2) - 0);
                        }
                        if (!!dimensions && dimensions[1] != "") {
                            var boxHeight = dimensions[1] - 0;
                        } else {
                            var boxHeight = $curImg.height();
                        }

                        curSettings = $.extend({}, curSettings, {
                            boxClasses: (galleryMode ? "gallery " : "image ") + curSettings.boxClasses,
                            boxWidth: boxWidth,
                            boxHeight: boxHeight,
                            beforeOpen: function() {
                                if (galleryMode) {
                                    // "Prev / Next" buttons
                                    nextPrev($elt, relSettings[0]);
                                }
                            }
                        });

                        // Open SuperBox!
                        $.superbox.open($curImg, curSettings);
                    });

                    // Append image to SuperBox! (to trigger loading)
                    $curImg.appendTo($innerbox);
                });

            });
        },

        // Gallery
        gallery: function($elt, curSettings) {

            // Extra settings
            var extraSettings = getRelSettings($elt.get(0));

            // Create group
            if (!galleryGroups[extraSettings[0]]) {
                galleryGroups[extraSettings[0]] = [];
            }

            // Add element to current group
            galleryGroups[extraSettings[0]].push($elt);

            $elt.data("superboxGroupKey", galleryGroups[extraSettings[0]].length - 1);

            // Image Box
            $.superbox["image"]($elt, curSettings, true);
        },

        // iframe
        iframe: function($elt, curSettings) {

            // On click event
            $elt.click(function() {

                $.superbox.wait(function() {

                    // Extra settings
                    var extraSettings = getRelSettings($elt.get(0));

                    // Dimensions
                    var dims = false;
                    if (extraSettings) {
                        dims = extraSettings[0].split("x");
                    }

                    curSettings = $.extend({}, curSettings, {
                        boxWidth: dims[0] || curSettings.boxWidth,
                        boxHeight: dims[1] || curSettings.boxHeight,
                        boxClasses: "iframe " + curSettings.boxClasses
                    });

                    // iframe element
                    //var $iframe = $('<iframe title="'+ $elt.text() +'" src="'+ $elt.attr("href") +'" name="'+ $elt.attr("href") +'" frameborder="0" scrolling="auto" width="'+ curSettings.boxWidth +'" height="'+ curSettings.boxHeight +'"></iframe>');
                    $iframe = $('<iframe src="' + $elt.attr("href") + '" name="' + $elt.attr("href") + '" frameborder="0" scrolling="auto" hspace="0" width="100%" height="100%" margin="0" marginheight="0" padding="0" marginwidth="0" leftmargin="0" rightmargin="0" topmargin="0" bottommargin="0"></iframe>');

                    // On iframe load
                    $iframe.one("load", function() {

                        // Open SuperBox!
                        $.superbox.open($iframe, curSettings);
                    });

                    // Append iframe to SuperBox! (to trigger loading)
                    $iframe.appendTo($innerbox);
                });

            });
        },

        // Content
        content: function($elt, curSettings) {

            // On click event
            $elt.click(function() {

                $.superbox.wait(function() {

                    // Extra settings
                    var extraSettings = getRelSettings($elt.get(0));

                    // Dimensions
                    var dims = false;
                    if (extraSettings) {
                        dims = extraSettings[0].split("x");
                    }

                    // Specific settings
                    curSettings = $.extend({}, curSettings, {
                        boxWidth: dims[0] || curSettings.boxWidth,
                        boxHeight: dims[1] || curSettings.boxHeight,
                        boxClasses: "content " + curSettings.boxClasses
                    });

                    // Open SuperBox!
                    $.superbox.open($($elt.attr('href')).clone(), curSettings);
                });

            });
        },

        // Ajax
        ajax: function($elt, curSettings) {

            // On click event
            $elt.click(function() {

                $.superbox.wait(function() {

                    // Extra settings
                    var extraSettings = getRelSettings($elt.get(0));

                    // Dimensions
                    var dims = false;
                    if (extraSettings && extraSettings[1]) {
                        dims = extraSettings[1].split("x");
                    }

                    // Extend default dimension settings
                    curSettings = $.extend({}, curSettings, {
                        boxWidth: dims[0] || curSettings.boxWidth,
                        boxHeight: dims[1] || curSettings.boxHeight,
                        boxClasses: "ajax " + curSettings.boxClasses
                    });

                    // Get Ajax URL + ID
                    var splitUrl = extraSettings[0].split("#");
                    var ajaxUrl = splitUrl[0];
                    var anchor = splitUrl[1] || false;

                    $.get(ajaxUrl, function(data) {

                        // Get a specific element (by ID)?
                        if (anchor !== false) {
                            data = $(data).find("#" + anchor);
                        }

                        // Open SuperBox!
                        $.superbox.open(data, curSettings);
                    });
                });
            });
        }
    });

    // Get extra settings in rel attribute
    function getRelSettings(elt) {
        return elt._relSettings.match(/([^\[\]]+)/g);
    };

    // Next / Previous
    function nextPrev($elt, group) {

        $nextprev.show();

        galleryMode = true;

        var nextKey = $elt.data("superboxGroupKey") + 1,
			prevKey = nextKey - 2;

        // Next
        if (galleryGroups[group][nextKey]) {
            $nextBtn.removeClass("disabled").unbind("click").bind("click", function() {
                galleryGroups[group][nextKey].click();
            });

        } else {
            $nextBtn.addClass("disabled").unbind("click");
        }

        // Prev
        if (galleryGroups[group][prevKey]) {
            $prevBtn.removeClass("disabled").unbind("click").bind("click", function() {
                galleryGroups[group][prevKey].click();
            });

        } else {
            $prevBtn.addClass("disabled").unbind("click");
        }

        // Keys shortcuts
        $(document)
			.unbind("keydown.superbox_np")
			.bind("keydown.superbox_np", function(e) {

			    // Left/right arrows
			    if (e.keyCode == 39) {
			        $nextBtn.click();

			    } else if (e.keyCode == 37) {
			        $prevBtn.click();
			    }
			});
    };

    // Hide Box
    function hideBox() {

        if (!!$curLink) {
            $curLink.focus();
        }

        $(document).unbind("keydown.spbx_close").unbind("keydown.superbox_np");
        $loading.hide();
        $nextprev.hide();
        $wrapper.hide().css({ position: "fixed", top: 0 });
        $innerbox.empty();
        $curLink = null;
    };

    // "Loading..."
    function initLoading(callback) {

        // Keys shortcuts
        $(document)
			.unbind("keydown.spbx_close")
			.bind("keydown.spbx_close", function(e) {

			    // Escape
			    if (e.keyCode == 27) {
			        $.superbox.close();
			    }
			});

        var loading = function() {

            // IE6
            if ($.browser.msie && $.browser.version < 7) {
                $wrapper.css({ position: "absolute", top: "50%" });
            }

            // Hide elements for IE6
            hideElts.hide();

            $loading.show();
            callback();
        };

        if (galleryMode) {
            $overlay.css("opacity", settings.overlayOpacity).show();
            loading();
        }
        else {
            $overlay.css("opacity", 0).show().fadeTo(300, settings.overlayOpacity, loading);
        }
    };

    // "Prepare" box : Show $superbox with top:-99999px;
    function prepareBox() {
        $wrapper.show();
        $innerbox.empty();
        $superbox.css({ position: "absolute", top: "-99999px" });
    };

    // Display box
    function showBox(curSettings) {

        curSettings = $.extend({}, settings, curSettings);

        // Stop "Loading..."
        $loading.hide();

        // Show $superbox
        $superbox.css({ position: "static", top: 0, opacity: 0 });

        // IE6 and IE7
        if ($.browser.msie && $.browser.version < 8) {
            $superbox.css({ position: "relative", top: "-50%" });

            // IE6
            if ($.browser.msie && $.browser.version < 7) {
                $wrapper.css({ position: "absolute", top: "50%" });
            }
        }

        // Position absolute if image height > window height
        if ($(window).height() < $wrapper.height()) {
            $wrapper.css({ position: "absolute", top: ($wrapper.offset().top + 10) + "px" });
        }

        curSettings.beforeOpen();

        $superbox.fadeTo(300, 1, function() {
            curSettings.afterOpen();
        }).focus();
    };

    // Create base elements (overlay, wrapper, box, loading)
    function createElements() {
        if (!$.superbox.elementsReady) {

            // Overlay (background)
            //$overlay = $('<div id="superbox-overlay"/>').appendTo("body").hide();
            $overlay = $('<iframe id="superbox-overlay" src="iframeMask.htm"></iframe>').appendTo("body").hide();

            // Wrapper
            $wrapper = $('<div id="superbox-wrapper"></div>').appendTo("body").hide();

            // Box container
            $container = $('<div id="superbox-container"></div>').appendTo($wrapper);

            // Box
            $superbox = $('<div id="superbox"></div>').appendTo($container);

            // Inner box
            $innerbox = $('<div id="superbox-innerbox"></div>').appendTo($superbox);

            // "Next / Previous"
            $nextprev = $('<p class="nextprev"></p>').appendTo($superbox).hide();
            $prevBtn = $('<a class="prev"><strong><span>' + settings.prevTxt + '</span></strong></a>').appendTo($nextprev);
            $nextBtn = $('<a class="next"><strong><span>' + settings.nextTxt + '</span></strong></a>').appendTo($nextprev);

            // Add close button
            $closeBtn = $('<p class="close"><a href="javascript:;">' + settings.closeTxt + '</a></p>').prependTo($superbox).find("a");

            $Copyright = $('<p class="CopyrightLightview"><strong>Carsa - Megatone.</strong> Todos los derechos reservados. Copyright 2009. </p>').appendTo($superbox);
            // "Loading..."
            $loading = $('<p class="loading">' + settings.loadTxt + '</p>').appendTo($container).hide();

            // Hide on click
            $overlay.add($wrapper).add($closeBtn).click(function() {
            $.superbox.close();
            });

            // Remove "hide on click" on superbox
            $superbox.click(function(e) {
                e.stopPropagation(true);
            });

            // Dont call this function twice
            $.superbox.elementsReady = true;
        }
    };

    // Init global events : close (echap), keyboard access (focus + enter)
    function initGlobalEvents() {

        // Hide on click
        $overlay.add($wrapper).add($closeBtn).click(function() {
            $.superbox.close();
        });

        // Remove "hide on click" on superbox
        $superbox.click(function(e) {
            e.stopPropagation();
        });

        // Opera already click on "focus + enter"
        if (!window.opera) {

            // Keyboard (focus + enter)
            $prevBtn.add($closeBtn).add($nextBtn).keypress(function(e) {
                if (e.keyCode === 13) {
                    $(this).click();
                }
            });
        }
    }

})(jQuery);
