/**
 * Pod1 Carousel extension
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 *
 *
 * @category   Pod1
 * @package    Pod1_Carousel
 * @extends    PodCore
 * @copyright  Copyright (c) 2010 Pod1 (http://www.pod1.com)
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
 
var Carousel=Class.create(Abstract,{initialize:function(scroller,container,controls,options){this.scrolling=false;this.scroller=$$(scroller)[0];this.container=$$(container)[0];this.controls=$$(controls);this.slides=this.container.childElements();this.options=Object.extend({duration:1,auto:false,frequency:3,visibleSlides:1,controlClassName:'carousel-control',jumperClassName:'carousel-jumper',disabledClassName:'carousel-disabled',selectedClassName:'carousel-selected',circular:false,wheel:true,effect:'scroll',transition:'sinoidal',orientation:'horizontal'},options||{});if(this.options.effect=='fade'){this.options.circular=true;}
if(this.controls){this.controls.invoke('observe','click',this.click.bind(this));}
if(this.options.wheel){this.scroller.observe('mousewheel',this.wheel.bindAsEventListener(this)).observe('DOMMouseScroll',this.wheel.bindAsEventListener(this));;}
if(!this.slides.length){this.scroller.hide();this.controls.invoke('hide');return;}
if(this.slides.length<=this.options.visibleSlides){this.controls.invoke('hide');}
this.addCircularBuffer();this.setDimensions();this.setSlideIndexes();if(this.options.auto){this.start();}
if(this.options.initial){this.slide(this.options.initial);}},setDimensions:function(){var dimensions={width:this.slides.first().getWidth(),height:this.slides.first().getHeight()}
for(var prop in dimensions){var val=dimensions[prop];if(!val){var style=this.slides.first().getStyle(prop);if(style){dimensions[prop]=style.replace('px','');}}}
if('vertical'==this.options.orientation){this.scroller.down().setStyle({height:(dimensions.height*this.slides.length)+'px',width:dimensions.width});return;}
this.scroller.down().setStyle({width:(dimensions.width*this.slides.length)+'px',height:dimensions.height});},addCircularBuffer:function(){if(this.slides.length<this.options.visibleSlides){return;}
if(this.options.circular&&1<this.options.visibleSlides){this.slides.each(function(slide,index){if(index<this.options.visibleSlides){var clone=$(slide.cloneNode(true));slide.up().insert({bottom:clone});this.slides.push(clone);}},this);}},setSlideIndexes:function(){this.slides.each(function(slide,index){slide._index=index;});},refresh:function(items){this.scroller.show();this.container.update(items);this.slides=this.container.childElements();if(this.slides.length>this.options.visibleSlides){this.addCircularBuffer();this.controls.invoke('show');}
this.setDimensions();this.setSlideIndexes();},moveTo:function(element){if(this.options.beforeMove&&(typeof this.options.beforeMove=='function')){this.options.beforeMove();}
this.previous=this.current?this.current:this.slides[0];this.current=$(element);var scrollerOffset=this.scroller.cumulativeOffset();var elementOffset=this.current.cumulativeOffset();if(this.scrolling){this.scrolling.cancel();}
switch(this.options.effect){case'fade':this.scrolling=new Effect.Opacity(this.scroller,{from:1.0,to:0,duration:this.options.duration,afterFinish:(function(){this.scroller.scrollLeft=elementOffset[0]-scrollerOffset[0];this.scroller.scrollTop=elementOffset[1]-scrollerOffset[1];new Effect.Opacity(this.scroller,{from:0,to:1.0,duration:this.options.duration,afterFinish:(function(){if(this.controls){this.activateControls();}
if(this.options.afterMove&&(typeof this.options.afterMove=='function')){this.options.afterMove();}}).bind(this)});}).bind(this)});break;case'scroll':default:var transition;switch(this.options.transition){case'spring':transition=Effect.Transitions.spring;break;case'easeto':transition=Effect.Transitions.ExpoEaseTo;break;case'sinoidal':default:transition=Effect.Transitions.sinoidal;break;}
this.scrolling=new Effect.SmoothScroll(this.scroller,{duration:this.options.duration,x:(elementOffset[0]-scrollerOffset[0]),y:(elementOffset[1]-scrollerOffset[1]),transition:transition,afterFinish:(function(){if(this.controls){this.activateControls();}
if(this.options.afterMove&&(typeof this.options.afterMove=='function')){this.options.afterMove();}
this.scrolling=false;}).bind(this)});break;}
return false;},click:function(event){this.stop();var element=event.findElement('a');if(!element.hasClassName(this.options.disabledClassName)){if(element.hasClassName(this.options.controlClassName)){eval("this."+element.rel+"()");}else if(element.hasClassName(this.options.jumperClassName)){this.moveTo(element.rel);if(this.options.selectedClassName){this.controls.invoke('removeClassName',this.options.selectedClassName);element.addClassName(this.options.selectedClassName);}}}
this.deactivateControls();event.stop();},slide:function(slide){var index=this.slides.indexOf($(slide));if(index>(this.options.visibleSlides-1)&&this.options.visibleSlides>1){if(index>this.slides.length-(this.options.visibleSlides+1)){index=this.slides.length-this.options.visibleSlides;}}
this.moveTo(this.slides[index]);},prev:function(){if(this.current){var currentIndex=this.current._index;var prevIndex=(currentIndex==0)?(this.options.circular?this.slides.length-1:0):currentIndex-1;}else{var prevIndex=(this.options.circular?this.slides.length-1:0);}
if(prevIndex==(this.slides.length-1)&&this.options.circular&&this.options.effect!='fade'){if('vertical'==this.options.orientation){this.scroller.scrollTop=(this.slides.length-1)*this.slides.first().getHeight();this.scroller.scrollLeft=0;}else{this.scroller.scrollLeft=(this.slides.length-1)*this.slides.first().getWidth();this.scroller.scrollTop=0;}
prevIndex=this.slides.length-this.calculateIndexLimit(1);}
this.moveTo(this.slides[prevIndex]);},next:function(){if(this.current){var currentIndex=this.current._index;var nextIndex=(this.slides.length-1==this.calculateIndexLimit(currentIndex))?(this.options.circular?0:currentIndex):currentIndex+1;}else{var nextIndex=1;}
if(nextIndex==0&&this.options.circular&&this.options.effect!='fade'){if('vertical'==this.options.orientation){this.scroller.scrollLeft=this.slides.first().getHeight()*(this.slides.length-(this.options.visibleSlides+1));this.scroller.scrollLeft=0;}else{this.scroller.scrollLeft=this.slides.first().getWidth()*(this.slides.length-(this.options.visibleSlides+1));this.scroller.scrollTop=0;}
nextIndex=(this.slides.length-this.options.visibleSlides);}
if(nextIndex>this.slides.length-(this.options.visibleSlides)&&this.options.circular){this.scroller.scrollLeft=0;this.scroller.scrollTop=0;nextIndex=1;}
if(nextIndex>this.slides.length-(this.options.visibleSlides+1)&&!this.options.circular){nextIndex=this.slides.length-this.options.visibleSlides;}
this.moveTo(this.slides[nextIndex]);},first:function(){this.moveTo(this.slides[0]);},last:function(){this.moveTo(this.slides[this.slides.length-1]);},toggle:function(){if(this.previous){this.moveTo(this.slides[this.previous._index]);}else{return false;}},stop:function(){if(this.timer){clearTimeout(this.timer);}},start:function(){this.periodicallyUpdate();},pause:function(){this.stop();this.activateControls();},resume:function(event){if(event){var related=event.relatedTarget||event.toElement;if(!related||(!this.slides.include(related)&&!this.slides.any(function(slide){return related.descendantOf(slide);}))){this.start();}}else{this.start();}},periodicallyUpdate:function(){if(this.timer!=null){clearTimeout(this.timer);this.next();}
this.timer=setTimeout(this.periodicallyUpdate.bind(this),this.options.frequency*1000);},wheel:function(event){event.cancelBubble=true;event.stop();var delta=0;if(!event){event=window.event;}
if(event.wheelDelta){delta=event.wheelDelta/120;}else if(event.detail){delta=-event.detail/3;}
if(!this.scrolling){this.deactivateControls();if(delta>0){this.prev();}else{this.next();}}
return Math.round(delta);},deactivateControls:function(){this.controls.invoke('addClassName',this.options.disabledClassName);},activateControls:function(){this.controls.invoke('removeClassName',this.options.disabledClassName);},calculateIndexLimit:function(index){if(!this.options.circular||this.options.visibleSlides<2){return index;}
return(index+this.options.visibleSlides);}});Object.extend(Effect.Transitions,{Elastic:function(pos){return-1*Math.pow(4,-8*pos)*Math.sin((pos*6-1)*(2*Math.PI)/2)+1;},EaseFromTo:function(pos){return-0.5*((pos-=2)*pos*pos*pos-2);},EaseFrom:function(pos){return Math.pow(pos,4);},EaseTo:function(pos){return Math.pow(-1*pos,4);},ExpoEaseTo:function(pos){return-1*Math.pow(2,-10*pos)+1;},SwingFromTo:function(pos){var s=1.70158;if((pos/=0.5)<1)return 0.5*(pos*pos*(((s*=(1.525))+1)*pos-s));return 0.5*((pos-=2)*pos*(((s*=(1.525))+1)*pos+s)+2);},SwingFrom:function(pos){var s=1.70158;return pos*pos*((s+1)*pos-s);},SwingTo:function(pos){var s=1.70158;return(pos-=1)*pos*((s+1)*pos+s)+1;},Bounce:function(pos){if(pos<(1/2.75)){return(7.5625*pos*pos);}else if(pos<(2/2.75)){return(7.5625*(pos-=(1.5/2.75))*pos+.75);}else if(pos<(2.5/2.75)){return(7.5625*(pos-=(2.25/2.75))*pos+.9375);}else{return(7.5625*(pos-=(2.625/2.75))*pos+.984375);}},BouncePast:function(pos){if(pos<(1/2.75)){return(7.5625*pos*pos);}else if(pos<(2/2.75)){return 2-(7.5625*(pos-=(1.5/2.75))*pos+.75);}else if(pos<(2.5/2.75)){return 2-(7.5625*(pos-=(2.25/2.75))*pos+.9375);}else{return 2-(7.5625*(pos-=(2.625/2.75))*pos+.984375);}}});Effect.SmoothScroll=Class.create();Object.extend(Object.extend(Effect.SmoothScroll.prototype,Effect.Base.prototype),{initialize:function(element){this.element=$(element);var options=Object.extend({x:0,y:0,mode:'absolute'},arguments[1]||{});this.start(options);},setup:function(){if(this.options.continuous&&!this.element._ext){this.element.cleanWhitespace();this.element._ext=true;this.element.appendChild(this.element.firstChild);}
this.originalLeft=this.element.scrollLeft;this.originalTop=this.element.scrollTop;if(this.options.mode=='absolute'){this.options.x-=this.originalLeft;this.options.y-=this.originalTop;}},update:function(position){this.element.scrollLeft=this.options.x*position+this.originalLeft;this.element.scrollTop=this.options.y*position+this.originalTop;}});
