// accordion.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
// 
// Accordion is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro: 
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//

/*-----------------------------------------------------------------------------------------------*/

if (typeof Effect == 'undefined') 
	throw("accordion.js requires including script.aculo.us' effects.js library!");

var accordion = Class.create();
accordion.prototype = {

	//
	//  Setup the Variables
	//
	showAccordion : null,
	currentAccordion : null,
	duration : null,
	effects : [],
	animating : false,
	
	//  
	//  Initialize the accordions
	//
	initialize: function(container, options) {
	  if (!$(container)) {
	    throw(container+" doesn't exist!");
	    return false;
	  }
	  
		this.options = Object.extend({
			resizeSpeed : 8,
			classNames : {
				toggle : 'accordion_toggle',
				toggleActive : 'accordion_toggle_active',
				content : 'accordion_content'
			},
			defaultSize : {
				height : null,
				width : null
			},
			direction : 'vertical',
			onEvent : 'click'
		}, options || {});
		
		this.duration = ((11-this.options.resizeSpeed)*0.15);

		var accordions = $$('#'+container+' .'+this.options.classNames.toggle);
		accordions.each(function(accordion) {
			Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false);
			if (this.options.onEvent == 'click') {
			  accordion.onclick = function() {return false;};
			}
			
			if (this.options.direction == 'horizontal') {
				var options = {width: '0px', display:'none'};
			} else {
				var options = {height: '0px', display:'none'};
			}
			// options.merge({display: 'none'});			
			
			this.currentAccordion = $(accordion.next(0)).setStyle(options);
		}.bind(this));
	},
	
	//
	//  Activate an accordion
	//
	activate : function(accordion,evt,donest) {

		/*
		*  additional tracking of accordions
		*  save the accordion reference ID before it is changed to 'current_accordion'
		*  revert the previously selected accordion before storing the newly selected accordion's values
		*/
		var accordionObj = window[$ACCORDION_STATUS];
		var nested = false;
		if (accordion.id.indexOf('nested') != -1) nested = true;
//alert('accordion.id = ' + accordion.id);
		// exit if user clicked on the current accordion
		if (evt.type == 'click' && (accordion.id == 'current_accordion' || accordion.id == 'current_nested_accordion')) {
			//alert('accordionObj.lastAccordionId :: ' + accordionObj.lastAccordionId + '\n\n' + 'accordionObj.lastNestedAccordionId :: ' + accordionObj.lastNestedAccordionId + '\n\n' + 'accordion.id :: ' + accordion.id);
			return false;
		}

		/*
		*  outer and nested accordions have to be handled separately
		*  convert a current accordion (not a starting accordion) back to its default data condition
		*  the accordion visual switch occurs further into this code
		*  also store the data condition for the as-yet-untoggled accordion, so it can be reset later when it loses focus
		*/
		/*
		if (!nested && accordionObj.startingAccordion === null) {
			// revert the current accordion to its default id and link
			document.getElementById('current_accordion').id = accordionObj.lastAccordionId;
			accordionLinks[accordionObj.lastAccordionId] = accordionObj.lastAccordionLink;
			// store for later
			accordionObj.lastAccordion = accordion;
			accordionObj.lastAccordionId = accordion.id;
			accordionObj.lastAccordionLink = accordionLinks[accordion.id];
			accordionObj.lastAccordionContent = accordionContent[accordion.id];
		}
		*/

		//alert('donest: ' + donest + "\n" + ' nested: ' + nested);
		if (nested) {
			if (accordionObj.startingNestedAccordion === null || typeof accordionObj.startingNestedAccordion === 'undefined') {

				// a parameter by the default name of the current accordion will not exist if it was the default accordion due to GET parameters
				if (typeof nestedAccordionLinks[accordionObj.lastAccordionId] == 'undefined' && accordionObj.lastAccordionId == 'current_accordion') {
					nestedAccordionLinks[accordionObj.lastAccordionId] = nestedAccordionLinks['current_accordion'];
				}

				// a prior nest accordian exists, revert the current accordion to its default id and link
				if (accordionObj.lastNestedAccordionId !== null && typeof accordionObj.lastNestedAccordionId !== 'undefined' && document.getElementById('current_nested_accordion')) {
					document.getElementById('current_nested_accordion').id = accordionObj.lastNestedAccordionId;
					if (typeof nestedAccordionLinks[accordionObj.lastAccordionId] == 'undefined') nestedAccordionLinks[accordionObj.lastAccordionId] = new Object();
					nestedAccordionLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId] = accordionObj.lastNestedAccordionLink;
				}

				// store for later using reference to 
				accordionObj.lastNestedAccordion = accordion;
				accordionObj.lastNestedAccordionId = accordion.id;
				accordionObj.lastNestedAccordionLink = nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordion.id];
				//accordionObj.lastNestedAccordionContent = nestedAccordionContent[accordionObj.lastAccordionId][accordion.id];

			} else {
				// store for later using refernce to the starting nested accordion
				accordionObj.lastNestedAccordion = accordion;
				accordionObj.lastNestedAccordionId = accordion.id;

/*
				if (accordionObj.lastAccordion.id == 'current_accordion') {
					accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordion.id][accordionObj.startingNestedAccordion];
				} else {
					accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordionId][accordionObj.startingNestedAccordion];
				}
*/
				//accordionObj.lastNestedAccordionContent = nestedAccordionContent[accordionObj.lastAccordionId][accordionObj.startingNestedAccordion];
			}
		}

		/*
		*  original handling of accordions
		*/
		if (this.animating) {
			return false;
		}
		
		this.effects = [];
	
		this.currentAccordion = $(accordion.next(0));
		this.currentAccordion.setStyle({
			display: 'block'
		});		
		
		this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive);

		if (this.currentAccordion == this.showAccordion) {
			//this.deactivate();
		} else {

			if (!nested) {

				// the id of the selected accordion has not yet been toggled to current_accordion
				var slide = accordionContent[accordion.id] === true ? true : false;

				// if the starting accordion is non-trivial, store its data condition, then make it unusable
				if (accordionObj.startingAccordion !== null) {
					if (firstLoad) {
						firstLoad = false;
						accordionLinks[accordionObj.startingAccordion] = accordionObj.startingAccordionLink;
						accordionObj.lastAccordionId = accordionObj.startingAccordion;
						accordionObj.lastAccordion = document.getElementById('current_accordion');
						accordionObj.lastAccordionLink = accordionObj.startingAccordionLink;
					} else {
						// a nested accordion remains from a previous accordion, remove all references to it and deactivate it
						if (accordionObj.lastNestedAccordion) {
							accordionObj.lastNestedAccordion = null;
							accordionObj.lastNestedAccordionId = null;
							accordionObj.lastNestedAccordionIndex = null;
							accordionObj.lastNestedAccordionLink = null;
							window.lastNestedAccordionObj.deactivate();
						}
						// revert the id of the current_accordion to its true id
						if (accordionObj.lastAccordion.id == "current_accordion") {
							document.getElementById('current_accordion').id = accordionObj.lastAccordionId;
							accordionLinks[accordionObj.lastAccordionId] = accordionObj.lastAccordionLink;
						}
						accordionObj.lastAccordion = document.getElementById(accordion.id);
						accordionObj.lastAccordionId = accordion.id;
						accordionObj.lastAccordionLink = accordionLinks[accordion.id];
						accordionObj.lastAccordionContent = accordionContent[accordion.id];
						accordionObj.startingAccordion = null;
						accordionObj.startingAccordionLink = null;
					}
				}

			} else {

				// nested link
				if (typeof accordionObj.lastAccordion !== 'undefined') {
				var iehack = false;

					if (typeof accordionObj.lastAccordion.id !== 'undefined' && typeof accordionObj.lastNestedAccordion.id !== 'undefined') {
						if (accordionObj.lastAccordion.id == 'current_accordion' 
							&& accordionObj.lastNestedAccordion.id == 'current_nested_accordion') {
							accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordion.id][accordionObj.lastNestedAccordion.id];
						} else {
							if (accordionObj.lastAccordion.id == 'current_accordion') {
								accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordion.id][accordionObj.lastNestedAccordionId];
							} else if (accordionObj.lastNestedAccordion.id == 'current_nested_accordion') {
								accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordion.id];
							} else {
								accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId];
							}
						}
					} else {
						accordionObj.lastNestedAccordionLink = nestedAccordionLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId];
					}

				// internet explorer runs nested accordions before main the accordion
				} else {

					// for the sake of debugging in IE
					var iehack = true;

					var localnestedAccordionDefaultLinks = nestedAccordionDefaultLinks;
					var localnestedAccordionLinks = nestedAccordionLinks;
					var localnestedAccordionContent = nestedAccordionContent;

					if (accordionObj.startingAccordion !== null && accordionObj.startingNestedAccordion !== null) {
						accordionObj.lastNestedAccordionLink = nestedAccordionDefaultLinks[accordionObj.startingAccordion][accordionObj.startingNestedAccordion];
					}

					accordionObj.lastAccordion = accordionObj.startingAccordion;
					accordionObj.lastAccordionId = 'current_accordion';
					accordionObj.lastNestedAccordion = accordionObj.startingNestedAccordion;
					accordionObj.lastNestedAccordionId = 'current_nested_accordion';
				}

				// default accordion due to GET parameters
				if (nestedAccordionLinks[accordionObj.lastAccordionId] == undefined && accordionObj.lastAccordionId == 'current_accordion') {
					nestedAccordionLinks[accordionObj.lastAccordionId] = nestedAccordionLinks['current_accordion'];
				}

				// if the starting accordion is non-trivial, store its data condition and make it unusable
				if (accordionObj.startingNestedAccordion !== null && typeof accordionObj.startingNestedAccordion !== 'undefined') {
					nestedAccordionLinks[accordionObj.lastAccordionId] = new Object();
					nestedAccordionLinks[accordionObj.lastAccordionId][accordionObj.startingNestedAccordion] = accordionObj.startingNestedAccordionLink;
					accordionObj.lastNestedAccordionId = accordionObj.startingNestedAccordion;
					accordionObj.lastNestedIndex = 1*accordionObj.lastNestedAccordionId.substring(6,7) - 1;
					accordionObj.lastNestedAccordionIndex = 1*accordionObj.lastNestedAccordionId.substring(16) - 1;
					accordionObj.lastNestedAccordion = document.getElementById('current_nested_accordion');
					accordionObj.lastNestedAccordionLink = accordionObj.startingNestedAccordionLink;
					accordionObj.startingNestedAccordion = null;
					accordionObj.startingNestedAccordionLink = null;

				// else use the current nested accordion; assign id and link of 'current_nested_accordion'
				} else {
					if (typeof accordionObj.lastNestedAccordion !== null) {
						document.getElementById(accordionObj.lastNestedAccordionId).id = 'current_nested_accordion';
						if (typeof nestedAccordionLinks[accordionObj.lastAccordionId] == 'undefined') {
							nestedAccordionLinks['current_accordion']['current_nested_accordion'] = accordionObj.lastNestedAccordionLink;
						} else {
							nestedAccordionLinks[accordionObj.lastAccordionId]['current_nested_accordion'] = accordionObj.lastNestedAccordionLink;
						}
					}
				}
			}

			// slide determination for nested accordions
			if (nested) {

				window.lastNestedAccordion = accordion;
				window.lastNestedAccordionObj = this;

				if (nestedAccordionContent[accordionObj.lastAccordionId] == undefined && accordionObj.lastAccordionId == 'current_accordion') {
					if (accordionObj.startingNestedAccordion !== null && typeof accordionObj.startingNestedAccordion !== 'undefined') {
						nestedAccordionContent[accordionObj.lastAccordionId] = nestedAccordionContent['current_accordion'];
						var slide = nestedAccordionContent[accordionObj.lastAccordionId][accordionObj.startingNestedAccordion] === true ? true : false;
					} else {
						nestedAccordionContent[accordionObj.lastAccordionId] = nestedAccordionContent['current_accordion']; //[accordionObj.lastNestedAccordionId]
						var slide = nestedAccordionContent[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId] === true ? true : false;
					}
				} else {
					if (typeof accordionObj.lastAccordion !== 'undefined') {
						if (typeof accordionObj.lastAccordion.id !== 'undefined' && typeof accordionObj.lastNestedAccordion.id !== 'undefined') {
							if (accordionObj.lastAccordion.id == 'current_accordion' 
								&& accordionObj.lastNestedAccordion.id == 'current_nested_accordion'
								&& nestedAccordionContent[accordionObj.lastAccordion.id] !== null) {
								var slide = nestedAccordionContent[accordionObj.lastAccordion.id][accordionObj.lastNestedAccordion.id] === true ? true : false;
							} else {
								var slide = nestedAccordionContent[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId] === true ? true : false;
							}
						} else {
							var slide = nestedAccordionContent[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId] === true ? true : false;
						}
					// internet explorer runs nested accordions before main the accordion
					} else {
						//
					}
				}
			} else {
				window.lastAccordion = accordion;
				window.lastAccordionObj = this;
			}

			// scaling determination based on slide for nested content
			if (this.options.direction == 'horizontal') {
				this.scaling = $H({
					scaleX: true,
					scaleY: false
				});
			} else {
				if (slide) {
					this.scaling = $H({
						scaleX: false,
						scaleY: true
					});
				} else {
					this.scaling = $H({
						scaleX: false,
						scaleY: false
					});
				}		
			}
		
			window[$ACCORDION_STATUS] = accordionObj;
			//if (accordionContent[accordionObj.lastNestedAccordionId] == true) 

			this._handleAccordion(accordion);

			/*
			*  load a url or scroll to an anchor within the id='scroll' DIV within the current document
			*/
			if (!nested) {
				// outer accordions are now treated as 'current_accordion'
				if (accordionLinks[accordion.id] !== undefined && accordionLinks[accordion.id] !== null) {
					if (accordionLinks[accordion.id][0] == 'url' 
						&& accordionLinks[accordion.id][1] !== undefined 
						&& accordionLinks[accordion.id][1] !== null) {
							if (evt.type == 'click') {
								location.href = accordionLinks[accordion.id][1];
							}
					} else if (accordionLinks[accordion.id][0] == 'anchor' 
						&& accordionLinks[accordion.id][1] !== undefined 
						&& accordionLinks[accordion.id][1] !== null) {
							new SoftDivScroll('scroll').go(accordionLinks[accordion.id][1]);

							// prevent any actions onclick of the current accordion
							//accordionLinks['current_accordion'] = null;
					}
				}
			} else {
				// hack for the sake of IE
				if (iehack && accordionObj.lastAccordionId == 'current_accordion'
					&& typeof nestedAccordionDefaultLinks[accordionObj.lastAccordionId] == 'undefined')
					accordionObj.lastAccordionId = accordionObj.lastAccordion;

				// all links are contained in default object
				if (nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId] !== undefined 
					&& nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId] !== null) {

					if (nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][0] == 'url' 
							&& nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][1] !== undefined 
							&& nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][1] !== null) {
							if (evt.type == 'click') {
								location.href = nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][1];
							}
					} else if (nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][0] == 'anchor' 
							&& nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][1] !== undefined 
							&& nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][1] !== null) {
							new SoftDivScroll('scroll').go(nestedAccordionDefaultLinks[accordionObj.lastAccordionId][accordionObj.lastNestedAccordionId][1]);
							// prevent any actions onclick of the current accordion
							//nestedAccordionLinks['current_nested_accordion'] = null;
					}
				//}
				}
			}
		}
	},
	
	// 
	// Deactivate an active accordion
	//
	deactivate : function() {
		var options = $H({
		  duration: this.duration,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			queue: {
				position: 'end', 
				scope: 'accordionAnimation'
			},
			scaleMode: { 
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			},
			afterFinish: function() {
				this.showAccordion.setStyle({
         			height: 'auto',
					display: 'none'
				});				
				this.showAccordion = null;
				this.animating = false;
			}.bind(this)
		});    

		this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
    
		new Effect.Scale(this.showAccordion, 0, options.update(this.scaling).toObject());
		
	},

  //
  // Handle the open/close actions of the accordion
  //
	_handleAccordion : function(accordion) {
		//if (accordion.id !== 'current_accordion') 
		var options = $H({
			sync: true,
			scaleFrom: 0,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			scaleMode: { 
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			}
		});
		options.merge(this.scaling);
		
		this.effects.push(
			new Effect.Scale(this.currentAccordion, 100, options.update(this.scaling).toObject())
		);

		if (this.showAccordion) {
			this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
			
			options = $H({
				sync: true,
				scaleContent: false,
				transition: Effect.Transitions.sinoidal
			});
			options.merge(this.scaling);
			
			this.effects.push(
				new Effect.Scale(this.showAccordion, 0, options.update(this.scaling).toObject())
			);
		}
		if ((mainpage && (accordionLinks[accordion.id] == undefined || accordionLinks[accordion.id] == null)) || !mainpage) {
			new Effect.Parallel(this.effects, {
				duration: this.duration, 
				queue: {
					position: 'end', 
					scope: 'accordionAnimation'
				},
				beforeStart: function() {
					this.animating = true;
				}.bind(this),
				afterFinish: function() {
					if (this.showAccordion) {
						this.showAccordion.setStyle({
							display: 'none'
						});				
					}
					if (accordionContent[accordion.id] !== null) {
						$(this.currentAccordion).setStyle({
						  height: 'auto'
						});
					}
					this.showAccordion = this.currentAccordion;
					this.animating = false;
				}.bind(this)
			});
		}
	}
}
