Array.prototype.remove = function(obj){
    for(var i=0; i<this.length; i++)
    {
        if(obj == this[i]) this.splice(i, 1);
    }
}

Array.prototype.indexOf = function(obj){
    for(var i=0; i<this.length; i++)
    {
        if(obj == this[i]) return i;
    }
    return -1;
}

var ___ACC___Settings = {
    Fps: 50,
    Speed: 0.3,
    CloseOnOpen: true,
    CanCloseAll: true,
    CloseSubLists: true,
    OpenOnHover: false
}

var ___ACC___Accordian = {}

var ___ACC___EffectType = {
	Linear: function (pos) { return pos; },
	Reverse: function (pos) { return 1 - pos; },
	EaseIn: function (pos) { 
		var ease = ( -Math.cos( pos*Math.PI ) / 2 ) + 0.5; 
		ease = ease * 1000;
		ease = Math.ceil(ease);
		ease = ease/1000;
		return ease;
	},
	EaseOut: function (pos) { 
		var ease = 1 - (( -Math.cos( pos*Math.PI ) / 2 ) + 0.5); 
		ease = ease * 1000;
		ease = Math.floor(ease);
		ease = ease/1000;
		return ease;
	}
}

var ___ACC___Effects = {
	fps: 0,
	speed: 0,
	delta: 0,
	queue: [],
	timer: false,
	init: function() {
		this.fps = ___ACC___Settings.Fps;
		this.speed = ___ACC___Settings.Speed;
		this.delta = 1 / this.speed / this.fps;		
	},
	add: function (obj, type) {
		var height = ___ACC___getAccordianHeight(obj);
		obj.style.height = (height * type(0)) + "px";
		this.queue.push( {"obj": obj, "type": type, "height": height, "pos": 0} );
		if(!this.timer) {
			var self = this;
			this.timer = setInterval(function() { self.animate(); }, 1000 / this.fps);
		}
	},
	remove: function (obj) {
		this.queue.remove(obj);		
		if(this.queue.length < 1) {
			clearInterval(this.timer);
			this.timer = null;
		}
	},
	animate: function() {
		var finished = [];
		for(var i = 0; i < this.queue.length; i++) 
		{
			var o = this.queue[i];
			o.pos = ((o.pos + this.delta) > 1) ? 1 : o.pos + this.delta;
			var ht = Math.floor(o.type(o.pos) * o.height);						
			if (o.pos == 1)
			{
				finished.push(o);
				var finalpos = o.type(o.pos);
				if(finalpos == 0) 
				{					
					o.obj.style.display = "none";		
					o.obj.style.height = "0px";
				}
				else 
				{ 
					o.obj.style.display = "block";
					o.obj.style.height = ""; // "100%";	
				}
			} 
			else 
			{ 
				o.obj.style.height = ht + "px"; 
				if (ht == 0)
				{
					o.obj.style.display = "none";
				}
				else { o.obj.style.display = "block"; }
			}
		}
		for(var o = 0; o < finished.length; o++) 
		{
		    var f = finished[o];		   
		    if (___ACC___Settings.CloseSubLists)
		    {
		        var pos = f.type(f.pos);
		        if (pos == 0)
		        {
		            ___ACC___closeChildAccordians(f.obj);
		        }
		    }
		    this.remove(f);
		}
	}
}

function ___ACC___BuildAccordian(openPanels, closeOnOpen, canCloseAll, closeSubLists, openOnHover)
{    
    if (typeof(closeOnOpen) != 'undefined') ___ACC___Settings.CloseOnOpen = closeOnOpen;
    if (typeof(canCloseAll) != 'undefined') ___ACC___Settings.CanCloseAll = canCloseAll;
    if (typeof(closeSubLists) != 'undefined') ___ACC___Settings.CloseSubLists = closeSubLists;
    if (typeof(openOnHover) != 'undefined') ___ACC___Settings.OpenOnHover = openOnHover;
    ___ACC___Effects.init();
    
    var accordians = ___ACC___getAccordians();
    for (var i=0; i<accordians.length; i++)
    {
        var acc = accordians[i];
        var items = ___ACC___getAccordianItems(acc);
        for (var j=0; j<items.length; j++)
        {
            var item = items[j];
            var link = item[0];            
            var ul = item[1];   
            var expanded = false;
            if (openPanels)
            {
                for (var k=0; k<openPanels.length; k++)
                {
                    if (openPanels[k] == link.id) 
                    {
                        expanded = true;
                        break;
                    }    
                }    
            }
            
            if (expanded)
            {
	            ul.style.display = 'block';
		        ul.style.height = ''; //'100%';
		        ___ACC___applyOpenClass(ul, true);
            }    
            else
            { 
				ul.style.height = '0px'; // added
				ul.style.display = 'none'; 
			}
                  
            ul.style.overflow = 'hidden';   
            if (openOnHover)
            {
				link.onmouseover = ___ACC___linkClick;   
				link.parentNode.onmouseout = ___ACC___listItemExit;         
            }
            else 
            {         
				link.onclick = ___ACC___linkClick;            
            }
            ___ACC___Accordian[link.id] = {AccordianID: i, List: ul, Expanded: expanded };
        }
    }
    
}

function ___ACC___applyOpenClass(el, expanded)
{
	var accordianLI = el;
	while (!___ACC___IsAccordianLI(accordianLI))
	{
		accordianLI = accordianLI.parentNode;
		if (!accordianLI) { break; }
	}
	if (accordianLI)
	{
		if (expanded)
		{
			if (accordianLI.className.indexOf('sys_open') == -1)
			{
				accordianLI.className = accordianLI.className + ' sys_open';
			}
		}
		else
		{
			if (accordianLI.className.indexOf('sys_open') != -1)
			{
				var classes = accordianLI.className.split(' ');				
				classes.remove('sys_open');				
				accordianLI.className = classes.join(' ');
			}
		}
	}
}

function ___ACC___getAccordianHeight(parentList)
{
	var display = parentList.style.display;
	parentList.style.display = 'block';
	var result = parentList.offsetHeight;
	
	if (result == 0)
	{
		var ht = parentList.style.height;
		parentList.style.height = '1px';
		result = parentList.scrollHeight;
		parentList.style.height = ht;
	}
	parentList.style.display = display;	
	return result;
}

function ___ACC___closeChildAccordians(parentList)
{
    var subLists = ___ACC___getChildAccordianLinks(parentList);
	for (var i=0; i<subLists.length; i++)
	{
	    ___ACC___Accordian[subLists[i].id].List.style.display = 'none';
		___ACC___Accordian[subLists[i].id].Expanded = false;
		___ACC___applyOpenClass(subLists[i], false);
		___ACC___closeChildAccordians(___ACC___Accordian[subLists[i].id].List);
	}
}

function ___ACC___IsAccordianLI(li)
{
	if (li.tagName)
	{
		if (li.tagName == 'LI')
		{
			if (li.className)
			{
				if (li.className.indexOf('sys_accordianitem') != -1)
				{
					return true;
				}
			}
		}
	}
	return false
}

function ___ACC___getAccordians()
{
    var lis = document.getElementsByTagName('li');        
    var result = new Array();    
    for (var i=0; i<lis.length; i++)
    {
        var li = lis[i];
        if (___ACC___IsAccordianLI(li))
        {
            var ul = li.parentNode;            
            if (result.indexOf(ul) == -1)
            {
                result[result.length] = ul;                
            }
        }
    }
    return result;
}

function ___ACC___getChildAccordianLinks(el)
{
    var lis = el.childNodes;
    var result = new Array();  
    if (lis)
    {  
	    for (var i=0; i<lis.length; i++)
		{
			var li = lis[i];
	        if (___ACC___IsAccordianLI(li))        
			{
                var anchor = null
                for (var j=0; j<li.childNodes.length; j++)
                {
                    if (li.childNodes[j].tagName)
                    {
                        if (li.childNodes[j].tagName == 'A')
                        {
                            anchor = li.childNodes[j];
                            break;
                        }
                        if (li.childNodes[j].tagName == 'DIV')
	                    {
							if (li.childNodes[j].className == 'sys_selected')
							{
								if (li.childNodes[j].childNodes[0].tagName == 'A')
								{
									anchor = li.childNodes[j].childNodes[0];
								}
							}
		                }
                    }
                }                
                if (result.indexOf(anchor) == -1)
                {
                    result[result.length] = anchor;
                }            
		   }
		}
    }
    return result;
}

function ___ACC___getAccordianObject(li)
{
	if (___ACC___IsAccordianLI(li))
	{
		var children = new Array();
        for (var i=0; i<li.childNodes.length; i++)
        {
			if (li.childNodes[i].tagName)
            {
				if ((li.childNodes[i].tagName == 'A') || (li.childNodes[i].tagName == 'UL'))
                {
					children[children.length] = li.childNodes[i];
                }
                if (li.childNodes[i].tagName == 'DIV')
                {
					if (li.childNodes[i].className == 'sys_selected')
					{
						if (li.childNodes[i].childNodes[0].tagName == 'A')
						{
							children[children.length] = li.childNodes[i].childNodes[0];
						}
					}
                }
            }
            if (children.length == 2) { break; }
        }        
        if (children.length == 2)
        {
			if ((children[0].tagName == 'A') && (children[1].tagName == 'UL'))
            {                    
                return children;
            }
        }
    }
    return null;
}

function ___ACC___getAccordianItems(accordian)
{
    var result = new Array();
    for (var i=0; i<accordian.childNodes.length; i++)
    {
        var item = accordian.childNodes[i];
        var children = ___ACC___getAccordianObject(item);
        if (children)
        {
			 result[result.length] = children;
        }       
    }
    return result;
}

function ___ACC___linkClick()
{
    var expandedList = ___ACC___getExpanded(___ACC___Accordian[this.id]);
    if (___ACC___Accordian[this.id].Expanded)
    {
        // closeit if allowed
        var canClose = true;
        if (!___ACC___Settings.CanCloseAll)
        {
            if (expandedList.length == 1) canClose = false;
        }
        if (canClose)
        {
            ___ACC___Effects.add(___ACC___Accordian[this.id].List, ___ACC___EffectType.EaseOut);
            ___ACC___Accordian[this.id].Expanded = false;
            ___ACC___applyOpenClass(this, false);
        }
    }
    else
    {
        // open it
        if (___ACC___Settings.CloseOnOpen)
        {
            for (var i=0; i<expandedList.length; i++)
            {
                ___ACC___Effects.add(expandedList[i].List, ___ACC___EffectType.EaseOut);
                expandedList[i].Expanded = false;
                ___ACC___applyOpenClass(expandedList[i].List, false);
            }
        }
        ___ACC___Effects.add(___ACC___Accordian[this.id].List, ___ACC___EffectType.EaseIn);
		___ACC___Accordian[this.id].Expanded = true;	
		___ACC___applyOpenClass(this, true);
    }    
    return false;
}

function ___ACC___listItemExit()
{
	if (this != event.target) { return; }
	
	var accObj = ___ACC___getAccordianObject(this);
	if (accObj)
	{
		var expandedList = ___ACC___getExpanded(___ACC___Accordian[accObj[0].id]);
		for (var i=0; i<expandedList.length; i++)
        {
			Effects.add(expandedList[i].List, ___ACC___EffectType.EaseOut);
            expandedList[i].Expanded = false;
            ___ACC___applyOpenClass(expandedList[i].List, false);
        }
	}	
}

function ___ACC___getExpanded(accordianItem)
{
    var result = new Array();
    for(var menu in ___ACC___Accordian) 
    {
        if(___ACC___Accordian[menu].AccordianID == accordianItem.AccordianID)
        {
            if(___ACC___Accordian[menu].Expanded) 
            {
                result[result.length] = ___ACC___Accordian[menu];
		    }
		}
    }   
    return result;  
}