/**
 * A slideshow system. Will display a single slide (with a description, title and image) at a time,
 * and will fade between the slides based on a duration. You can manually jump to specific slides.
 *
 * @copyright   2010, Blizzard Entertainment, Inc
 * @class       Slideshow
 * @example
 *
 *      Slideshow.initialize('#slideshow', []);
 *
 */

var Slideshow = {
    object: null,
    timer: null,
    index: 0,
    data: [],
    slides: [],
    playing: false,
    lastSlide: null,

    /**
     * Initialize the slider by building the slides based on this.data and starting the rotation.
     *
     * @param object - CSS expression
     * @param data
     * @constructor
     */
    initialize: function(object, data) {
        Slideshow.object = $(object);
        Slideshow.data = data;
        Slideshow.slides = Slideshow.object.find('.slide');

        // Apply events
        Slideshow.object.find('.mask').hover(
            function() { Slideshow.pause(); },
            function() { Slideshow.play(); }
        );

        Slideshow.object.find('.paging a').mouseleave(function() {
            Slideshow.object.find('.preview').empty().hide();
        });

        // Save views
        if (Slideshow.data.length > 0 && Slideshow.data[0].id) {
            var firstId = Slideshow.data[0].id;
			var cookie = Cookie.read('slideViewed');

            if (!cookie)
                cookie = [];
            else
                cookie = decodeURIComponent(cookie).split(',');

            if ($.inArray(firstId.toString(), cookie) < 0)
                cookie.push(firstId);

            if (cookie.length > 100)
                cookie.shift();

            Cookie.create('slideViewed', cookie.join(','), {
                escape: true,
                expires: 744 // 1 month
            });
        }

        if (Slideshow.slides.length <= 1)
            Slideshow.object.find('.controls, .paging').hide();

        Slideshow.link(0);
        Slideshow.play();

		//Force Load
		Slideshow.index = -1;
		Slideshow.rotate();
    },

    /**
     * Fade out the slides and fade in selected.
     *
     * @param index
     */
    fade: function(index) {
        Slideshow.slides.stop(true, true).fadeOut('normal');
        Slideshow.slides.eq(index).fadeIn(1500);
        Slideshow.link(index);

        var caption = Slideshow.object.find('.caption');

        caption.stop(true, true).fadeOut('fast', function() {
            if (Slideshow.data[index]) {
                caption.html("")
                    .append('<h3><a href="'+ Slideshow.data[index].url +'" class="link" target="' + Slideshow.data[index].target + '">'+ Slideshow.data[index].title +'</a></h3>')
                    .append(Slideshow.data[index].desc)
                    .fadeIn(1500);
            }
        });

        Slideshow.lastSlide = index;
    },

    /**
     * Manually jump to a specific slide. Pauses rotation.
     *
     * @param index
     * @param control
     */
    jump: function(index, control) {
        if ((Slideshow.lastSlide == index) || (Slideshow.slides.length <= 1))
            return;

        Slideshow.pause();
        Slideshow.fade(index);
        Slideshow.index = index;

        Slideshow.object.find('.paging a').removeClass('current');
        $(control).addClass('current');
    },

    /**
     * Link the mask overlay and track the event.
     *
     * @param index
     */
    link: function(index) {
        if (Slideshow.data[index]) {
            Slideshow.object
                .find('.mask')
                    .unbind('click.slideshow')
                    .bind('click.slideshow', function() {
                        if (typeof _gaq != 'undefined') {
                            var pushEvent = [
                                '_trackEvent',
                                Core.project +' Banners',
                                'Banner Click-Throughs',
                                'Banner-'+ Slideshow.data[index].id +'-'+ encodeURIComponent(Slideshow.data[index].title.replace(' ','_')) +'-'+ Core.locale
                            ];
                            _gaq.push(pushEvent);
                        }

                        Core.goTo(Slideshow.data[index].url);
                    })
                .end()
                .find('.link')
                    .attr('href', Slideshow.data[index].url)
					.attr('target', Slideshow.data[index].target)
                .end();
        }
    },

    /**
     * Play the rotation.
     */
    play: function() {
        if (Slideshow.slides.length <= 1)
            return;

        if (!Slideshow.playing) {
            Slideshow.playing = true;
            Slideshow.timer = window.setInterval(Slideshow.rotate, 5000);
        }
    },

    /**
     * Pause the automatic rotation.
     */
    pause: function() {
        if (Slideshow.slides.length <= 1)
            return;

        window.clearInterval(Slideshow.timer);

        Slideshow.playing = false;
    },

    /**
     * Display a tooltip preview.
     *
     * @param index
     */
    preview: function(index) {
        if (Slideshow.data[index]) {
            var tooltip = Slideshow.object.find('.preview'),
                top = (index * 15) + 15;

            if (Slideshow.data[index].image) {
                $('<img/>', {
                    src: Slideshow.data[index].image,
                    width: 100,
                    height: 47,
                    alt: ''
                }).appendTo(tooltip);
            }

            tooltip.append('<span>'+ Slideshow.data[index].title +'</span>').css('top', top);
            tooltip.show();
        }
    },

    /**
     * Automatically cycle through all the slides.
     */
    rotate: function() {
        var slideIndex = Slideshow.index + 1;

        if (slideIndex > (Slideshow.slides.length - 1))
            slideIndex = 0;

        if (Slideshow.lastSlide == slideIndex)
            return;

        Slideshow.fade(slideIndex);
        Slideshow.index = slideIndex;

        // Set control to current
        Slideshow.object
            .find('.paging a').removeClass('current').end()
            .find('.paging a:eq('+ slideIndex +')').addClass('current');
    },

    /**
     * Toggle between play and pause.
     */
    toggle: function() {
        if (Slideshow.playing)
            Slideshow.pause();
        else
            Slideshow.play();
    }

};


/**
 * Methods for creating, reading, and deleting cookies.
 */
var Cookie = {

	/**
	 * Cached cookies.
	 */
	cache: {},

	/**
	 * Create a cookie. Can accept a third parameter as a literal object of options.
	 *
	 * @param key
	 * @param value
	 * @param options
	 */
	create: function(key, value, options) {
		options = $.extend({}, options);
		options.expires = options.expires || 1; // 1 hour

		if (typeof options.expires == 'number') {
			var hours = options.expires;
			options.expires = new Date();
			options.expires.setTime(options.expires.getTime() + (hours * 3600000));
		}

		var cookie = [
			encodeURIComponent(key) +'=',
			options.escape ? encodeURIComponent(value) : value,
			options.expires ? '; expires=' + options.expires.toUTCString() : '',
			options.path ? '; path=' + options.path : '',
			options.domain ? '; domain=' + options.domain : '',
			options.secure ? '; secure' : ''
		];

		document.cookie = cookie.join('');

		if (Cookie.cache) {
			if (options.expires == -1)
				delete Cookie.cache[key];
			else
				Cookie.cache[key] = value;
		}
	},

	/**
	 * Read a cookie.
	 *
	 * @param key
	 * @return string
	 */
	read: function(key) {
		// Use cache when available
		if (Cookie.cache[key])
			return Cookie.cache[key];

		var cache = {};
		var cookies = document.cookie.split(';');

		if (cookies.length > 0) {
			for (var i = 0; i < cookies.length; i++) {
				var parts = cookies[i].split('=');

				if (parts.length >= 2)
					cache[$.trim(parts[0])] = parts[1];
			}
		}

		Cookie.cache = cache;
		return cache[key] || null;
	},

	/**
	 * Delete a cookie.
	 *
	 * @param key
	 */
	erase: function(key) {
		Cookie.create(key, true, {
			expires: -1
		});
	}
};

