Position.GetWindowSize = function(w) {
    var width, height;
    w = w ? w : window;
    this.width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);
    this.height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);
    return this;
}

/** 
 * @classDescription	Initializes context menu: attaching events and creating initial menu element. Defines show() and hide() methods.
 * @param				{string/object} selector; Selector to attach context menu functionality to (the area which will show menu on right-click), accepts any CSS3 selector
 * @param				{string} menuClassName; Class name for menu styling. It is recommended to keep all styles inside css file under this name
 * @param				{object} links; Object of key value pairs, where key is a {string} which acts as a link name and value is a {function} which gets called once corresponding link is clicked
*/

var Menu = Class.create();
Menu.prototype = {
	initialize: function (selector, menuClassName, oLinks, options) {
		this.options = {
			trigger:       'contextmenu',
            dropMenu:      false
		}
		
		Object.extend(this.options, options || {});

		$$(selector).each(function(el){
			el.observe(this.options.trigger, function(e){
				this.show(e);
				Event.stop(e);
			}.bindAsEventListener(this));
			if (window.opera && (this.options.trigger == 'contextmenu')){
				el.observe('click', function(e){
					if (e.ctrlKey == true) {
						this.show(e);
						Event.stop(e);
					}
				}.bindAsEventListener(this));
			}
		}.bind(this));
		
        this.closer = this.hide.bindAsEventListener(this);

		Event.observe(document, 'click', this.closer, false);
		
		this.container = document.createElement('div');
		Element.addClassName(this.container, menuClassName);
		$A(oLinks);
		for (o in oLinks){
			if (oLinks[o] === '') {
				var link = document.createElement('div');
				Element.addClassName(link,'separator');
				this.container.appendChild(link);
			}
			else {
				var link = document.createElement('a');
				link.href = '#';
				link.title = o;
				link._onClick = oLinks[o];
				if (link._onClick === false) {
					Element.addClassName(link,'disabled');
				}
				Element.observe(link, 'click', function(e){
					if (Event.element(e)._onClick !== false) {
						this.container.hide();
						Event.element(e)._onClick(this.el);
					}
					Event.stop(e);
				}.bindAsEventListener(this));
				link.appendChild(document.createTextNode(o));
				this.container.appendChild(link);
			}
		}
		this.container.style.display = 'none';
	    this.container.observe('mouseover',
                this.swallow.bindAsEventListener(this)); 

		document.body.appendChild(this.container);
	},
	
	show: function(e){
        if (this.container.style.display == 'none') {
            this.el = Event.element(e);
            if (this.options.dropMenu) {
                this.container.style.left = this.el.offsetLeft + 'px';
                this.container.style.top = this.el.offsetTop + this.el.offsetHeight + 'px';
            } else {
                var x = Event.pointerX(e);
                var y = Event.pointerY(e);
                var scrollX = x - e.clientX;
                var scrollY = y - e.clientY;
                var w = this.container.getWidth();
                var h = this.container.getHeight();
                var dim = Position.GetWindowSize();

                if (x + w > dim.width + scrollX) {
                    x = dim.width - w + scrollX;
                    if (x < 0)
                        x = 0;
                }

                if (y + h > dim.height + scrollY) {
                    y = dim.height - h + scrollY;
                    if (y < 0)
                        y = 0;
                }

		        this.container.style.left = x + 'px';
		        this.container.style.top = y + 'px';

            }
		    this.container.style.display = '';
    
		    Event.observe(document, 'mouseover', this.closer, false);
        }
	},
	
    swallow: function(e) {
        Event.stop(e);
    },

	hide: function(e){
		this.container.style.display = 'none';
		Event.stopObserving(document, 'mouseover', this.closer, false);
		return true;
	}
};

/*
Event.observe(window, 'load', function(){
	
	var externalStopFunction = function(){
		alert('stop function called externally');
	}
	var oLinks = {
		'Back': function(){alert('Back function called')},
		'Forward': function(){alert('Forward function called')},
		'1': '',
		'Reload': function(){alert('Reload function called')},
		'Reload Every': function(){alert('Reload Every function is called')},
		'Stop': externalStopFunction,
		'2': '',
		'Undo Close Tab': function(){alert('Undo close tab called')},
		'3': '',
		'View Page in IE Tab': function(){alert('Viewing page in IE tab')},
		'View Page in Ext. App.': function(){alert('Viewing page in ext. app.')},
		'Disabled option': false
	}
	
	var menuObj = new Menu('#desc', 'menu', oLinks);
	
}, false);
*/
