

var ScrollWindow = Class.create();

ScrollWindow.prototype = {
	
	linkList:null,
	contentList:null,
	initialItem:null,
	viewingWindow:null,
	scrollLeftArrow:null,
	scrollRightArrow:null,
	titleLabel:null,
	selectionBackground:null,
	
	listLength:null,
	farLeft:null,
	farRight:null,
	viewportLength:null,
	
	scrollLength:null,
	scrollDuration:null,
	scrollFastDuration:null,
	scrollType:Effect.Transitions.linear,
	pixelsPerSecond:165,
	fastPixelsPerSecond:null,
	
	scrollEffect:null,
	activeContent:null,
	
	contentEffectIn:Effect.SlideDown,
	contentEffectOut:Effect.Fade,
	contentEffectInOptions:null,
	contentEffectOutOptions:null,
	contentEffectDuration:0.3,
	contentEffectQueue:'content',
	
	linkIdPrefix:'link',
	contentIdprefix:'content',
	
	scrollDirection:'ltr', // options are 'ltr' or 'rtl' for left-to-right and right-to-left respectively
	
	shouldHighlightArrows:true,
	addArrowHoverEffect:true,
	
	//////////////// getters & setters //////////////////////
	
	get_linkList:function () { return this.linkList; },
	get_contentList:function() { return this.contentList; },
	get_initialItem:function() { return this.initialItem; },
	get_viewingWindow:function() { return this.viewingWindow; },
	get_scrollLeftArrow:function() { return this.scrollLeftArrow; },
	get_scrollRightArrow:function() { return this.scrollRightArrow; },
	get_titleLabel:function() { return this.titleLabel; },
	
	set_linkList:function(value) { this.linkList=value; },
	set_contentList:function(value) { this.contentList=value; },
	set_initialItem:function(value) { this.initialItem=value; },
	set_viewingWindow:function(value) { this.viewingWindow=value; },
	set_scrollLeftArrow:function(value) { this.scrollLeftArrow=value; },
	set_scrollRightArrow:function(value) { this.scrollRightArrow=value; },
	set_titleLabel:function(value) { this.titleLabel=value; },
	
	
	////////////////////////////////////////////////
	initialize:function (list,larrow,rarrow,content,visibleWindow,titleObj,firstItem, selectionBkgd)
	{
		
		this.linkList=list;
		this.scrollLeftArrow=larrow;
		this.scrollRightArrow=rarrow;
		this.contentList=content;
		this.viewingWindow=visibleWindow;
		this.titleLabel=titleObj;
		this.initialItem=firstItem;
		this.selectionBackground=selectionBkgd;
		
		this.linkList._scrollWindowObject=this;
	},
		
	/////////////////////// initialize methods /////////////////////////
	initializeObjects: function ()
	{
		
		this.initScrollEffect();
		this.initScrollArrows();
		this.initLinks();
		this.initContent();
		if(this.shouldHighlightArrows)this.HighlightArrows();

		if(this.initialItem)this.timelineItem_click(this.initialItem); 
	},
	initScrollArrows:function()
	{
		this.scrollLeftArrow._scrollWindowObject=this;
		this.scrollRightArrow._scrollWindowObject=this;
		
		if(this.scrollRightArrow!=null)
		{
			this.scrollRightArrow.onmousedown=function() { if (this._scrollWindowObject != null)this._scrollWindowObject.rightArrow_mouseDown(); }
			this.scrollRightArrow.onmouseover=function() { if (this._scrollWindowObject != null)this._scrollWindowObject.rightArrow_mouseover(); }
			this.scrollRightArrow.onmouseout=function() {  if (this._scrollWindowObject != null)this._scrollWindowObject.rightArrow_mouseout(); }
		}

		if(this.scrollLeftArrow!=null)
		{
			this.scrollLeftArrow.onmousedown=function() { if (this._scrollWindowObject != null)this._scrollWindowObject.leftArrow_mouseDown(); }
			this.scrollLeftArrow.onmouseover=function() { if (this._scrollWindowObject != null)this._scrollWindowObject.leftArrow_mouseover(); }
			this.scrollLeftArrow.onmouseout=function() {  if (this._scrollWindowObject != null)this._scrollWindowObject.leftArrow_mouseout(); }
		}
	},
	initScrollEffect:function()
	{
		this.viewportLength = this.viewingWindow.offsetWidth; 
		this.listLength = this.linkList.offsetWidth; 
		
		if(this.scrollDirection=='rtl')
		{
			this.farLeft=0;
			this.farRight=this.listLength - this.viewportLength;
		}
		else
		{
			this.farLeft=-this.listLength + this.viewportLength;
			this.farRight=0;
		}
		
		this.scrollLength=this.farRight-this.farLeft;
		
		if(this.fastPixelsPerSecond==null)this.fastPixelsPerSecond=this.pixelsPerSecond*7;
		
		this.scrollDuration=this.calculateDuration(this.pixelsPerSecond);
		this.scrollFastDuration=this.calculateDuration(this.fastPixelsPerSecond);

	},
	calculateDuration:function(pixelsPerSecond) { return this.scrollLength/pixelsPerSecond; },
	initLinks:function() { 
	if(!this.AddLinkAttributes || !this.isLinkItem || !this.linkList ) return;
		var items = this.linkList.descendants();
		for(i=0;i<items.length;i++)
			if(this.isLinkItem(items[i]))
				this.AddLinkAttributes(items[i]);
	},
	initContent:function() {
		if(!this.AddContentAttributes || !this.isContentItem || !this.contentList) return;
		var items = this.contentList.descendants();
		for(i=0;i<items.length;i++)
			if(this.isContentItem(items[i]))
				this.AddContentAttributes(items[i]);
	},
	
	
	
	
	
	////////////////////// events ////////////////////////////
	callFunction:function(target) { if(target)target();	},
	
	on_leftArrow_mouseover:null,
	on_leftArrow_mouseout:null,
	on_rightArrow_mouseover:null,
	on_rightArrow_mouseout:null,
	on_leftArrow_mouseDown:null,
	on_rightArrow_mouseDown:null,
	on_timelineItem_click:null,
	
	leftArrow_mouseover:function() { 
		if(this.on_leftArrow_mouseover)this.on_leftArrow_mouseover(); 
		this.scrollLeft(this.linkList); 
		if(this.addArrowHoverEffect==true)this.enlargeArrow(this.scrollLeftArrow);
	},
	leftArrow_mouseout:function() { 
		if(this.on_leftArrow_mouseout)this.on_leftArrow_mouseout(); 
		this.cancelEffect(this.linkList); 
		this.cancelEffect(this.selectionBackground); 
		if(this.addArrowHoverEffect==true)this.shrinkArrow(this.scrollLeftArrow);
	},
	rightArrow_mouseover:function() { 
		if(this.on_rightArrow_mouseover)this.on_rightArrow_mouseover(); 
		this.scrollRight(this.linkList);  
		if(this.addArrowHoverEffect==true)this.enlargeArrow(this.scrollRightArrow);
	},
	rightArrow_mouseout:function() { 
		if(this.on_rightArrow_mouseout)this.on_rightArrow_mouseout(); 
		this.cancelEffect(this.linkList); this.cancelEffect(this.selectionBackground); 
		if(this.addArrowHoverEffect==true)this.shrinkArrow(this.scrollRightArrow);
	},
	
	leftArrow_mouseDown:function(sender)
	{
		if(this.on_leftArrow_mouseDown)this.on_leftArrow_mouseDown(); 
		this.scrollLeft(this.linkList,this.fastPixelsPerSecond)
	},
	rightArrow_mouseDown:function(sender)
	{
		if(this.on_rightArrow_mouseDown)this.on_rightArrow_mouseDown(); 
		this.scrollRight(this.linkList,this.fastPixelsPerSecond)
	},
	timelineItem_click:function(sender)
	{
		if(this.on_timelineItem_click)this.on_timelineItem_click(sender);
		
		this.MoveSelectionBackground(sender,sender.parentNode.offsetLeft);
		var newId = this.getContentIdByLinkId(sender.id);
		
		if(this.activeContent!=null) this.FadeItem(this.activeContent);
		
		this.set_TitleText(sender.title);
		this.activeContent = $(newId)
		
		this.AppearItem(this.activeContent);
	},
	
	
	
	/////////////////////////// effects //////////////////////////////
	
	enlargeArrow:function(target)
	{
		var efxDuration = 0.1;
		var efx = new Effect.Scale (target,125,{ scaleY: false, duration:efxDuration, scaleMode: {originalWidth:40} }); 
	},
	shrinkArrow:function(target)
	{
		var efxDuration = 0.1;
		var efx = new Effect.Scale (target,100,{ scaleY: false, duration:efxDuration, scaleMode: {originalWidth:40}  }); 
	},
	
	
	MoveSelectionBackground:function(target, finalLocation)
	{
		if(!target) return;
		if(!this.selectionBackground) return;
		
		var effectDuration = 0.5;
		var effectTransition = Effect.sinoidal;
		var efx = new Effect.Move (this.selectionBackground,{ x: finalLocation,  mode: 'absolute', duration: effectDuration, transition:effectTransition}); 

		if(target!=null) {
			this.selectionBackground.style.height = this.getHeight(target) + 'px';
			this.selectionBackground.style.width = target.offsetWidth + 'px';
			target._currenteffect=efx;
		}
	},
	getHeight:function(target)
	{
		if(!target) return 0;
		var height = target.offsetHeight;

		var lineHeight = 13;	/* mindless work around for IE 6 */
		if (target.getStyle)
			lineHeight = parseFloat(target.getStyle('lineHeight'));
		return height + lineHeight; 
	},
	
	
	scrollLeft:function(target,speed) 
	{ 
		var pixelsPerSecond = speed || this.pixelsPerSecond;

		var remainingDistance=Math.abs(this.viewOffset());
		var newDuration = remainingDistance/pixelsPerSecond;

		this.cancelEffect(target);
		target._currentEffect=new Effect.Move (target,{ x: this.farRight,  mode: 'absolute', duration: newDuration, transition: this.scrollType}); 
		
	},
	scrollRight:function(target,speed) 
	{ 
		var pixelsPerSecond = speed || this.pixelsPerSecond;
		
		var remainingDistance;
		
		if(this.scrollDirection=='rtl')
			remainingDistance=Math.abs(this.farRight-this.viewOffset());
		else
			remainingDistance=Math.abs(this.farLeft+this.viewOffset());
		
		var newDuration = remainingDistance/pixelsPerSecond;

		this.cancelEffect(target);
		target._currentEffect=new Effect.Move (target,{ x: this.farLeft,  mode: 'absolute', duration: newDuration, transition: this.scrollType}); 
	},
	
	ShowItem:function(target) { target.style.display='';  },
	HideItem:function(target) { target.style.display='none';  },
	
	FadeItem:function(target) { 
		if((target==null)||(target=='')) return;
		var defaultOptions = {duration:this.contentEffectDuration,queue:{position:'front',scope:this.contentEffectQueue}};
		this.cancelEffect(target);
		target._currentEffect=new this.contentEffectOut(target, Object.extend(defaultOptions,this.contentEffectOutOptions || {})); 
	},
	
	AppearItem:function(target) { 
		if((target==null)||(target=='')) return;
		
		var defaultOptions = {duration:this.contentEffectDuration,queue:{position:'end',scope:this.contentEffectQueue}};
		this.cancelEffect(target);
		target._currentEffect=new this.contentEffectIn(target, Object.extend(defaultOptions,this.contentEffectInOptions || {})); 
	},
	
	cancelEffect:function(target) { if(target && target._currentEffect)target._currentEffect.cancel(); },
	cancelScroll:function() { this.cancelEffect(this.linkList); },
	
	
	
	
	//////////////////////////// misc ///////////////////////////////////
	
	/* overload the following five functions to customize the items and behaviors that recieve the ScrollWindow effects and events:
		getContentIdByLinkId, isLinkItem, isContentItem, AddLinkAttributes, AddContentAttributes
	*/
	getContentIdByLinkId:function(linkId) { return this.contentIdprefix + linkId.replace(this.linkIdPrefix,''); },
	isLinkItem:function(target) { return (target.tagName=='A'); },
	isContentItem:function(target) { return (target.tagName=='LI'); },

	AddLinkAttributes:function(target) { 
		target._scrollWindowObject=this;
		Event.observe(target,'click',function(){ this._scrollWindowObject.timelineItem_click(target); } );
	},
	AddContentAttributes:function(target) { 
		target._scrollWindowObject=this;
		this.HideItem(target); 
	},
	
	HighlightArrows:function()
	{
		
		var effectDuration = 6;
		var minOpacity = 0.3;
		var numPulses = 10;
		var transitionType = Effect.Transitions.linear
		
		new Effect.Pulsate(this.scrollLeftArrow,{duration:effectDuration, from:minOpacity, pulses:numPulses, transition: transitionType});
		new Effect.Pulsate(this.scrollRightArrow,{duration:effectDuration, from:minOpacity, pulses:numPulses, transition: transitionType});
	},
	
	viewOffset:function() { return -1 * this.linkList.offsetLeft; },
	
	set_TitleText:function(value) { if(this.titleLabel)this.titleLabel.innerHTML=value; }

}

////////////////////////////////Friend functions/////////////////////////////////////

