/*********************************************************************
  Copyright 2006-2009 .
  
  Auteur : Boudchicha naime -- WWW.NEW6TM.COM
           Manager@new6tm.com
***********************************************************************/
NEW6TM.UI.Iterator = Class.create(NEW6TM.UI.Options, {
  options: {
    direction               : "horizontal",
    previousButton          : ".previous_button",
    nextButton              : ".next_button",
    container               : ".container",
    scrollInc               : "auto",
    disabledButtonSuffix : '_disabled',
    overButtonSuffix : '_over'
  },
  initialize: function(element, options) {
    this.setOptions(options);
    this.element = $(element);
    this.id = this.element.id;
	this.Diveffect   = this.element.down(this.options.container);
    this.container   = this.element.down(this.options.container).firstDescendant();
    this.elements    = this.container.childElements();
    this.previousButton = this.options.previousButton == false ? null : this.element.down(this.options.previousButton);
    this.nextButton = this.options.nextButton == false ? null : this.element.down(this.options.nextButton);
	
    this.posAttribute = (this.options.direction == "horizontal" ? "left" : "top");
    this.dimAttribute = (this.options.direction == "horizontal" ? "width" : "height");
      
    this.elementSize = this.computeElementSize();
	//alert(this.elementSize);
    this.nbVisible = this.currentSize() / this.elementSize;
    
    var scrollInc = this.options.scrollInc;
    if (scrollInc == "auto")
      scrollInc = Math.floor(this.nbVisible);
	if (this.nextButton) {
    [ this.previousButton, this.nextButton ].each(function(button) {
      if (!button) return;
      var className = (button == this.nextButton ? "next_button" : "previous_button") + this.options.overButtonSuffix;
      button.clickHandler = this.scroll.bind(this, (button == this.nextButton ? -1 : 1) * scrollInc * this.elementSize);
      button.observe("click", button.clickHandler)
            .observe("mouseover", function() {button.addClassName(className)}.bind(this))
            .observe("mouseout",  function() {button.removeClassName(className)}.bind(this));
    },this);
    this.updateButtons();}
  },
  destroy: function($super) {
    [ this.previousButton, this.nextButton ].each(function(button) {
      if (!button) return;
        button.stopObserving("click", button.clickHandler);
    }, this);
	  this.element.remove();
	  this.fire('destroyed');
  },
  fire: function(eventName, memo) {
    memo = memo || { };
    memo.carousel = this;
    return this.element.fire('carousel:' + eventName, memo);
  },
  observe: function(eventName, handler) {
    this.element.observe('carousel:' + eventName, handler.bind(this));
    return this;
  },
  stopObserving: function(eventName, handler) {
	  this.element.stopObserving('carousel:' + eventName, handler);
	  return this;
  },
  checkScroll: function(position, updatePosition) {
    if (position > 0)
      position = 0;
    else {
      var limit = this.elements.last().positionedOffset()[this.posAttribute] + this.elementSize;
      var carouselSize = this.currentSize();

      if (position + limit < carouselSize)
        position += carouselSize - (position + limit);
      position = Math.min(position, 0);
    }
    if (updatePosition)
      this.container.style[this.posAttribute] = position + "px";

    return position;
  },
  scroll: function(deltaPixel) {
	 
    if (this.animating)
      return this;
    var position =  this.currentPosition() + deltaPixel;
    position = this.checkScroll(position, false);
	// alert("current position :" + this.currentPosition());
	// alert("delta = " + deltaPixel);
    deltaPixel = position - this.currentPosition();
    if (deltaPixel != 0) {
      this.animating = true;
      this.fire("scroll:started",{position : this.currentPosition()});
      var that = this;
      this.Diveffect.morph("opacity:0.3", {duration: 0.2, afterFinish: function() {
        that.container.morph(that.posAttribute + ": " + position + "px", {
          duration: 0.4,
          delay: 0.2,
          afterFinish: function() {
            that.Diveffect.morph("opacity:1", {
              duration: 0.1,
              afterFinish: function() {
                that.animating = false;
                that.updateButtons()
                  .fire("scroll:ended", { shift: deltaPixel / that.currentSize() });
              }
            });
          }
        });
      }});
    }
    return this;
  },
  scrollTo: function(index) {
    if (this.animating || index < 0 || index > this.elements.length || index == this.currentIndex() || isNaN(parseInt(index)))
      return this;
	  
    return this.scroll((this.currentIndex() - index) * this.elementSize);
  },
  updateButtons: function() {
   if (this.nextButton) {
	  this.updatePreviousButton();
      this.updateNextButton();}
    return this;
  },

  updatePreviousButton: function() {
    var position = this.currentPosition();
    var previousClassName = "previous_button" + this.options.disabledButtonSuffix;

    if (this.previousButton.hasClassName(previousClassName) && position != 0) {
      this.previousButton.removeClassName(previousClassName);
      this.fire('previousButton:enabled');
    }
    if (!this.previousButton.hasClassName(previousClassName) && position == 0) {
	    this.previousButton.addClassName(previousClassName);
      this.fire('previousButton:disabled');
    }
  },

  updateNextButton: function() {
    var lastPosition = this.currentLastPosition();
    var size = this.currentSize();
    var nextClassName = "next_button" + this.options.disabledButtonSuffix;

    if (this.nextButton.hasClassName(nextClassName) && lastPosition != size) {
      this.nextButton.removeClassName(nextClassName);
      this.fire('nextButton:enabled');
    }
    if (!this.nextButton.hasClassName(nextClassName) && lastPosition == size) {
	    this.nextButton.addClassName(nextClassName);
      this.fire('nextButton:disabled');
    }
  },
  computeElementSize: function() {
    return this.elements.first().getDimensions()[this.dimAttribute];
  },
  currentIndex: function() {
    return - this.currentPosition()/this.elementSize;
  },
  currentLastPosition: function() {
    if (this.container.childElements().empty())
      return 0;
    return this.currentPosition() +
           this.elements.last().positionedOffset()[this.posAttribute] +
           this.elementSize;
  },
  currentPosition: function() {
    return this.container.getNumStyle(this.posAttribute);
  },
  currentSize: function() {
    return this.container.parentNode.getDimensions()[this.dimAttribute];
  },
  updateSize: function() {
    this.nbVisible = this.currentSize() / this.elementSize;
    var scrollInc = this.options.scrollInc;
    if (scrollInc == "auto")
      scrollInc = Math.floor(this.nbVisible);

    [ this.previousButton, this.nextButton ].each(function(button) {
      if (!button) return;
      button.stopObserving("click", button.clickHandler);
      button.clickHandler = this.scroll.bind(this, (button == this.nextButton ? -1 : 1) * scrollInc * this.elementSize);
      button.observe("click", button.clickHandler);
    }, this);

    this.checkScroll(this.currentPosition(), true);
    this.updateButtons().fire('sizeUpdated');
    return this;
  }
});

/********************************************************************
     UI Iterator Periodicale
********************************************************************/

NEW6TM.UI.Iterator.Periodicale = Class.create(NEW6TM.UI.Iterator,{
  options : {								
    previousButton          : false,
    nextButton              : false,
	time                    : 6		
  },
  activePe                : true,
  nextPosition            : 0,
  initialize: function($super,element, options) 
    { 
	  $super(element, options);
	  this.time = (options.time ? options.time : this.options.time);
	  var cloneds = options.cloneElement;
	  
	    if (cloneds) {
           this.observe("scroll:started", function() {
					this.elements[this.nextPosition].clonner();
					
		     })};
		  
	   this.elements.each(function(button) { 		  	
		  button.observe("mouseover", function(event) {
							this.activePe = false;
							}.bind(this));
		  button.observe("mouseout", function(event) {
							this.activePe = true;
							}.bind(this));	
		  button = Element.extend(button);
		  if (cloneds) {
          Object.extend(button, {
				elem : cloneds,
			 	clonner : function() {
					 for(el in this.elem) {
					   if (button.down(el))
				         $(this.elem[el]).update(button.down(el).innerHTML);
					 }					  
					}
				 }); 
		  for (el in cloneds) {
             if (button.down(el)) (button.down(el)).hide();
		  }}
		  },this);	      
	 this.Pe = this.periodicalScroll();
	 
    },
  periodicalScroll : function(){
    var gCallCount = this.currentIndex();
	return new PeriodicalExecuter(function(pe){
         if ((this.activePe) && (!this.animating)) {         		 
           if (++gCallCount > this.elements.length - 1)
              gCallCount = 0;  
			 
			  this.nextPosition = gCallCount;
              this.scrollTo(gCallCount);}
         }.bind(this), this.time);
  }
});

/********************************************************************
     UI Image Loader
********************************************************************/
NEW6TM.UI.Iterator.ImageLoader = Class.create(NEW6TM.UI.Iterator,{
	  initialize: function($super,element, options) 
    { 
	  $super(element, options);	  
	}
})


/********************************************************************
     UI Page Loader & Scroller
********************************************************************/
NEW6TM.UI.Iterator.Pager = Class.create(NEW6TM.UI.Iterator,{
	  initialize: function($super,element, options) 
    { 
	  $super(element, options);	  
	}
});

