if(!Control) var Control = {};
Control.UserMenu = Class.create();

Control.UserMenu.prototype = {
	cachedResults: {},
	cachedUsers: {},
	mouseInTimer: null,
	mouseOutTimer: null,
	currentId: null,
	elementsMenu: {},

	initialize: function(options) {
		this.options = options || {};
		this.showDelay = parseInt(this.options.showDelay) || 300;
		this.hideDelay = parseInt(this.options.hideDelay) || 200;

		this.eventMouseOver = this.mouseOver.bindAsEventListener(this);
		this.eventMouseOut = this.mouseOut.bindAsEventListener(this);
		Event.observe(document.body, "mousemove", this.eventMouseOver);

		this.DOMLoad();
	},

	DOMLoad: function() {
		this.load_timer = setInterval(this.setData.bind(this), 250);
	},

	setData: function() {
		if (this.load_timer) clearInterval(this.load_timer);
		this.load_timer = null;

		this.cachedResults = {};
		this.cachedUsers = {};
		this.elementsMenu = {};
		if (this.mouseInTimer) {
			window.clearTimeout(this.mouseInTimer);
			this.mouseInTimer = null;
		};
		if (this.mouseOutTimer) {
			window.clearTimeout(this.mouseOutTimer);
			this.mouseOutTimer = null;
		}

		var users = [];
		var domObjects = document.getElementsByTagName("*");
		for (var i=0; i < domObjects.length; i++) {
            if (Element.hasClassName(domObjects[i], "avatar")) users.push(domObjects[i]);
		}

		var userElements = [];
		users.each( function(u) {
			var imgs = u.getElementsByTagName("img");
			for (var i=0; i < imgs.length; i++) {
				var img = imgs.item(i);
				if (/avatar.+?\/\d+\.\w+$/.test(img.src)) {
					userElements.push(img);
					img.alt = "";
				}
			}
		});

		var menuId = 1;
		userElements.each( (function(ue) {
			this.elementsMenu[menuId + ""] = ue;
			ue.menuId = menuId++;
			ue.id = "avatar" + ue.menuId;
		}).bind(this));
	},

	mouseOver: function(e) {
		var target = e.target || Event.element(e);
		var menuId = target.menuId;
		if (!menuId) {
			var par = target.parentNode; var j = 0;
			// цикл пока не дойдем до родителя, у которого tagName == 'div', но не более 5 шагов
			while ((j++ < 5) && par.parentNode && (!par.tagName || (par.tagName.toUpperCase() != 'DIV'))) {
				par = par.parentNode;
			}
			menuId = par.menuId;
		}

		if (!target || !menuId) {
			if (this.mouseInTimer) {
				window.clearTimeout(this.mouseInTimer);
				this.mouseInTimer = null;
			};

			if (this.menu) {
				if (this.mouseInTimer || this.mouseOutTimer) return;
				this.mouseOutTimer = window.setTimeout(this.eventMouseOut, this.hideDelay);
				return;
			}
		}

		if (this.mouseOutTimer) {
			window.clearTimeout(this.mouseOutTimer);
			this.mouseOutTimer = null;
		}

		if (!menuId) return;

		if (!this.mouseInTimer && (!this.menu || (this.currentId && this.currentId != menuId))) {
			this.mouseInTimer = window.setTimeout(function() {this.showMenu(menuId)}.bind(this), this.showDelay);
		}
	},

	mouseOut: function(e) {
		if (this.mouseInTimer) window.clearTimeout(this.mouseInTimer);
		if (this.mouseOutTimer) window.clearTimeout(this.mouseOutTimer);
		this.mouseInTimer = null;
		this.mouseOutTimer = null;
		this.currentId = null;
		this.hideMenu();
	},

	hideMenu: function() {
		if (this.menu) this.menu.parentNode.removeChild(this.menu);
		this.menu = null;
	},

	updateMenu: function(menuId) {
		if (!this.menu || (this.currentId && this.currentId != menuId)) return;

		var retdata = this.cachedResults[menuId + ""];
		if (!retdata || (retdata && !retdata.userid && !retdata.htmldata)) {
			this.hideMenu();
			return;
		}
		// set new data & render
		this.menu.innerHTML = retdata.htmldata;
	},

	getUserMenu: function(request) {
		if (request.status == 200) {
			var rt = request.responseText;
			var menuId = parseInt(rt.match(/<menuId>(.+)<\/menuId>/i)[1]);
			if (menuId) {
				var retdata = {};
				retdata.htmldata = rt.match(/<htmlData><\!\[CDATA\[(.*)\]\]><\/htmlData>/i)[1];
				retdata.userid = parseInt(rt.match(/<userId>(.+)<\/userId>/i)[1]);
				this.cachedResults[menuId + ""] = retdata;
				this.cachedUsers[retdata.userid + ""] = menuId;
				this.updateMenu(menuId);
			}
		} else {
			this.hideMenu();
		}
	},

	showMenu: function(menuId) {
		if (this.mouseInTimer) window.clearTimeout(this.mouseInTimer);
		this.mouseInTimer = null;

		if (this.menu && (this.currentId && this.currentId == menuId)) return;

		this.currentId = menuId;
		this.constructMenu(menuId);
		var retdata;
		var userid = parseInt(this.elementsMenu[menuId + ""].src.match(/avatar.+?\/(\d+)\.\w+$/)[1]);
		if (this.cachedUsers[userid + ""]) {
			retdata = this.cachedResults[this.cachedUsers[userid + ""] + ""];
			this.cachedResults[menuId + ""] = retdata;
		} else {
			retdata = this.cachedResults[menuId + ""];
		}
		if (!retdata) {
			// ajax-запрос
			var url = '/inc/getUserMenu.cgi';
			var par = 'userid=' + userid + '&menuid=' + menuId + '&rand=' + Math.random();
			new Ajax.Request( url, { method: 'get', parameters: par, onComplete: this.getUserMenu.bind(this) } );
		} else {
			this.updateMenu(menuId);
		}
	},

	constructMenu: function(menuId) {
		this.hideMenu();

		if (!this.container) {
			this.container = document.createElement("div");
			document.body.appendChild(this.container);
		}
		this.container.innerHTML = '<div id="menu' + menuId + '" style="position:absolute;"></div>';

		var menu = $('menu'+menuId);
		var elem = this.elementsMenu[menuId + ""];
		if ((!menu) || (!elem)) return;

		Position.clone(elem, menu, {
			setHeight: false,
			setWidth: false,
			offsetTop: elem.offsetHeight
		});
		Element.setStyle(menu, {
			'background-color': '#ffffee',
			'border': 'solid 1px #000000',
			'padding': '5px',
			'z-index': '999'
		});

		menu.menuId = menuId;
		menu.innerHTML = "Загрузка...";
		this.menu = menu;
	}
};

var myUserMenu = null;
function _initMenu() {
	myUserMenu = new Control.UserMenu();
}

if (typeof window.onload == "undefined" || window.onload == null) {
	window.onload = _initMenu;
} else {
	(function() {
		var oldOnload = window.onload;
		window.onload = function() { oldOnload(); _initMenu(); }
	})();
}

