// jQuery Box model Slider Plugin
//
// Version 1.00
//
// Mauro Fasolo
//+
//
// Terms of Use
//
// This software is licensed under a Creative Commons License and is copyrighted
// (C)2008 by Cory S.N. LaViska.
//
// For details, visit http://creativecommons.org/licenses/by/3.0/us/
//

$.fn.elementSlider = function(options) {

  var defaults = {
      viewable: 5,
      increase: 1, // haw many black had to shift
      hideCallback: hideElement, // passing arrays to all callback
      displayCallback: displayElement,
      disableCallback: disableElement,
      disableButtonCallback: disableButtonElement,
      enableButtonCallback: enableButtonElement,
      enableCallback: enableElement,
      nextButton: $('.next'),
      prevButton: $('.prev')
  };
  var options = $.extend(defaults, options);
  var observeButtons = function(slider, options) {
    // check out buttons
    // previous
    if(!slider.hasPrevious()) {
      options.disableButtonCallback({'object':options.prevButton});
    }
    else {
      options.enableButtonCallback({'object':options.prevButton});
    }

    // next
    if(!slider.hasNext()) {
      options.disableButtonCallback({'object':options.nextButton});
    }
    else {
      options.enableButtonCallback({'object':options.nextButton});
    }
  }
  
  return this.each(function() {
    // store all item in an object that handle all functions
    //slider.init(options);
    //slider.fill($(this).find(".slideItem"));
    
    // my slider object
    var slider = new Batch(options);
    slider.fill($(this).find(".slideItem"));
    
    var hidden_items = 0;
    
    // hide all elements
    $.each( slider.getItems(), function(index, item){
      //if(item) options.hideCallback({'object':item});
	if(item) {
	    if($(item).css('display') == 'none')
		hidden_items++;
	    $(item).hide();
	}
    });
    
    // display
    $.each( slider.getDisplayable(), function(index, item){
      if(item) $(item).show();
      //if(item) options.displayCallback({'object':item});
      //options.displayCallback({'object':slider.getItem(index)});
    });
    
    // check out buttons
    observeButtons(slider, options);
    
    
    // prepare next and previous button to be clicked
    // prev action
    options.prevButton.click(function() {
      for(var index=0; index < slider.getIncrease(); index++) {
        if(slider.hasPrevious()) {
          try {
	    var last = slider.getLastItem();
            options.hideCallback({'ohide':last});
            slider.decreaseIndex();
            options.displayCallback({
		'oshow':slider.getFirstItem(),
		'ohide':last,
		'direction':'prev' });
          }
          catch(e) {
            // does not exist
            alert('Previous error:'+e);
          } 
        }
        else {
          break;
        }
      }
      // check out buttons
      observeButtons(slider, options);
    });
  
    // next action
    options.nextButton.click(function() {
      for(var index=0; index < slider.getIncrease(); index++) {
        if(slider.hasNext()) {
          try {
	    var first = slider.getFirstItem();
            options.hideCallback({'ohide':slider.getFirstItem()});
            slider.increaseIndex();
            options.displayCallback({
		'oshow':slider.getCurrentItem(),
		'ohide':first,
		'direction':'next' });
          }
          catch(e) {
            // does not exist
            alert('Next error:'+e);
          } 
        }
        else {
          break;
        }
      }
      // check out buttons
      observeButtons(slider, options);
    });
    
    //options.nextButton.click();
    
    //alert(hidden_items);
    for(var i = 0; i < hidden_items; i++) {
	options.nextButton.click();
    }
    
    
  });
  
}


function Batch(options){
  
  this.viewable = options.viewable;
  this.index = 0;
  this.increase = options.increase;
  this.items = {};
  this.counter = 0;
  
  this.addItem = function(index, item) {
    this.counter++;
    this.items[index] = item;
    return true;
  }

  this.fill = function(items) {
    var new_items = {};
    var counter = 0;
    $.each( items, function(index, item){
      //this.addItem(index, item);
      counter++;
      new_items[index] = item;
    });
    this.counter = counter;
    this.items = new_items;
    if(this.counter > this.viewable) {
      this.index = this.viewable - 1;
    }
    else {
      this.index = this.counter - 1;
    }
  }

  this.getItems = function() {
    return this.items;
  }

  // getDisplayable
  this.getDisplayable = function() {
    var items = {};
    var startindex = (this.getIndex() - this.getViewable()) + 1;
    if(startindex < 0) {
      startindex = 0;
    }
    for(var index=startindex; index < startindex+this.getViewable(); index++) {
      try {
        items[index] = this.getItem(index);
      } catch(e) {
        // index not present
      }
    }
    return items;
  }
  
  this.getItem = function(index) {
    return this.items[index];
  }
  
  this.getCurrentItem = function() {
    return this.getItem(this.getIndex());
  }
  
  this.getFirstItem = function() {
    var index = (this.getIndex() - this.getViewable()) + 1;
    return this.getItem(index);
  }
  
  this.decreaseIndex = function() {
    if(this.hasPrevious()) {
      var i = this.index;
      i--;
      this.index = i;
      return true;
    }
    return false;
  }
  this.increaseIndex = function() {
    if(this.hasNext()) {
      var i = this.index;
      i++;
      this.index = i;
      return true;
    }
    else {
      return false;
    }
  }
  
  
  this.getLastItem = function() {
    return this.getCurrentItem();
  }  
  
  this.getIncrease = function() {
    return this.increase;
  }
  
  this.getViewable = function() {
    return this.viewable;
  }
  
  this.getIndex = function() {
    return this.index;
  }
  
  this.hasNext = function() {
    if((this.index+1) < this.counter) {
      return true;
    }
    return false;
  }
  
  this.hasPrevious = function() {
    if(this.getIndex() - this.getViewable() >= 0) {
      return true;
    }
    return false;
  }  
  
}

function hideElement(options) {
    //$(options.ohide).hide();
}


function displayElement(options) {
    if(options.direction == 'next') {
	$(options.ohide).hide();
	$(options.oshow).show();
	//$(options.ohide).css('visibility','hidden');
	//$(options.ohide).animate({width: 0}, 400);
	//$(options.oshow).css('visibility','visible');
	//$(options.oshow).width(0);
	//$(options.oshow).animate({width: 68}, 400);
    }
    else {
	$(options.ohide).hide();
	$(options.oshow).show();
	//$(options.ohide).css('visibility','hidden');
	//$(options.ohide).animate({width: 0}, 400);
	//$(options.oshow).css('visibility','visible');
	//$(options.oshow).width(0);
	//$(options.oshow).animate({width: 68}, 400);
    }
    //$(options.oshow).show();
}


function displayVElement(options) {
    if(options.direction == 'next') {
	$(options.ohide).hide();
	$(options.oshow).show();
    }
    else {
	$(options.ohide).hide();
	$(options.oshow).show();
    }
}

// ok
//function displayElement(options) {
//    if(options.direction == 'next') {
//	$(options.ohide).css('visibility','hidden');
//	$(options.ohide).animate({width: 0}, 400);
//	$(options.oshow).css('visibility','visible');
//	$(options.oshow).width(0);
//	$(options.oshow).animate({width: 68}, 400);
//    }
//    else {
//	$(options.ohide).css('visibility','hidden');
//	$(options.ohide).animate({width: 0}, 400);
//	$(options.oshow).css('visibility','visible');
//	$(options.oshow).width(0);
//	$(options.oshow).animate({width: 68}, 400);
//    }
//    //$(options.oshow).show();
//}

function disableButtonElement(options) {
    $(options.object).css('visibility', 'hidden');
}

function enableButtonElement(options) {
    $(options.object).css('visibility', 'visible');
}

function disableElement(options) {
    $(options.object).css('visibility', 'hidden');
}

function enableElement(options) {
    $(options.object).css('visibility', 'visible');
    //$(options.object).show();
    //$(options.object).css('opacity', 1.0);
}