var Timeline = new Class({
	
	options : {
		'timeInterval' : 'year', 							// requires hour, day, week, month, year, decade or century
		'intervalDistance' : 160,							// requires interval distance for specified time increment
		'startDate' : 01/01/07, 								// if null, then the first date is used, format: mm/dd/yy
		'endDate': 01/01/12, 									// if null, the the last date is used, format: mm/dd/yy
		'timelineWrapperId' : 'timelineWrapper',			// the id for the timeline wrapper
		'milestoneWrapperId' : 'milestoneWrapper',			// the id for the milestone wrapper 
		'milestoneIconClass' : 'milestone',					// the class for the milestones to be inserted
		'milestoneIconActiveClass' : 'activeMilestone',		// the class for the active milestone
		'milestoneDateClass' : 'Date',						// the date in the defenition list to be used for the milestones
		'sliderId' : 'timelineSlider'						// the id for the slider element
	},
	
// 'timeline' should be the ordered list to be interpreted into the actual timeline
	initialize : function(timeline, options){
		this.setOptions(options);
		this.timelineEvents = $(timeline);
		this.milestones = this.timelineEvents.getElements('.' + this.options.milestoneDateClass);
		this.milestones.each(function(milestone){	
			milestone.date = this.convertDate(milestone.get('text'));
		}, this);
		this.startDate = this.convertDate(this.options.startDate) || this.milestones[0].date;
		this.endDate = this.convertDate(this.options.endDate) || this.milestones[this.milestones.length - 1].date;
		this.range = this.endDate - this.startDate;
		this.setIntervals();
		this.createTimeline();
	},
	
	convertDate : function(dateStr){
		if (!dateStr)
			return false;
		var temp = dateStr.split('/');
		var tempDate = new Date();
		tempDate.setMonth(temp[0] - 1);
		tempDate.setDate(temp[1]);
		tempDate.setFullYear(temp[2]);
		return Date.parse(tempDate) / 1000;
	},
	
	setIntervals : function(){
		switch(this.options.timeInterval){
			case 'century':
				// time range divided by the number of seconds in a day, divided by number of days in a year, divided by 100 years
				this.intervals =  ((((this.range) / 86400) / 365) / 100);
				break;
			case 'decade':
				// time range divided by the number of seconds in a day, divided by number of days in a year, divided by 10 years
				this.intervals =  ((((this.range) / 86400) / 365) / 10);
				break;
			case 'year':
				// time range divided by the number of seconds in a day, divided by number of days in a year
				this.intervals = (((this.range) / 86400) / 365);
				break;
			case 'month':
				// time range divided by the number of seconds in a day, divided by number of days in a year, multiplied by 12 months
				this.intervals = ((((this.range) / 86400) / 365) * 12);
				break;
			case 'week':
				// time range divided by the number of seconds in a day, divided by number of days in a year, multiplied by 52 weeks
				this.intervals = ((((this.range) / 86400) / 365) * 52);
				break;
			case 'hour':
				// time range divided by the number of seconds in a day, divided by number of days in a year, multiplied by 52 weeks, times number of hours in a week
				this.intervals = (((((this.range) / 86400) / 365) * 52) * 168);
				break;
		}
	},
	
	createTimeline : function(){
		// get timeline width based on intervals multiplied by interval distance
		this.timelineWidth = this.intervals * this.options.intervalDistance;
		
		// create a wrapper to put everything in, apply id option, appl width
		this.timelineWrapper = new Element('div', {
			'id' : this.options.timelineWrapperId,
			'styles' : {
				'width' : this.timelineWidth
			}
		}).injectBefore(this.timelineEvents);
		
		// create a wrapper for the milestones and put it in the timeline wrapper
		this.milestoneWrapper = new Element('div', {
			'id' : this.options.milestoneWrapperId
		}).injectInside(this.timelineWrapper);
		
		// add each milestone to the milestone wrapper and set its position based on the percentage of the total range
		this.milestones.each(function(milestone, index){
			var percent = ((this.startDate - milestone.date) / (this.endDate - this.startDate)) * -100;
			var percent = (percent * this.timelineWidth) / 100;
			var current = new Element('div', {
				'class' : this.options.milestoneIconClass
			}).injectInside(this.milestoneWrapper)
			percent = (percent - (current.clientWidth / 2)) - (current.clientWidth * index);
			current.setStyle('left', percent);
		}, this);
		
		// create the slider and put it in the timeline wrapper after the milestone wrapper
		this.slider = new Element('div', {
			'id' : this.options.sliderId
		}).injectInside(this.timelineWrapper);
		
		// create the fx for the slider to use when a milestone is clicked 
		this.slider.scroll = new Fx.Tween(this.slider, {
			'transition' : Fx.Transitions.Back.easeOut,
			'link' : 'cancel'
		});
		
		// create the accordion to hide/show milestone description when milestones are clicked, onActive will move the slider to the milestone
		this.accordion = new Accordion($$('.' + this.options.milestoneIconClass), this.timelineEvents.getElements('dt'), {
			onActive: function(toggler){
				toggler.addClass(this.options.milestoneIconActiveClass);			
				var togglerCenter = (toggler.clientWidth / 2);
				var sliderCenter = (this.slider.clientWidth / 2);
				if(togglerCenter > sliderCenter)
					var center = togglerCenter / 2;
				else
					var center = (sliderCenter * -1) + togglerCenter;
				var slideTo = toggler.getLeft() + center;
				this.slider.scroll.start('left', slideTo);
			}.bind(this),
			onBackground: function(toggler){
				toggler.removeClass(this.options.milestoneIconActiveClass);				
			}.bind(this)			
		});
	}
	
});

Timeline.implement(new Options, new Events);