var WMContextMenu = Class.create();

/**
 * The WMContextMenu is a javascript component for context (right click) menu's
 *
 * Changelog
 * ---------
 *
 * Ron Rademaker Wed Jun 27 2007
 * -----------------------------
 * - Added comments
 * - Rewrote parts to become more flexible
 *
 * USAGE
 * -----
 *
 * <ul id='contextmenu'/>
 * ...
 * var wmMenu = new WMContextMenu("contextmenu");
 * wmMenu.populate({"foo" => "/foo", "bar" => "/?ct=bar"});
 * ...
 * <div id='someelement'>...</div>
 * ...
 * wmMenu.registerElement($("someelement") );
 *
 * @author Giso Stallenberg
 * @since unknown
 **/
WMContextMenu.prototype = {

	/**
	 * initialize
	 *
	 * Initializes a new WMContextMenu for html component with id
	 *
	 * @since unknown
	 * @access public
	 * @param string id
	 * @return void
	 **/
	initialize: function(id) {
		this.contextMenu = $(id);
		this.contextMenu.oncontextmenu = this.cancelDefault.bindAsEventListener(this);
		this.hoverActive = true;
		Element.hide(this.contextMenu);
	},

	/**
	 * registerElement
	 *
	 * Register a HTML element to use this context menu instead of its default
	 *
	 * @access public
	 * @since unknown
	 * @param htmlelement element
	 * @return void
	 **/
	registerElement: function(element) {
		element.oncontextmenu = this.show.bindAsEventListener(this);
	},

	/**
	 * populate
	 *
	 * (Re)Fills the contextmenu with the items set in the hash
	 *
	 * @access public
	 * @since unknown
	 * @param hash hash
	 * @return void
	 **/
	populate: function(hash) {
		// clear current contents
		if (this.title == null) {
			this.contextMenu.innerHTML = "";
		}
		else {
			this.contextMenu.innerHTML = "<h1>" + this.title + "</h1>";
		}


		if (this.hoverActive) {
			for (var i in hash) {
				var link = document.createElement("a");
				link.href = hash[i];
				var li = document.createElement("li");
				var textNode = document.createTextNode(i);
				li.appendChild(textNode);
				link.appendChild(li);
				this.contextMenu.appendChild(link);
			}
		}
	},

	/**
	 * setTitle
	 *
	 * Sets a title for a context menu
	 *
	 * @since Wed Jun 27 2007
	 * @access public
	 * @param string title
	 * @return void
	 **/
	setTitle: function(title) {
		this.title = title;
	},

	/**
	 * setHoverActive
	 *
	 * Sets the hoverActive attribute (as fas as I can see this is a enabled / disabled boolean
	 *
	 * @since unknown
	 * @access public
	 * @param boolean bool
	 * @return void
	 **/
	setHoverActive: function(bool) {
		this.hoverActive = bool;
	},

	/**
	 * show
	 *
	 * Shows the menu at the clicked location
	 *
	 * @since unknown
	 * @access public
	 * @param event e
	 * @return void
	 **/
	show: function(e){
		if (!e.shiftKey) {
			var viewportscroll = document.viewport.getScrollOffsets();
			var posX = Event.pointerX(e) - 1 + viewportscroll[0];
			var posY = Event.pointerY(e) - 1 + viewportscroll[1];

			Element.setStyle(this.contextMenu, {"position" : "absolute", "top" : posY + "px", "left" : posX + "px", "display" : "block"});
			Event.observe(document, "mousemove", this.hide.bindAsEventListener(this) );
			Event.stop(e);
		}
	},

	/**
	 * hide
	 *
	 * Hides the menu again if the mouse has moved away from it
	 *
	 * @since unknown
	 * @access public
	 * @param event e
	 * @return void
	 **/
	hide: function(e) {
		var posX = Event.pointerX(e);
		var posY = Event.pointerY(e);

		if (Position.within(this.contextMenu, posX, posY) == false) {
			Element.hide(this.contextMenu);
		}
	},

	/**
	 * cancelDefault
	 *
	 * Cancels the default contextmenu event (actually this, function cancels any event, it just use only for the oncontextmenu event)
	 *
	 * @since unknown
	 * @access public
	 * @param event e
	 * @return void
	 **/
	cancelDefault: function(e) {
		if (!e.shiftKey) {
			Event.stop(e);
		}
	},

	/**
	 * cancelHide
	 *
	 * Shows the contextmenu
	 * Note: is this function at all useful?
	 *
	 * @since unknown
	 * @access public
	 * @param event e
	 * @return void
	 **/
	cancelHide: function(e){
		Element.show(this.contextMenu);
	}
};


