// Copyright (c) 2010 Larry Kluger
// Based on sw by Antonio Lupetti--
// http://woork.blogspot.com/2008/07/fantastic-news-ticker-newsvine-like.html 
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

var NewsTicker = new Class({
         options: {}, // set by setOptions
         mytimer: null, 
         //
         //  initialize
         //
         initialize: function(el,options){
                  this.setOptions(options);
                  this.el = $(el); // the ticker el (which changes) within the ticker container
                  if (!this.options.no_mouse_pause) {
                     this.el.addEvent('mouseenter', function(){this.pause();}.bind(this));
                     this.el.addEvent('mouseleave', function(){this.resume();}.bind(this));                  
                  };
                  this.items = this.el.getElements('li'); // array of the items to be scrolled
                  
                  var w = 0, // total width (visible and invisible) 
                      h = 0; // height width (visible and invisible)
                      
                  if(this.options.direction.toLowerCase()=='horizontal') {
                h = this.el.getSize().y;
                         this.items.each(function(li,index) {w += li.getSize().x;});
             } else {
                        // vertical ticker
                        w = this.el.getSize().x;
                        this.items.each(function(li,index) {h += li.getSize().y;});
                  }
                  
                  // initialize place and size within container
                  this.el.setStyles({position: 'absolute', top: 0, left: 0, width: w,   height: h});
                  
                  // create fx object. Set options for the fx object's future use
                  this.fx = new Fx.Morph(this.el,
                    {duration:this.options.speed,
                     onComplete:function() {
                           // Each time an effect completes, do:
                           var i = (this.current==0) ? this.items.length : this.current;
                           this.items[i-1].inject(this.el, 'bottom'); // MOVES the prior item (which is now
                                                                      // not visible) to the bottom of el
                           this.el.setStyles({left:0,   top:0});
                     }.bind(this)});
                  
                  this.current = 0; // initialize
                  
                  this.delay_then_next(); // start 'er up!
         },
         
         //
         // setOptions
         //
         setOptions: function(options) {
            // set options, manage defaults and enforce requirements
                           this.options.speed = options.speed || 500;
                           this.options.delay = options.delay || 5000;
                       this.options.direction = options.direction || 'vertical';
                  this.options.no_mouse_pause = options.no_mouse_pause; // undefined will be false, which is the default
                  // requirements
                  if (options != null && options.delay < 150) {this.options.delay = 150;}  
         },
         
         //
         // next
         //
         next: function() {
            // scroll to next item
                  this.current++;
                  if (this.current >= this.items.length) this.current = 0;
                  
                  var pos = this.items[this.current];
                  this.fx.start({         // moves the el -- scrolls it from 0 to new position (up or left)
                         top: -pos.offsetTop,
                         left: -pos.offsetLeft
                  });
                  
                  this.delay_then_next();
         },
         
         //
         // delay_then_next
         //
         delay_then_next: function() {
                  // call next after waiting for effect to finish and delay time 
                  this.mytimer = this.next.bind(this).delay(this.options.delay + this.options.speed);
         },      
         
         //
         // pause 
         //
         pause: function() {
            $clear(this.mytimer); // stop timer
            this.mytimer = null;
         },

         //
         // resume
         //
         resume: function() {
            // call next if not running
            if (this.mytimer == null) {this.next();}
         }
});
