
(function ($) {

  // static constructs
  $.tools = $.tools || { version: '1.2.5' };

  $.tools.scrollable = {

    conf: {
      circular: false,
      clonedClass: 'cloned',
      disabledClass: 'disabled',
      easing: 'swing',
      initialIndex: 0,
      item: null,
      items: '.items',
      keyboard: false,
      mousewheel: false,
      next: '.next',
      prev: '.prev',
      current: '.current',
      total: '.total',
      speed: 400,
      vertical: false,
      touch: false,
      wheelSpeed: 0
    }
  };

  // get hidden element's width or height even though it's hidden
  function dim(el, key) {
    var v = parseInt(el.css(key), 10);
    if (v) { return v; }
    var s = el[0].currentStyle;
    return s && s.width && parseInt(s.width, 10);
  }

  function find(root, query) {
    var el = $(query);
    return el.length < 2 ? el : root.parent().find(query);
  }

  var current;

  // constructor
  function Scrollable(root, conf) {

    // current instance
    var self = this,
			 fire = root.add(self),
			 itemWrap = root.children(),
			 index = 0,
			 vertical = conf.vertical;

    if (!current) { current = self; }
    if (itemWrap.length > 1) { itemWrap = $(conf.items, root); }

    // methods
    $.extend(self, {

      getConf: function () {
        return conf;
      },

      getIndex: function () {
        return index;
      },

      getSize: function () {
        return self.getItems().size();
      },

      getNaviButtons: function () {
        return prev.add(next);
      },

      getRoot: function () {
        return root;
      },

      getItemWrap: function () {
        return itemWrap;
      },

      getItems: function () {
        return itemWrap.children(conf.item).not("." + conf.clonedClass);
      },

      move: function (offset, time) {
        return self.seekTo(index + offset, time);
      },

      next: function (time) {
        return self.move(1, time);
      },

      prev: function (time) {
        return self.move(-1, time);
      },

      begin: function (time) {
        $(conf.total).text(self.getSize());
        return self.seekTo(0, time);
      },

      end: function (time) {
        return self.seekTo(self.getSize() - 1, time);
      },

      focus: function () {
        current = self;
        return self;
      },

      addItem: function (item) {
        item = $(item);

        if (!conf.circular) {
          itemWrap.append(item);
        } else {
          itemWrap.children("." + conf.clonedClass + ":last").before(item);
          itemWrap.children("." + conf.clonedClass + ":first").replaceWith(item.clone().addClass(conf.clonedClass));
        }

        fire.trigger("onAddItem", [item]);
        return self;
      },


      /* all seeking functions depend on this */
      seekTo: function (i, time, fn) {

        // ensure numeric index
        if (!i.jquery) { i *= 1; }

        // check that index is sane				
        if (!conf.circular && i < 0 || i > self.getSize() || i < -1) { return self; }

        var item = i;

        if (i.jquery) {
          i = self.getItems().index(i);

        } else {
          item = self.getItems().eq(i);
        }

        // onBeforeSeek
        var e = $.Event("onBeforeSeek");
        if (!fn) {
          fire.trigger(e, [i, time]);
          if (e.isDefaultPrevented() || !item.length) { return self; }
        }

        var pageOffset = ($(window).width()) / 2;
        var itemOffset = ($(item).width()) / 2;
        var paddingOffset = 50;//($(window).width()) / 4; /* Meta della distanza fra un immagine e l'altra*/
        var props = vertical ? { top: -item.position().top} : { left: -item.position().left + pageOffset - itemOffset + paddingOffset };

        index = i;
        current = self;
        if (time === undefined) { time = conf.speed; }

        itemWrap.animate(props, time, conf.easing, fn || function () {
          fire.trigger("onSeek", [i]);
        });

		var currentIndex = index + 1;
        if (currentIndex > 0) $(conf.current).text(currentIndex);
		
        return self;
      }

    });

    // callbacks	
    $.each(['onBeforeSeek', 'onSeek', 'onAddItem'], function (i, name) {

      // configuration
      if ($.isFunction(conf[name])) {
        $(self).bind(name, conf[name]);
      }

      self[name] = function (fn) {
        if (fn) { $(self).bind(name, fn); }
        return self;
      };
    });

    // next/prev buttons
    var prev = find(root, conf.prev).click(function () { self.prev(); }),
			 next = find(root, conf.next).click(function () { self.next(); });

    if (!conf.circular && self.getSize() > 1) {

      self.onBeforeSeek(function (e, i) {
        setTimeout(function () {
          if (!e.isDefaultPrevented()) {
            prev.toggleClass(conf.disabledClass, i <= 0);
            next.toggleClass(conf.disabledClass, i >= self.getSize() - 1);
          }
        }, 1);
      });

      if (!conf.initialIndex) {
        prev.addClass(conf.disabledClass);
      }
    }

    // touch event
    if (conf.touch) {
      var touch = {};

      itemWrap[0].ontouchstart = function (e) {
        var t = e.touches[0];
        touch.x = t.clientX;
        touch.y = t.clientY;
      };

      itemWrap[0].ontouchmove = function (e) {

        // only deal with one finger
        if (e.touches.length == 1 && !itemWrap.is(":animated")) {
          var t = e.touches[0],
						 deltaX = touch.x - t.clientX,
						 deltaY = touch.y - t.clientY;

          self[vertical && deltaY > 0 || !vertical && deltaX > 0 ? 'next' : 'prev']();
          e.preventDefault();
        }
      };
    }

    if (conf.keyboard) {

      $(document).bind("keydown.scrollable", function (evt) {

        // skip certain conditions
        if (!conf.keyboard || evt.altKey || evt.ctrlKey || $(evt.target).is(":input")) { return; }

        // does this instance have focus?
        if (conf.keyboard != 'static' && current != self) { return; }

        var key = evt.keyCode;

        if (vertical && (key == 38 || key == 40)) {
          self.move(key == 38 ? -1 : 1);
          return evt.preventDefault();
        }

        if (!vertical && (key == 37 || key == 39)) {
          self.move(key == 37 ? -1 : 1);
          return evt.preventDefault();
        }

      });
    }

    // initial index
    if (conf.initialIndex) {
      self.seekTo(conf.initialIndex, 0, function () { });
    }
  }


  // jQuery plugin implementation
  $.fn.scrollable = function (conf) {

    // already constructed --> return API
    var el = this.data("scrollable");
    if (el) { return el; }

    conf = $.extend({}, $.tools.scrollable.conf, conf);

    this.each(function () {
      el = new Scrollable($(this), conf);
      $(this).data("scrollable", el);
    });

    return conf.api ? el : this;

  };


})(jQuery);

/**
 * @license 
 * jQuery Tools @VERSION / Scrollable Autoscroll
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/scrollable/autoscroll.html
 *
 * Since: September 2009
 * Date: @DATE 
 */
(function($) {		

	var t = $.tools.scrollable; 
	
	t.autoscroll = {
		
		conf: {
			autoplay: false,
			interval: 3000,
			autopause: false
		}
	};	
	
	// jQuery plugin implementation
	$.fn.autoscroll = function(conf) { 

		if (typeof conf == 'number') {
			conf = {interval: conf};	
		}
		
		var opts = $.extend({}, t.autoscroll.conf, conf), ret;
		
		this.each(function() {		
				
			var api = $(this).data("scrollable");			
			if (api) { ret = api; }
			
			// interval stuff
			var timer, stopped = true;
	
			api.play = function() { 
				
				// do not start additional timer if already exists
				if (timer) { return; }
				
				stopped = false;
				
				// construct new timer
				timer = setInterval(function() { 
					api.next();				
				}, opts.interval);
				
			};	

			api.pause = function() {
				timer = clearInterval(timer);
			};
			
			// when stopped - mouseover won't restart 
			api.stop = function() {
				api.pause();
				stopped = true;	
			};
		
			/* when mouse enters, autoscroll stops */
			if (opts.autopause) {
				api.getRoot().add(api.getNaviButtons()).hover(api.pause, api.play);
			}
			
			if (opts.autoplay) {
				api.play();				
			}

		});
		
		return opts.api ? ret : this;
		
	}; 
	
})(jQuery);		

