


Position.setpage = function( forElement, x, y ) {
    var valueT = y, valueL = x;

    var element = forElement;
    do {
      valueT -= element.offsetTop  || 0;
      valueL -= element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent==document.body)
        if (Element.getStyle(element,'position')=='absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
    } while (element = element.parentNode);

    forElement.style.left = valueL + 'px';
    forElement.style.top = valueT + 'px';
	forElement.style.visibility = 'visible';
}


if( ! Widget ) var Widget = {};

Widget.MenuItem = Class.create();
Widget.MenuItem.prototype = {
	initialize: function( parent, activator_element, sub_element, options )
	{
		this.childs = [];
		this.parent = parent;
		this.menu = null;
		this.activator = activator_element;
		this.sub = sub_element;

		this.offset = [0,0];
		if( typeof options['offset'] != 'undefined' ){
			this.offset = options['offset'];
		}

		this.updateposition = true;
		this.positionupdated = false;
		if( typeof options['updateposition'] != 'undefined' ){
			this.updateposition = options['updateposition'];
		}

		if( this.parent )
			this.parent.addChild( this );

		this.initSubElement();
		this.initActivator();
	},

	getActivatorId: function()
	{
		if( this.activator )
			return this.activator.id;
		else
			return null;
	},

	initSubElement: function()
	{
		if( ! this.sub )
			return;

		var st = this.sub.style;
		/*
		if( this.updateposition ){
			var pos = Position.page(this.activator);
			var dim = Element.getDimensions(this.sub);
			Position.setpage( this.sub, pos[0] - dim.width + this.offset[0], pos[1] + this.offset[1] );
		}
		*/
		Event.observe( this.sub, 'mouseout', this.onMouseOut.bindAsEventListener(this) );
		Event.observe( this.sub, 'mouseover', this.stopDeactivate.bindAsEventListener(this) );
	},

	initActivator: function()
	{
		if( this.activator )
			Event.observe( this.activator, 'mouseover', this.onMouseOver.bindAsEventListener(this) );
	},

	addChild: function( child )
	{
		this.childs.push(child);
		if( this.menu )
			child.setMenu(this.menu);
	},

	setMenu: function( menu )
	{
		this.menu = menu;
		this.childs.each( function(child){ child.setMenu( menu ); } );
	},

	activate: function()
	{
		if( this.parent ){
			this.parent.deActivateChilds();
		}
		else if( this.menu ){
			this.menu.deActivateChilds();
		}
		if( this.sub ){
			Element.show( this.sub );
			Element.addClassName( this.activator, 'activated' );
			this.sub.style.visibility = 'visible';
			// new Effect.Appear( this.sub, {duration:0.2} );
		}
		this.stopDeactivate();
		if( this.parent )
			this.parent.stopDeactivate();

		if( this.updateposition && ! this.positionupdated && this.sub ){
			var pos = Position.page(this.activator);
			var dim = Element.getDimensions(this.sub);
			Position.setpage( this.sub, pos[0] - dim.width + this.offset[0], pos[1] + this.offset[1] );
			this.positionupdated = true;
		}
	},
	deActivateWithTimeout: function()
	{
		if( this.sub && this.parent ){
			this.sub.deactivate_timeout = setTimeout( this.deActivate.bindAsEventListener(this), 500 );
		}
	},
	deActivate: function()
	{
		Element.removeClassName( this.activator, 'activated' );
		if( this.sub ){
			Element.hide( this.sub );
			// new Effect.Fade(this.sub, {duration:0.1} );
		}
		this.deActivateChilds();
	},
	stopDeactivate: function()
	{
		if( this.sub && this.sub.deactivate_timeout ){
			clearTimeout( this.sub.deactivate_timeout );
		}
		if( this.parent ){
			this.parent.stopDeactivate();
		}
	},
	deActivateChilds: function()
	{
		this.childs.each( function(child) {
			child.deActivate();
		} );
	},

	onMouseOver: function(e)
	{
		this.activate();
	},
	onMouseOut: function(e)
	{
		if( this.sub ) {
			if( ! Position.within( this.sub, Event.pointerX(e), Event.pointerY(e) ) )
				this.deActivateWithTimeout();
		}
	}
}


Widget.Menu = Class.create();
Widget.Menu.prototype = {
	initialize: function()
	{
		this.childs = [];
	},

	addChild: function(child)
	{
		this.childs.push(child);
		child.setMenu(this);
	},
	addChilds: function( childs )
	{
		for( var i = 0; i < childs.length; i ++ ){
			this.addChild( childs[i] );
		}
	},

	deActivateChilds: function()
	{
		for( var i = 0; i < this.childs.length; i ++ ){
			this.childs[i].deActivate();
		}
	},

	deActivate: function()
	{
		this.deActivateChilds();
	},

	activateByActivatorId: function( id )
	{
		for( var i = 0; i < this.childs.length; i ++ ){
			var child = this.childs[i];
			if( child.getActivatorId() == id ){
				child.activate();
			}
		}
	}
}












