if (typeof(AC) == "undefined") AC = {};

AC.Slider = Class.create();
AC.Slider.prototype = {
  orientation: 'horizontal',
  container: null,
  items: null,
  currentPage: 1,
  itemsPerPage: null,
  totalPages: null,
  maskInnerDimension: null,
  isAnimating: false,
  uniqueName: null,

  readCookie:function(cookieName) {
	  var cookieValue = "";
	  var searchCookie = cookieName + "=";
	  if (document.cookie.length > 0) {
		  offset = document.cookie.indexOf(searchCookie);
		  if (offset != -1) {
			  offset += searchCookie.length;
			  end = document.cookie.indexOf(";", offset);
			  if (end == -1) end = document.cookie.length;
			  cookieValue = unescape(document.cookie.substring(offset, end));
		  }
	  }
	  return cookieValue;
  },

  writeCookie:function(cookieName, cookieValue, expireDays) {
	  var expire = "";
	  if (expireDays != null) {
		  expire = new Date((new Date()).getTime() + expireDays * 24 * 60 * 60 * 1000);
		  expire = "; expires=" + expire.toGMTString();
	  }
	  document.cookie = cookieName + "=" + escape(cookieValue) + expire + "; path=/";
  },

  initialize:function(containerId, sliderElements) {
    this.items = new Array();
    this.container = $(containerId);
    this.populate(sliderElements);
  },

  populate:function() {
    this.container.innerHTML = 'The slider requires population with data. You need to call this.render(itemsPerList) from your custom this.populate() function.';
  },

  render:function(uniqueName, itemsPerList, title, orientation, showDots) {
    this.orientation = orientation;
    this.uniqueName = uniqueName;
    this.container.innerHTML = '';
    this.itemsPerPage = itemsPerList;
    this.list = Builder.node('ul', this.renderItems());

    if (this.orientation == 'vertical')
      this.createUpArrow();

    var mask = Builder.node('div', {'class':'ACSliderMaskDiv'}, [this.list]);
    this.container.appendChild(mask);

    this.positionWithinMask(mask);

    if (this.orientation == 'horizontal')
      this.createArrows();
    else
      this.createDownArrow();

    this.totalPages = Math.ceil(this.items.length / this.itemsPerPage);
    this.createDots(title, showDots);

    var page_index = parseInt(this.readCookie(this.uniqueName + "-CurrentPage"));
    if (!isNaN(page_index))
      this.jumptoPageNumber(page_index);
  },

  positionWithinMask:function(mask) {
    if (this.orientation == 'horizontal') {
      this.maskInnerDimension = Element.getInnerDimensions(mask).width;
      this.list.style.left = -this.maskInnerDimension * this.currentPage + 'px';
    } else {
      this.maskInnerDimension = Element.getInnerDimensions(mask).height;
      this.list.style.top = -this.maskInnerDimension * this.currentPage + 'px';
    }
  },

  renderItems:function() {
    var list = [];

    var lastPageStart = this.items.length - this.items.length % this.itemsPerPage;
    if (lastPageStart == this.items.length)
      lastPageStart = this.items.length - this.itemsPerPage;

    var overflowAmount = this.itemsPerPage - this.items.length % this.itemsPerPage;
    if (overflowAmount == this.itemsPerPage)
      overflowAmount = 0;

    list.push(this.renderPlaceholderItems(lastPageStart, this.items.length));

    for (var i = 0; i < overflowAmount; i++) {
      var listItem = Builder.node('li', {'class':'empty'});
      list.push(listItem);
    }

    for (var i = 0; i < this.items.length; i++) {
      var listItem = this.items[i].render().cloneNode(true);
      list.push(listItem);
    }

    for (var i = 0; i < overflowAmount; i++) {
      var listItem = Builder.node('li', {'class':'empty'});
      list.push(listItem);
    }

    list.push(this.renderPlaceholderItems(0, this.itemsPerPage));

    return list;
  },

  renderPlaceholderItems:function(start, finish) {
    var list = [];
    if (this.items != null && this.items.length > 0) {
      for (var i = start; i < finish; i++) {
        if ( i >= this.items.length ){
			continue;
        }
        
        var listItem = this.items[i].render().cloneNode(true);

        if (listItem.id)
          listItem.removeAttribute(id);

        for (var j = 0, child; child = listItem.childNodes[j]; j++) {
          if (child.getAttribute('id'))
            child.removeAttribute('id');
        }

        $(listItem).addClassName('cloned');
        list.push(listItem);
      }
    }
    return list;
  },

  createArrows:function() {
    var prevArrow = Builder.node('a', {'class':'ACSliderPreviousArrow'}, '&lt;');
    prevArrow.onclick = this.getPrevious.bindAsEventListener(this);
    this.container.appendChild(prevArrow);

    var nextArrow = Builder.node('a', {'class':'ACSliderNextArrow'}, '&gt;');
    nextArrow.onclick = this.getNext.bindAsEventListener(this);
    this.container.appendChild(nextArrow);
  },

  createUpArrow:function() {
    var prevArrowContainer = Builder.node('div', {'class':'ACSliderPreviousArrowContainer'});
    var prevArrow = Builder.node('a', {'class':'ACSliderPreviousArrow'}, '&lt;');
    prevArrow.onclick = this.getPrevious.bindAsEventListener(this);
    prevArrowContainer.appendChild(prevArrow);
    this.container.appendChild(prevArrowContainer);
  },

  createDownArrow:function() {
    var nextArrowContainer = Builder.node('div', {'class':'ACSliderNextArrowContainer'});
    var nextArrow = Builder.node('a', {'class':'ACSliderNextArrow'}, '&gt;');
    nextArrow.onclick = this.getNext.bindAsEventListener(this);
    nextArrowContainer.appendChild(nextArrow);
    this.container.appendChild(nextArrowContainer);
  },

  createDots:function(title, showDots) {
    this.pageNav = Builder.node('div', {'class':'ACSliderPageNav'});

    var pageNavList = Builder.node('ul');
    for (var i = 1; i <= this.totalPages; i++) {
      var navListItemAnchor = (i == this.currentPage) ? Builder.node('a', {'class':'active'}, i) : Builder.node('a', i);
      navListItemAnchor.onclick = this.scrolltoPageNumber.bind(this, i, false);

      var navListItem = Builder.node('li', [navListItemAnchor]);
      pageNavList.appendChild(navListItem);
    }

    this.pageNav.innerHTML = title;
    if (showDots)
      this.pageNav.appendChild(pageNavList);

    this.container.appendChild(this.pageNav);
  },

  getPrevious:function() {
    var previousPageIndex = this.currentPage - 1;
    this.scrolltoPageNumber(previousPageIndex, 1);
  },

  getNext:function() {
    var nextPageIndex = this.currentPage + 1;
    this.scrolltoPageNumber(nextPageIndex, -1);
  },

  scrolltoPageNumber:function(toPageNumber, direction) {
    if (this.currentPage != toPageNumber && !this.isAnimating) {
      if (!direction)
        var direction = this.currentPage - toPageNumber;
      this.isAnimating = true;
      this.currentPage = toPageNumber;
      this.resetPages();

      var pageNavAnchors = this.pageNav.getElementsByTagName('a');
      for (var i = 0, anchor; anchor = pageNavAnchors[i]; i++) {
        if (Element.hasClassName(anchor, 'active'))
          Element.removeClassName(anchor, 'active');
        if (anchor.innerHTML == this.currentPage)
          Element.addClassName(anchor, 'active');
      }

      try {
        console.debug(this.list, "Scrolling to page", toPageNumber);
      } catch(e) { }

      var options = {
        duration: 0.5,
        queue: {position:'end', scope:'sliderQueue', limit:1},
        afterFinish: this.afterScroll.bind(this)
      };

      if (!this.maskInnerDimension) {
        this.positionWithinMask(this.container);
      }

      if (this.orientation == 'horizontal') {
        try {
          console.debug("X: ", this.maskInnerDimension * direction);
        } catch(e) { }
        new Effect.MoveBy(this.list, 0, this.maskInnerDimension * direction, options);
      } else {
        new Effect.MoveBy(this.list, this.maskInnerDimension * direction, 0, options);
      }

      this.writeCookie(this.uniqueName + "-CurrentPage", this.currentPage, 365);
    }
  },

  jumptoPageNumber:function(toPageNumber) {
    if ((this.orientation == 'vertical') || (this.currentPage != toPageNumber && !this.isAnimating)) {
      var direction = this.currentPage - toPageNumber;
      this.currentPage = toPageNumber;
      this.resetPages();

      var pageNavAnchors = this.pageNav.getElementsByTagName('a');
      for (var i = 0, anchor; anchor = pageNavAnchors[i]; i++) {
        if (Element.hasClassName(anchor, 'active'))
          Element.removeClassName(anchor, 'active');
        if (anchor.innerHTML == this.currentPage)
          Element.addClassName(anchor, 'active');
      }

      if (this.orientation == 'horizontal') {
        new Effect.MoveBy(this.list, 0, this.maskInnerDimension * direction);
      } else {
        new Effect.MoveBy(this.list, this.maskInnerDimension * direction, 0);
      }
    }
  },

  resetPages:function() {
    if (this.currentPage == 0) {
      this.currentPage = this.totalPages;
      this.positionOffset = -this.maskInnerDimension * this.totalPages + 'px';
    } else if (this.currentPage == this.totalPages + 1) {
      this.currentPage = 1;
      this.positionOffset = -this.maskInnerDimension + 'px';
    } else {
      this.positionOffset = false;
    }
  },

  afterScroll:function() {
    if (this.positionOffset) {
      if (this.orientation == 'horizontal') {
        this.list.style.left = this.positionOffset;
      } else {
        this.list.style.top = this.positionOffset;
      }
    }
    this.isAnimating = false;
  },

  jumpToPage:function(toPageNumber){
  }

};

AC.SliderItem = Class.create();
AC.SliderItem.prototype = {
  html: 'List items must be populated with data; it can be an HTML object or HTML as a string.',

  initialize:function(input) {
    if (input)
      this.html = input;
  },

  render:function() {
    if (typeof(this.html) == 'string') {
      var li = Builder.node('li');
      li.innerHTML = this.html;
    } else {
      var li = Builder.node('li', [this.html]);
    }
    return li;
  }

};