/*
Written by Spellcoder (Mark de Jong) in 2009
*/
/*

CSS classes:
.thumb
.thumbSelected
.arrowup
.arrowup_disabled
.arrowdown
.arrowdown_disabled



- multi-instance (no usage of id's, no globals)


- styling options
  - HOVER
        - working :hover in IE6
          - for .thumbcont
          - for .thumbcont img
  - SELECTION
        - .thumbcont get's an extra class .thumbcont_selected
        - an extra element .thumbselection


- Getting a border *inside* the selected image
        - style .thumbselection to use the full size of it's parent minus the size of the borders
        - then give a border to .thumbselection
*/

function slidingselector(options)
{
  this.thumbcontainer = options.thumbcontainer;

  // smooth scroll duration in milliseconds
  this.scrollduration = (typeof options.scrollduration == 'undefined') ? 800 : options.scrollduration;
  this.animationsteps = (typeof options.animationsteps == 'undefined') ? 20 : options.animationsteps;
  this.stepinterval   = this.scrollduration / this.animationsteps;
  this.onselect       = (typeof options.onselect == 'undefined') ? null : options.onselect;

  // if wrap=true the item on the other end is selected when we go beyond the start/end
  this.wrap           = (typeof options.wrap == 'undefined') ? false : options.wrap;

  this.maxthumbwidth  = 96;

  this.normalthumbclass = 'thumbcont';
  this.selectedthumbclass = 'thumbcont_selected';

  this.currentitem = null;

  // extra element added to a selected thumbnail to provide additional styling options
  // (like an overlay or inner border)
  this.selectionelement = document.createElement('div');
  this.selectionelement.className = 'thumbselection';

  if (options.items && options.items.length > 0)
  {
    this.items = options.items;
    this.createlist(options.items);
    this.selectitem(0);
  }
}

slidingselector.prototype.createlist = function slidingselector_createlist()
{
  var self = this;

  if (!this.thumbcontainer)
    return;

  // generate the DOM for each item
  for(var itemid=0; itemid < this.items.length; itemid++)
  {
    var item = this.items[itemid];

    // encase each item in a <a> so we can use :hover in IE6
    var thumbcontainer = document.createElement('a');
    thumbcontainer.className = this.normalthumbclass;
    thumbcontainer.thumbid = itemid;
    thumbcontainer.onclick = function() { self.selectitem(this.thumbid); };

    item.node = thumbcontainer; // keep reference for determining y position of an item
//    this.items[itemid].node = document.createElement('div');

    var thumbimg = document.createElement('img');

    if (item.thumb.width)
      thumbimg.style.width = item.thumb.width+'px';
    else
      thumbimg.width = this.maxthumbwidth;

    if (item.thumb.height)
      thumbimg.style.height = item.thumb.height+'px';

    thumbimg.src   = item.thumb.src
    thumbimg.title = item.title; // mouseover tooltip
    thumbimg.alt   = item.title; // text in case image can't be displayed

    thumbcontainer.appendChild(thumbimg);
    this.thumbcontainer.appendChild(thumbcontainer);
  }
}

slidingselector.prototype.previtem = function slidingselector_previtem()
{
  var prev = this.currentitem - 1;

  if (prev < 0)
    if (this.wrap)
      prev = this.items.length-1;
    else
      return;

  this.selectitem(prev);
}

slidingselector.prototype.nextitem = function slidingselector_nextitem()
{
  var next = this.currentitem + 1;

  if (next > this.items.length-1)
    if (this.wrap)
      next = 0;
    else
      return;

  this.selectitem(next);
}

slidingselector.prototype.selectitem = function slidingselector_selectitem(itemid)
{
  // find vertical position of the item within the list
  // (don't assume all images share the same height or use a fixed height)
  var item = this.items[itemid];

//  if (typeof item == 'undefined')
//    alert('item #'+itemid+' is missing.');
  var itemy = item.node.offsetTop;
  var itemmiddley = itemy + item.node.clientHeight/2;
  var viewheight = this.thumbcontainer.clientHeight;
  var listheight = this.thumbcontainer.scrollHeight;

  // center list of thumbnails around the middle of the selected item
  var scrolly = itemmiddley - viewheight/2;

  if (scrolly + viewheight > listheight)
    scrolly = listheight - viewheight;

  if (scrolly < 0)
    scrolly = 0;

  this.SmoothScrollTo(scrolly);

  // remove selection state from previous selection
  if (this.currentitem != null)
  {
    var itemcontainer = this.items[this.currentitem].node;
    itemcontainer.className = this.normalthumbclass;
    itemcontainer.removeChild(this.selectionelement);
  }

  this.currentitem = itemid;

  item.node.className = this.normalthumbclass+' '+this.selectedthumbclass;

  item.node.appendChild(this.selectionelement);

  if (this.onselect)
    this.onselect(item, { itemid:    itemid
                        , itemcount: this.items.length
                        });
}

slidingselector.prototype.SmoothScrollTo = function slidingselector_SmoothScrollTo(destinationy)
{
  var currentscrolly = this.thumbcontainer.scrollTop;

  // already at the destination?
  if (destinationy == currentscrolly)
    return;

  var self = this;

  // set info for animation
  // (if still scrolling, then just start a new animation from the current position)
  this.starty = currentscrolly;
  this.endy   = destinationy;
  this.anim   = 0;

  if (!this.scrolltimer)
    this.scrolltimer = setTimeout( function() { self.DoScroll() } , this.stepinterval );
}

slidingselector.prototype.DoScroll = function slidingselector_DoScroll()
{
  this.anim++;

  if (this.anim == this.animationsteps)
  {
    this.thumbcontainer.scrollTop = this.endy;
    this.scrolltimer = null; // scroll animation has finished
    return;
  }

  var self = this;

  var runtime = this.stepinterval * this.anim;
  var effectstrength = Math.sin(Math.PI / 2 * runtime / this.scrollduration);
  var newvalue = this.starty + (this.endy - this.starty) * effectstrength;

  this.thumbcontainer.scrollTop = newvalue;

  this.scrolltimer = setTimeout( function() { self.DoScroll() } , this.stepinterval );
}

slidingselector.prototype.destroy = function slidingselector_Destroy()
{
  if (this.scrolltimer)
    clearTimeout(this.scrolltimer);

  this.thumbcontainer = null;

  // destroy references between DOM elements
  for(var tel=0; tel<this.items.length; tel++)
  {
    this.items[tel].node.onclick = null; // remove reference back to our slidingselector instance
    this.items[tel].node = null;         // remove reference to DOM element
  }
}