﻿// version 4.1 : slight modification to code upon reaching the far right of the screen
// version 4.0 : rewritten to real jQuery plugin as per http://docs.jquery.com/Plugins/Authoring (returning the collection from version 3.0) breaks my logic...
// version 3.0 : rewritten to real jQuery plugin
// version 2.0 : rewritten to jQuery
// version 1.0 : first

(function ($) {

	var methods = {
		init: function () {
			var instance = this;

			return this.find("*[msjsToolTip]").each(function (intIndex, node) {
				var o = $(node);
				if (o.attr("msjsToolTip") !== undefined) {
					var objThis = $(this);

					objThis.data("msjsToolTip", {
						parent: instance
					});
					objThis.bind("mouseover.msjsToolTip", function (event) {
						methods["showTip"].apply(
								this, new Array(
									this, o.attr("msjsToolTip"), event, instance
								)
							);
					}
					); // namespacing! ;-)

					if (instance.options.autoHide) {
						objThis.bind("mouseout.msjsToolTip", function (event) {
							methods["hideTip"].apply(
									this, new Array(
										instance
									)
								);
						}
						);
					} else {
						instance.tip.bind("click.msjsToolTip", function (event) {
							methods["hideTip"].apply(
								this, new Array(
									instance
								)
							);
						}
						).css("cursor", "pointer");
					}
					objThis.bind("mousemove.msjsToolTip", function (event) {
						methods["moveTip"].apply(
								this, new Array(
									event, instance
								)
							);
					}
					);
				}
			});
		},

		moveTip: function (objEvent, objJq) {
			var posx = 0;
			var posy = 0;
			var evt = objEvent;

			if (typeof (evt) == "undefined")
				evt = (typeof (event) == "undefined" ? window.event : event);
			if (!evt)
				return;
			if (evt.pageX || evt.pageY) {
				posx = evt.pageX;
				posy = evt.pageY;
			} else if (evt.clientX || evt.clientY) {
				posx = evt.clientX;
				posy = evt.clientY;
			}

			var left = 0;
			if (objJq.options.showTipRightOfMouse)
				left = (posx + objJq.options.positionOffset);
			else
				left = (posx - objJq.tip.width() - objJq.options.positionOffset);

			var top = posy;
			top = (top < 0 ? 0 : top);

			left = (left < 0 ? posx + objJq.options.positionOffset : left);

			var minHeight = $(window).height() - objJq.tip.height();
			if (top > minHeight)
				top = minHeight;

			var minLeft = $(window).width() - objJq.tip.width();
			if (left > minLeft) {
				left = minLeft + $(window).scrollLeft() - objJq.options.positionOffset;
			}

			objJq.tip.css("left", left + "px");
			objJq.tip.css("top", (top + objJq.options.positionOffset) + "px");
		},

		hideTip: function (objJq) {
			objJq.tip.hide();
		},

		showTip: function (obj, tooltipText, objEvent, objJq) {
			objJq.tip.width("").height("");
			
			if (tooltipText.indexOf("fnc:") == 0) {
				tooltipText = tooltipText.replace("fnc:", "");
				$(obj).attr("msjsToolTip", tooltipText); // send tooltip text back to element to avoid triggering several ajax callbacks
				objJq.tip.html("<img src=\"img/loading.gif\" />").show();
				eval(tooltipText);
			} else {
				objJq.tip.html(tooltipText).show();
				if (objJq.options.widthMax > 0) { // max width
					if (objJq.tip.width() > objJq.options.widthMax) {
						objJq.tip.width(objJq.options.widthMax); //.css("overflow", "auto");
					}
				}
				if (objJq.options.heightMax > 0) { // max height
					if (objJq.tip.height() > objJq.options.heightMax) {
						objJq.tip.height(objJq.options.heightMax); //.css("overflow", "auto");
					}
				}
			}
			setTimeout(function () { methods.moveTip(objEvent, objJq); }, 50);
		}
	};


	$.fn.msjsToolTip = function (options, method) {
		switch (method) {
			case "update":
				try {
					// update the tooltip text with [web service] output
					var parent = this.data("msjsToolTip").parent;
					//parent.tip.html(this.attr("msjsToolTip")); // when called like $(element).msjsToolTip('parent') "this" = the element, NOT the class object
					methods.showTip(this, this.attr("msjsToolTip"), event, parent);
					// make sure to reposition the tooltip now that dimensions may have changed
					if (arguments.length == 3) // event handler needs to pass event object 
						setTimeout(function () { methods.moveTip(arguments[2], parent); }, 50);
				} catch (err) { }
				break;
			default:
				var defaults = {
					widthMax: 230, heightMax: 0, autoHide: true, zIndex: 900,
					showTipAboveMouse: false, showTipRightOfMouse: true,
					positionOffset: 12
				};
				
				this.elements = new Array(); // tooltip text collection
				this.options = $.extend(defaults, options);
				this.tip = $("<div></div>");
				this.tip.attr("style", "overflow:auto;border:solid 1px #77787b;background:#ffffff;padding:4px;position:absolute;top:-200px;left:-200px;z-index:" + this.options.zIndex + ";");
				$(document.body).find(">:first-child").before(this.tip);
				return methods["init"].apply(this, Array.prototype.slice.call(arguments, 1));
				break;
		}


	};

})(jQuery);
