/*  =Slideshow (Class)
  ----------------------------------------------- */
  dojo.declare("Slideshow", null, {

  // Attributes
    debugMode                  : false,
    items/*Array*/             : null, // An array of slideshow items
    window/*Element*/          : null, // The "window" through which we see the slideshow
    itemsContainer/*Element*/  : null, // The parent element of the items
    nextButton/*Element*/      : null,
    previousButton/*Element*/  : null,
    fullWidth                  : 0,    // The total width of all the slideshow items
    visibleWidth               : 930,  // The width of the "window". TBD: Make this dynamic?
    offset                     : 0,    // The number of pixels which the slideshow is offset from the left side of the window
    visibleItems               : 3,    // The number of slideshow items which are visible in the window. TBD: Make this dynamic?
    itemCursor                 : 0,    // The index number of the first slideshow item which is visible in the window

  // Methods
    constructor: function(items) {
      if (items.length <= 0) return;

      this.items = items;

      this.window = this.wrapElements(this.items);
      dojo.addClass(this.window, "recipes");

      this.itemsContainer = this.wrapElements(this.items);
      dojo.addClass(this.itemsContainer, "inner");
      
      for (var index = 0; index < this.items.length; index++) {
        this.fullWidth += this.items[index].offsetWidth;
      }
      
      this.resize();
      Page.addEventListener("update", dojo.hitch(this, this.resize));
      
      dojo.style(this.itemsContainer, "width", this.fullWidth + "px");

      this.prepareNav();
      this.updateNavState();
    },
    resize: function() {
      var visibleHeight = this.getMaxSlideHeight();
      dojo.style(this.window, "height", visibleHeight + "px");
      dojo.style(this.itemsContainer, "height", visibleHeight + "px");
    },
    getMaxSlideHeight: function()/*Number*/ {
      var visibleHeight = 0;
      for (var index = 0; index < this.items.length; index++) {
        var nextHeight = this.items[index].offsetHeight;
        if (nextHeight > visibleHeight) {
          visibleHeight = nextHeight;
        }
      }
      return visibleHeight;
    },
    numItems: function()/*Number*/ {
      return this.items.length;
    },
    addItem: function(html/*String*/) {
      var item = dojo.doc.createElement("div");
      
      // KLUDGE: Need to find a way to add the item without specific references to recipes
      // class names (i.e. the slideshow class should be a general use class).
      dojo.addClass(item, "recipe");
      var firstItem = this.items[0];
      firstItem.parentNode.appendChild(item);
      
      /* KLUDGE: Need to find a way to create the element directly. */
      item.innerHTML = html;
      var firstChild = dojo.query(".recipe", item)[0];
      item.setAttribute("id", firstChild.getAttribute("id"));
      item.innerHTML = firstChild.innerHTML;
      
      this.items[this.items.length] = item;
      this.updateWidth();
      this.updateNavState();
    },
    removeItem: function(isTarget/*Function*/) {
      var target = null;
      var items = [];
      for (var index = 0; index < this.items.length; index++) {
        var item = this.items[index];
        if (!isTarget(item)) {
          items[items.length] = item;
        } else {
          item.parentNode.removeChild(item);
          this.updateWidth(true);
        }
      }
      this.items = items;
      this.updateNavState();
    },
    updateWidth: function(subtract) {
      var width = this.items[this.items.length - 1].offsetWidth;
      if (subtract) {
        this.fullWidth -= width;
      } else {
        this.fullWidth += width;
      }
      dojo.style(this.itemsContainer, "width", this.fullWidth + "px");
    },
    prepareNav: function() {
      var nav = dojo.doc.createElement("div");
      dojo.addClass(nav, "nav");

      /* KLUDGE: Until I figure out how to do this right with Dojo. */
      nav.innerHTML =
          '<h3>Navigation</h3>'
        + '<ul>'
        + '<li class="next"><a href="#next">Next</a></li>'
        + '<li class="previous"><a href="#previous">Previous</a></li>'
        + '</ul>';
      //dojo.place(nav, this.window, "after");
      this.window.parentNode.appendChild(nav);

      this.nextButton = dojo.query(".nav .next", this.window.parentNode)[0];
      dojo.connect(this.nextButton, "onclick", function(e) {
        e.preventDefault();
        this.slideshow.next();
      });
      this.nextButton.slideshow = this;
      this.previousButton = dojo.query(".nav .previous", this.window.parentNode)[0];
      dojo.connect(this.previousButton, "onclick", function(e) {
        e.preventDefault();
        this.slideshow.previous();
      });
      this.previousButton.slideshow = this;
    },
    nextEnabled: function() {
      return (this.itemCursor + this.visibleItems < this.items.length);
    },
    previousEnabled: function() {
      return (this.itemCursor > 0);
    },
    updateNavState: function() {
      if (this.nextEnabled()) {
        dojo.removeClass(this.nextButton, "disabled");
      } else {
        dojo.addClass(this.nextButton, "disabled");
      }
      if (this.previousEnabled()) {
        dojo.removeClass(this.previousButton, "disabled");
      } else {
        dojo.addClass(this.previousButton, "disabled");
      }
    },
    wrapElements: function(elements) {
      var container = dojo.doc.createElement("div");
      elements[0].parentNode.insertBefore(container, elements[0]);

      for (var index = 0; index < elements.length; index++) {
        var nextElement = elements[index];
        nextElement.parentNode.removeChild(nextElement);
        container.appendChild(nextElement);
      }
      return container;
    },
    next: function() {
      if (this.debugMode) console.log("next");
      if (!this.nextEnabled()) return;
      dojo.animateProperty({ node: this.itemsContainer, duration:1000,
        properties:{
          left: {end:(this.offset -= this.visibleWidth)}
        }
      }).play();

      this.itemCursor += this.visibleItems;
      this.updateNavState();
    },
    previous: function() {
      if (this.debugMode) console.log("previous");
      if (!this.previousEnabled()) return;
      dojo.animateProperty({ node: this.itemsContainer, duration:1000,
        properties:{
          left: {end:(this.offset += this.visibleWidth)}
        }
      }).play();

      this.itemCursor -= this.visibleItems;
      this.updateNavState();
    }
  });
