/// <reference path="jquery-1.6.2.js" />
/// <reference name="MicrosoftAjax.js"/>

/**
*	jquery.slideShow (1.0.7)
* 	by Marcel Eichner (www.marceleichner.de) <love@ephigenia.de>
*		and charles kline <ckline@discmakers.com>
* 
*	This simple slideshow plugin will provide your effect gallery with
* 	some simple features:
*
*	- auto slideshow with repeat and a lot of options
*	- callback for slide changing (gotoSlide) and slide Clicks (onSlideClick)
*	- different option variables to configure
*	- change of slide through clicking numbers, next, prev etc and mouse
*	  movement over the slides
*	- text over images possible
*	- random start slide via { start: 'rnd' }
*	- start/stop slideshow and read playing status
*	
*	learn more about this plugin and other projects at:
*	http://code.marceleichner.de/project/jquery.slideShow/
*
*	Copyright (c) 2009 Marcel Eichner (www.marceleichner.de)
*	Licensed under the MIT license:
*	http://www.opensource.org/licenses/mit-license.php
*
*	NOTE: This script requires jQuery to work.  Download jQuery at www.jquery.com
*/
(function ($) {

    $.fn.slideShow = function (options) {

        // multiple elements
        if (this.length > 1) {
            this.each(function () { $(this).slideShow(options) });
            return this;
        }

        // private vars
        this.defaults = {
            start: 0, 	// start index, set to 'random' or 'rnd' to random start
            interval: 3, // interval, autoplay, set to false for no auto-play, in seconds
            repeat: true, // repeat at the end
            transition: {
                mode: 'fade',
                speed: 1000
            },
            slideSize: 'auto', // size for slides (used for mouseover and stuff)
            hoverNavigation: false, // enable mouse to change images 
            slideClick: false, // insert callback method for slide clicks
            gotoSlide: false, 	// slide change callback
            mousePause: false 	// set to true to stop animation on mouse hover
        };
        this.options = $.extend({}, this.defaults, options);

        // internal vars
        this.numSlides = this.find('.Slide').length;
        if (this.options.start == 'random' || this.options.start == 'rnd') {
            this.current = Math.floor(Math.random() * this.numSlides) + 1;
        } else {
            this.current = this.options.start;
        }
        if (this.current >= this.numSlides) {
            this.current = this.numSlides - 1;
        }
        this.last = false;
        this.elm = $(this);
        this.interval = false;
        this.mouse = {
            x: 0, 	// store mouse x relative position on element
            y: 0, 	// store mouse y relative position on element
            over: false	// store mouse over Boolean value
        };

        // init slideshow
        this.init = function () {

            // set slide container to correct width and height
            if (this.find('.Slides').length) {
                // auto-detect slide size
                if (this.options.slideSize == 'auto') {
                    this.options.slideSize = {
                        // AO ------------------------------------------
                        width: this.find('.Slide:first').width(),
                        height: this.find('.Slide:first').height()
                        // ---------------------------------------------
                        //width: this.find('.Slide:first img').width(),
                        //height: this.find('.Slide:first img').height()
                        // ---------------------------------------------
                    };
                }

                // don't set size of slides and slide container if not needed
                if (this.options.slideSize != 'none' && this.options.slideSize != false) {
                    this.find('.Slides').css({
                        height: this.options.slideSize.height + 'px',
                        width: this.options.slideSize.width + 'px',
                        overflow: 'hidden'
                    });
                }
            }

            // set slides to be positioned absolute
            this.find('.Slide').css('position', 'absolute');

            // hide slides if not hidden already
            this.find('.Slide:not(:eq(' + this.current + '))').hide();

            // navigation shortcuts
            this.find('.first, .next, .prev, .last, .navigation, .Slide, .page, .Slides').data('SlideShow', this);
            this.find('.first').click(this.first);
            this.find('.next').click(this.next);
            this.find('.prev').click(this.previous);
            this.find('.last').click(this.last);

            // init pagination buttons if available
            this.find('.navigation .page:eq(' + this.current + ')').addClass('selected');
            this.find('.page').click(function (e) {
                if (!(slideShow = $(this).data('SlideShow'))) {
                    var slideShow = this;
                }
                // determine position in navigation
                var index = $(this).html();
                if (!(index = parseInt($(this).html() - 1))) {
                    var index = $(this).parents('.navigation').find('.page').index($(this));
                }
                e.preventDefault();
                slideShow.gotoSlide(index);
            });

            // init mouse move handler
            this.find('.Slide').mousemove(function (event) {
                var slideShow = $(this).data('SlideShow');
                // calculate mouse relative position and store it
                slideShow.mouse.x = Math.abs(event.clientX - $(this).position().left);
                slideShow.mouse.y = Math.abs(event.clientY - $(this).position().top);
                if (slideShow.mouse.x > slideShow.options.slideSize.width) slideShow.mouse.x = slideShow.options.slideSize.width;
                if (slideShow.mouse.y > slideShow.options.slideSize.height) slideShow.mouse.y = slideShow.options.slideSize.height;
                // use mouse for navigation, calculate new page from mouse position
                if (slideShow.options.hoverNavigation) {
                    var index = Math.round((slideShow.numSlides - 1) * slideShow.mouse.x / slideShow.options.slideSize.width);
                    slideShow.gotoSlide(index, true);
                }
            });

            // mouse enter handler
            this.find('.Slide').mouseenter(function () {
                var slideShow = $(this).data('SlideShow');
                slideShow.mouse.over = true;
                if (slideShow.options.mousePause) { // added conditional for mouse pausing animation
                    slideShow.stopAuto();
                }
            });

            // mouse leave handler
            this.find('.Slide').mouseleave(function () {
                var slideShow = $(this).data('SlideShow');
                slideShow.mouse.over = false;
                slideShow.auto();
            });

            // on click handler
            if (typeof (this.options.slideClick) == 'function') {
                this.find('.Slide').click(function () {
                    var slideShow = $(this).data('SlideShow');
                    slideShow.options.slideClick(slideShow);
                });
            }

            var g = this.current;
            this.current = -1;
            this.gotoSlide(g);
            // start interval for auto animation
            if (this.options.interval > 0) {
                this.auto();
            }
            return this;
        };

        // public methods
        this.auto = function () {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            if (!slideShow.interval && slideShow.options.interval > 0.001) {
                slideShow.interval = window.setInterval(function () {
                    slideShow.next();
                }, slideShow.options.interval * 1000);
            }
            return this;
        }
        // check if slideshow is running
        this.isPlaying = function () {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            return slideShow.interval;
        }
        // stop/play slideshow automatic 
        this.togglePlayback = function () {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            if (slideShow.isPlaying()) {
                slideShow.stopAuto();
            } else {
                slideShow.auto();
            }
        },
        // stop automatic slideshow
		this.stopAuto = function () {
		    if (!(slideShow = $(this).data('SlideShow'))) {
		        var slideShow = this;
		    }
		    if (slideShow.interval) {
		        window.clearInterval(slideShow.interval);
		        slideShow.interval = false;
		    }
		    return this;
		}
        // goto first slide
        this.first = function (elm) {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            return slideShow.gotoSlide(0);
        };
        // goto last slide
        this.next = function () {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            return slideShow.gotoSlide(slideShow.current + 1);
        };
        this.previous = function () {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            return slideShow.gotoSlide(slideShow.current - 1);
        };
        this.last = function () {
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }
            return slideShow.gotoSlide(slideShow.numSlides);
        };
        this.gotoSlide = function (index, noanimation) {
            if (index < 0) {
                index = this.numSlides - 1;
            }
            if (index >= this.numSlides) {
                index = 0;
            }
            if (index === this.current) return this;
            // get slide elements
            var oldSlide = this.find('.Slide:eq(' + this.current + ')');
            var newSlide = this.find('.Slide:eq(' + index + ')');

            // -------------------------------------------------------------------------------
            // AO - Scale images before display
            // -------------------------------------------------------------------------------
            var image = newSlide.children("img").first();
            ScaleImage(image, this.options.slideSize.width, this.options.slideSize.height);
            // -------------------------------------------------------------------------------

            // callbacks for animation finished
            var oldFinished = function () {
                $(this).removeClass('selected');
                if (!(slideShow = $(this).data('SlideShow'))) {
                    var slideShow = this;
                }
                slideShow.elm.find('.navigation .page:eq(' + slideShow.current + ')').addClass('selected');
                if (!slideShow.mouse.over) {
                    slideShow.auto();
                }
            }
            var newFinished = function () {
                if (!(slideShow = $(this).data('SlideShow'))) {
                    var slideShow = this;
                }
                if (slideShow.current >= 0) {
                    slideShow.elm.find('.navigation .page:not(:eq(' + slideShow.current + '))').removeClass('selected');
                }
                $(this).addClass('selected');
            }
            // get slideshow
            if (!(slideShow = $(this).data('SlideShow'))) {
                var slideShow = this;
            }

            // NOTE
            //slideShow.stopAuto();

            // call callback
            if (typeof (this.options.gotoSlide) == 'function') {
                this.options.gotoSlide(slideShow, index);
            }
            // start transition
            if (noanimation) {
                oldSlide.hide(1, oldFinished);
                newSlide.show(1, newFinished);
            } else {
                if (typeof (this.options.transition.mode) == 'function') {
                    this.call(this.options.transition.mode, newSlide, oldSlide);
                } else {
                    switch (this.options.transition.mode) {
                        default:
                        case 'fade':
                            oldSlide.fadeOut(this.options.transition.speed, oldFinished);
                            newSlide.fadeIn(this.options.transition.speed, newFinished);
                            break;
                        case 'slide': // added by charles kline - ckline@discmakers.com
                            if (this.current == -1) {
                                oldSlide.hide(0, oldFinished);
                                newSlide.show();
                            } else {
                                oldSlide.animate({}, {});
                                oldSlide.animate({ width: 'hide' }, this.options.transition.speed, oldFinished);
                                newSlide.animate({ width: 'show' }, this.options.transition.speed, newFinished);
                            }
                            break;
                    }
                }
            }
            // alter height of slides to new slide height
            this.find('.slides').animate({
                height: newSlide.height()
            });

            this.last = this.current;
            this.current = index;
            return this;
        };

        function ScaleImage(image, boundWidth, boundHeight) {

            var imgHeight = image[0].height;
            var imgWidth = image[0].width;

            var debugMessage = "Image Size = W: " + imgWidth + "px; H: " + imgHeight + "px;"

            // Scale image only if it goes out of bounds
            if (imgWidth == 0 && imgWidth == 0 || imgHeight - boundHeight > 0 || imgWidth - boundWidth > 0) {

                Sys.Debug.trace(debugMessage + " | Scale operation performed");

                var boundingShape = GetShape(boundWidth, boundHeight);
                var imageShape = GetShape(imgWidth, imgHeight);

                if (boundingShape == 'w' && imageShape == 'w')
                    ComputeScaleThenResize();
                else if (boundingShape == 'w' && imageShape == 't')
                    ReiszeImage('w');
                else if (boundingShape == 'w' && imageShape == 's')
                    ReiszeImage('w');
                else if (boundingShape == 't' && imageShape == 'w')
                    ReiszeImage('w');
                else if (boundingShape == 't' && imageShape == 't')
                    ComputeScaleThenResize();
                else if (boundingShape == 't' && imageShape == 's')
                    ReiszeImage('t');
                else if (boundingShape == 's' && imageShape == 'w')
                    ReiszeImage('t');
                else if (boundingShape == 's' && imageShape == 't')
                    ReiszeImage('w');
                else if (boundingShape == 's' && imageShape == 's')
                    ReiszeImage('w');
            }
            else {
                Sys.Debug.trace(debugMessage);
            }

            function GetShape(width, height) {
                if (width > height)
                    return 'w'; // wide
                else if (width < height)
                    return 't'; // tall
                else if (width == height)
                    return 's'; // square
            }

            function ReiszeImage(scale) {
                switch (scale) {
                    case 't':
                        image.attr('width', boundWidth);
                        break;
                    case 'w':
                        image.attr('height', boundHeight);
                        break;
                }
            }

            function ComputeScaleThenResize() {
                if ((imgWidth * boundHeight / imgWidth) >= boundWidth)
                    ReiszeImage('t');
                else
                    ReiszeImage('w');
            }
        }

        return this.init();
    }

})(jQuery);
