////////////////////// THE CYCLE OBJECT CLASS //////////////////////
// This is essentially a class which cycles through the div ids passed
// to it on creation
function CycleObject(ids, transType) {

  // Methods
  this.setVisible = function(index) {

    switch(this.transType) {

      case 'normal':
        $(this.ids[this.currentlyVisible]).hide();
        $(this.ids[index]).show();
        this.currentlyVisible = index;
        break;

      case 'fade':
        new Effect.Fade(
          this.ids[this.currentlyVisible],
      		{
      			from: 1.0,
      			to: 0.0,
      			duration: 0.3,
      			queue: 'end'
      		}
      	);

      	new Effect.Appear(
          this.ids[index],
      		{
      			from: 0.0,
      			to: 1.0,
      			duration: 0.3,
      			queue: 'end'
      		}
      	);
        this.currentlyVisible = index;
        break;
    }
    
    // Notify any 'listeners'
    if(this.callbackFunction){
      this.callbackFunction(this.ids[index], index);
    }
    
  }

  this.nextItem = function() {
    // If we're at the end of the list...
    if( this.currentlyVisible == this.ids.length - 1 ) {
      return false;
    } else {
      this.setVisible(this.currentlyVisible + 1);
      return true;
    }
  }

  this.prevItem = function() {
    // If we're at the beginning of the list...
    if( this.currentlyVisible == 0 ) {
      ;// do nothing
    } else {
      this.setVisible(this.currentlyVisible - 1);
    }
  }

  this.selectItem = function(itemID){
      // Get the index
    index = null;
    for(i = 0; i < this.ids.length; i++) {
      if(this.ids[i] == itemID) {
        index = i;
        break;
      }
    }
    
    // If the id exists, show it
    if(index != null){
      this.setVisible(index);
    }
  }

  this.startCycle = function(maxNumCycles) {
  
    if(maxNumCycles){
      this.maxNumCycles = maxNumCycles;
    } else {
      // null means infinite in this case
      this.maxNumCycles = null;
    }
    this.cycleObject = new PeriodicalExecuter(
      this.onUpdateCycle.bind(this), 5 // this is the number of seconds between each interval
    );
  }

  this.stopCycle = function() {
    if(this.cycleObject){
      this.cycleObject.stop();
    }
    this.cycleObject = null;
  }

  this.toggleCycle = function() {
    if (this.cycleObject == null) {
      this.startCycle();
    } else {
      this.stopCycle();
    }
  }

  this.assignCallback = function(callbackFunction){
    this.callbackFunction = callbackFunction;
  }

  this.onUpdateCycle = function (pe) {
    if (this.nextItem() == false) {
      this.setVisible(0);
      this.cycleCount++;
    }
    if (this.cycleCount == this.maxNumCycles){
      this.stopCycle();
    }
  }

  // Properties

  // An array of ids over which the object will cycle
  // First check that the id exists, if not, discard it
  this.ids = [];
  for(i = 0; i < ids.length; i++) {
    if($(ids[i]) != null) {
      this.ids.push(ids[i]);
    }
  }

  // Transition is 'fade' by default
  this.transType = typeof(transType) != 'undefined' ? transType : 'fade';

  // The index (of the array ids) of the currently visible div
  this.currentlyVisible = 0;
  
  // The call back function which gets called every time an item
  // is made visible
  this.callbackFunction = null;
  
  // The number of cycles it goes through when startCycle() is called
  // null means infinity
  this.cycleCount = 0;
  this.maxNumCycles = null;

  // Initialisation
  this.cycleObject = null;
  // Set the first one as visible and all the others as not
  $(this.ids[0]).show();
  for(i = 1; i < this.ids.length; i++){
    $(this.ids[i]).hide();
  }

}

/////////// END OF CYCLEOBJECT CLASS //////////////////
