
function addEvent(el, evType, fn) {
if (typeof(el)=='string') el=$(el);
if (typeof(el)!='object') {alert('addEvent: object not found, el='+el); return;}
if (el.addEventListener) { el.addEventListener(evType, fn, false); return true; }
else if (el.attachEvent) { var r = el.attachEvent('on'+evType, fn); return r; }
else { el['on'+evType] = fn; }
}

function vMnu(id) {
if (!document.getElementById || !document.getElementsByTagName) return false;
this.menu=document.getElementById(id);
this.submenus=new Array();
this.speed=4;
this.markCurrent=false;
this.onlyOne=true;
this.remember=false;
}

vMnu.prototype.menuClick=function(event) {
el=event.target || event.srcElement;
el.blur();
if (el.parentNode.parentNode.parentNode.tagName.toLowerCase()!='li') 
el.parentNode.cls.toggleMenu(el.parentNode.getElementsByTagName("ul")[0]);
}

vMnu.prototype.init=function() {
var mainInstance=this;

for (var i=0; i<this.menu.childNodes.length; i++) {
if (this.menu.childNodes[i].nodeType==1) {
if (this.menu.childNodes[i].getElementsByTagName("ul").length) {
var submenu=this.menu.childNodes[i].getElementsByTagName("ul")[0];
this.submenus.push(submenu);
this.menu.childNodes[i].cls=this;

addEvent(this.menu.childNodes[i], 'click', this.menuClick);
if (submenu.className!='expanded') submenu.style.display='none';
}
}
}

if (this.markCurrent) {
var links=this.menu.getElementsByTagName("a");
for (var i=0; i<links.length; i++)
if (links[i].href==document.location.href) {
links[i].className='on';
break;
}
}
if (this.remember) {
var regex=new RegExp("vmnu_"+this.menu.id+"=([01]+)");
var match=regex.exec(document.cookie);
if (match) {
var states=match[1].split("");
for (var i=0; i<states.length; i++) {
if (states[i]==0) {
this.submenus[i].style.display='';
this.submenus[i].className='expanded';
}else this.submenus[i].className='';
}
}
}
};

vMnu.prototype.toggleMenu=function(submenu) {
if (submenu.className!='expanded') this.expand(submenu);
else this.collapse(submenu);
};

vMnu.prototype.expand=function(submenu) {
submenu.style.display='';
submenu.style.height='1px';
var fullHeight=0;
for (var i=0; i<submenu.childNodes.length; i++) if (submenu.childNodes[i].nodeType==1) fullHeight+=submenu.childNodes[i].offsetHeight;
var moveBy=Math.round(this.speed * submenu.childNodes.length);
var mainInstance=this;
var intId=setInterval(function() {
var curHeight=submenu.offsetHeight;
var newHeight=curHeight + moveBy;
if (newHeight<fullHeight) submenu.style.height=newHeight+'px';
else {
clearInterval(intId);
submenu.style.height='';
submenu.className='expanded';
mainInstance.memorize();
}
}, 30);
this.collapseOthers(submenu);
};

vMnu.prototype.collapse=function(submenu) {
var moveBy=Math.round(this.speed * submenu.childNodes.length);
var mainInstance=this;
var intId=setInterval(function() {
var curHeight=submenu.offsetHeight;
var newHeight=curHeight - moveBy;
if (newHeight>0) submenu.style.height=newHeight+'px';
else {
clearInterval(intId);
submenu.style.display='none';
submenu.style.height='1px';
submenu.className='';
mainInstance.memorize();
}
}, 30);
};

vMnu.prototype.collapseOthers=function(submenu) {
if (this.onlyOne) for (var i=0; i<this.submenus.length; i++) if (this.submenus[i]!=submenu && this.submenus[i].className=='expanded') this.collapse(this.submenus[i]);
};

vMnu.prototype.expandAll=function() {
var oldonlyOne=this.onlyOne;
this.onlyOne=false;
for (var i=0; i<this.submenus.length; i++) if (this.submenus[i].className!='expanded') this.expand(this.submenus[i]);
this.onlyOne=oldonlyOne;
};

vMnu.prototype.collapseAll=function() {
for (var i=0; i<this.submenus.length; i++) if (this.submenus[i].className=='expanded') this.collapse(this.submenus[i]);
};

vMnu.prototype.memorize=function() {
if (this.remember) {
var states=new Array();
for (var i=0; i<this.submenus.length; i++) states.push(this.submenus[i].className=='expanded' ? 0 : 1);
var d=new Date();
d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000));
document.cookie="vmnu_"+ this.menu.id +"="+ states.join("") +"; expires="+ d.toGMTString() +"; path=/";
}
};
