﻿/// <reference path="jquery.vsdoc.js" />

/*globals $, jQuery, window, event */
/*jslint browser: true */

/*!
* jQuery Banner Rotator Plugin
* Version: 0 (unreleased)
* Requires: jQuery v1.6.2 or later
* Author: Tom Robinson
*/
(function ($) {

    "use strict";

    $.fn.bannerrotator = function (options) {

        var settings;

        // Default settings which will be merged into passed options
        settings = {
            "transition": {
                "delay": 4000,
                "speed": 1500
            }
        };

        return this.each(function () {

            var rotate, transitionType, rotateSwitch, initialise, bannerViewfinderWidth, numberOfBanners, imageReelWidth,
                activebanner, transitionTimer, cropMargin, setWidths, waitForFinalEvent;

            rotate = function (speed) {

                var bannerID, bannerReelHorizontalOffset;

                bannerID = activebanner.attr("rel"); // Get number of times to slide
                bannerReelHorizontalOffset = ((bannerID - 1) * bannerViewfinderWidth) + (((bannerID * 2) - 1) * cropMargin);

                $(".bannerPaging a").removeClass('active'); // Remove all active class
                activebanner.addClass('active'); // Add active class

                if (transitionType === "fade") {
                    $(".bannerReel").fadeOut("normal").animate({
                        left: -bannerReelHorizontalOffset
                    }, "fast").fadeIn("normal");
                    transitionType = "slide";
                } else {
                    $(".bannerReel").animate({
                        left: -bannerReelHorizontalOffset
                    }, speed, "easeOutBack");
                }

            };

            waitForFinalEvent = (function () {
                var timers = {};
                return function (callback, ms, uniqueId) {
                    if (!uniqueId) {
                        uniqueId = "Don't call this twice without a uniqueId";
                    }
                    if (timers[uniqueId]) {
                        clearTimeout(timers[uniqueId]);
                    }
                    timers[uniqueId] = setTimeout(callback, ms);
                };
            })();

            rotateSwitch = function () {
                clearInterval(transitionTimer);
                transitionTimer = setInterval(function () {

                    activebanner = $('.bannerPaging a.active').next();

                    if (activebanner.length === 0) { // If paging reaches the end...
                        activebanner = $('.bannerPaging a:first'); // Go back to first
                        transitionType = "fade";
                    }

                    rotate(settings.transition.speed); // Trigger the paging and slider function
                }, settings.transition.delay);
            };

            setWidths = function () {

                // Make the viewfinder the full width of the page, unless the page is wider than the banner itself
                if ($(window).width() < settings.banner.width) {
                    $(".bannerViewfinder").width($(window).width());
                    $(".bannerrotator").width($(window).width());
                } else {
                    $(".bannerViewfinder").width(settings.banner.width);
                    $(".bannerrotator").width(settings.banner.width);
                }

                // Record the width of the viewfinder
                bannerViewfinderWidth = $(".bannerViewfinder").width();

                // Get the total number of banners
                numberOfBanners = $(".bannerReel img").size();

                // Get the width of the full image reel (all images horizontally stacked)
                imageReelWidth = bannerViewfinderWidth * numberOfBanners;

                // Calculate how much of the banners needs to be hidden/cropped to centre the image on the page
                //cropMargin = (settings.banner.width - $(window).width()) / 2;
                cropMargin = (settings.banner.width - bannerViewfinderWidth) / 2;

                $(".bannerPaging").css("left", (bannerViewfinderWidth / 2) - (numberOfBanners * (11 + 6)) - 3);

            };

            initialise = function () {

                // If options exist, lets merge them with our default settings
                if (options) {
                    $.extend(settings, options);
                }

                // Show the paging and activate its first link
                $(".bannerPaging").show();
                $(".bannerPaging a:first").addClass("active");
                activebanner = $('.bannerPaging a:first');

                setWidths();

                rotateSwitch();

                // Adjust the image reel to its new size
                $(".bannerReel").css("left", -cropMargin);

                $(".bannerPaging a").click(function () {

                    if ((activebanner !== undefined)
                            && (activebanner[0].rel !== undefined)
                            && ($(this)[0].rel !== undefined)
                            && (Math.abs(activebanner[0].rel - $(this)[0].rel) <= 1)) {
                        transitionType = "slide";
                    } else {
                        transitionType = "fade";
                    }

                    activebanner = $(this); // Activate the clicked paging

                    // Reset Timer
                    clearInterval(transitionTimer); // Stop the rotation
                    rotate(settings.transition.speed); // Trigger rotation immediately
                    rotateSwitch(); // Resume rotation timer

                    return false; // Prevent browser jump to link anchor
                });

                // When the window loses focus pause the transitions
                $(window).focus(function () {
                    rotateSwitch(); // Resume rotation timer
                });

                // When the window regains focus, resume the transitions
                $(window).blur(function () {
                    clearInterval(transitionTimer); // Stop the rotation
                });

                // When the window is resized
                $(window).resize(function () {

                    // Stop the event firing too often
                    waitForFinalEvent(function () {
                        setWidths();
                        rotate(0);
                    }, 200, "resize");
                });
            };

            initialise();

        });

    };
}(jQuery));

