if (typeof ABLE == "undefined" || !ABLE) {
    var ABLE = {};
}

ABLE.currentTouch = {};

ABLE.init = function(whiteTitles, params){
  this.wrapper = document.getElementById(params.wrapper);
  this.whiteTitles = whiteTitles;
  this.itemID = this.wrapper.getElementsByTagName("li");
  this.gallery = document.getElementById('gallery');
  this.galleryItems = this.gallery.getElementsByTagName("li");
  this.itemWidth= document.width; // this is mobile only

  $.extend(jQuery.browser,{SafariMobile : navigator.userAgent.toLowerCase().match(/iP(hone|ad)/i)});

  this.checkForHash = function(){
    var hasHash = window.location.hash.replace('#!/','');
    var lastChar = hasHash.substring(hasHash.length, hasHash.length-1);
    if(lastChar == '/'){
      hasHash = hasHash.substring(0, hasHash.length-1);
    } 
    if(hasHash){
      var elem = document.getElementById(hasHash);
      var nodes = elem.parentNode.childNodes, node;
      var i = count = 0;
      while( (node=nodes.item(i++)) && node!=elem ){
        if( node.nodeType==1 ){
          count++
        };
      }
      return count + 1; // would otherwise return the index, but we want page numbers    
    }
    else {
      return 1;
    }
  }

  this.ablecarousel_moveCallback = function(carousel) {
    if($('#next').length){
      window.location.hash = '!/' + ABLE.itemID[carousel.first-1].id;
      document.title = $('#'+ABLE.itemID[carousel.first-1].id+' img:first').attr('title');
      if(carousel.first == 1){
        $('#previous').css('visibility','hidden');
      } else {
        $('#previous').css('visibility','visible');
      }
    }
    $('body').removeClass('white');
    $.each(ABLE.whiteTitles, function(index, value) {
      if(carousel.first == value){
        $('body').addClass('white');
      }
    });

    var galleryItemCount = ABLE.galleryItems.length;
    for ( var i=galleryItemCount-1; i>=0; --i ){
      ABLE.galleryItems[i].className = '';
    }
    var currentGalleryNode = ABLE.galleryItems[carousel.first-1];
    currentGalleryNode.className = 'gallerySelected';
    return false;
  }
  
  this.ablecarousel_initCallback = function(carousel) {
    $('#gallery a').bind('click', function() {
      carousel.scroll($.jcarousel.intval($(this).parent().index()+1));
      return false;
    });
    $('#next').bind('click', function() {
      carousel.next();
      return false;
    });
    $('#previous').bind('click', function() {
      carousel.prev();
      return false;
    });
    $('a.info').click(function(){
      $('.infobox').toggleClass('hide');
      return false;
    });

    $(document).keydown(function(e){
      // left
      if (e.keyCode == 37) { 
        carousel.prev();
        return false;
      }
      // right
      if (e.keyCode == 39) { 
        carousel.next();
        return false;
      }
      // i
      if (e.keyCode == 73) { 
        $('.infobox').toggleClass('hide');
        return false;
      }
      // up
      if (e.keyCode == 38) { 
        $("#gallery").animate({"top": "-640px"});
        return false;
      }
      // down
      if (e.keyCode == 40) { 
        $("#gallery").animate({"top": "25px"},200);
        return false;
      }
    });
  }

  /* more touching! */
  
  this.currentPos = 0;
  this.movePos = 0;
  this.tempPos = 0;
  this.direction = 0;
  this.yMovement = false;
  this.xMovement = false;
  this.threshold = params.threshold;
  
  this.titleColor = function(){
    var that = this;
    var page = Math.abs(that.currentPos/that.itemWidth)+1;
    var galleryItemCount = that.galleryItems.length;
    for ( var i=galleryItemCount-1; i>=0; --i ){
      that.galleryItems[i].className = '';
    }
    that.galleryItems[page-1].className = 'gallerySelected';
    $('body').removeClass('white');
    $.each(that.whiteTitles, function(index, value) {
      if(page == value){
        $('body').addClass('white');
      }
    });
  }

  this.move = function(speed){
    var that = this;
    var itemLength = -1 * that.galleryItems.length * that.itemWidth;
    if(speed < 0){
      that.currentPos = that.currentPos + that.itemWidth;
      if(that.currentPos > 0){
        that.currentPos = 0;
      }
    }
    else {
      that.currentPos = that.currentPos - that.itemWidth;
      if(that.currentPos <= itemLength){
        that.currentPos = itemLength + that.itemWidth;
      }
    }
    $('#'+params.wrapper).css('-webkitTransitionDuration','0.4s');
    $('#'+params.wrapper).css('-webkitTransform', 'translate3d('+that.currentPos+'px,0,0)');;
    that.titleColor();
  };
  
  this.bindTouches = function(){
    var that = this;

    $('#gallery a').bind('click', function() {
      $('#'+params.wrapper).css('webkitTransform', 'translate3d('+(that.itemWidth*$(this).parent().index())*-1+'px,0,0)');
      that.currentPos = (that.itemWidth*$(this).parent().index())*-1;
      that.titleColor();
      return false;
    });
    
    that.wrapper.addEventListener('touchstart', function(e) {
      e.preventDefault();
      var touch = e.touches[0];
      ABLE.currentTouch.startX = touch.screenX;
      ABLE.currentTouch.startY = touch.screenY;
    },false);
    that.wrapper.addEventListener('touchmove', function(e) {
      var touch = e.touches[0];
      var begin = ABLE.currentTouch.startX;
      var beginY = ABLE.currentTouch.startY;
      var updown = Math.abs(touch.screenY - beginY);
      that.movePos = that.currentPos + touch.screenX - begin;
      if(updown >= that.threshold){
        that.yMovement = true;
      }
        else {
          if(that.tempPos > that.movePos){
            that.direction = 1;
          }
          else {
            that.direction = -1;
          }
          $('#'+params.wrapper).css('-webkitTransitionDuration','0s');
          $('#'+params.wrapper).css('-webkitTransform','translate3d('+that.movePos+'px,0,0)');
        }
        that.tempPos = that.movePos;
      },false);
    that.wrapper.addEventListener('touchend', function(e) {
      e.preventDefault();
      var touch = e.changedTouches[0];
      var updown = touch.screenY - ABLE.currentTouch.startY;
      var leftright = Math.abs(touch.screenX - ABLE.currentTouch.startX);
      if(that.yMovement && leftright <= that.threshold){
        if(updown < 0){
          that.gallery.style.webkitTransform = 'translate3d(0,-645px,0)';
        }
        else {
          that.gallery.style.webkitTransform = 'translate3d(0,645px,0)';
        }
        $('#'+params.wrapper).css('-webkitTransitionDuration','0.4s');
        $('#'+params.wrapper).css('-webkitTransform','translate3d('+that.currentPos+'px,0,0)');
        that.yMovement = false;
      } else {
        ABLE.currentTouch.endX = touch.screenX;
        ABLE.currentTouch.endY = touch.screenY;
        if(leftright >= that.threshold){
          that.move(that.direction);
        }
        else {
          $('#'+params.wrapper).css('-webkitTransitionDuration','0.4s');
          $('#'+params.wrapper).css('-webkitTransform','translate3d('+that.currentPos+'px,0,0)');
        }
      }
    }, false);
  };
  $(function(){
    if($.browser.SafariMobile){
      ABLE.wrapper.style.width = ABLE.itemWidth * ABLE.galleryItems.length + 'px';
      ABLE.bindTouches();
    } else {
       $('#collage').jcarousel({
         visible: 1,
         scroll: 1,
         start: $('#next').length ? ABLE.checkForHash() : Math.floor(Math.random()*5),
         initCallback: ABLE.ablecarousel_initCallback,
         itemFirstInCallback: ABLE.ablecarousel_moveCallback,
         wrap: 'last',
         buttonNextHTML: null,
         buttonPrevHTML: null
       });
      }
  });
}
