/** 
 * @description		prototype.js based context menu
 * @author			Juriy Zaytsev; kangax@gmail.com; http://thinkweb2.com/projects/prototype
 * @version			0.5
 * @date			8/22/07
 * @requires		prototype.js 1.6.0_rc0
*/


// temporary unobtrusive workaround for 'contextmenu' event missing from DOMEvents in 1.6.0_RC0
/*
if (!Event.DOMEvents.include('contextmenu')) {
	Event.DOMEvents.push('contextmenu')
}
*/

// nifty helper for setting element's property in a chain-friendly manner
Element.addMethods({
	__extend: function(element, hash) {
		return Object.extend($(element), hash);
	}
})

if (Object.isUndefined(Proto)) { var Proto = { } }
Proto.Menu = Class.create();
Proto.Menu.prototype = {
	initialize: function (options) {
		this.options = Object.extend({
			selector: '.contextmenu',
			className: '.protoMenu',
			pageOffset: 25,
			fade: false,
			containerId: null
		}, options || { });
		// Setting fade to true only if Effect is defined
		if ( this.options.myOffsetTop && this.options.myOffsetLeft ) {
			this.myOffsetTop = this.options.offsetTop;
			this.myOffsetLeft = this.options.offsetLeft;
		}
		this.options.fade = this.options.fade && !Object.isUndefined(Effect);
		this.container = new Element('div', {
				className: this.options.className, 
				style: 'display: none', 
				id:(this.options.containerId?this.options.containerId:null)
			}
		);
		this.container.setStyle({
			position:'absolute',
			top: ( this.options.myOffsetTop ? this.options.myOffsetTop + 'px' : '0px' ),
			left:( this.options.myOffsetLeft ? this.options.myOffsetLeft + 'px' : '0px' )
		});
		
		this.options.menuItems.each(function(item){
			this.container.insert( 
				new Element('div', {}).insert(
				new Element('a', {
						href: item.url,
						title: item.name,
						className: ''
					})
					.observe('click', this.onClick.bind(this) )
					.__extend({_callback: item.callback})
					.insert(
						new Element('span', {className:'item'})
							.update(item.name)
							.__extend({_callback: item.callback})
					)
				)
			);
		}.bind(this));
		$('menuContainer').insert(this.container);
		
		Event.observe(document, 'click', function(e){
			this.container.hide();
		}.bind(this));
		
		$$(this.options.selector).invoke('observe', Prototype.Browser.Opera ? 'click' : 'contextmenu', function(e){
			if (Prototype.Browser.Opera && !e.ctrlKey) {
				return;
			}
			this.show(e);
		}.bind(this));
		
		this.containerWidth = this.container.getWidth();
		this.containerHeight = this.container.getHeight();
	},
	show: function(e) {
		$A(document.getElementsByClassName('macifSubmenu')).each(function(element) {
			element.hide();
		});

		e.stop();
		var viewport = document.viewport.getDimensions(),
			offset = document.viewport.getScrollOffsets(),
			containerWidth = this.container.getWidth(),
			containerHeight = this.container.getHeight();

		/*
		this.container.setStyle({
//			left: ((e.pageX + containerWidth + this.options.pageOffset) > viewport.width ? (viewport.width - containerWidth - this.options.pageOffset) : e.pageX) + 'px',
//			top: ((e.pageY - offset.top + containerHeight) > viewport.height && (e.pageY - offset.top) > containerHeight ? (e.pageY - containerHeight) : e.pageY) + 'px'
		}).hide();
		*/
		this.container.hide();

		this.options.fade ? Effect.Appear(this.container, {duration: 0.25}) : this.container.show();
	},
	onClick: function(e) {
		e.stop();
		if (e.target._callback && !e.target.hasClassName('disabled')) {
			this.container.hide();
			e.target._callback(e);
		}
	},
	
	getContainer: function() {
		return this.container;
	}
} // class Menu


Proto.GroupMenu = Class.create();
Proto.GroupMenu.prototype = {
	
	initialize: function() {
		this.arrMenuList = new Array();
	}, // initialize
	
	addMenu: function( objMenu ) {
		this.arrMenuList.push( objMenu );
	},
	
	hideAll: function() {
		this.arrMenuList.each( function( objMenuItem ) {
			objMenuItem.getContainer().hide();
		} );
	}
	
} // class GroupMenu
