﻿/***************************************************/
// usage:   1) $(".selector").carousel({params})
//             window.onbeforeunload = carousel.Stop; //Makes sure carousel animation is stopped mage, dumping request in IE if timed just wrong.
// params : 
//	@autoPlay: (boolean) enables the caroursel to start automatically default: false
//	@timer: (integer) sets the interval in seconds between each media (autoPlay must be set to True)  default: 5
//	@slide: (boolean) enables the caroursel to slide between the media changes default: true
//	@speed: (integer) the animation speed default: 300
//	@navInside: (boolean) set if the navigation should be outside the carousel or part of the media zone default: true
//	@navCenter: (boolean) set if the navigation should be centered to the carousel default: true
//	@navShow: (boolean) set if the navigation should be displayed default: true
//	@mediaContainer: (string) className of the element containing the media files  default: "mediaContainer"
//	@navContainer: (string) className of the element containing the carousel navigation  default: "carouselNav"
//	@activeClassName: (string) className that will be use on the navigation when its active  default: "active"
/**********************************************************/
var carouselTimerId;
var carouselDisabled = false; //Extra precaution to avoid timer getting re-attached if it is already in the middle of firing.

var carousel = {
    Stop: function() {

        carouselDisabled = true;

        if (carouselTimerId) {
            clearTimeout(carouselTimerId);
        }

        if (window.carouselReInitTimerId) {
            clearTimeout(window.carouselReInitTimerId);
        }
    }
};

jQuery.fn.carousel = function(settings) {
    var defaults, validateParams, loadMedias,
		setDimension, show, playShow, play;

    defaults = {
        autoPlay: true,
        timer: 6, // in seconds
        slide: false,
        speed: 800,
        navInside: false,
        navCenter: false,
        navShow: true,
        navContainer: "spotlight_paging",
        mediaContainer: "carouselMedia",
        activeClassName: "active"
    };
    settings = $.extend(defaults, settings);

    carouselTimerId = 0;

    // Validate Params
    validateParams = function() {
        if (typeof (settings.autoPlay) !== "boolean") {
            settings.autoPlay = false;
        }
        if (isNaN(settings.timer)) {
            settings.timer = 5;
        }
        if (typeof (settings.slide) !== "boolean") {
            settings.slide = false;
        }
        if (isNaN(settings.speed)) {
            settings.speed = 300;
        }
        if (typeof (settings.navInside) !== "boolean") {
            settings.navInside = false;
        }
        if (typeof (settings.navCenter) !== "boolean") {
            settings.navCenter = true;
        }
        if (typeof (settings.navShow) !== "boolean") {
            settings.navShow = true;
        }
        if (typeof (settings.navContainer) !== "string") {
            settings.navContainer = "spotlight_paging";
        }
        if (typeof (settings.mediaContainer) !== "string") {
            settings.mediaContainer = "carouselMedia";
        }
        if (typeof (settings.activeClassName) !== "string") {
            settings.activeClassName = "active";
        }
    };

    // set images width/height by loading the images
    loadMedias = function($carouselImages) {
        if ($.isFunction($.loadImages)) {
            $carouselImages.each(function() {
                var $image = $(this),
					$link, toHide;

                if ($image.attr("id") === "") {
                    if (document.getElementById($image.parent().attr("id")).nodeName === "A") {
                        $link = $($image.parent());
                        toHide = false;

                        if (!$link.is(":visible")) {
                            toHide = true;
                            $link.show();
                        }
                        return function() {
                            $.loadImages($("img", $link));
                            if (toHide) { $link.hide(); }
                        };
                    }
                } else {
                    return function() { $.loadImages($image); };
                }
            });
        }
    };

    // set carousel dimension by tallest and widest image
    setDimension = function($element) {
        var tallestH = 0,
			tallestW = 0,
			totalImgW = 0,
			dimension = {
			    height: 0,
			    width: 0
			},
			validData = false,
			$carouselImages = $element.find("." + settings.mediaContainer + " img"),
			zIndex, $img, imgH, imgW, killOutLine,
			$nav;

        // load images
        loadMedias($carouselImages);

        zIndex = 66666;

        $carouselImages.each(function(i) {
            $img = $(this);
            imgH = $img.outerHeight();
            imgW = $img.outerWidth();

            // functionality check
            if (imgH === 0) {
                // somethings wrong !!!
                return false;
            } else {
                validData = true;
            }

            if (imgH > tallestH) {
                tallestH = imgH;
            }

            if (imgW > tallestW) {
                tallestW = imgW;
            }
            dimension.height = tallestH;
            dimension.width = tallestW;

            totalImgW += imgW;

            if (!$img.attr("id")) {
                if (document.getElementById($img.parent().attr("id")).nodeName === "A") {
                    $img = $($img.parent());
                }
            }

            // always show first
            if (i === 0) { $img.show(); }

            if (i === 0 || !settings.slide) {
                $img.css("left", 0);
                if (i > 0 && !settings.slide) {
                    $img.hide();
                }
                if (!settings.slide) {
                    $img.css("position", "absolute");
                }
            } else {
                $img.css("left", totalImgW - imgW + "px").css("float", "left");
            }
        });

        // functionality check
        if (!validData) {
            // Somethings wrong exit function
            return false;
        } else {
            // Everything seems to be OK! Now set Mask width
            if (dimension.width) {
                $element.width(dimension.width);
            }

            // Set the media container width
            $element.find("." + settings.mediaContainer).each(function() {
                if (settings.slide) {
                    $(this).width(totalImgW);
                } else {
                    $(this).width(dimension.width);
                }
            });

            killOutLine = false;
            if ($.isFunction($().outLineKiller)) {
                killOutLine = true;
            }

            // position navigation
            $element.find("." + settings.navContainer).each(function() {
                $nav = $(this);
                if (settings.navShow) {
                    if (settings.navCenter) {
                        $nav.css("left", (dimension.width - $nav.width()) / 2 + "px");
                    }
                    if (killOutLine) {
                        $("a", $nav).outLineKiller();
                    }

                    if (dimension.height) {
                        if (settings.navInside) {
                            $element.height(dimension.height);
                            $nav.css("zIndex", zIndex++);
                        } else {
                            $element.height(dimension.height + $nav.outerHeight(true));
                        }
                    }
                } else {
                    $nav.hide();
                    if (dimension.height) {
                        $element.height(dimension.height);
                    }
                }
            });
            return true;
        }
    };

    // Show media
    show = function(element, lnk, arrMedia) {
        var $element = $(element),
			$link = $(lnk),
			imageId,
			$img, $media;

        $element.find("." + settings.navContainer + " a").each(function() {
            $(this).removeClass(settings.activeClassName);
        });
        $link.addClass(settings.activeClassName);

        imageId = $link.attr("href").split("#")[1];
        $img = $("#" + imageId);

        if (settings.slide) {
            $element.find("." + settings.mediaContainer).each(function() {
                if ($img.length) {
                    $(this).stop().animate({ left: "-" + $img.css("left") }, settings.speed);
                }
            });
        } else {
            $.each(arrMedia, function(idx, value) {
                $media = $(value);
                if ($media.is(":visible") && ($img.attr("id") !== $media.attr("id"))) {
                    if (settings.navInside) {
                        $media.css("bottom", 0);
                    }
                    $media.fadeOut(settings.speed, function() {
                        $img.fadeIn(settings.speed);
                    });
                    return false;
                }
            });
        }
    };

    // AutoPlay Show
    playShow = function(element, content, arrMedia, index) {
        var $element = $(element),
			$content = $(content),
			zIndex = 66666, //$.getHighestZIndex(),
			$nav = $element.find("." + settings.navContainer);

        $content.css("zIndex", zIndex);
        $content.fadeIn(settings.speed);

        if ($nav.length) {
            $nav.css("zIndex", zIndex++);
        }
        
        if (carouselDisabled)
            return;
        
        carouselTimerId = setTimeout(function() {
            var nextIdx = index + 1 > arrMedia.length - 1 ? 0 : index + 1;
            play($element, arrMedia, nextIdx, false);
        }, settings.timer * 1000);

    };


    // on autoPlay mode
    play = function(element, arrMedia, index, isFirstTimeLoad) {
        if (arrMedia.length) {
            var $element = $(element),
				$img = $(arrMedia[index]),
				$media,
				nextIdx, href;
            
            if (carouselDisabled)
                return;
                
            // get media link
            $element.find("a").each(function() {
                href = $(this).attr("href").split("#")[1];
                if (href === $img.attr("id")) {
                    $(this).removeClass(settings.activeClassName).addClass(settings.activeClassName);
                } else {
                    $(this).removeClass(settings.activeClassName);
                }
            });

            if (settings.slide) {
                $element.find("." + settings.mediaContainer).each(function() {
                    $(this).stop().animate({ left: "-" + $img.css("left") }, settings.speed, function() {
                        //interval validation
                        if (isNaN(settings.timer)) {
                            settings.timer = defaults.timer;
                        }
                        carouselTimerId = setTimeout(function() {
                            nextIdx = index + 1 > arrMedia.length - 1 ? 0 : index + 1;
                            play($element, arrMedia, nextIdx, false);
                        }, settings.timer * 1000);
                    });
                });
            } else {
                $.each(arrMedia, function(idx, value) {
                    $media = $(value);

                    if ($media.is(":visible")) {
                        if (!isFirstTimeLoad) {
                            $media.fadeOut(settings.speed, function() {
                                playShow($element, $img, arrMedia, index);
                            });
                        } else {
                            playShow($element, $img, arrMedia, index);
                        }
                        return false;
                    }
                });
            }
        }
    };

    return this.each(function(idx) {
        var $element = $(this),
			$links, media, $link,
			$content, contentId;

        //validateParams
        if (idx === 0) { validateParams(); }

        // Set Carousel dimension
        if (!$.data($element.get(0), "initialized")) {
            if (setDimension($element)) {
                // error functionality check
                if (window.carouselReInitTimerId) {
                    clearTimeout(window.carouselReInitTimerId);
                }

                if (!settings.slide) {
                    $element.css("overflow", "visible");
                }

                // find links and initialize it
                $links = $element.find("." + settings.navContainer + " a");

                if ($links.length > 1) {
                    // Get media array
                    media = [];

                    $links.each(function(i) {
                        $link = $(this);
                        contentId = $link.attr("href").split("#")[1];
                        if (i === 0) {
                            $link.addClass(settings.activeClassName);
                        } else {
                            $link.removeClass(settings.activeClassName);
                        }
                        try {
                            $content = $("#" + contentId);

                            if ($content.length) {
                                if (settings.navInside) {
                                    $content.css("bottom", 0);
                                }
                                media.push($content);
                            }
                        } catch (e) { }

                        $link.unbind("click").click(function() {
                            show($element, $(this), media);
                            clearTimeout(carouselTimerId);
                            return false;
                        });
                    });

                    // autoPlay mode
                    if (settings.autoPlay) {
                        play($element, media, 0, true);
                    }
                } else if ($links.length === 1) {
                    // We only show navigation for at least 2 items
                    $links.hide();
                }
                $.data($element.get(0), "initialized", true);
            } else {
                // re-run carousel initialization call
                window.carouselReInitTimerId = setTimeout(function() {
                    $element.carousel(settings);
                }, 100);
            }
        }
    });
};

