/**
 * @description	  prototype.js based context & dropdown menus
 * @author        Juriy Zaytsev; kangax [at] gmail [dot] com; http://thinkweb2.com/projects/prototype/
 * @version       0.6
 * @date          12/03/07
 * @requires      prototype.js 1.6
 * @modified by   Yannick Luescher (Patch3 for Hivemail)
*/
/**************************************************************
This combines 2 menus and 2 approaches thus it's a bit messy...
Hide mode creates menu once, then shows/hides on click
Destroy mode creates and destroys menus on click
action: [context || dropdown]
mode: [hide || destroy]
***************************************************************/

if (Object.isUndefined(Proto)) { var Proto = { } }

Proto.Menu = Class.create({
	initialize: function() {
		var e = Prototype.emptyFunction;
		this.ie = Prototype.Browser.IE;
		this.options = Object.extend({
			selector: '.contextmenu',
			className: 'protoMenu',
			pageOffset: 25,
			fade: false,
			zIndex: 100,
			beforeShow: e,
			beforeHide: e,
			beforeSelect: e
		}, arguments[0] || { });

		this.shim = new Element('iframe', {
			style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none',
			src: 'javascript:false;',
			frameborder: 0
		});

		this.options.fade = this.options.fade && !Object.isUndefined(Effect);

        // MENU CREATION
        if (this.options.mode == 'hide') {
           this.create_container_hide(this.options.e);
           this.show(this.options.e);
        } else {
           this.create_container_destroy(this.options.e);
           this.show(this.options.e);
        }

        // EVENT OBSERVERS
        // Left Click
        document.observe('click', function(e) {
        // this.container.className == 'menu desktop' && $(this.options.id) && !e.element()hasAttribute(this.options.attribute)
        	if (this.options.mode == 'hide' && this.container.visible() && !e.isRightClick()) {
				this.options.beforeHide(e);
				if (this.ie) this.shim.hide();
				this.container.hide();
			}
            // Remove the to be destroyed div on each click, but not when clicking on the dropdown element
            // Remove the container if not clickinig on opening link
            else if (this.options.mode == 'destroy' && !e.isRightClick() && $(this.options.id) && !e.element().hasAttribute(this.options.attribute)) {
               // alert ('drop removed');
               this.remove_container(e);
            }
            // Create the destroyed div again
            // We don't create if it's a context menu
            else if (this.options.mode == 'destroy' && this.options.action != 'context' && !e.isRightClick() && !$(this.options.id) && e.element().hasAttribute(this.options.attribute)) {
               this.create_container_destroy(e);
               this.show(e);
            } else {
                 return;
            }
		}.bind(this));

        // Right Click
       	// $$(this.options.selector).invoke('observe', Prototype.Browser.Opera ? 'click' : 'contextmenu', function(e){
        if (this.options.action == 'context') {
		document.observe(Prototype.Browser.Opera ? 'click' : 'contextmenu', function(e){
        	if (Prototype.Browser.Opera && !e.ctrlKey) {
				return;
			}
            if (this.options.mode == 'hide') {
            // alert(e.element().hasAttribute(this.options.attribute));
              if (e.element().hasAttribute(this.options.attribute)) {
			     this.show(e);
              } else if (this.container.visible()) {
                 this.options.beforeHide(e);
                 if (this.ie) this.shim.hide();
			     this.container.hide();
              } else {
                 return;
              }
            } else {
              if ($(this.options.id) && !e.element().hasAttribute(this.options.attribute)) {
                 this.remove_container(e);
              } else if ($(this.options.id) && e.element().hasAttribute(this.options.attribute)) {
                 this.show(e);
              } else if (!$(this.options.id) && e.element().hasAttribute(this.options.attribute)) {
                 this.create_container_destroy(e);
               this.show(e);
              } else {
                 return;
              }
            }
		}.bind(this));
        }
	},
    // CONTAINER MODE HIDE
    create_container_hide: function(e) {
        this.container = new Element('div', {id: this.options.id, className: this.options.className, style: 'display:none'});
	    var list = new Element('ul');
        var number = 1;
        this.options.menuItems.each(function(item) {
             list.insert(
	         new Element('li', {className: item.separator ? 'separator' : ''}).insert(
	             item.separator
						? ''
						: Object.extend(new Element('a', {
							href: '#',
                            id: this.options.actualcontext+'item'+number,
							//title: item.name,
							className: (item.className || '') + (item.disabled ? ' disabled' : ' enabled')
						}), { _callback: item.callback })
						.observe('click', this.onClick.bind(this))
						.observe('contextmenu', Event.stop)
						.update(item.name)
				)
			)
          number++;
		  }.bind(this));
		  $(document.body).insert(this.container.insert(list));
		  if (this.ie) { $(document.body).insert(this.shim) }
    },
    // CONTAINER MODE DESTROY
    create_container_destroy: function(e) {
        // The attribute is refreshed after each AJAX call. We process it here
        // The destroy mode doesn't allow to disable elements atm
        this.options.menuItems = e.element().getAttribute(this.options.attribute).toQueryParams();
        this.container = new Element('div', {id: this.options.id, className: this.options.className, style: 'display:none'});
		var list = new Element('ul');
        $H(this.options.menuItems).each(function(pair) {
                //alert(pair.value);
                if (this.options.replaceitem) {
                   $H(this.options.replaceitem).each(function(pair2) {
                   pair.value = ((pair.value == pair2.key) ? pair2.value : pair.value)
                   })
                }
                // This prepends a prefix (eg arrow, bullet) to each item, except for those in the itemprefixexclude array
                pair.value = (this.options.itemprefix ? (this.options.itemprefixexclude ? ((this.options.itemprefixexclude.include(pair.value)) ?
                              pair.value : this.options.itemprefix + ' ' + pair.value) : pair.value) : pair.value)
            	list.insert(
				new Element('li').insert(
					Object.extend(new Element('a', {
							href: '#',
                            className: (pair.value.include(this.options.itemprefix)) ? 'capitalize enabled' : ' enabled'
						}), { _callback: function(e){this.options.callback(e,pair.key)}.bind(this) })
						.observe('click', this.onClick.bind(this))
						.observe('contextmenu', Event.stop)
						.update(pair.value)
				)
			)
		  }.bind(this));
        $(document.body).insert(this.container.insert(list));
		if (this.ie) { $(document.body).insert(this.shim) }
    },
	show: function(e) {
		e.stop();
        this.options.beforeShow(e);
		var x = Event.pointer(e).x,
			y = Event.pointer(e).y,
			vpDim = document.viewport.getDimensions(),
			vpOff = document.viewport.getScrollOffsets(),
			elDim = this.container.getDimensions();
        // Since this is used for a dropdown box too...
        if (this.options.action == 'dropdown') {
            var elOff = {
                left: (x - elDim.width / 2) + 'px',
                top: (y + 10) + 'px'
            };
        } else {
			var elOff = {
				left: ((x + elDim.width + this.options.pageOffset) > vpDim.width
					? (vpDim.width - elDim.width - this.options.pageOffset) : x) + 'px',
				top: ((y - vpOff.top + elDim.height) > vpDim.height && (y - vpOff.top) > elDim.height
					? (y - elDim.height) : y) + 'px'
			};
        }
		this.container.setStyle(elOff).setStyle({zIndex: this.options.zIndex});
		if (this.ie) {
			this.shim.setStyle(Object.extend(Object.extend(elDim, elOff), {zIndex: this.options.zIndex - 1})).show();
		}
		this.options.fade ? Effect.Appear(this.container, {duration: 0.25}) : this.container.show();
		this.event = e;
	},
    remove_container: function(e) {
        // Event removing seems to work
        $$('#'+this.options.id+' a').each(function(item) {
           // alert(item.className);
           Event.stopObserving(item, 'click', this.onClick);
           Event.stopObserving(item, 'contextmenu', Event.stop);
        });
        $(this.options.id).remove();
        if (this.ie) this.shim.remove();
    },
	onClick: function(e) {
		e.stop();
		if (e.target._callback && !e.target.hasClassName('disabled')) {
			this.options.beforeSelect(e);
            if (this.options.mode == 'destroy') {
              // alert ('drop sel removed');
              this.remove_container(e);
            } else {
			  if (this.ie) this.shim.hide();
			  this.container.hide();
            }
			e.target._callback(this.event);
		}
	}
})

// function to disable items dynamically
function mailcontextdisable(e){
// Check the Row
checkMail(e.element().getAttribute('a'), 1, 1, 0, 1);
if (e.element().getAttribute('b').indexOf('new') == -1) {
   $('mailitem10').className='disabled';
   $('mailitem11').className='enabled';
} else {
   $('mailitem11').className='disabled';
   $('mailitem10').className='enabled';
}
if (e.element().getAttribute('c') == 1) {
   $('mailitem12').className='disabled';
   $('mailitem13').className='enabled';
} else {
   $('mailitem13').className='disabled';
   $('mailitem12').className='enabled';
}}

function foldercontextdisable(e){
if (e.element().getAttribute('x') == -5) {
   $('folderitem2').className='disabled';
   $('folderitem6').className='disabled';
   $('folderitem7').className='disabled';
   $('folderitem10').className='disabled';
   $('folderitem11').className='disabled';
} else {
   $('folderitem2').className='enabled';
   $('folderitem6').className='enabled';
   $('folderitem7').className='enabled';
   $('folderitem10').className='enabled';
   $('folderitem11').className='enabled';
}
if (e.element().getAttribute('x') < 0) {
   $('folderitem4').className='disabled';
   $('folderitem8').className='disabled';
} else {
   $('folderitem4').className='enabled';
   $('folderitem8').className='enabled';
}}
