(function ($) {
    $.fn.lightbox = function (options) {
        var defaults = {
            use: "element:self", //any attr path:filepath, ajax:pageurl
            type: "gallery", // single
            speed: 600,
            modal: "lbModal",
            cover: "lbCover",
            height: "auto",
            width: "auto",
            description: true,
            descsource: "attr:alt",
            desclocation: "bottom",
            descposition: "inside"
        };
        var options = $.extend(defaults, options);

        return this.each(function () {
            var a = [];
            a[0] = $(this);
            a[1] = options.type;
            a[2] = options.speed;
            a[3] = options.modal;
            a[4] = options.cover;
            a[5] = options.use.split(":");
            a[6] = options.height;
            a[7] = options.width;
            a[8] = options.description;
            a[9] = options.descsource.split(":");
            a[10] = options.desclocation;
            a[11] = "lbDescCover";
            a[12] = "lbDescBox";
            a[13] = options.descposition;
            a[14] = "<a class='lbClose' />";

            var o = [];
            o[0] = "<span style='display:block;position:fixed;height:100%;width:100%;top:0px;left:0px;text-align:center;'></span>";
            o[1] = "<span style='height:100%;zoom:1;vertical-align:middle;display:inline-block;'></span>";
            o[2] = "<div style='overflow:hidden;position:absolute;" + a[10] + ":0px;" + ((a[10] == "top" || a[10] == "bottom") ? "width:100%;left:0px;height:auto;padding:5px 0px;" : "height:100%;top:0px;width:auto;padding:0px 5px;") + "'></div>";
            o[3] = "<a class='lbPrev'><span>Prev</span></a><a class='lbNext'><span>Next</span></a>"
            var lb = [];
            var s = [];
            var p = 0;
            var descSwitch = false;
            var first = true;

            // FIND DESCRIPTION
            function getDesc() {
                $("." + a[12]).fadeTo(a[2] / 4, 0);
                if (a[8] == false || a[0].attr(a[9][1]) == "") {
                    return false;
                } else {
                    if (a[9][0] == "attr") {
                        lb[10] = $(s[p]).attr(a[9][1]);
                        descSwitch = true;
                    } else if (a[9][0] == "ajax") {
                        $.ajax({
                            type: "GET",
                            url: a[9][1],
                            success: function (data) {
                                lb[10] = data;
                                descSwitch = true;
                            }
                        });
                    }
                }
            }
            // insert description
            function showDesc() {
                if (descSwitch = false) {
                    setTimeout(showDesc, 100);
                } else {
                    descSwitch = false;
                    if ($("." + a[11]).length == 0) { //determine if description box exists
                        $(o[2]).css({ "opacity": 0.6 }).addClass(a[11]).prependTo("." + a[3] + ">.lbWrap");
                        $(o[2]).css({ "opacity": 0 }).addClass(a[12]).prependTo("." + a[3] + ">.lbWrap");
                        $("." + a[12]).html(lb[10]);
                    } else {
                        $("." + a[12]).html(lb[10]);
                    }

                    if (a[10] == "top" || a[10] == "bottom") {
                        var tdem = $("." + a[12]).height();
                        $("." + a[11]).animate({ "height": tdem + "px" }, a[2] / 2, function () {
                            $("." + a[12]).fadeTo(a[2] / 4, 1);
                        });
                        if (a[13] == "outside") {
                            (a[10] == "top") ? $(".lbMain").animate({ "padding-top": tdem + 10 + "px" }, a[2] / 2) : $(".lbMain").animate({ "padding-bottom": tdem + 10 + "px" }, a[2] / 2);
                        };
                    } else {
                        var tdem = $("." + a[12]).width();
                        $("." + a[11]).animate({ "width": tdem + "px" }, a[2] / 2, function () {
                            $("." + a[12]).fadeTo(a[2] / 4, 1);
                        });
                        if (a[13] == "outside") {
                            (a[10] == "left") ? $(".lbMain").animate({ "padding-left": tdem + 10 + "px" }, a[2] / 2) : $(".lbMain").animate({ "padding-right": tdem + 10 + "px" }, a[2] / 2);
                        };
                    }
                }
            }

            // Set Array of slides
            function setArr() {
                if (a[5][0] == "element") {
                    if (a[5][1] == "self") {
                        s = a[0].parent().children(lb[7]);
                        p = s.index(a[0]);
                    } else {
                        s = $(a[5][1]).children();
                        p = a[0].parent().children(lb[7]).index(a[0]);
                    }
                } else if (a[5][0] == "path") {
                    s = a[0].parent().children(lb[7]);
                    p = s.index(a[0]);
                } else if (a[5][0] == "ajax") {
                    $.ajax({ type: "GET", url: a[5][1], success: function (data) {
                        alert(data);
                    }
                    });
                }
            };

            // Set Utility Functions
            function lbSetUtil() {
                $(".lbClose").bind("click", function () {
                    $("." + a[3]).children("*").fadeTo(a[2] / 2, 0, function () {
                        $(this).remove();
                    });
                    $("." + a[3]).css({ "height": $("." + a[3]).height(), "width": $("." + a[3]).width() }).delay(a[2] / 2).animate({ "width": "0px", "height": "0px" }, a[2] / 2, function () {
                        $(".lbSpanner").remove();
                    });
                    $("." + a[4]).fadeTo(a[2], 0, function () {
                        $(this).remove();
                    });
                });

                $(".lbNext").bind("click", function () {
                    $(".lbMain").fadeTo(a[2] / 2, 0, function () {
                        $(this).empty();
                    });
                    (p == (s.length - 1)) ? p = 0 : p += 1;
                    setNextElement();
                }).bind("mouseenter", function () {
                    $(this).stop().fadeTo(200, 1);
                }).bind("mouseleave", function () {
                    $(this).stop().fadeTo(200, 0);
                }).fadeTo(0, 0);
                $(".lbPrev").bind("click", function () {
                    $(".lbMain").fadeTo(a[2] / 2, 0, function () {
                        $(this).empty();
                    });
                    (p == (0)) ? p = (s.length - 1) : p -= 1;
                    setNextElement();
                }).bind("mouseenter", function () {
                    $(this).stop().fadeTo(200, 1);
                }).bind("mouseleave", function () {
                    $(this).stop().fadeTo(200, 0);
                }).fadeTo(0, 0);
            }


            // FETCH OBJECT
            function setNextElement() {
                if (a[5][0] == "element") {
                    lb[4] = $(s[p]).clone();
                } else if (a[5][0] == "path") {
                    if (lb[7] != "IMG") {
                        lb[4] = $(s[p]).clone();
                    } else {
                        var imgarr = $(s[p]).attr("src").split("/");
                        var imgname = imgarr[imgarr.length - 1];
                        lb[4] = $("<img src='" + a[5][1] + imgname + "' alt='' />");
                    }
                }
                if (lb[7] == "IMG") {
                    lb[4].css({ "max-height": "100%", "max-width": "100%" }).attr({ "class": "", "id": "" });
                }
                if (first == true) {
                    lb[4].appendTo("." + a[3]).wrap("<div class='lbWrap' style='position:relative;height:100%;' />").wrap("<div class='lbMain' style='height:100%;' />");
                    $(".lbMain").prepend(o[1]);
                }
                getFinalSize();
            }

            // FIND FINAL WIDTH/HEIGHT FOR POPUP
            function getFinalSize() {
                lb[4].clone().attr({ "class": "lbTestClass", "id": "" }).css({ "visibility":"hidden", "position": "absolute", "height": "auto", "width": "auto" }).bind("load", function () {
                    if (a[6] == "auto" || a[7] == "auto") {
                        (a[13] == "outside" && a[10] == "left" || a[13] == "outside" && a[10] == "right") ? lb[12] = $("." + a[12]).width() + 10 : lb[12] = 0;
                        (a[13] == "outside" && a[10] == "top" || a[13] == "outside" && a[10] == "bottom") ? lb[13] = $("." + a[12]).height() + 10 : lb[13] = 0;
                        lb[6] = (a[6] == "auto") ? $(".lbTestClass").height() + lb[13] + "px" : a[6];
                        lb[5] = (a[7] == "auto") ? $(".lbTestClass").width() + lb[12] + "px" : a[7];
                        $(".lbTestClass").remove();
                    } else {
                        lb[5] = (a[7].indexOf("%") > 0) ? $(window).width() * (parseFloat(a[7]) / 100) + "px" : a[7];
                        lb[6] = (a[6].indexOf("%") > 0) ? $(window).height() * (parseFloat(a[6]) / 100) + "px" : a[6];

                    }
                    slidePerform();
                }).appendTo("body");
            }
            function aniCallback() {
                if (first == true) {
                    first = false;
                    $("." + a[3]).css({ "left": "auto", "top": "auto", "position": "relative", "height": "auto", "width": "auto" });
                }
                $(".lbMain").html(lb[4]).prepend(o[1]).fadeTo(a[2] / 2, 1, function () {
                    if (a[8] == true) {
                        showDesc();
                    }
                });
                $("." + a[3]).css({ "width": a[7], "height": a[6] });
            }
            function slidePerform() {
                if (a[8] == true) {
                    getDesc();
                }
                if (first == true) {
                    $("." + a[3]).animate({ "left": (($(window).width() - parseFloat(lb[5])) / 2) - lb[8] + "px", "top": (($(window).height() - parseFloat(lb[6])) / 2) - lb[9] + "px", "width": lb[5], "height": lb[6] }, a[2], aniCallback);
                } else {
                    $("." + a[3]).animate({ "width": lb[5], "height": lb[6] }, a[2], aniCallback);
                }
            }

            a[0].click(function (e) {
                e.preventDefault();
                //set cover
                $(o[0]).addClass(a[4]).css("opacity", "0").appendTo("body").fadeTo(a[2], 0.6);
                lb[7] = this.tagName;
                setArr();
                lb[0] = a[0].width();
                lb[1] = a[0].height();
                lb[2] = this.offsetLeft;
                lb[3] = this.offsetTop;
                //set initial position/size
                $(o[0]).addClass("lbSpanner").append(o[1] + "<span class='" + a[3] + "' style='vertical-align:middle;display:inline-block;zoom:1;position:absolute;max-width:100%;max-height:100%;width:" + lb[0] + "px;height:" + lb[1] + "px;'></span>").appendTo("body");
                // account for padding offset
                lb[8] = parseFloat($("." + a[3]).css("padding-left"));
                lb[9] = parseFloat($("." + a[3]).css("padding-top"));
                // initial reposition
                $("." + a[3]).css({ "left": (lb[2] - lb[8]) + "px", "top": (lb[3] - lb[9]) + "px" });
                lb[11] = a[14]; //get the close button
                if (a[1] == "gallery") {
                    lb[11] += o[3]; // if it's a gallery, also get controls
                }
                $(lb[11]).appendTo("." + a[3]);

                setNextElement();
                // initial object addition, wrapped in divs

                lbSetUtil(); //set click/hover events for close/next/prev elements
            });
        });
    };
})(jQuery);
