/*
	Display c in a carousel format - auto scrolling only
	Example (option parameters are optional):
	new Carousel('more-c', { number:3, duration:5000, selector:'.tip-container', direction:'horizontal'});
*/

var Carousel = function (container,opts) {
  opts = opts || {};
	var selector = opts.selector || '.item';
  var number = opts.number || 3;
  var rotationTime = opts.duration || 5000;
	var direction = opts.direction || 'vertical';
  
  var startIndex = 0, endIndex = 0;
  var list = container.select(selector);
  var hiddenFragment = document.createDocumentFragment();
  var clippingContainer = new Element('div');		// mask out the items
  var holderContainer = new Element('div');			// hold lists of active/inactive c
  var oMargin = 0;

  if (list.length<=0) {
		if (console) console.log('The carousel must have at least one item');
		return;
	}

  // pre-process - creating and inserting two holding divs
  container.insert(clippingContainer);
  clippingContainer.setStyle({overflow:'hidden'}).insert(holderContainer);

	// prepare elements
	if (direction == 'horizontal') {
		var totalWidth = 0;
		list.each(function(o) {
			o.setStyle({'float':'left'});
			totalWidth+=o.getWidth()+parseFloat(o.getStyle('margin-left'))+parseFloat(o.getStyle('margin-right')); 
		});
		holderContainer.setStyle({'width':totalWidth+'px'});
		oMargin = parseInt(list[0].getStyle('margin-left'));
	} else {
    var totalHeight = 0;
		for (var i=0;i<number;i++){
      totalHeight += list[i].getHeight();
    }
	  oMargin = parseInt(list[0].getStyle('margin-top'));
    clippingContainer.setStyle({'height':totalHeight+'px'});
	}
	
	// ----------------------------------------------------------------------------------
  // Private Methods
  var showC = function(){
    if (list.length<=number) return;	// don't rotate if there are enough items
  
    var visibleList = list.findAll(function(e){ return e.visible(); });

    // show the first five
    if (holderContainer.childElements().length==0) { 
      startIndex = 0; endIndex = number-1;
      // if first time, insert everything
      list.each(function(e,i) { hiddenFragment.appendChild(e); });
      list.slice(startIndex,endIndex+1).each(function(e,i) { holderContainer.insert(e); });
	   	return;	// exit
    } else if (endIndex+1 >= list.length) {
      endIndex = 0;
    } else {
      endIndex += 1;
    }
    
    // remove the first item in the visible list and insert another one
    var oldItem = holderContainer.down(0);
    var newItem = list[endIndex];
    
    // reveal animation
		var margin = (direction=='horizontal'?'margin-left':'margin-top');
		var dist = (direction=='horizontal'?oldItem.getWidth():oldItem.getHeight());
		
    new Effect.Morph(oldItem, {style:margin+':'+-dist+'px', duration:0.6, 
      beforeStart:function(){ 
        var h=0, beforeStyle={};
				beforeStyle[margin.camelize()] = oMargin+'px';
        newItem.setStyle(beforeStyle);
        holderContainer.insert(newItem);
				
				// resize vertically to display longer content

        holderContainer.childElements().slice(1).each(function(e,i) {
          var m = parseInt(e.getStyle('margin-top'));
          h = h==0 ? h + m*2 + e.getHeight() : h + m + e.getHeight();
        });
        
        // reset container
        if (!clippingContainer.hasClassName('resized')) { clippingContainer.addClassName('resized'); }
        new Effect.Morph(clippingContainer, {style:'height:'+h+'px', duration:0.6 }); 
      },
      afterFinish:function(){
        hiddenFragment.appendChild(oldItem); 
      } 
    });
  }
  
  // every interval, show other fives until the end
  var startRotate = function () { return setInterval(showC, rotationTime); }
  
	// ----------------------------------------------------------------------------------
  // Public Methods
	this.start = function() {
	  if (!this.cInterval) { this.cInterval = startRotate(); }
	}
	
	this.stop = function() {
    clearInterval(this.cInterval); 
    this.cInterval = undefined;
	}

	// ----------------------------------------------------------------------------------
  // Event handlers
  // when mouse over container, stop rotating
  container.observe('mouseover', this.start.bindAsEventListener(this));
  
  // resume when mouse out
  container.observe('mouseout', this.stop.bindAsEventListener(this));
  
	// ----------------------------------------------------------------------------------
  // Main
  // show c initially and begin rotation
  this.cInterval = startRotate();
	showC();
};

function limitText(limitField, limitCount, limitNum) {
	if (limitField.value.length > limitNum) {
		limitField.value = limitField.value.substring(0, limitNum);
	} else {
		limitCount.value = limitNum - limitField.value.length;
	}
}
;

