/**
 * @author Leonard Martin <leonard.martin@heathwallace.com>
 * @author Luke Cuthbertson <luke.cuthbertson@heathwallace.com>
 * @version 1.2
 */

(function($){

	$.fn.accordion = function(options) {
		var $this = $(this);

		var defaults = {
			node: 		'div.node',
			heading:	'h2',
			content:	'div.content',
			open:		'open',
			speed:		'normal',
			update:		[],
			forceClose:	true,
			blockLinks:	true
		};
		
		var opts = $.extend(defaults, options);
		
		return $(this).each(function(){
			var nodes = $(opts.node,this);
			var openElm = null;
			
			
			nodes.each(function(){

				var obj = this;
				
				setDims(this);
				
				if($(this).hasClass(opts.open) && (!openElm || !opts.forceClose)) {
					openElm = obj;
					update(obj,true);
					setTimeout(function(){$this.trigger('accordion.open',obj);}, 0);
				}
				else {
					$(this).removeClass(opts.open);
					$(opts.content,this).hide();
					update(obj,false);
					setTimeout(function(){$this.trigger('accordion.close',obj);}, 0);
				};

				$(this).find(opts.heading)
					.each(function(i){
						if($(this).attr('checked')){
							/**
							 * @todo set open/closed
							 */
						};
					})
					.css({cursor:'pointer'})
					.click(function(){
						//FF fires click event on input as well as label, IE does not
						//to even out cancel event on label and manually trigger event on input
						var tag = $(this).attr('nodeName').toLowerCase();
						var type = $(this).attr('type');
						if(tag == 'label'){
							$('#'+$(this).attr('htmlFor')).click();
							return false;
						};
						
						if(openElm && openElm != obj && opts.forceClose) {
							closeElem(openElm,function(){
								if(toggleElem(obj)) {
									openElm = obj;
								}
							});
						}
						else {		
							if (openElm && $this.find(opts.heading).attr('type') == 'radio') {
								return;
							};								
							if(toggleElem(obj)) {
								openElm = obj;
								update(obj,true);
							};
						};
						//cancel default on things that would cause page to reload
						if (tag == 'a' || tag == 'input' && type == 'submit') {
							return false;
						};
					})
					.find('a').each(function(){
						if(opts.blockLinks) {
							$(this).click(function(e){e.preventDefault();});
						};
					});
					
			});
		});
		
		function setDims(node) {
			$(opts.content,node)
				.show()
				.each(function(){
					var w = this.offsetWidth,
						h = this.offsetHeight;
					$(this).css({width:w+'px',height:h+'px'});
				});
			if (!$(node).hasClass(opts.open)) {
				$(opts.content,node).hide();
			};
			
		};
		
		function closeElem(node,callback) {
			
			$('*',node).css({position:'static'});
			if ($(opts.content, node).length > 0) {
				$(opts.content, node).slideUp(opts.speed, function(){
					$(node).removeClass(opts.open);
					callback();
				});
			}
			else{
				$(node).removeClass(opts.open);
				callback();				
			};
			update(node,false);
		};
		
		function update(node,isopen) {
			for(var i=0;i<opts.update.length;i++) {
				$(opts.update[i].selector,node).html(opts.update[i].text[isopen?0:1]).click(function(e){e.preventDefault()});
			};
		};
		
		function toggleElem(node) {
			var open = !$(node).hasClass(opts.open);
			if(open){
				$(node).toggleClass(opts.open);
				$this.trigger('accordion.open',node);
			};
			$('*',node).css({position:'static'});
			if ($(opts.content, node).length > 0) {
				$(opts.content, node).slideToggle(opts.speed, function(){
					$('*', node).css({
						position: ''
					});
					if (!open) {
						$(node).toggleClass(opts.open);
						$this.trigger('accordion.close', node);
					}
				});
			}
			else{
				$('*', node).css({
					position: ''
				});
				if (!open) {
					$(node).toggleClass(opts.open);
					$this.trigger('accordion.close', node);
				};		
			};
			update(node,open);
			return open;
		};
		
	};

})(jQuery);
