/**
 *  Accordion Class
 *  functions based on class names, no need to assign unique IDs, those are assigned automatically
 *  @requires prototype.js 1.5+
 *  @requires scriptaculous 1.7+
 *  @requires alttech common.js - specifically the Cookie class definition
 */
Accordion = Class.create();
Accordion.prototype = {
	/**
	 *  attach event listeners and assign unique IDs
	 *  @param parent_id - id of parent container
	 *  @param clickable - clickable element to trigger accordion
 	 *  @param item - container item for each accordion item - optional
	 *  @param contents - contents item for each accordion item's contents - optional
	 */
	initialize:function(parent_id,clickable,options) {
		if(!clickable) { alert('clickable must be defined for accordion.js to function'); }
		else { options.clickable = clickable; }
		this.set_options(options || {});
		var items = $$('#' + parent_id + ' .' + this.options.item);
		var counter = 0;
		var tgt = this.check_target();
		items.each(function(item) {
				var item_id = 'item_' + ++counter;
				var contents_id = 'contents_' + counter;
				item.id = item_id;
				var header = $$('#' + item_id + ' ' + clickable)[0];
				if(header)
				{
					header.clickable = true;
					if(!header.id) { header.id = 'header_' + counter; }
					Event.observe(header,'click',this.accordion.bindAsEventListener(this),false);
					if(this.options.onclick) { Event.observe(header,'click',this.options.onclick.bindAsEventListener(this),false); }

					var contents = $$('#' + item_id + ' .' + this.options.contents)[0];
					if(contents != undefined) // contents are optional - script simply won't run if there's nothing to show
					{
						if (counter > 1 && contents.getStyle('display') != 'none' && tgt.empty()) { contents.setStyle({display: 'none'}); }
						else if (!tgt.empty() && header.id != tgt) { contents.setStyle({display: 'none'}); }
						else if (!tgt.empty() && header.id == tgt) { contents.setStyle({display: 'block'}); }
						
						item.has_contents = true;
						contents.id = contents_id;
						if(contents.style.display == 'none') { item.addClassName(this.options.closed_class); }
						else
						{
							item.addClassName(this.options.open_class);
							this.currentItem = item.id;
						}
						contents.innerHTML = '<div>' + contents.innerHTML + '</div>';
					}
				}
			}.bind(this));			
	},
	/**
	  * Set options from passed in data
	  * @param - array
	  */
	set_options:function(options) {
		this.options = $H({
				duration: .5,			 					// how long the effect should last
				scrollbar: false,		 					// if the window scrollbars should always be visable
				item: 'item',			 					// className of parent item
				clickable: 'h2',							// element type to trigger the effect
				contents: 'contents',	 					// className of div to be toggled
				scope: 'accordion',		 					// unique scope for animations
				open_class: 'open',		 					// className for open item
				closed_class: 'closed',	 					// className for closed item
				onclick: false,			 					// onclick action for clickable item
				transition: Effect.Transitions.sinoidal,	// if by chance you want a different transitional point
				scroll: false,								// should we scroll to the next entry
				scrollOffset: 0,							// offset for item scroll
				scrollDuration: 1,							// scroll duration/speed
				preferCookie: false							// wether a cookie should override the URL for opening sections
			}).merge(options);

		if(this.options.scrollbar) { $$('html')[0].style.overflow = 'scroll'; }
	},
	/**
	  *  open item
	  *  will close an item that is clicked on twice
	  *  @param item - parent node of clicked item
	  */
	accordion:function(event) {
		var clicked = $(Event.element(event));
		// kind of a hack, but needed if a nested element to the clickable element is the registered click
		if(!clicked.clickable) { clicked = clicked.up(this.options.clickable); }
		var item = clicked.up('.' + this.options.item);
		if(this.currentItem) { this.currentItem = $(this.currentItem); }

		if((!this.currentItem && item.has_contents) || (item.id != this.currentItem.id && item.has_contents))
		{
			if(this.currentItem)
			{
				// multiple items are open, open and close
				var elo = document.getElementsByClassName(this.options.contents,item)[0];
				var elc = $(document.getElementsByClassName(this.options.contents,this.currentItem.id)[0].id);

				item.addClassName(this.options.open_class);
				item.removeClassName(this.options.closed_class);
				new Effect.Parallel(
						[new Effect.BlindDown(elo,{sync: true}), new Effect.BlindUp(elc,{sync: true})],
						{duration: this.options.duration, transition: this.options.transition, queue: { scope: this.options.scope }}
					);
				this.currentItem.removeClassName(this.options.open_class);
				this.currentItem.addClassName(this.options.closed_class);
			}
			else
			{
				// nobody is open, just open clicked item
				var elo = document.getElementsByClassName(this.options.contents,item)[0];
				item.addClassName(this.options.open_class);
				item.removeClassName(this.options.closed_class);
				new Effect.BlindDown(elo,{duration: this.options.duration, transition: this.options.transition, queue: {position: 'end', scope: this.options.scope, limit: 2}});
			}
			this.currentItem = item;
			new Effect.ScrollTo(elo.id,{duration: this.options.scrollDuration, offset: this.options.scrollOffset});
			if(clicked.id) 
			{ 
				Cookie.set('open_accordion',clicked.id);
				window.location.hash = clicked.id; 
			}
		}
		else
		{
			// open item was clicked, close it
			if(this.currentItem)
			{
				var elc = $(document.getElementsByClassName(this.options.contents,this.currentItem.id)[0].id);
				new Effect.BlindUp(elc,{duration: this.options.duration, transition: this.options.transition, queue: {position: 'end', scope: this.options.scope, limit: 2}});
				this.currentItem.removeClassName(this.options.open_class);
				this.currentItem.addClassName(this.options.closed_class);
				this.currentItem = null;
				if(clicked.id) { Cookie.erase('open_accordion'); }
			}
		}

	},
	/**
	 * see if there's an id specified in the url hash and if that id exists in the page
	 * @return string
	 */
	check_target:function()
	{
		var t = window.location.hash.replace(/#/,'');
		if((!t || t.empty()) || (t && this.options.preferCookie && Cookie.get('open_accordion'))) { t = Cookie.get('open_accordion'); }
		if($(t))
		{
			$(t).scrollTo();
			return t;
		}
		else { return ''; }
	}
}