/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
(function($){
    $.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 timer

    $.extend({
        timer: {
            guid: 1,
            global: {},
            regex: /^([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 = parseInt(result[1], 10);
                    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;

                if (!element.$timers)
                    element.$timers = {};

                if (!element.$timers[label])
                    element.$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 (!element.$timers[label][fn.$timerID])
                    element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);

                if ( !this.global[label] )
                    this.global[label] = [];
                this.global[label].push( element );

            },
            remove: function(element, label, fn) {
                var timers = element.$timers, 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 )
                        element.$timers = null;
                }
            }
        }
    });
})(jQuery);

ThumbSlider = function(options){
    //CONSTANTS
    var evntNameSpace = "thumbslider";
    
    //PRIVATE VARIABLES
    var $Context;
    var $Slides;
    var $SelSlideFrame;
    var $SlideContainer
    var nCurSelSlide;
    var _this = this;
    
    //PRIVATE FUNCTIONS
    var init;
    var startAuto;
    var stopAuto;
    
    init = function(){
        options = $.extend({},ThumbSlider.defOptions, options);
        $Context = options.$Context;
        if(!$Context){
            return;
        }
        $Context.css({
            overflow: "hidden",
            position: "relative"
        });
        $Slides = $Context.children();        
        $Slides.css({
            //            display: 'inline-block',
            'float': 'left' 
        });
        
        $SlideContainer = $("<div/>").addClass(options.sSlideContainerClass).css({
            position: "relative"
        });
        $SlideContainer.appendTo($Context);               
        $SlideContainer.append($Slides.detach());
        $SlideContainer.append('<div style="clear:both;"></div>');
        
        if(options.sSelectedSlideFrame){
            $Slides = $Slides.filter(":not(" + options.sSelectedSlideFrame +")");
            $SelSlideFrame = $(options.sSelectedSlideFrame, $Context);            
            $SelSlideFrame.css({
                'position': 'absolute'
            });
        }

//        $Context.hover(stopAuto, startAuto);
//        
//        $Slides.click(function(){
//            stopAuto();
//            _this.select($(this).index());
//            startAuto();
//        });
        
               
        if(options.onSelect){
            _this.onSelect(options.onSelect);
        }
        
        _this.select(options.nInitSelSlide);
        if(options.bAuto){
            startAuto();
        }

    };
    
    startAuto = function(){
        if(options.bAuto){
            $Context.everyTime(options.nAutoInterval, "auto", _this.next);
        }
    };
    
    stopAuto = function(){
        $Context.stopTime("auto");
    };
    
    //PUBLIC FUNCTIONS
    this.select = function(slide){
        var $Slide;
        if(typeof slide == "number"){
            $Slide = $Slides.eq(slide);
        }else if(typeof slide == "string"){
            $Slide = $Slides.find("#"+slide);
        }
        nCurSelSlide = $Slide.index();        
        if($SelSlideFrame){
            //            $SelSlideFrame.css("left", ($Slide.position().left) + 'px');            
            $SelSlideFrame.animate({
                left: ($Slide.position().left) + 'px'
            }, options.nAnimationTime, "");
        }
        $Context.trigger("select." +evntNameSpace, nCurSelSlide);
    };
    
    this.next = function(){
        var index = nCurSelSlide + 1;
        if(index >= $Slides.length){
            index = 0;
        }
        _this.select(index);
    };
    
    this.prev = function(){
        var index = nCurSelSlide - 1;
        if(index < 0){
            index = $Slides.length - 1;
        }
        _this.select(index);
    };
    
    this.onSelect = function(fnCallback){
        $Context.bind("select."+evntNameSpace, fnCallback);
    };

    this.stopAuto = function(){
        stopAuto();
    };

    this.startAuto = function(){
        startAuto();
    }
    
    init();
    
};

ThumbSlider.defOptions = {
    sSelectedSlideClass : "active",
    nInitSelSlide: 0,
    sSlideContainerClass: "slideContainer",
    bAuto: false,
    nAutoInterval: 4000
};

ProgressBar = function($Context){
    var _this = this;
    var init;
    
    init = function(){
        $Context.addClass("ajax-loader");
    };
    
    this.show = function(){        
        $Context.show();
    };
    
    this.hide = function(){
        $Context.hide();
    };
    
    
    this.reposition = function(){
    };
    
    init();
};


FadeSlideshow = function(settings){
    //constants
    var activeClass="active";    
    //private variables
    var $target;
    var $slides;
    var nCurIndex;
    var _this=this;
    var nContainerWidth;
    var nContainerHeight;
    
    var oProgressBar;
    
    //private functions
    var init;
    var findPositionAndSizeOfImage;
    var setImageSizeAndPosition;
    var startAuto;
    var stopAuto;

    var defaultSettings={
        nAnimationTime:1000,
        defSelectedIndex: 0,
        imgPlaceHolder: "a.placeHolder",
        bAuto: true,
        nAutoInterval: 4500
        
    }


    init=function(){
        settings=$.extend(defaultSettings,settings);
        $target = settings.$target;        
        $target.css({
            "overflow":"hidden",
            "position":"relative"
        });
        
        nContainerWidth = $target.width();
        nContainerHeight = $target.height();

        $slides=$target.children().css({
            "position":"absolute",
            "zIndex":"0",            
            "top": "0px",
            "left": "0px",
            "width": "100%",
            "height": "100%",
            "display": "none"
        });
        
        var $progressBar  = $("<div/>").attr('class', "dwProgressBar");
        $target.append($progressBar);
        oProgressBar = new ProgressBar($progressBar);
        if(settings.bAuto){
            startAuto();
        }

    }
    
    startAuto = function(){
        if(settings.bAuto){
            $target.everyTime(settings.nAutoInterval, "auto", _this.next);
        }
    };
    
    stopAuto = function(){
        $target.stopTime("auto");
    };
    
    
    findPositionAndSizeOfImage = function(nImgWidth, nImgHeight){
        var r=new Object();
        var imgRatio = nImgWidth/nImgHeight;
        var containerRatio = nContainerWidth/nContainerHeight;
        if(containerRatio > imgRatio){
            r.width = nContainerWidth;
            r.height = r.width/imgRatio;
        }else{
            r.height = nContainerHeight;            
            r.width = r.height*imgRatio;
        }
        //        r.top  = (nContainerHeight - r.height)/2;
        //        r.left  = (nContainerWidth - r.width)/2;
        r.top = 0;
        r.left = 0;
       
        return r;
    };
    
    
    setImageSizeAndPosition = function($Slide){
        $Slide.css({
            'visibility':'hidden',
            'display': 'block'
        });
        var $img = $Slide.find("img");
        $img.css({
            width: "auto",
            height: "auto"
        });
        var nImgWidth = $img.width();
        var nImgHeight = $img.height();
        var oPosSize = findPositionAndSizeOfImage(nImgWidth, nImgHeight);
        $img.css({
            width: oPosSize.width + "px",
            height: oPosSize.height + "px",
            top: oPosSize.top + "px",
            left: oPosSize.left + "px",
            position: "relative"
        });
        $Slide.css("visibility","visible");
    };
    

    this.goToSlide = function(ind){
        if(ind >= $slides.length){
            return;
        }
        nCurIndex = ind;
        var fadeIn = function($Slide){
            setImageSizeAndPosition($Slide);
            $slides.filter("."+activeClass).css('display','none');            
            $Slide.addClass(activeClass).css({
                "display":"none",
                "zIndex":"1"
            }); 
            oProgressBar.hide();
            $Slide.fadeIn(settings.nAnimationTime);
        }
        var secondAnimation = function(){
            var $CurSlide = $($slides[ind]);
            var $img = $CurSlide.find("img");
            if($img.length > 0){
                fadeIn($CurSlide);
                return;
            }
            oProgressBar.show();
            var $A =$CurSlide.find(settings.imgPlaceHolder);
            var sImgSrc = $A.attr('href');
            //$img = $("<img/>").attr('src',sImgSrc).attr('alt', sImgSrc);
            $img = $("<img/>").attr('src',sImgSrc).attr('alt', '');
            $A.replaceWith($img);
            preloadImg($img, function(){                
                fadeIn($CurSlide);
            });
        };
        
        var $ActiveSlides = $slides.filter("."+activeClass).removeClass(activeClass).css("z-index","1");
        if($ActiveSlides.length > 0){            
            $ActiveSlides.fadeOut(settings.nAnimationTime);
            secondAnimation();
        }else{            
            secondAnimation();
        }
    };

    this.prev = function(){
        nCurIndex=(nCurIndex==0)?$slides.length-1:nCurIndex-1;
        _this.goToSlide(nCurIndex);
    };

    this.next = function(){
        nCurIndex=(nCurIndex==$slides.length-1)?0:nCurIndex+1;
        _this.goToSlide(nCurIndex);
    };
    
    this.updateImagePositions = function(){
        oProgressBar.reposition();
        nContainerWidth = $target.width();
        nContainerHeight = $target.height();        
        var $CurSlide = $($slides[nCurIndex]);
        setImageSizeAndPosition($CurSlide);
    };
    
    this.stopAuto = function(){
        stopAuto();
    };

    this.startAuto = function(){
        startAuto();
    }
    

    init();

};

preloadImg = function($imgObj,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;
    $imgObj.each(function(){
        var src = $(this).attr('src');
        if(src != undefined && src != null){
            imgArray[counter++] = src;
        }
    });
    loadImages(imgArray, callback);
};

DWSlider = function($Context){
    //private variables
    var oCSSClasses = {
        sSlider: "main",
        sNavigator: "navigator"
    }
    
    //private functions
    var init;

    init = function(){
        var $Slider = $Context.find("." + oCSSClasses.sSlider);
        var $Navigator = $Context.find("." + oCSSClasses.sNavigator);
        $Slider.find("img").each(function(ind){
            var $this = $(this);
//            $this.attr('src','images/'+(ind+12) +".jpg");
            var $imgPlaceHolder = $("<a/>");
            $imgPlaceHolder.addClass("placeHolder");
            $imgPlaceHolder.attr('href', $this.attr('src'));
            $this.replaceWith($imgPlaceHolder);
        });
        var simpleSlider = new FadeSlideshow({
            $target: $Slider,
            nAnimationTime: 750
        });
        
        var navigator = new ThumbSlider({
            $Context: $Navigator,
            sSelectedSlideFrame: ".frame",
            nAnimationTime: 750,
            onSelect: function(e, index){
                simpleSlider.goToSlide(index);
            }
        });

        $Slider.hover(navigator.stopAuto, navigator.startAuto);
    };
    
    init();
};

$.fn.dwSlider = function(){
    var $Context = $(this);
    new DWSlider($Context);
    return $Context;
};



