//generic rollover module

function Rollover(rollovers, displays, config) {

  // Set up the lists and add the specified observer to them.
  this.initialize = function(rollovers, displays, config) {
    this.rolloverList = this.generateList(rollovers);
    this.displayList = this.generateList(displays);
    if (config == null) config = {};
    this.imageList = this.generateList(config.images);
    this.period = config.period;
    var rollAction = config.action || 'mouseover';
    this.imageShow = config.imageShow || '_over.gif';
    this.imageHide = config.imageHide || '_up.gif';
    this.showType = config.showType || 'block';
    var startingPoint = config.startingPoint || 0;
    this.switchUp(startingPoint, true);
    this.cycle(startingPoint);
    this.rolloverList.each(function (item, index) {
      item.observe(rollAction, this.switchUp.bind(this, index));
      if (rollAction=='click' || rollAction == 'dblclick' || rollAction=='mousedown')
	item.setStyle({cursor:'pointer'});
    }, this);
    this.cacheImages();
  };


  // Perform the content switching on index'th element.
  // Use periodic to stop execution of auto rotation.
  this.switchUp = function(index, periodic) {
    if (this.period!= null && periodic!=true)
      this.period = null;
    this.displayList.each(function (item) {
      item.hide();
    });
    this.displayList[index].style.display = this.showType;
    this.swapImages(index);
  };

  //if the images are defined, switch one for the other.
  this.swapImages = function (index) {
    if (this.imageList!=null && this.imageList.length!=0) {
      this.imageList.each(function (item) {
	item.src = item.src.replace(this.imageShow, this.imageHide);
      }, this);
      this.imageList[index].src = this.imageList[index].src.replace(this.imageHide, this.imageShow);
    }
  };

  // If a period is defined, cycle through the list automatically.
  this.cycle = function(index) {
    if (this.period != null) {
      this.switchUp(index, true);
      var nextIndex = (index+1) % this.rolloverList.length;
      setTimeout(this.cycle.bind(this, nextIndex, true), this.period);
    }
  };

  // Parse the input to return the list of element references.
  this.generateList = function(input) {
    if (Object.isString(input)) {
      return $$(input);
    }
    else if (Object.isArray(input)) {
      var output = [];
      input.each(function (element) {
	output.push($(element));
      }, this);
      return output;
    }
    else {
      return null;
    }
  };

  // Cache the rollover images so there is no visual delay.
  this.cacheImages = function() {
    if (this.imageList!=null) {
      this.imageList.each(function (img) {
	new Element('img', {src:this.toggleImageSource(img)});
      }, this);
    }
  };

  // Get the reverse name of any toggle image.
  this.toggleImageSource = function(image) {
    if (image.src.indexOf(this.imageShow)==-1)
      return image.src.replace(this.imageHide, this.imageShow);
    else
      return image.src.replace(this.imageShow, this.imageHide);
  };

  this.initialize(rollovers, displays, config);
}
