/*
    Sightglass ver. 0.1.9
    ---------------------
    Simplistic class implementation of a horizontal "carousel" using
    NON-semantic markup... :)
    
    Plan for 0.2 is to have the exposed custom events send out relevant
    bits of data when they are fired so that you can do things with this
    constructor that are beyond your wildest dreams...
  
    The joke here, of course, is that one with *only* css, one
    can just set overflow:auto and pretty much get something
    functionally identical (with a slider, even), but maybe not
    the way you want it to look...
    
    Change History:
      * ver. 0.1.9: Remove useless "OST" namespace. This should make it more useful
        for folks who just want to cut and paste code
      * ver. 0.1.2: First release and attempt at making fancy, longish comments
    
    Requires YUI Utilities (utilities.js) or
  
      * Yahoo Global Object
      * Event
      * Dom
      * Connection Manager
      * Animation
      * Drag & Drop

    (cc) MMVII, Robert Otani. otanistudio.com
    This work is licensed under a 
    Creative Commons Attribution-ShareAlike 2.5 License
    http://creativecommons.org/licenses/by-sa/2.5/
    
    More robust carousel implementations are available at:
      http://prototype-carousel.xilinus.com/
      http://billwscott.com/carousel/
      http://clientside.cnet.com/cnet.gf/docs/files/addons/carousel-js.html
*/

var Sightglass = function(sightglass, itemContainer, controllers) {
  
  // Custom events in case you want to do some other cool thing...
  // TODO: Make these events unique to every class instance
  this.scrollComplete = new YAHOO.util.CustomEvent('SIGHTGLASS_SCROLL_COMPLETE');
  this.scrollStart = new YAHOO.util.CustomEvent('SIGHTGLASS_SCROLL_START');
  this.onNext = new YAHOO.util.CustomEvent('SIGHTGLASS_NEXT');
  this.onPrev = new YAHOO.util.CustomEvent('SIGHTGLASS_PREV');
  this.onFirst = new YAHOO.util.CustomEvent('SIGHTGLASS_FIRST');
  this.onLast = new YAHOO.util.CustomEvent('SIGHTGLASS_LAST');
  this.onpb2 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB2');
  this.onpb3 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB3');
  this.onpb4 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB4');
  this.onpb5 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB5');
  this.onpb6 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB6');
  this.onpb7 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB7');
  this.onpb8 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB8');
  this.onpb9 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB9');
  this.onpb10 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB10');
  this.onpb11 = new YAHOO.util.CustomEvent('SIGHTGLASS_PB11');

  // Watch yer scope
  var that = this;
  
  // private methods and properties
  var _animating = false;
  
  var _autovalue = function(value) {
    if ("auto" === value || "undefined" === typeof value) {
      value = 0;
    }
    return parseInt(value);
  };
  
  var _scrollBy = function() {
    // TODO: Instead, find every position of every Nth element
    //       so that one may scroll there. This prevents possible
    //       clipping annoyances via the sightglass...
    return _autovalue(YAHOO.util.Dom.getStyle(sightglass, 'width')) || 200;
  };
  
  var _boundary = function(side) {    
    var listLeft = _autovalue(YAHOO.util.Dom.getStyle(itemContainer, 'left'));
    var listWidth = 0;
    var items = document.getElementById(itemContainer).childNodes;
    for (var i=0; i < items.length; i++) {
        if (1 === items[i].nodeType) {
          listWidth += _autovalue(items[i].offsetWidth)
          + _autovalue(YAHOO.util.Dom.getStyle(items[i].id, 'padding-right'))
          + _autovalue(YAHOO.util.Dom.getStyle(items[i].id, 'padding-left'));
        }
    }
    var sightglassWidth = _autovalue(YAHOO.util.Dom.getStyle(sightglass, 'width')) + 200;
    var sightglassLeft  = _autovalue(YAHOO.util.Dom.getStyle(sightglass, 'left'));

    if (side === "left") {
      if (listLeft < sightglassLeft) {
        return true;
      } else {
        return false;
      }
    } else if (side === "right") {
      if (listWidth + listLeft > sightglassWidth) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
      }
  };
  
  var _move = function(properties, time, eventTarget) {
    // properties is a configuration object for YUI animation 
    // make sure anims are complete before starting a whole new one...
    if(!_animating) {
      var _anim = new YAHOO.util.Anim(itemContainer, properties, time, YAHOO.util.Easing.easeOut);
      _anim.onStart.subscribe(
        function(){
          _animating = true;
          that.scrollStart.fire();
        }
      );
      _anim.onComplete.subscribe(_buttonState);
      _anim.onComplete.subscribe(
        function(){ 
          _animating = false; 
          that.scrollComplete.fire();
        }
      );
      _anim.animate();
    }
  };
  
  var _buttonState = function() {
    if(_boundary("left")) {
      YAHOO.util.Dom.setStyle(controllers.buttons.left, 'opacity', '1');
    } else {
      YAHOO.util.Dom.setStyle(controllers.buttons.left, 'opacity', '0.33');
    }
    
    if(_boundary("right")) {
      YAHOO.util.Dom.setStyle(controllers.buttons.right, 'opacity', '1');
    } else {
      YAHOO.util.Dom.setStyle(controllers.buttons.right, 'opacity', '0.33');
    }
  };

  if ('undefined' === typeof that._INITIALIZED ) {

    Sightglass.prototype.next = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -1 * _scrollBy()}}, 0.6);
      }
      that.onNext.fire();
    };
	
	
	Sightglass.prototype.pb2 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -1 * _scrollBy()}}, 0);
      }
      that.onpb2.fire();
    };
	Sightglass.prototype.pb3 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -2 * _scrollBy()}}, 0);
      }
      that.onpb3.fire();
    };
	Sightglass.prototype.pb4 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -3 * _scrollBy()}}, 0);
      }
      that.onpb4.fire();
    };
	Sightglass.prototype.pb5 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -4 * _scrollBy()}}, 0);
      }
      that.onpb5.fire();
    };
	Sightglass.prototype.pb6 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -5 * _scrollBy()}}, 0);
      }
      that.onpb6.fire();
    };
	Sightglass.prototype.pb7 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -6 * _scrollBy()}}, 0);
      }
      that.onpb7.fire();
    };
	Sightglass.prototype.pb8 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -7 * _scrollBy()}}, 0);
      }
      that.onpb8.fire();
    };
	Sightglass.prototype.pb9 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -8 * _scrollBy()}}, 0);
      }
      that.onpb9.fire();
    };
	Sightglass.prototype.pb10 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -9 * _scrollBy()}}, 0);
      }
      that.onpb10.fire();
    };
	Sightglass.prototype.pb11 = function(e) {
      if (_boundary("right")) {
        _move({"left": {by: -10 * _scrollBy()}}, 0);
      }
      that.onpb11.fire();
    };
    
    Sightglass.prototype.previous = function(e) {
      if (_boundary("left")) {
        _move({"left" : {by: _scrollBy()}}, 0.6);
      }
      that.onPrev.fire();
    };
    
    Sightglass.prototype.first = function(e) {
      if (_boundary("left")) {
        _move({"left" : {to: 0}}, 1.2);
      }
      that.onFirst.fire();
    };
  
    Sightglass.prototype.last = function(e) {
      var items = YAHOO.util.Dom.get(itemContainer).getElementsByTagName('div');

      // Calculate where to move the item cluster based on
      // locations of first and last items.
      var lastItemLocation = items[items.length-1].offsetLeft;
      var firstItemLocation = items[0].offsetLeft;
      var sightglassWidth = _autovalue(YAHOO.util.Dom.getStyle(sightglass, 'width'));

      if (_boundary("right")) {
        var aProp = {
          "left" : {
            to: Math.ceil(
              firstItemLocation - lastItemLocation + (0.5 * sightglassWidth)
             )
           }
        };
        _move(aProp, 1.2);
      }
      that.onLast.fire();
    };    
    that._INITIALIZED = true;
  }
  
};

