function RolloverMenu(_el, _ul0Class, _type, _opacity) {
//	SJEL.CreateLog();
	var ref = this;
	var zIndex = 100;
	var speed = 250;
	var useOpacity = _opacity||false;
	
	this.el = SJEL.$(_el);
	this.ul0Class = _ul0Class||"";
	this.type = _type||"down";
	
	if (!this.ul0Class) {
		alert("RolloverMenu error: no class specified!");
		return;
	}
	
	this.parents = new Array();
	SJEL.RemoveClass(this.el, "nojs");
	
	this.uls = SJEL.$A(this.el, "class", _ul0Class, "ul");
	if (this.uls.length == 0)
		return;

	this.WalkTree = function(_ul, _level) {
		var lis = SJEL.$T(_ul, "li");
		if (lis.length == 0)
			return;

		var li = null, ul = null;		
		for (var i = 0; i < lis.length; i++) {
			ul = null;
			li = lis[i];
			
			if (li.parentNode != _ul)
				continue;
				
			if (ul = IsParent(li)) {
				this.parents.push(new Parent(li, ul, _level));
				this.WalkTree(ul, _level + 1);
			}
		}
	};
	
	for (var i = 0; i < this.uls.length; i++)
		this.WalkTree(this.uls[i], 0);
		
	for (var i = 0; i < this.parents.length; i++)
		SJEL.SStyle(this.parents[i].c, {display: "none"});
	
	function Parent(_li, _ul, _level) {
		if (Parent.counter == undefined)
			Parent.counter = 0;
		
		var rf = this;
		this.id = Parent.counter++;
		this.p = _li;
		this.c = _ul;
		this.level = _level;
		this.w = parseInt(this.c.offsetWidth);
		this.h = parseInt(this.c.offsetHeight);
		this.t = parseInt(this.c.offsetTop);
//		this.b = parseInt(this.c.offsetBottom);
		this.b = 26;
		this.l = parseInt(this.c.offsetLeft);
		this.m = new SJEL.Morph("easyin");
		this.finished = false;
		this.di = SJEL.CE("div");

		var diSt = {};
		diSt.position = "absolute";
		diSt.left = this.l + "px";
		diSt.width = this.w + "px";
		diSt.overflow = "hidden";
		//diSt.display = "none";
		
		if ((this.level == 0) && (ref.type == "up")) {
			diSt.bottom = this.b + "px";
			diSt.height = "0px";
		} else
			diSt.top = this.t + "px"
		
		SJEL.SStyle(this.di, diSt);
//		SJEL.SStyle(this.di, {position: "absolute", top: this.t + "px", left: this.l + "px", width: this.w + "px", overflow: "hidden"});
		this.c.parentNode.appendChild(this.di);
		this.di.appendChild(this.c);
		SJEL.SStyle(this.c, {position: "static"});
		//this.di = this.c.cloneNode(true);
		
//		var st = {visibility: "hidden"};
		var st = {};
		
		if ((this.level == 0) && (ref.type == "down"))
			st.marginTop = -this.h + "px";
		else if ((this.level == 0) && (ref.type == "up"))
			st.marginTop = this.h + "px";
		else
			st.marginLeft = -this.w + "px";
		
		if (!SJEL.ie && useOpacity) st.opacity = 0.0;

		SJEL.SStyle(this.c, st);
		
		this.p.onmouseover = function(_e) {
			if (_e == undefined)
				_e = window.event;

			var relte = (!SJEL.ie) ? _e.relatedTarget : _e.fromElement;
			if (!SJEL.IsIn(relte, rf.p)) {
				SJEL.Log("over: " + rf.id);
				rf.m.Stop();
				//SJEL.SStyle(rf.c, {visibility: "visible"});
				SJEL.SStyle(rf.c, {display: "block"});
				SJEL.SStyle(rf.di, {overflow: "hidden"});
				
				if ((rf.level == 0) && (ref.type == "down"))
					st = {marginTop: "0px"};
				else if ((rf.level == 0) && (ref.type == "up")) {
					st = {marginTop: "0px"};
					SJEL.SStyle(rf.di, {height: rf.h + "px"});
				} else
					st = {marginLeft: "0px"};

				if (!SJEL.ie && useOpacity) st.opacity = 1.0;

				rf.m.Init(rf.c, st, speed);
				rf.m.Morph();
				rf.m.OnMorphFinished(function(){SJEL.SStyle(rf.di, {overflow: "visible"});});
			}
		};

		this.p.onmouseout = function(_e) {
			if (_e == undefined)
				_e = window.event;
				
			var relte = (!SJEL.ie) ? _e.relatedTarget : _e.toElement;
			if (!SJEL.IsIn(relte, rf.p)) {
				SJEL.Log("out: " + rf.id);
				rf.m.Stop();
				SJEL.SStyle(rf.di, {overflow: "hidden"});
				
				if ((rf.level == 0) && (ref.type == "down"))
					st = {marginTop: -rf.h + "px"};
				else if ((rf.level == 0) && (ref.type == "up")) {
					st = {marginTop: rf.h + "px"};
				} else
					st = {marginLeft: -rf.w + "px"};

				rf.m.Init(rf.c, st, speed);
				rf.m.Morph();
				rf.m.OnMorphFinished(function() {
					//st = {visibility: "hidden"};
					st = {display: "none"};
					if (!SJEL.ie && useOpacity) st.opacity = 0.0;
					SJEL.SStyle(rf.c, st);
					SJEL.SStyle(rf.di, {overflow: "visible"});
					if ((rf.level == 0) && (ref.type == "up"))
						SJEL.SStyle(rf.di, {height: "0px"});
				});
			}
		};
		
//		SJEL.Log(this.w + " " + this.h + " " + this.t + " " + this.l);
	};

	function IsParent(_li) {
		var uls = SJEL.$T(_li, "ul");
		if (uls.length > 0)
			return uls[0];
		else
			return null;
	};
};
