	var Togl = {
		//configurable properties set to their default values
		id: 				'body',		//id of the parent element containing the toggles
		toggle: 			'li',		//element acting as toggle container. Must have class='togl', and optionally 'togl-nocollapse'
		target: 			'div',		//element acting as the target to toggle
		heading:			false,		//element containing the toggle heading text. Actual text should be wrapped in a <span> with class='togltitle'
		openSrc:			false,		//path to the 'open' graphic
		closedSrc:			false,		//path to the 'closed' graphic
		slidr:				false,		//boolean indicating whether to slide
		slidrSpeed:			500,		//speed of slidr in px/s
		slidrMinDuration:	250,		//minimum duration of slidr in ms
		fadr:				false,		//boolean indicating whether to fade
		fadrDuration:		750,		//duration of fadr in ms
		fadrBgColor:		[],			//array containing [start,end] colors
		fadrBorderColor:	[],			//array containing [start,end] colors
		
		//internal properties
		elements: {
			span:		document.createElement('span'),
			img: 		document.createElement('img')
		},
		originalHeight:	false,
		valve:			false,
		
		// utility functions
		getBodyHeight: function(){		//cross-browser height retrieval
			bodyHeight = (document.viewport.getHeight() == 0) ? document.body.scrollHeight : $$('body')[0].getHeight();
			return bodyHeight;
		},
		
		initialize: function(params){

			this.id =					(typeof(params.id) != 'undefined') ? params.id : this.id;
			this.toggle =				(typeof(params.toggle) != 'undefined') ? params.toggle : this.toggle;
			this.target =				(typeof(params.target) != 'undefined') ? params.target : this.target;
			this.heading =				params.heading;
			this.openSrc =				params.openSrc;
			this.closedSrc =			params.closedSrc;
			this.slidr =				params.slidr || false;
			this.slidrSpeed =			(typeof(params.slidrSpeed) != 'undefined') ? params.slidrSpeed : this.slidrSpeed;
			this.slidrMinDuration =		(typeof(params.slidrMinDuration) != 'undefined') ? params.slidrMinDuration : this.slidrMinDuration;
			this.fadr =					params.fadr || false;
			this.fadrDuration =			(typeof(params.fadrDuration) != 'undefined') ? params.fadrDuration : this.fadrDuration;
			this.fadrBgColor =			(typeof(params.fadrBgColor) != 'undefined') ? params.fadrBgColor : this.fadrBgColor;
			this.fadrBorderColor =		(typeof(params.fadrBorderColor) != 'undefined') ? params.fadrBorderColor : this.fadrBorderColor;
			
			var self = this;
			
			//create new togl objects
			Utils.addLoadEvent(
				function(){
					var parent = $(this.id);
					var toggles = parent.select(this.toggle+'.togl');
					toggles.each(
						function(item,i){
							var toglrParams = {
								toggle:			item,
								target:			item.getElementsByTagName(this.target)[0],
								img:			this.elements.img.cloneNode(true),
								span:			this.elements.span.cloneNode(true),
								textcontent:	null
							}
							var toglr = new ToglObj(toglrParams);
						}.bind(this)
					)
				}.bind(self)
			);

			//create the valve element
			Event.observe(window, 'load', function() {
					this.originalHeight = document.height;
					this.valve = $(document.createElement('div'));
					this.valve.style.position = 'absolute';
					this.valve.style.width = '1px';
					this.valve.style.height = this.getBodyHeight()+'px';
					$$('body')[0].insert({top:this.valve});
				}.bind(self)
			);

		} //end of initialize
	} //end of Togl
	
	var ToglObj = Class.create();
	ToglObj.prototype = {
	
		toggle:				false,
		target:				false,
		mooSlide:			false,
		mooUnslide:			false,
		mooFade:			false,
		mooUnfade:			false,
		fadrTextColor:		false,
		fadrLinkcolor:		false,
		fadrFadeColor:		false,
		img:				false,
		span:				false,
		textcontent:		false,
		openHeight:			false,
		closedHeight:		false,
		computedHeight:		false,
		startValveHeight:	false,
		
		initialize: function(params){
			this.toggle =		params.toggle;
			this.target =		$(params.target);
			this.img =			params.img;
			this.span =			params.span;
			this.textcontent =	params.textcontent;
			//set text colors
			this.fadrTextColor = '#3f3f3f';
			this.fadrLinkColor = '#4744dd';
			this.fadrFadeColor = '#cccccc';
			
			
			var self= this;
			
			this.hideTarget();
			this.createImg();
			Event.observe(this.img, 'click', this.clickImg.bind(this));			
		}, //end of initialize

		hideTarget: function(){
			this.target.style.position = 'relative'; //just in case it isn't already
			this.target.style.overflow = 'hidden';
			this.closedHeight = 1; //closedHeight=0 breaks IE
			this.openHeight = this.target.getHeight();
			this.computedHeight = this.openHeight-this.closedHeight;
			this.slidrDuration = (this.openHeight / Togl.slidrSpeed)*1000;
			//set a floor for the duration so small toggles don't open too quickly
			this.slidrDuration = (this.slidrDuration <= Togl.slidrMinDuration) ? Togl.slidrMinDuration : this.slidrDuration;
			this.mooSlide = new Fx.Styles(this.target,{duration:this.slidrDuration,onComplete:this.slideFunctions,context:this});
			this.mooUnslide = new Fx.Styles(this.target,{duration:this.slidrDuration,onComplete:this.unSlideFunctions,context:this});
			if (this.toggle.hasClassName('togl-nocollapse')){
				this.target.addClassName('togl-opened');
			}else{
				this.mooSlide.set({'height':this.closedHeight});
				this.target.addClassName('togl-closed');
			}
		}, //end of hideTarget
	
		createImg: function(){
			//find the element that contains the text within the heading element		
			var oTopElement = this.toggle.getElementsByTagName(Togl.heading);
			var oContainer = $(oTopElement[0]).select('.togltitle');
			var oTextNode;
			//check to see if the title has been replaced by sIFR
			var bHasSifr = oContainer[0].hasClassName('sIFR-replaced');
			(bHasSifr) ?
				oTextNode = oContainer[0].lastChild.firstChild :
				oTextNode = oContainer[0];
			//retrieve heading text or use default message
			(oTextNode.nodeType == Utils.node.TEXT_NODE) ?
				this.textcontent = oTextNode.nodeValue :
				this.textcontent = 'this item';
			//create img id from toggle id
			var sImgId = this.toggle.getAttribute('id').substring(2);
			//create span and image nodes and attach to document
			this.span.setAttribute('class', 'toglrSpan');
			this.img.style.display = 'inline';
			//IE bugfix - won't change the cursor when added as a style rule, probably b/c of the DOMready load function
			this.img.style.cursor = 'hand';
			this.img.setAttribute('id', 'img'+sImgId);
			this.img.setAttribute('class', 'toglrImg');
	
			if (this.toggle.hasClassName('togl-nocollapse')){
				this.img.setAttribute('title', 'collapse ' + this.textcontent);
				this.img.setAttribute('src', Togl.openSrc);
			}else{
				this.img.setAttribute('title', 'expand ' + this.textcontent);
				this.img.setAttribute('src', Togl.closedSrc);
			}
			oTopElement[0].insert({top:this.span});
			$(this.span).insert({top:this.img});
		}, //end of createImg
					
		clickImg: function(){
			//initialize valve height
			this.startValveHeight = Togl.valve.getHeight();
			this.resetOpacity();
			//alert(this.target.style.opacity);
			if (this.target.hasClassName('togl-closed')){
				
				this.img.setAttribute('src', Togl.openSrc);
				this.img.setAttribute('title', 'collapse ' + this.textcontent);
				
			
				if (Togl.slidr){
					this.target.removeClassName('togl-closed');
					this.target.addClassName('togl-opening');
					this.target.style.color = this.fadrFadeColor;
					var links = this.target.getElementsByTagName('a');
					var i;
					for (i=0;i<links.length;i++){
						links[i].style.color = this.fadrFadeColor;
					}
					this.mooSlide.custom({'height':[this.closedHeight,this.openHeight]}); //onComplete calls setValve()
				}else{
					this.mooSlide.set({'height':this.openHeight});
					this.target.removeClassName('togl-closed');
					this.target.addClassName('togl-opened');	
				}
			}
			else if (this.target.hasClassName('togl-opened')){
			
				this.img.setAttribute('src', Togl.closedSrc);
				this.img.setAttribute('title', 'expand ' + this.textcontent);
			
				if (Togl.slidr){
					this.target.removeClassName('togl-opened');
					this.target.addClassName('togl-closing');
					//alert('togl-closing');
					this.mooUnslide.custom({'height':[this.openHeight,this.closedHeight]}); //onComplete calls releaseValve()
					//alert('mooSlide called');
				}else{
					this.mooSlide.set({'height':this.closedHeight});
					this.target.removeClassName('togl-opened');
					this.target.addClassName('togl-closed');
				}
			}
			else{return false;}
		}, //end of clickImg
		
		slideFunctions: function(){
			this.setValve();
			//alert(Fx.Base.prototype.log.inspect());
				//Fx.Base.prototype.log = [];
		},
		
		unSlideFunctions: function(){
			this.releaseValve();
			this.doUnfade(1,0);
			
		},
		
		doFade: function(from,to){
			this.mooFade = new Fx.Styles(this.target,{duration:Togl.fadrDuration,onStart:this.resetTextStyles,context:this,unit:''});
			this.mooFade.custom({'opacity':[from,to]});
			
		},
		
		doUnfade: function(from,to){
			this.mooUnfade = new Fx.Styles(this.target,{duration:100,onComplete:this.resetOpacity,context:this,unit:''});
			this.mooUnfade.custom({'opacity':[from,to]});
			
		},
		
		resetOpacity: function(){
			
			this.target.style.opacity=0;
		},

		
		resetTextStyles: function(){
			//reset the text and link colors to the original css
			this.target.style.color = this.fadrTextColor;
			var links = this.target.getElementsByTagName('a');
			for (i=0;i<links.length;i++){
				links[i].style.color = this.fadrLinkColor;
			}
		},

		setValve: function(){
			if (this.target.hasClassName('togl-opening')){
				this.target.removeClassName('togl-opening');
				this.target.addClassName('togl-opened');	
				
				this.startValveHeight = Togl.valve.getHeight();
				var startBodyHeight = Togl.getBodyHeight()-this.computedHeight;
				var startValveBuffer = this.startValveHeight-startBodyHeight;
				var endValveHeight = false;
				var endBodyHeight = Togl.getBodyHeight();
				
				var scrollOffset = document.viewport.getScrollOffsets().top;
				var viewportHeight = (document.viewport.getHeight() == 0) ? document.body.clientHeight : document.viewport.getHeight();
				var pageBottom = scrollOffset+viewportHeight;
				
				//conditionals for determining endValveHeight
				if (pageBottom <= startBodyHeight){ //default state: if there's no valve or it isn't in the viewport 
					endValveHeight = endBodyHeight;
				}
				if (pageBottom > startBodyHeight){ //if any of the valve is showing
					if (startValveBuffer <= this.computedHeight){ //if the buffer space isn't tall enough, or is the same height
						endValveHeight = endBodyHeight;
					}
					if (startValveBuffer > this.computedHeight){ //if the buffer space is taller than the slider
						if (pageBottom-startBodyHeight > this.computedHeight){//if the amount showing in the viewport is taller than the slider
							endValveHeight = pageBottom;
						}
						if (pageBottom-startBodyHeight <= this.computedHeight){//if the amount showing is shorter than the slider, or the same
							endValveHeight = endBodyHeight;
						}
					}
				}
				var valveChange = endValveHeight-this.startValveHeight;
				/*
				alert ('startValveHeight: '+this.startValveHeight+'\n'
					   +'startBodyHeight: '+startBodyHeight+'\n'
					   +'startValveBuffer: '+startValveBuffer+'\n'
					   +'endValveHeight: '+endValveHeight+'\n'
					   +'endBodyHeight: '+endBodyHeight+'\n'
					   +'document.height: '+document.body.scrollHeight+'\n'
					   +'pageBottom: '+pageBottom+'\n'
					   +'valveChange: '+valveChange+'\n\n'
					   +'scrollOffset: '+scrollOffset+'\n'
					   +'viewportHeight: '+viewportHeight+'\n'
					   +'computedHeight: '+this.computedHeight);
				*/
					Togl.valve.style.height = endValveHeight+'px';	
			}else{return false;}
			this.doFade(0,1);
		}, //end of setValve
		
		releaseValve: function(){
			//alert('releaseValve called');
			var startBodyHeight = Togl.getBodyHeight();
			var startValveHeight = Togl.valve.getHeight();
			var startValveBuffer = this.startValveHeight-startBodyHeight;
			var endValveHeight = false;
			var endBodyHeight = startBodyHeight - this.computedHeight;

			var scrollOffset = document.viewport.getScrollOffsets().top;
			var viewportHeight = (document.viewport.getHeight() == 0) ? document.body.clientHeight : document.viewport.getHeight();
			var pageBottom = scrollOffset+viewportHeight;
			/*
			alert ('pageBottom: '+pageBottom+'\n'
				   	+'startBodyHeight: '+startBodyHeight+'\n'
					+'startValveHeight: '+this.startValveHeight+'\n'
					+'viewportHeight: '+viewportHeight+'\n'
					+'computedHeight: '+this.computedHeight);
			*/
			//conditionals for determining endValveHeight
			if (pageBottom <= startBodyHeight){ //if you're not scrolled at least to the bottom of body
				if (pageBottom >= (startBodyHeight-this.computedHeight)){ //if collapsed body will rise above the bottom
					endValveHeight = pageBottom;
				}
				if (pageBottom < (startBodyHeight-this.computedHeight)){ //if collapsed body won't rise above the bottom
					endValveHeight = endBodyHeight;
				}
			}
			if (pageBottom > startBodyHeight){ //if you're scrolled past the bottom of body, so that some valve space is showing
				endValveHeight = pageBottom;
			}
			
			Togl.valve.style.height = endValveHeight+'px';
			
			this.target.removeClassName('togl-closing');
			this.target.addClassName('togl-closed');
		} //end of releaseValve
	} //end of ToglObj

//pass this object into Togl.initialize
var initParams = {
	id: 'ulalbumparent',
	toggle: 'li',
	target: 'div',
	heading: 'h4',
	openSrc: 'http://www.shrineaudio.com/img/arrowopen.gif',
	closedSrc: 'http://www.shrineaudio.com/img/arrowclosed.gif',
	slidr: true,
	slidrMinDuration: 250,
	fadr: true,
	fadrBgColor: ['#ffffff','#f4f8fd'],
	fadrBorderColor:['#ffffff','#cdd0f1']
	}
//create a new Togl instance
var togl1 = Togl.initialize(initParams);


Event.observe(window, 'load', function() {
		var messageField = document.getElementById('ContactMessage');
		var contactForm = document.getElementById('ContactAddForm');
	
		contactForm.onsubmit = (function () {
			if (messageField.value == ''){
				alert ('Please enter a message');
			return false;
			}
		});
	}.bind(this)
);
/*
	var Slidr = Class.create();
	Slidr.prototype = {

		target: 		false,
		img:			false,
		textcontent:	false,
		mask:			false,
		
		initialize: function(params){

			this.target =		params.target;
			this.img =			params.img;
			this.textcontent =	params.textcontent;

			var self = this;

			//create a mask on the target element
			this.createMask();
			//assign the slide image click event handler
			ADS.addEvent(this.img, 'click', ADS.bindFunction(self, this.slideElement));
		}, //end of initialize
		
		createMask: function(){
			this.mask = document.createElement('div');
			//append original div's id with a suffix and add a class for styling
			var sTargetId = this.target.getAttribute('id');
			var oParent = this.target.parentNode;
			this.target.setAttribute('id',sTargetId+'masked');
			ADS.addClassName(this.target, 'slidrcontent');
			
			//give the mask the original target's id, and a class for styling
			this.mask.setAttribute('id',sTargetId);
			ADS.addClassName(this.mask, 'slidrmask');
			this.mask.style.overflow = 'hidden';
			this.mask.style.position = 'relative';

			//append original target as a child
			this.mask.appendChild(this.target);
			oParent.appendChild(this.mask);
		}, //end of createMask

		slideElement: function(){

			this.mask.id = this.mask.getAttribute('id');
			this.target.id = this.target.getAttribute('id');

			if (ADS.hasClassName(this.target,'togl-closed')){

				// switch target to display:block

				//collapse mask to (0)height
				this.mask.style.height = '0px';

				ADS.removeClassName(this.target,'togl-closed');
				ADS.addClassName(this.target,'togl-opened');
			
				this.target.height = this.target.offsetHeight;
				//move target to (-)height
				this.target.style.top = (0-this.target.height)+'px';
				
				//animate mask
				ExpandElement(this.mask.id,this.target.height,20,10);
				//animate target
				MoveElement(this.target.id,0,20,10);
				
				this.img.setAttribute('src', Togl.openSrc);
				this.img.setAttribute('title', 'collapse ' + this.textcontent);
				
			}else{
				this.target.top = parseInt(this.target.style.top) - this.target.height;
				//animate target
				MoveElement(this.target.id,this.target.top,20,6);
				//animate mask
				ExpandElement(this.mask.id,0,20,6);
				
				ADS.removeClassName(this.target,'togl-opened');
				ADS.addClassName(this.target,'togl-closed');

				this.img.setAttribute('src', Togl.closedSrc);
				this.img.setAttribute('title', 'expand ' + this.textcontent);
			}

		} //end of slideElement
	} //end of Slidr
*/
/*
//stuff still left to fix:

function InitializeToggleFlash(sourceElementId) {
	var sourceElement;
	//if the browser supports embeds, and the collection is not empty
	if (document.embeds && document.getElementsByTagName('embed').length != 0) {
		sourceElement = document.getElementsByTagName('embed');
		for (i=0, limit = sourceElement.length; i < limit; i++) {
			if (sourceElement[i].getAttributeNode("name").value != null) {
				if (sourceElement[i].getAttributeNode("name").value == sourceElementId) {
					ClickToggleFlash(sourceElement[i]);
				}
			}
		}
	}
	else {
		//otherwise for IE, Opera
		sourceElement = document.getElementById(sourceElementId);
			ClickToggleFlash(sourceElement);
	}
}

function ClickToggleFlash(sourceElement){
	oImg = sourceElement.parentNode.previousSibling.firstChild;
	oDiv = oImg.divElement;
	oContent = sourceElement.nextSibling.firstChild.value;
	if (oDiv.style.display == "none") {
		oDiv.style.display = "block";
		oImg.setAttribute("src", "http://www.shrineaudio.com/images/arrowopen.gif");
		oImg.setAttribute("title", "collapse " + oContent);
		SlideToggle(oDiv, 'open');
	}
	else if (oDiv.style.display == "block") {
		SlideToggle(oDiv, 'close');
		oImg.setAttribute("src", "http://www.shrineaudio.com/images/arrowclosed.gif");
		oImg.setAttribute("title", "expand " + oContent);
	}
	else {
		return false;
	}
}
*/
