/* Copyright (c) 2008 Kean Loong Tan http://www.gimiti.com/kltan
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * jFlow
 * Version: 1.1 (May 22, 2008)
 * Requires: jQuery 1.2+
 */
 
(function($) {
    var methods = {
        _transition : function(data) 
        {
            if (data.needScroll) {
                var margin = 0;
                if (data.cur >= data.navSlots) {
                    margin = (1 + data.cur - data.navSlots) * data.navHeight;
                }
                data.nav.animate({
                    marginTop: "-" + margin + "px"
                }, data.opts.navDuration, function(){
                    if (data.opts.navigationDidEnd) {
                        data.opts.navigationDidEnd($(".jFlowControl").eq(data.cur), $(".jFlowControl").eq(data.prev));
                    }
                })
            }
            if (data.opts.transitionDidEnd) {
                data.opts.transitionDidEnd($("#jFlowSlide"));
            }
            /* If current nav has a valid selector as title, clone the target element and use as caption */
            if (data.opts.caption) {
                var selector = $(".jFlowSlideContainer:eq(" + data.cur + ")").find(":first-child").attr('title');
                if (selector && selector != '') {
                    $(data.opts.caption).empty().append($(selector).clone().fadeIn());
                    var sliderCaptionHeight = $("#sliderCaption").height();
                    var captionHeight = $("#sliderCaption").find(":first-child").height();
                    /* adjust vertical position */
                    /* FIXME: how to do this with CSS only? */
                    $("#sliderCaption").find(":first-child").css({marginTop:(sliderCaptionHeight-captionHeight)/2});
                    if (data.opts.captionDidAppear) {
                        data.opts.captionDidAppear($("#sliderCaption").find(":first-child"));
                    }
                }
            }
        }
    }
	$.fn.jFlow = function(options) {
        var flag = false;
        var data = {};
        data.cur = 0;
        data.prev = -1;
		data.opts = $.extend({}, $.fn.jFlow.defaults, options);
		data.maxi = $(".jFlowControl").length;
        data.nav = this;
        /* assume all elements have equal height */
        data.navHeight = $(".jFlowControl:eq(0)").height();
        data.navSlots = Math.floor(this.height() / data.navHeight);
        data.needScroll = (data.maxi * data.navHeight) > this.height();
		$(this).find(".jFlowControl").each(function(i){
			$(this).click(function(){
				$(".jFlowControl").removeClass("jFlowSelected");
				$(this).addClass("jFlowSelected");
				var dur = Math.abs(data.cur-i);
				$(data.opts.slides).animate({
					marginLeft: "-" + (i * $(data.opts.slides).find(":first-child").width() + "px")
				}, data.opts.duration*(dur), function(){methods._transition(data)});
                data.prev = data.cur;
				data.cur = i;
			});
		});	
		
		$(data.opts.slides).before('<div id="jFlowSlide"></div>').appendTo("#jFlowSlide");
		
		$(data.opts.slides).find("div").each(function(){
			$(this).before('<div class="jFlowSlideContainer"></div>').appendTo($(this).prev());
		});
		
		//initialize the controller
		$(".jFlowControl").eq(data.cur).addClass("jFlowSelected");
		
		var resize = function (x){
			$("#jFlowSlide").css({
				position:"relative",
				width: data.opts.width,
				height: data.opts.height,
				overflow: "hidden"
			});
		
			$(data.opts.slides).css({
				position:"relative",
				width: $("#jFlowSlide").width()*$(".jFlowControl").length+"px",
				height: $("#jFlowSlide").height()+"px",
				overflow: "hidden"
			});
		
			$(data.opts.slides).children().css({
				position:"relative",
				width: $("#jFlowSlide").width()+"px",
				height: $("#jFlowSlide").height()+"px",
				"float":"left"
			});
			
			$(data.opts.slides).css({
				marginLeft: "-" + (data.cur * $(data.opts.slides).find(":first-child").width() + "px")
			});
		}
		
		resize();
		
		$(window).resize(function(){
			resize();						  
		});
		
		$(".jFlowPrev").click(function(){
            data.prev = data.cur;
			if (data.cur > 0) {
				data.cur--;
            } else {
				data.cur = data.maxi -1;
            }	
			$(".jFlowControl").removeClass("jFlowSelected");
			$(data.opts.slides).animate(
                {
                    marginLeft: "-" + (data.cur * $(data.opts.slides).find(":first-child").width() + "px")
                }, data.opts.duration, function(){methods._transition(data)});
			$(".jFlowControl").eq(data.cur).addClass("jFlowSelected");
		});
		
		$(".jFlowNext").click(function(){
            data.prev = data.cur;
			if (data.cur < data.maxi - 1) {
				data.cur++;
            }
			else {
				data.cur = 0;
            }    
			$(".jFlowControl").removeClass("jFlowSelected");
			$(data.opts.slides).animate(
                {
                    marginLeft: "-" + (data.cur * $(data.opts.slides).find(":first-child").width() + "px")
                }, data.opts.duration, function(){methods._transition(data)});
			$(".jFlowControl").eq(data.cur).addClass("jFlowSelected");
		});
        /* show/hide prev and next elements */
        $(".jFlowPrev").css({cursor:"pointer"});
        $(".jFlowNext").css({cursor:"pointer"});
        this.mouseenter(event, function(){
			if (data.opts.userDidInteracted) {
				data.opts.userDidInteracted();
			}
            if ($(event.relatedTarget).hasClass("jFlowNext") || $(event.relatedTarget).hasClass("jFlowPrev")) {
                return;
            }
            $(".jFlowPrev").fadeIn();
            $(".jFlowNext").fadeIn();
        }).mouseleave(event, function(){
            if ($(event.relatedTarget).hasClass("jFlowNext") || $(event.relatedTarget).hasClass("jFlowPrev")) {
                return;
            }
            $(".jFlowPrev").fadeOut();
            $(".jFlowNext").fadeOut();
        });
        /* wrap controls to allow scrolling */
        $(".jFlowControl").css({cursor:"pointer"});
        this.wrap("<div id='jFlowNav'/>");
        $("#jFlowNav").css({
            overflow: 'hidden',
            position: this.css('position'),
            top: this.css('top'),
            left: this.css('left'),
            width: this.css('width'),
            height: this.css('height')
        });
        this.css({
            overflow: '',
            position: 'relative',
            top: '0px',
            left: '0px',
            height: (data.maxi * data.navHeight) + 'px'
        });
        $(".jFlowPrev").appendTo("#jFlowNav");
        $(".jFlowNext").appendTo("#jFlowNav");
        this.data('jFlow', data);
        methods._transition(data);
	};
	
	$.fn.jFlow.defaults = {
		easing: "swing",
        caption: null,
		duration: 400,
        navDuration: 200,
		width: "100%",
	};
})(jQuery);

