﻿if(window.addEventListener)
{
	FixPrototypeForGecko();
}
function FixPrototypeForGecko()
{
	HTMLElement.prototype.__defineGetter__("runtimeStyle",element_prototype_get_runtimeStyle);
	window.constructor.prototype.__defineGetter__("event",window_prototype_get_event);
	Event.prototype.__defineGetter__("srcElement",event_prototype_get_srcElement);
}
function element_prototype_get_runtimeStyle()
{
	return this.style;
}
function window_prototype_get_event()
{
	return SearchEvent();
}
function event_prototype_get_srcElement()
{
	return this.target;
}

function SearchEvent()
{
	if(document.all)
		return window.event;
	
	func=SearchEvent.caller;
	while(func!=null){
		var arg0=func.arguments[0];
		if(arg0){
			if(arg0.constructor==MouseEvent)
			return arg0;
		}
		func=func.caller;
	}
	return null;
}

function getOffsetToBody(object){
	if(object){
		var offset = {x: object.offsetLeft, y: object.offsetTop};
		while(object = object.offsetParent){
			offset.x += object.offsetLeft;
			offset.y += object.offsetTop;
		}
		return offset;
	}
}

var PopupMenu = function() {
	this.init();
}

PopupMenu.SEPARATOR = 'PopupMenu.SEPARATOR';
PopupMenu.current = null;
PopupMenu.addEventListener = function(element, name, observer, capture) {
	if (typeof element == 'string') {
		element = document.getElementById(element);
	}
	if (element.addEventListener) {
		element.addEventListener(name, observer, capture);
	} else if (element.attachEvent) {
		element.attachEvent('on' + name, observer);
	}
};
PopupMenu.prototype = {
	init: function() {
		this.divitems = [];
		this.items  = [];
		this.width  = 0;
		this.height = 0;
	},
	setSize: function(width, height) {
		this.width  = width;
		this.height = height;
		if (this.element) {
			var self = this;
			with (this.element.style) {
				if (self.width)  width  = self.width  + 'px';
				if (self.height) height = self.height + 'px';
			}
		}
	},

//直接绑定对象，右击对象自动弹出菜单，自能绑定一次
	bindauto: function(element) {
		if(!element){return false;}
		var self = this;
		if (!element) {
			element = document;
		} else if (typeof element == 'string') {
			element = document.getElementById(element);
		}
		
		this.target = element;
		this.target.oncontextmenu = function(e) {
			self.show.call(self, e);
			return false;
		};

		if(!(this.eventAttached)){
			var listener = function() { 
				self.hide.call(self);
			};
			PopupMenu.addEventListener(document, 'click', listener, true);
			this.eventAttached = true;
		}
	},
//直接绑定对象，需要手动调用该方法在鼠标位置弹出菜单	
	bindmanual: function(element) {
		if(!element){return false;}
		var self = this;
		if (!element) {
			element = document;
		} else if (typeof element == 'string') {
			element = document.getElementById(element);
		}
		
		var args = arguments; //存储参数，以便回调
		var newargs = new Array();
		if(args){
			for(var i = 1; i< args.length; i++){
				newargs.push(args[i]);
			}
		}		
		this.extra_data = newargs;
		
		if(this.target != element){
			self.show.call(self, null);
		}
		this.target = element;
		
		this.clicked = true;
		var listener = function() { 
			if(!(self.clicked)){
				self.hide.call(self);
			}
			self.clicked = false;
		};
		if(!(this.eventAttached)){
			PopupMenu.addEventListener(document, 'click', listener, true);
			this.eventAttached = true;
		}
	},
//直接绑定对象，需要手动调用该方法在对象左下方位置弹出菜单	
	binddropdown: function(element){
		if(!element){return false;}
		var self = this;
		if (typeof element == 'string') {
			element = document.getElementById(element);
		}
		var args = arguments; //存储参数，以便回调
		var newargs = new Array();
		if(args){
			for(var i = 1; i< args.length; i++){
				newargs.push(args[i]);
			}
		}		
		this.extra_data = newargs;
		
		this.target = element;		
		var offset = getOffsetToBody(element);	
		
		if(offset){
			var height = element.offsetHeight;		
			offset.y += height;
			this.showat(offset.x, offset.y);			
		}

		this.clicked = true;
		var listener = function() { 
			if(!(self.clicked)){
				self.hide.call(self);
			}
			self.clicked = false;
		};

		if(!(this.eventAttached)){
			PopupMenu.addEventListener(document, 'click', listener, true);
			this.eventAttached = true;
		}
	},
	add: function(text, callback, id) {
		this.items.push({text: text, callback: callback, id: id, visible: true });
	},
	addSeparator: function() {
		this.items.push({text: "", id: PopupMenu.SEPARATOR, visible: true});
	},
	setPos: function(e) {
		if (!this.element) return;
		if (!e) e = window.event;
		var x, y;
		if (window.opera) {
			x = e.clientX;
			y = e.clientY;
		} else if (document.all) {
			x = document.body.scrollLeft + event.clientX;
			y = document.body.scrollTop + event.clientY;
		} else if (document.layers || document.getElementById) {
			x = e.pageX;
			y = e.pageY;
		}
		this.element.style.top  = y + 'px';
		this.element.style.left = x + 'px';
	},    
	showat: function(x, y){
		if (PopupMenu.current && PopupMenu.current != this) return;
		PopupMenu.current = this;
		if (this.element) {
			this.element.style.top  = y + 'px';
			this.element.style.left = x + 'px';
			this.element.style.display = '';
		} else {
			this.element = this.createMenu(this.items);
			this.element.style.top  = y + 'px';
			this.element.style.left = x + 'px';
			document.body.appendChild(this.element);
		}    
	},
	show: function(e) {
		if (PopupMenu.current && PopupMenu.current != this) return;
		PopupMenu.current = this;
		if (this.element) {
			this.setPos(e);
			this.element.style.display = '';
		} else {
			this.element = this.createMenu(this.items);
			this.setPos(e);
			document.body.appendChild(this.element);
		}
	},
	hide: function() {
		PopupMenu.current = null;
		if (this.element) this.element.style.display = 'none';
	},
	showItem: function(i){
		if(i< this.items.length){
			this.items[i].visible = true;
		}
		if(i < this.divitems.length){
			this.divitems[i].style.display = '';
		}
	},
	
	showItems: function(){
		var args = arguments;
		if(args){
			for(var i = 0; i< args.length; i++){
				this.showItem(args[i]);
			}
		}
	},
	
	hideItem: function(i){		
		if(i< this.items.length){
			this.items[i].visible = false;
		}
		if(i < this.divitems.length){
			this.divitems[i].style.display = 'none';
		}	
	},
	
	hideItems: function(){
		var args = arguments;
		if(args){
			for(var i = 0; i< args.length; i++){
				this.hideItem(args[i]);
			}
		}
	},
	
	createMenu: function(items) {
		var self = this;
		var menu = document.createElement('div');
		with (menu.style) {
			if (self.width)  width  = self.width  + 'px';
			if (self.height) height = self.height + 'px';
			border     = "1px solid gray";
			background = '#FFFFFF';
			color      = '#000000';
			position   = 'absolute';
			display    = 'block';
			padding    = '2px';
			cursor     = 'default';
		}
		for (var i = 0; i < items.length; i++) {
			var item;
			if (items[i].id == PopupMenu.SEPARATOR) {
				item = this.createSeparator();
			} else {
				item = this.createItem(items[i]);
			}
			if(items[i].visible){
				item.style.display = '';
			} else {
				item.style.display = 'none';
			}
			this.divitems.push(item);
			menu.appendChild(item);
		}
		return menu;
	},
	createItem: function(item) {
		var self = this;
		var elem = document.createElement('div');
		elem.className ="popupMenuItem";
		elem.style.padding = '2px 2px 2px 25px';
		var callback = item.callback;
		var id = item.id;
		PopupMenu.addEventListener(elem, 'click', function(_callback, _id) {
			return function() {
				self.hide();
				var _newdata = {
					id: _id,
					data: self.extra_data,
					target: self.target
				};
				_callback(self.target, _newdata);
			};
		}(callback, id), true);
		PopupMenu.addEventListener(elem, 'mouseover', function(e) {
			elem.style.background = '#B6BDD2';
		}, true);
		PopupMenu.addEventListener(elem, 'mouseout', function(e) {
			elem.style.background = '#FFFFFF';
		}, true);
		
		elem.appendChild(document.createTextNode(item.text));
		
		return elem;
	},
	createSeparator: function() {
		var sep = document.createElement('div');
		with (sep.style) {
			borderTop = '1px dotted #CCCCCC';
			fontSize  = '0px';
			height    = '0px';
		}
		return sep;
	}
};

