Ext.ns('nfc');
nfc.Accordion = function (){
	var that = {};
	
	var defaults = {
		menuCls        : 'nfcAccordion',
		openCls        : 'open',
		childCls       : 'child',
		parentCls      : 'parent',
		keepActiveOpen : 1,
		downSpeed	   : 0.1,
		upSpeed        : 0.1 
	};
	
	var options = {};
	var setOptions = function(opts){
		options = opts;
	}
	var getOptions = function(options){
		var opts = {};
		Ext.apply(opts,options, defaults);
		return opts;
	}

	
	
	var hideSubMenus = function(el){
		Ext.query('ul.' + options.childCls, el).each(function(el){
			el = Ext.get(el);
			el.setStyle('display', 'none');
			el.parent().removeClass(options.openCls);
		});
	}
	
	var showActiveMenuPath = function (el){
		//enable active sub menus
		Ext.query('li.' + options.parentCls + ' ul', el ).each(function(el){
			el = Ext.get(el);
			el.setStyle('display', 'block');
		});
	}
	
	var getAllMenuWithChild = function(el){
		var ret = [];
		Ext.query('li', el).each(function(child){
			if (Ext.query('ul', child).length > 0){
				ret.push(child);
			}
		});
		return ret;
		
	}
	
	var getAllRootMenus = function (){
		return Ext.query('ul.' + options.menuCls);
	}
	
	var closeOtherMenus = function(el, rootMenu){
		
		getAllMenuWithChild().each(function(child){
			child = Ext.get(child);
			if(child.down('ul').id == el.id){
				return;
			}
			
			if( child.hasClass(options.parentCls) && options.keepActiveOpen == 1){
				return;
			}
			
			var link = child.down('a');
			var childUl = link.next('ul');
			if (options.upSpeed == 0){
				childUl.setStyle('display', 'none');
			}else{
				window.setTimeout(function(){
					that.menuUp(childUl);
				}, 10);
				
			}
			
			child.removeClass(options.openCls);
			return childUl;
		});
	}
	
	var animateMenu = function(li, rootMenu){
		li = Ext.get(li);
		var scope = this;
		var eventOptions = {preventDefault: true};
		
		var link = li.down('a');
		var childUl = link.next('ul');

		link.on('click',function(event, el, config){
			
			//do not animate if keepActiveOpen is set
			if( li.hasClass(options.parentCls) && options.keepActiveOpen == 1){
				return;
			}
			
			if( li.hasClass(options.openCls)){
				that.menuUp(childUl);
				li.removeClass(options.openCls);
			}else{
				closeOtherMenus(childUl, rootMenu);
				that.menuDown(childUl);
				li.addClass(options.openCls);
			}
			
		}, scope, eventOptions)
	}
	
	var doAnimation = function(rootMenu){
		//hide all sub menus
		hideSubMenus(rootMenu);
		
		//show path to current active menu
		showActiveMenuPath(rootMenu);
		
		//atach animation to all menus with children
		var childs = getAllMenuWithChild(rootMenu);
		childs.each(function(el){
			animateMenu(el, rootMenu);
		});
	}
	
	that = {
		options: [],
		
		menuUp : function(el){
			el = Ext.get(el);
			el.syncFx().slideOut('t', {
				easing: 'easeNone',
				duration: this.options.upSpeed,
				remove: false,
				block: false,
				useDisplay: true 
			});
		},
		
		menuDown : function (el){
			el = Ext.get(el);
			el.syncFx().slideIn('t', {
				easing: 'easeIn',
			    duration: this.options.downSpeed,
			    remove: false,
			    block: false,
			    useDisplay: true
			});
		},
		
		init: function(options){
			this.options = getOptions(options);
			setOptions(this.options);
			
			var AccordionMenus = getAllRootMenus();
			
			AccordionMenus.each(doAnimation, this)
			
		}//init
		
		
	};
	return that;
};
