	function getElements(classname, tagname, root){
		if(!root) root = document;
		else if (typeof root == "string") root = document.getElementById(root);
		if(!tagname) tagname = "*";
		var all = root.getElementsByTagName(tagname);
		if(!classname) return all;
		var elements = [];
		for(var i = 0; i < all.length; i++){
			var element = all[i];
			if(isMember(element,classname))
				elements.push(element)
		}
		return elements;
	}
function isMember(element, classname){
		var classes = element.className;
		if(!classes) return false;
		if(classes ==classname) return true;
		var whitespace = /\s+/;
		if (!whitespace.test(classes)) return false;
		var c = classes.split(whitespace);
		for(var i = 0; i < c.length; i++)
			if (c[i] == classname) return true;
		return false;
	}
	function isDescendant(ancestor, descendant){
		if(!ancestor || !descendant) return;
		var similarDescendants = ancestor.getElementsByTagName(descendant.nodeName);
		for(var i=0; i<similarDescendants.length; i++)
			if( similarDescendants[i] == descendant ) return true;
		return false;
	}
    function getAncestors(element){
        var parents = new Array( );
        while( element.parentNode ){
            if( element.parentNode.nodeType == 1 )
                parents.push(element.parentNode);
                element = element.parentNode;
        }
        return parents;
    }


function Drawer(args){
        var drawerObject =this;
        this.args = args;
        this.drawer = document.getElementById(this.args.drawer_id);
        this.drawers = getElements('drawer', 'DIV', this.drawer);
        window.setTimeout(function(){drawerObject.initialize();},0);    
    }
    Drawer.prototype.initialize = function(){
        var drawerObject = this;
        var switchType = this.args.switch_type || 'simple';
        this.switchMethod = this.rollingSwitch;
        this.drawerContentHeight = 39;
        for(var i=0; i<this.drawers.length; i++)
            this.drawers[i].onclick = function(event){drawerObject.switchMethod(event)};
    }
    Drawer.prototype.rollingSwitch = function(event){
        var evt = event || window.event;
        if(this.movingFlag) return;
        var closingDrawer = this.getActiveDrawer();
        var closingDrawerContent = this.getActiveDrawerContent();
        var shrinkingHeight = this.getDrawerContentHeight() + 39;
        var openingDrawer;
        if(!window.addEventListener){
            for(var i=0; i<this.drawers.length; i++)
                if( isDescendant(this.drawers[i], evt.srcElement) ) openingDrawer = this.drawers[i];
        }
        else openingDrawer = event.currentTarget;
        var openingDrawerContent = getElements('drawer_content', 'DIV', openingDrawer)[0];
        var openingFinalHeight = openingDrawerContent.offsetHeight + 39;
        var growingHeight = 39;
        var speed = this.args.speed || 6;
        var drawerObject = this;
        if(closingDrawerContent == openingDrawerContent) return;
        closingDrawer.className += ' closing';
        openingDrawer.className += ' opening';
        for(var i=0; i<drawerObject.drawers.length; i++)
            drawerObject.drawers[i].className = drawerObject.drawers[i].className.replace('opened', 'closed');
        openingDrawer.className = openingDrawer.className.replace('closed', 'opened');
        this.movingFlag = true;
        var clearer2 = setInterval( function(){
            closingDrawer.style.height = shrinkingHeight + 'px';
            if(shrinkingHeight - speed >= 39){
                shrinkingHeight -= speed;
            }else{
                clearInterval(clearer2);
                closingDrawer.style.height = 39 + 'px';
                closingDrawer.className = closingDrawer.className.replace('closing', '');
                drawerObject.movingFlag = false;
            }
        },10);
        var clearer = setInterval( function(){
            openingDrawer.style.height = growingHeight + 'px';
            if(growingHeight + speed <= openingFinalHeight){
                growingHeight += speed;
            }else{
                clearInterval(clearer);
                openingDrawer.style.height = openingFinalHeight + 'px';
                openingDrawer.className = openingDrawer.className.replace('opening', '');
                drawerObject.movingFlag = false;
            }
        },10);
    }
    Drawer.prototype.getDrawerContentHeight = function(){
        var openedDrawerContent = this.getActiveDrawerContent();
        return openedDrawerContent.offsetHeight;
    }
    Drawer.prototype.getActiveDrawer = function(){return getElements('opened', 'DIV', this.drawer)[0];}
    Drawer.prototype.getActiveDrawerContent = function(){
        var openedDrawer = this.getActiveDrawer();
        var openedDrawerContent = getElements('drawer_content', 'DIV', openedDrawer)[0];
        return openedDrawerContent;
    }

	function DropdownMenu(args){
		this.args = args;
		this.list = document.getElementById(args.listId);
		this.itemElements = this.getItems( );
		this.itemObjects = this.setupItems( );
	}
	DropdownMenu.prototype.getItems = function( ){
		var itemElements = new Array( );
		for(var i=0; i<this.list.childNodes.length; i++)
			if(this.list.childNodes[i].nodeName == 'LI')
				itemElements.push(this.list.childNodes[i]);
		return itemElements;
	}
	DropdownMenu.prototype.setupItems = function( ){
		var itemObjects, openFunc, closeFunc;
        openFunc = this.openFunc, closeFunc = this.closeFunc;
        itemObjects = new Array( );
		for(var i=0; i<this.itemElements.length; i++)
			itemObjects.push(
				new DropdownItem({
					itemElement: this.itemElements[i],
					hiddenMenuClass: this.args.hiddenMenuClass,
                    openFunc: this.args.openFunc,
                    closeFunc: this.args.closeFunc
				}) 
			);
		return itemObjects;
	}
	function DropdownItem(args){
		var instance = this;
		this.itemElement = args.itemElement;
		this.trigger = getElements(args.triggerClass,null,this.itemElement)[0];
        this.openFunc = args.openFunc;
        this.closeFunc = args.closeFunc;
        this.menu = getElements(args.hiddenMenuClass,null,this.itemElement)[0];
		if(this.menu){
			this.itemElement.onmouseover = function(event){instance.handleLIMouseOver(event);}
			this.itemElement.onmouseout = function(event){instance.handleLIMouseOut(event);}
		}
	}
	DropdownItem.prototype.handleLIMouseOver = function(event){
		var evt, prevElement;
        evt = event || window.event;
		prevElement = evt.relatedTarget || evt.fromElement;
		if(prevElement != this.itemElement && !isDescendant(this.itemElement,prevElement)) 
            this.activate( );
	}
	DropdownItem.prototype.handleLIMouseOut = function(event){
		var evt, nextElement;
        evt = event || window.event; 
		nextElement = evt.relatedTarget || evt.toElement;
		if(nextElement != this.itemElement && !isDescendant(this.itemElement,nextElement))
			this.deactivate( );
	}
	DropdownItem.prototype.activate = function(event){
        this.menu.className = this.menu.className.replace(/inactive/g,'');
        var ancestors = getAncestors(this.menu);
        for(var i=0; i<ancestors.length; i++)
            ancestors[i].style.zIndex = '1000'
        if(this.openFunc) this.openFunc( );
	}
	DropdownItem.prototype.deactivate = function(event){
        var ancestors = getAncestors(this.menu);
        for(var i=0; i<ancestors.length; i++)
            ancestors[i].style.zIndex = ''
		this.menu.className += ' inactive';
        if(this.closeFunc) this.closeFunc( );
	}

