/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

function SlideShow(xmlurl, target){
    var _this = this;
    var slider;
    var $title;
    var $slides;
    var $slideSelectors;
    var $arrow;
    var curIndex;
    var totalSlides;
    var titles = [];
    var settings;

    var slideWidth=515, slideSpacing = 6, slideHeight = 340;
    ;

    var init, getDOM, readXML;
    init = function(){
        settings.target = target;
        target.html("<h5>Loading...</h5>");
        var $dom = getDOM(settings);
        $slides.find('img').preloadImages(function(){
            settings.target.empty().append($dom);            
            target.css({
                width: $dom.width(),
                height: slideHeight + 66,
                position: "relative"
            });
            target.createCurveContainer();
            _this.select(0);
        });
        slider = new Slider({
            '$slides' : $slides,
            changeListener : _this.select,
            width: slideWidth,
            height: slideHeight,
            slideSpacing: slideSpacing,
            autoplay : settings.autoplay,
            interval: settings.interval
        });
        $slideSelectors.bind('click', function(e){
            var index = $(e.target).index();
            _this.select(index);
            slider.restartTimer();
            slider.goToSlide(index);
        });        
    };

    readXML = function(){
        $.ajax({
            type : "GET",
            url: xmlurl,
            success : function(data){
                var slides = $("images image", data).map(function(){
                    var _this =$(this);
                    return {
                        link : _this.attr('link'),
                        image: _this.attr('name'),
                        title: _this.attr('buttonLabel')
                    };
                }).get();
                settings = {
                    imagesPath : $("settings imagesPath", data).text(),
                    autoplay : $("settings autoplay", data).text().toLowerCase() == "true",
                    viewTime : parseInt($("settings viewTime", data).text()),
                    slides : slides
                }
                init();
            },
            dataType : "xml"
        });
    };

    getDOM = function(settings){
        slideWidth = 515;
        slideSpacing = 6;
        var imgPath = settings.imagesPath;
        var slides = settings.slides;
        $slides = $([]);
        $slideSelectors = $([]);
        for(var i=0; i<slides.length; i++){            
            $slides = $slides.add($('<a href="'+slides[i].link+'" class="slide"><img src="'+imgPath + slides[i].image+'" /></a>'));
            titles[i] = slides[i].title;
            $slideSelectors = $slideSelectors.add($('<div class="slideSelector">'+(i+1)+'</div>'));
        }
        var $container = $('<div style="width:'+(slideWidth+slideSpacing)+'px; position: relative;" class="slideshow">'+
            '<div class="arrow"></div>'+
            '<div class="titleBar"><div class="left"></div><div class="right"></div><div style="clear: both;"></div>'+
            '<div class="content"><div class="title"></div><div style="float: right; margin-right: 10px;" class="slideSelectorContainer"></div>'+
            '<div style="clear: both;"></div></div></div>'
            );
        $title = $(".title", $container);
        $arrow = $(".arrow", $container);
        $container.prepend($slides);
        $(".slideSelectorContainer", $container).append($slideSelectors);
        return $container;
    };

    this.select =  function(index){
        if(curIndex == index || curIndex < 0 || curIndex >= totalSlides){
            return;
        }
        curIndex = index;
        $($slideSelectors.removeClass('sel').get(index)).addClass('sel');
        $arrow.animate({
            left: $($slideSelectors.get(index)).position().left - 3
        });
        $title.html(titles[index]);
    };
    
    readXML();
}


function Slider(settings){
    var width, height, slideSpacing, transitionTime, interval, $slides, autoplay, circular, changeListener;
    var currentSlide, totalSlides, $slideInner, _this = this;
    var $slideContainer;
        
    var init, setVars;
    init = function(){
        setVars();
        $slideContainer = $("<div id='slideContainer'></div>").css({
            'overflow': "hidden",
            'width': width + slideSpacing + 'px',
            'height': height + 'px'
        });
        $($slides.get(0)).before($slideContainer);        
        $slideInner = $('<div id="slideInner"></div>').css({
            'width': (totalSlides*(width+slideSpacing) + slideSpacing) + 'px',
            'height': height + 'px'
        });
        $slideContainer.append($slideInner);
        $slideInner.append($slides);
        var $slide = $("<div></div>").css({
            'float': 'left',
            'width': width + 'px',
            'height' : height + 'px',
            'padding-left': slideSpacing/2 + 'px',
            'padding-right': slideSpacing/2 + 'px',
            'overflow' : 'hidden'
        });
        $slides.wrap($slide);
        _this.restartTimer();
        
    };

    setVars = function(){
        var defaults = {
            slideSpacing : 6,
            transitionTime : 500,
            interval: 5000,
            autoplay: true,
            circular: true
        };
        settings = $.extend(defaults, settings);
        $slides = settings.$slides;
        changeListener = settings.changeListener;
        width = settings.width;
        height = settings.height;
        slideSpacing = settings.slideSpacing;
        transitionTime = settings.transitionTime;
        interval = settings.interval;
        autoplay = settings.autoplay;
        circular = settings.circular;
        
        currentSlide = 0;
        totalSlides = $slides.length;
    }

    this.restartTimer = function(){
        if(autoplay){
            $slideContainer.stopTime('slider');
            $slideContainer.everyTime(interval, "slider", _this.next);
        }
    }

    this.goToSlide = function(index){        
        if(index < 0 || index >= totalSlides){
            return;
        }        
        if(changeListener){
            changeListener(index);
        }
        $slideInner.animate({
            'marginLeft' : (width + slideSpacing)*(-index)
        }, transitionTime);
        currentSlide = index;
    };

    this.prev = function(){
        if(circular && currentSlide == 0){
            _this.last();
        }else{
            _this.goToSlide(currentSlide-1);
        }
    };

    this.next = function(){
        if(circular && currentSlide == totalSlides-1){
            _this.first();            
        }else{
            _this.goToSlide(currentSlide+1);
        }

    };

    this.first = function(){
        _this.goToSlide(0);
    };

    this.last = function(){
        _this.gotToSlide(totalSlides);
    };

    init();
        
}


jQuery.fn.extend({
    everyTime: function(interval, label, fn, times, belay) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, times, belay);
        });
    },
    oneTime: function(interval, label, fn) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, 1);
        });
    },
    stopTime: function(label, fn) {
        return this.each(function() {
            jQuery.timer.remove(this, label, fn);
        });
    }
});

jQuery.event.special

jQuery.extend({
    timer: {
        global: [],
        guid: 1,
        dataKey: "jQuery.timer",
        regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
        powers: {
            // Yeah this is major overkill...
            'ms': 1,
            'cs': 10,
            'ds': 100,
            's': 1000,
            'das': 10000,
            'hs': 100000,
            'ks': 1000000
        },
        timeParse: function(value) {
            if (value == undefined || value == null)
                return null;
            var result = this.regex.exec(jQuery.trim(value.toString()));
            if (result[2]) {
                var num = parseFloat(result[1]);
                var mult = this.powers[result[2]] || 1;
                return num * mult;
            } else {
                return value;
            }
        },
        add: function(element, interval, label, fn, times, belay) {
            var counter = 0;

            if (jQuery.isFunction(label)) {
                if (!times)
                    times = fn;
                fn = label;
                label = interval;
            }

            interval = jQuery.timer.timeParse(interval);

            if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
                return;

            if (times && times.constructor != Number) {
                belay = !!times;
                times = 0;
            }

            times = times || 0;
            belay = belay || false;

            var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});

            if (!timers[label])
                timers[label] = {};

            fn.timerID = fn.timerID || this.guid++;

            var handler = function() {
                if (belay && this.inProgress)
                    return;
                this.inProgress = true;
                if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
                    jQuery.timer.remove(element, label, fn);
                this.inProgress = false;
            };

            handler.timerID = fn.timerID;

            if (!timers[label][fn.timerID])
                timers[label][fn.timerID] = window.setInterval(handler,interval);

            this.global.push( element );

        },
        remove: function(element, label, fn) {
            var timers = jQuery.data(element, this.dataKey), ret;

            if ( timers ) {

                if (!label) {
                    for ( label in timers )
                        this.remove(element, label, fn);
                } else if ( timers[label] ) {
                    if ( fn ) {
                        if ( fn.timerID ) {
                            window.clearInterval(timers[label][fn.timerID]);
                            delete timers[label][fn.timerID];
                        }
                    } else {
                        for ( var fn in timers[label] ) {
                            window.clearInterval(timers[label][fn]);
                            delete timers[label][fn];
                        }
                    }

                    for ( ret in timers[label] ) break;
                    if ( !ret ) {
                        ret = null;
                        delete timers[label];
                    }
                }

                for ( ret in timers ) break;
                if ( !ret )
                    jQuery.removeData(element, this.dataKey);
            }
        }
    }
});

jQuery(window).bind("unload", function() {
    jQuery.each(jQuery.timer.global, function(index, item) {
        jQuery.timer.remove(item);
    });
});


(function($){

    $.fn.preloadImages = function(callback){
        var loadImages = function(imagePaths, callback){
            var img;
            var images = new Array();
            for(var i in imagePaths){
                img = new Image();
                img.src = imagePaths[i]
                images[i] = img;
            }
            var loaded = 0;
            var failed = 0;
            for(i in images){
                if(images[i].complete){
                    loaded ++;
                }else{
                    $(images[i]).load(function(){
                        loaded ++ ;
                        if((loaded + failed) == images.length){
                            callback(failed, loaded);
                        }
                    });
                    $(images[i]).error(function(){
                        failed++;
                        if((loaded + failed) == images.length){
                            callback(failed, loaded);
                        }
                    });
                }
            }
            if((loaded + failed) == images.length){
                callback(failed, loaded);
            }
        };

        var imgArray = new Array();
        var counter = 0;
        this.each(function(){
            var src = $(this).attr('src');
            if(src != undefined && src != null){
                imgArray[counter++] = src;
            }
        });
        loadImages(imgArray, callback);
    };
    
    $.fn.createCurveContainer=function(){
        var curDiv=$(this);
        var width = curDiv.width();
        var height = curDiv.height();
        var container = $("<div/>").addClass('curvedContainer').css({
            width: width,
            height: height
        });
        curDiv.wrap(container);
        container = curDiv.parent();
        container.prepend($("<div/>").addClass('topleft'));
        container.prepend($("<div/>").addClass('top'));
        container.prepend($("<div/>").addClass('topright'));
        container.prepend($("<div/>").addClass('left'));
        container.prepend($("<div/>").addClass('right'));
        container.prepend($("<div/>").addClass('bottomleft'));
        container.prepend($("<div/>").addClass('bottom'));
        container.prepend($("<div/>").addClass('bottomright'));
    };

})(jQuery);
