
var FM = {};

Event.observe(window, 'load', function() {
	 externalLinks();
   new fadeFeature('feature', { periodicalTime: 6 });
});


function externalLinks() {
    ($$('a[rel="external"]')).each(function(elm) {
        elm.onclick = function() {window.open(this.href); return false; };
    });
}

FM.Feature = Class.create({

  feature: null,
  window: null,
  features: [],
  totalFeatures: null,
  pips: [],
  totalPips: [],
  nextElms: [],
  prevElms: [],
  pe: null,
  selectedIndex: null,
  nextIndex: null,

	initialize: function(featureId, options) {
		if($(featureId)) {
      this.feature = $(featureId);
      this.options = Object.extend({
        windowClass: 'window', //content area requires features to be in li's
        nextClass: null,
        nextEventType: 'mouseover',
        prevClass: null,
        prevEventType: 'mouseover',
        pipsClass: null, //pip area requires pips to be in li's
        pipEventType: 'mouseover',
        periodicalTime: null,
        selectedClass: 'selected',
        selectedIndex: 0 //if a class of 'selectedClass' isnt already added to an li set selected to index.
      }, options || {});

      this.setupElements();
      this.setupSelected();
      this.layout();
      this.linkActions();
      this.periodicalIncrement();
    }
  },

  setupElements: function() {
    this.window = this.feature.select('.' + this.options.windowClass)[0];

    this.window.select('li').each(function(elm, i) {
      elm.index = i;
      this.features.push(elm);
    }.bind(this));
		this.totalFeatures = this.features.size();

    if(this.options.pipsClass != null) {
      this.feature.select('.' + this.options.pipsClass + ' li').each(function (elm, i) {
        elm.index = i;
        this.pips.push(elm);
      }.bind(this));
      this.totalPips = this.pips.size();
    }

    if(this.options.nextClass != null) {
      this.feature.select('.' + this.options.nextClass).each(function (elm) {
        this.nextElms.push(elm);
      }.bind(this));
    }

    if(this.options.prevClass != null) {
      this.feature.select('.' + this.options.prevClass).each(function (elm) {
        this.prevElms.push(elm);
      }.bind(this));
    }
  },

  layout: function() {
    throw('override layout method in extended class');
  },

  setupSelected: function() {
    this.selectedFeature = this.feature.select('.' + this.options.windowClass + ' .' + this.options.selectedClass)[0];
    if(this.selectedIndex == null) {
       this.selectedIndex = this.options.selectedIndex;
		 	 this.setSelected(this.options.selectedIndex);
		}
  },

  setSelected: function(index) {
		this.features[this.selectedIndex].removeClassName(this.options.selectedClass);
    if(this.options.pipsClass != null) {
      this.pips[this.selectedIndex].removeClassName(this.options.selectedClass);
    }
    this.selectedIndex = index;

    this.features[this.selectedIndex].addClassName(this.options.selectedClass);
    if(this.options.pipsClass != null) {
      this.pips[this.selectedIndex].addClassName(this.options.selectedClass);
    }
	},

  linkActions: function() {
    if(this.options.pipsClass != null) {
      this.pips.invoke('on', this.options.pipEventType, this.pipAction.bind(this));
    }
    if(this.options.nextClass != null) {
      this.nextElms.invoke('on', this.options.nextEventType, this.nextAction.bind(this));
    }
    if(this.options.prevClass != null) {
      this.prevElms.invoke('on', this.options.prevEventType, this.prevAction.bind(this));
    }
  },

  nextAction: function(pips, elm) {
		this.incrementIndex(this.selectedIndex + 1);
  },
  prevAction: function(pips, elm) {
		this.incrementIndex(this.selectedIndex - 1);
  },
	pipAction: function(event, elm) {
    this.incrementIndex(elm.up('li').index);
	},

  periodicalIncrement: function() {
		if(this.options.periodicalTime != null ){
      this.pe = new PeriodicalExecuter(function(pe) {
        this.incrementIndex(this.selectedIndex + 1);
      }.bind(this), this.options.periodicalTime);
		}
	},

  incrementIndex: function(index) {

    this.nextIndex = index;
		this.transition(this.nextIndex);
    
		if (this.pe != null && this.pe != undefined) {
			this.pe.stop();
			this.periodicalIncrement(this.options.periodicalTime);
		}

  },

  transition: function(index) {
    throw('override transition method in extended class');
  }
});


var fadeFeature = Class.create(FM.Feature,{
  layout: function() {
    
  },
  transition: function(index) {
    if(this.totalFeatures > 1) {
      if(index == this.totalFeatures) {
        index = 0;
        this.nextIndex = index;
      }

      var selected = this.features[this.selectedIndex];
      var next = this.features[index];

      next.addClassName('next');
      new Effect.Fade(selected, {
        duration: 2,
        from: 1,
        to: 0,
        afterFinish: function() {
          next.removeClassName('next');
          this.setSelected(this.nextIndex);
          selected.setStyle({'display': 'block'});
        }.bind(this)
      });
    }
  }
})
