/*
 * Apache License
 * Version 2.0, January 2004
 * http://www.apache.org/licenses/
 *
 * Copyright 1996-2008 by Sven Homburg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 */

/*
 * MyTip 0.1.0
 * by Peter Host
 * 2007.09.18
 * 
 * Licensed under the Creative Commons Attribution 3.0 License
 * http://creativecommons.org/licenses/by/3.0/
 */

var Prototip = {
  Version: '2.0.4'
};

var Tips = {
  options: {
    images: '/images/mytip/', // image path, can be relative to this file or an absolute url
    zIndex: 6000                   // raise if required
  }
};

Prototip.Styles = {
  // The default style every other style will inherit from.
  // Used when no style is set through the options on a tooltip.
  'default': {
    border: 3,
    borderColor: '#c7c7c7',
    className: 'default',
    closeButton: false,
    hideAfter: false,
    hideOn: 'mouseleave',
    hook: false,
	//images: 'styles/creamy/',    // Example: different images. An absolute url or relative to the images url defined above.
    radius: 3,
	showOn: 'mousemove',
    stem: {
      //position: 'topLeft',       // Example: optional default stem position, this will also enable the stem
      height: 12,
      width: 15
    }
  },

  'protoblue': {
    className: 'protoblue',
    border: 6,
    borderColor: '#116497',
    radius: 6,
    stem: { height: 12, width: 15 }
  },

  'darkgrey': {
    className: 'darkgrey',
    border: 6,
    borderColor: '#363636',
    radius: 6,
    stem: { height: 12, width: 15 }
  },

  'creamy': {
    className: 'creamy',
    border: 6,
    borderColor: '#ebe4b4',
    radius: 6,
    stem: { height: 12, width: 15 }
  },

  'protogrey': {
    className: 'protogrey',
    border: 3,
    borderColor: '#606060',
    radius: 3,
    stem: { height: 12, width: 15 }
  }
};

Object.extend(Prototip, {
	REQUIRED_Prototype: "1.6.0.3",
	start: function()
	{
		this.require("Prototype");
		if (/^(https?:\/\/|\/)/.test(Tips.options.images)) 
		{
			Tips.images = Tips.options.images
		}
		else 
		{
			var A = /prototip(?:-[\w\d.]+)?\.js(.*)/;
			Tips.images = (($$("head script[src]").find(function(B)
			{
				return B.src.match(A)
			}) ||
			{}).src || "").replace(A, "") + Tips.options.images
		}
		if (Prototype.Browser.IE && !document.namespaces.v) 
		{
			document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
			document.observe("dom:loaded", function()
			{
				document.createStyleSheet().addRule("v\\:*", "behavior: url(#default#VML);")
			})
		}
		Tips.initialize();
		Element.observe(window, "unload", this.unload)
	},
	require: function(A)
	{
		if ((typeof window[A] == "undefined") || (this.convertVersionString(window[A].Version) < this.convertVersionString(this["REQUIRED_" + A]))) 
		{
			throw ("Prototip requires " + A + " >= " + this["REQUIRED_" + A]);
		}
	},
	convertVersionString: function(A)
	{
		var B = A.replace(/_.*|\./g, "");
		B = parseInt(B + "0".times(4 - B.length));
		return A.indexOf("_") > -1 ? B - 1 : B
	},
	_captureTroubleElements: $w("input textarea"),
	capture: function(A)
	{
		if (Prototype.Browser.IE) 
		{
			return A
		}
		A = A.wrap(function(G, F)
		{
			var E = Object.isElement(this) ? this : this.element, B = F.relatedTarget;
			try 
			{
				var D = E.tagName, C = B.tagName
			} 
			catch (H) 
			{
				return
			}
			if (Prototip._captureTroubleElements.member(E.tagName.toLowerCase())) 
			{
				if (B != E && !B.descendantOf(E)) 
				{
					G(F)
				}
			}
			else 
			{
				if (B != E && !$A(E.select("*")).member(B)) 
				{
					G(F)
				}
			}
		});
		return A
	},
	toggleInt: function(A)
	{
		return (A > 0) ? (-1 * A) : (A).abs()
	},
	unload: function()
	{
		Tips.removeAll()
	}
});
Object.extend(Tips, {
	tips: [],
	visible: [],
	initialize: function()
	{
		this.zIndexTop = this.zIndex
	},
	useEvent: (function(A)
	{
		return {
			mouseover: (A ? "mouseenter" : "mouseover"),
			mouseout: (A ? "mouseleave" : "mouseout"),
			mouseenter: (A ? "mouseenter" : "mouseover"),
			mouseleave: (A ? "mouseleave" : "mouseout")
		}
	})(Prototype.Browser.IE),
	specialEvent: {
		mouseover: "mouseover",
		mouseout: "mouseout",
		mouseenter: "mouseover",
		mouseleave: "mouseout"
	},
	_inverse: {
		left: "right",
		right: "left",
		top: "bottom",
		bottom: "top",
		middle: "middle",
		horizontal: "vertical",
		vertical: "horizontal"
	},
	_stemTranslation: {
		width: "horizontal",
		height: "vertical"
	},
	inverseStem: function(A)
	{
		return !!arguments[1] ? this._inverse[A] : A
	},
	fixIE: (function(B)
	{
		var A = new RegExp("MSIE ([\\d.]+)").exec(B);
		return A ? (parseFloat(A[1]) < 7) : false
	})(navigator.userAgent),
	WebKit419: (Prototype.Browser.WebKit && !document.evaluate),
	add: function(A)
	{
		this.tips.push(A)
	},
	remove: function(A)
	{
		var B = this.tips.find(function(C)
		{
			return C.element == $(A)
		});
		if (B) 
		{
			B.deactivate();
			if (B.tooltip) 
			{
				B.wrapper.remove();
				if (Tips.fixIE) 
				{
					B.iframeShim.remove()
				}
			}
			this.tips = this.tips.without(B)
		}
		A.prototip = null
	},
	removeAll: function()
	{
		this.tips.each(function(A)
		{
			this.remove(A.element)
		}
.bind(this))
	},
	raise: function(C)
	{
		if (C == this._highest) 
		{
			return
		}
		if (this.visible.length === 0) 
		{
			this.zIndexTop = this.options.zIndex;
			for (var B = 0, A = this.tips.length; B < A; B++) 
			{
				this.tips[B].wrapper.setStyle({
					zIndex: this.options.zIndex
				})
			}
		}
		C.wrapper.setStyle({
			zIndex: this.zIndexTop++
		});
		if (C.loader) 
		{
			C.loader.setStyle({
				zIndex: this.zIndexTop
			})
		}
		this._highest = C
	},
	addVisibile: function(A)
	{
		this.removeVisible(A);
		this.visible.push(A)
	},
	removeVisible: function(A)
	{
		this.visible = this.visible.without(A)
	},
	hideAll: function()
	{
		Tips.visible.invoke("hide")
	},
	hook: function(B, F)
	{
		B = $(B), F = $(F);
		var K = Object.extend({
			offset: {
				x: 0,
				y: 0
			},
			position: false
		}, arguments[2] ||
		{});
		var D = K.mouse || F.cumulativeOffset();
		D.left += K.offset.x;
		D.top += K.offset.y;
		var C = K.mouse ? [0, 0] : F.cumulativeScrollOffset(), A = document.viewport.getScrollOffsets(), G = K.mouse ? "mouseHook" : "target";
		D.left += (-1 * (C[0] - A[0]));
		D.top += (-1 * (C[1] - A[1]));
		if (K.mouse) 
		{
			var E = [0, 0];
			E.width = 0;
			E.height = 0
		}
		var I = {
			element: B.getDimensions()
		}, J = {
			element: Object.clone(D)
		};
		I[G] = K.mouse ? E : F.getDimensions();
		J[G] = Object.clone(D);
		for (var H in J) 
		{
			switch (K[H])
			{
				case "topRight":
				case "rightTop":
					J[H].left += I[H].width;
					break;
				case "topMiddle":
					J[H].left += (I[H].width / 2);
					break;
				case "rightMiddle":
					J[H].left += I[H].width;
					J[H].top += (I[H].height / 2);
					break;
				case "bottomLeft":
				case "leftBottom":
					J[H].top += I[H].height;
					break;
				case "bottomRight":
				case "rightBottom":
					J[H].left += I[H].width;
					J[H].top += I[H].height;
					break;
				case "bottomMiddle":
					J[H].left += (I[H].width / 2);
					J[H].top += I[H].height;
					break;
				case "leftMiddle":
					J[H].top += (I[H].height / 2);
					break
			}
		}
		D.left += -1 * (J.element.left - J[G].left);
		D.top += -1 * (J.element.top - J[G].top);
		if (K.position) 
		{
			B.setStyle({
				left: D.left + "px",
				top: D.top + "px"
			})
		}
		return D
	}
});
Tips.initialize();
var Tip = Class.create({
	initialize: function(C, E)
	{
		this.element = $(C);
		if (!this.element) 
		{
			throw ("Prototip: Element not available, cannot create a tooltip.");
			return
		}
		Tips.remove(this.element);
		var A = (Object.isString(E) || Object.isElement(E)), B = A ? arguments[2] || [] : E;
		this.content = A ? E : null;
		if (B.style) 
		{
			B = Object.extend(Object.clone(Prototip.Styles[B.style]), B)
		}
		this.options = Object.extend(Object.extend({
			ajax: false,
			border: 0,
			borderColor: "#000000",
			radius: 0,
			className: Tips.options.className,
			closeButton: Tips.options.closeButtons,
			delay: !(B.showOn && B.showOn == "click") ? 0.14 : false,
			hideAfter: false,
			hideOn: "mouseleave",
			hideOthers: false,
			hook: B.hook,
			offset: B.hook ? {
				x: 0,
				y: 0
			} : {
				x: 16,
				y: 16
			},
			fixed: (B.hook && !B.hook.mouse) ? true : false,
			showOn: "mousemove",
			stem: false,
			style: "default",
			target: this.element,
			title: false,
			viewport: (B.hook && !B.hook.mouse) ? false : true,
			width: false
		}, Prototip.Styles["default"]), B);
		this.target = $(this.options.target);
		this.radius = this.options.radius;
		this.border = (this.radius > this.options.border) ? this.radius : this.options.border;
		if (this.options.images) 
		{
			this.images = this.options.images.include("://") ? this.options.images : Tips.images + this.options.images
		}
		else 
		{
			this.images = Tips.images + "styles/" + (this.options.style || "") + "/"
		}
		if (!this.images.endsWith("/")) 
		{
			this.images += "/"
		}
		if (Object.isString(this.options.stem)) 
		{
			this.options.stem = {
				position: this.options.stem
			}
		}
		if (this.options.stem.position) 
		{
			this.options.stem = Object.extend(Object.clone(Prototip.Styles[this.options.style].stem) ||
			{}, this.options.stem);
			this.options.stem.position = [this.options.stem.position.match(/[a-z]+/)[0].toLowerCase(), this.options.stem.position.match(/[A-Z][a-z]+/)[0].toLowerCase()];
			this.options.stem.orientation =["left","right"] .member(this.options.stem.position[0]) ? "horizontal" : "vertical";
			this.stemInverse = {
				horizontal: false,
				vertical: false
			}
		}
		if (this.options.ajax) 
		{
			this.options.ajax.options = Object.extend({
				onComplete: Prototype.emptyFunction
			}, this.options.ajax.options ||
			{})
		}
		this.useEvent = $w("area input").member(this.element.tagName.toLowerCase()) ? Tips.specialEvent : Tips.useEvent;
		if (this.options.hook.mouse) 
		{
			var D = this.options.hook.tip.match(/[a-z]+/)[0].toLowerCase();
			this.mouseHook = Tips._inverse[D] + Tips._inverse[this.options.hook.tip.match(/[A-Z][a-z]+/)[0].toLowerCase()].capitalize()
		}
		this.fixSafari2 = (Tips.WebKit419 && this.radius);
		this.setup();
		Tips.add(this);
		this.activate();
		Prototip.extend(this)
	},
	setup: function()
	{
		this.wrapper = new Element("div", {
			className: "prototip"
		}).setStyle({
			zIndex: Tips.options.zIndex
		});
		if (this.fixSafari2) 
		{
			this.wrapper.hide = function()
			{
				this.setStyle("left:-9500px;top:-9500px;visibility:hidden;");
				return this
			};
			this.wrapper.show = function()
			{
				this.setStyle("visibility:visible");
				return this
			};
			this.wrapper.visible = function()
			{
				return (this.getStyle("visibility") == "visible" && parseFloat(this.getStyle("top").replace("px", "")) > -9500)
			}
		}
		this.wrapper.hide();
		if (Tips.fixIE) 
		{
			this.iframeShim = new Element("iframe", {
				className: "iframeShim",
				src: "javascript:false;",
				frameBorder: 0
			}).setStyle({
				display: "none",
				zIndex: Tips.options.zIndex - 1,
				opacity: 0
			})
		}
		if (this.options.ajax) 
		{
			this.showDelayed = this.showDelayed.wrap(this.ajaxShow)
		}
		this.tip = new Element("div", {
			className: "content"
		});
		this.title = new Element("div", {
			className: "title"
		}).hide();
		if (this.options.closeButton || (this.options.hideOn.element && this.options.hideOn.element == "closeButton")) 
		{
			this.closeButton = new Element("div", {
				className: "close"
			}).setPngBackground(this.images + "close.png")
		}
	},
	build: function()
	{
		if (document.loaded) 
		{
			this._build();
			this._isBuilding = true;
			return true
		}
		else 
		{
			if (!this._isBuilding) 
			{
				document.observe("dom:loaded", this._build);
				return false
			}
		}
	},
	_build: function()
	{
		$(document.body).insert(this.wrapper);
		if (Tips.fixIE) 
		{
			$(document.body).insert(this.iframeShim)
		}
		if (this.options.ajax) 
		{
			$(document.body).insert(this.loader = new Element("div", {
				className: "prototipLoader"
			}).setPngBackground(this.images + "loader.gif").hide())
		}
		var G = "wrapper";
		if (this.options.stem.position) 
		{
			this.stem = new Element("div", {
				className: "prototip_Stem"
			}).setStyle({
				height: this.options.stem[this.options.stem.orientation == "vertical" ? "height" : "width"] + "px"
			});
			var B = this.options.stem.orientation == "horizontal";
			this[G].insert(this.stemWrapper = new Element("div", {
				className: "prototip_StemWrapper clearfix"
			}).insert(this.stemBox = new Element("div", {
				className: "prototip_StemBox clearfix"
			})));
			this.stem.insert(this.stemImage = new Element("div", {
				className: "prototip_StemImage"
			}).setStyle({
				height: this.options.stem[B ? "width" : "height"] + "px",
				width: this.options.stem[B ? "height" : "width"] + "px"
			}));
			if (Tips.fixIE && !this.options.stem.position[1].toUpperCase().include("MIDDLE")) 
			{
				this.stemImage.setStyle({
					display: "inline"
				})
			}
			G = "stemBox"
		}
		if (this.border) 
		{
			var D = this.border, F;
			this[G].insert(this.borderFrame = new Element("ul", {
				className: "borderFrame"
			}).insert(this.borderTop = new Element("li", {
				className: "borderTop borderRow"
			}).setStyle("height: " + D + "px").insert(new Element("div", {
				className: "prototip_CornerWrapper prototip_CornerWrapperTopLeft"
			}).insert(new Element("div", {
				className: "prototip_Corner"
			}))).insert(F = new Element("div", {
				className: "prototip_BetweenCorners"
			}).setStyle({
				height: D + "px"
			}).insert(new Element("div", {
				className: "prototip_Between"
			}).setStyle({
				margin: "0 " + D + "px",
				height: D + "px"
			}))).insert(new Element("div", {
				className: "prototip_CornerWrapper prototip_CornerWrapperTopRight"
			}).insert(new Element("div", {
				className: "prototip_Corner"
			})))).insert(this.borderMiddle = new Element("li", {
				className: "borderMiddle borderRow"
			}).insert(this.borderCenter = new Element("div", {
				className: "borderCenter"
			}).setStyle("padding: 0 " + D + "px"))).insert(this.borderBottom = new Element("li", {
				className: "borderBottom borderRow"
			}).setStyle("height: " + D + "px").insert(new Element("div", {
				className: "prototip_CornerWrapper prototip_CornerWrapperBottomLeft"
			}).insert(new Element("div", {
				className: "prototip_Corner"
			}))).insert(F.cloneNode(true)).insert(new Element("div", {
				className: "prototip_CornerWrapper prototip_CornerWrapperBottomRight"
			}).insert(new Element("div", {
				className: "prototip_Corner"
			})))));
			G = "borderCenter";
			var C = this.borderFrame.select(".prototip_Corner");
			$w("tl tr bl br").each(function(I, H)
			{
				if (this.radius > 0) 
				{
					Prototip.createCorner(C[H], I, {
						backgroundColor: this.options.borderColor,
						border: D,
						radius: this.options.radius
					})
				}
				else 
				{
					C[H].addClassName("prototip_Fill")
				}
				C[H].setStyle({
					width: D + "px",
					height: D + "px"
				}).addClassName("prototip_Corner" + I.capitalize())
			}
.bind(this));
			this.borderFrame.select(".prototip_Between", ".borderMiddle", ".prototip_Fill").invoke("setStyle", {
				backgroundColor: this.options.borderColor
			})
		}
		this[G].insert(this.tooltip = new Element("div", {
			className: "tooltip " + this.options.className
		}).insert(this.toolbar = new Element("div", {
			className: "toolbar"
		}).insert(this.title)));
		if (this.options.width) 
		{
			var E = this.options.width;
			if (Object.isNumber(E)) 
			{
				E += "px"
			}
			this.tooltip.setStyle("width:" + E)
		}
		if (this.stem) 
		{
			var A = {};
			A[this.options.stem.orientation == "horizontal" ? "top" : "bottom"] = this.stem;
			this.wrapper.insert(A);
			this.positionStem()
		}
		this.tooltip.insert(this.tip);
		if (!this.options.ajax) 
		{
			this._update({
				title: this.options.title,
				content: this.content
			})
		}
	},
	_update: function(E)
	{
		var A = this.wrapper.getStyle("visibility");
		this.wrapper.setStyle("height:auto;width:auto;visibility:hidden").show();
		if (this.border) 
		{
			this.borderTop.setStyle("height:0");
			this.borderTop.setStyle("height:0")
		}
		if (E.title) 
		{
			this.title.show().update(E.title);
			this.toolbar.show()
		}
		else 
		{
			if (!this.closeButton) 
			{
				this.title.hide();
				this.toolbar.hide()
			}
		}
		if (Object.isElement(E.content)) 
		{
			E.content.show()
		}
		if (Object.isString(E.content) || Object.isElement(E.content)) 
		{
			this.tip.update(E.content)
		}
		this.tooltip.setStyle({
			width: this.tooltip.getWidth() + "px"
		});
		this.wrapper.setStyle("visibility:visible").show();
		this.tooltip.show();
		var C = this.tooltip.getDimensions(), B = {
			width: C.width + "px"
		}, D = [this.wrapper];
		if (Tips.fixIE) 
		{
			D.push(this.iframeShim)
		}
		if (this.closeButton) 
		{
			this.title.show().insert({
				top: this.closeButton
			});
			this.toolbar.show()
		}
		if (E.title || this.closeButton) 
		{
			this.toolbar.setStyle("width: 100%")
		}
		B.height = null;
		this.wrapper.setStyle({
			visibility: A
		});
		this.tip.addClassName("clearfix");
		if (E.title || this.closeButton) 
		{
			this.title.addClassName("clearfix")
		}
		if (this.border) 
		{
			this.borderTop.setStyle("height:" + this.border + "px");
			this.borderTop.setStyle("height:" + this.border + "px");
			B = "width: " + (C.width + 2 * this.border) + "px";
			D.push(this.borderFrame)
		}
		D.invoke("setStyle", B);
		if (this.stem) 
		{
			this.positionStem();
			if (this.options.stem.orientation == "horizontal") 
			{
				this.wrapper.setStyle({
					width: this.wrapper.getWidth() + this.options.stem.height + "px"
				})
			}
		}
		this.wrapper.hide()
	},
	activate: function()
	{
		this.eventShow = this.showDelayed.bindAsEventListener(this);
		this.eventHide = this.hide.bindAsEventListener(this);
		if (this.options.fixed && this.options.showOn == "mousemove") 
		{
			this.options.showOn = "mouseover"
		}
		if (this.options.showOn == this.options.hideOn) 
		{
			this.eventToggle = this.toggle.bindAsEventListener(this);
			this.element.observe(this.options.showOn, this.eventToggle)
		}
		if (this.closeButton) 
		{
			this.closeButton.observe("mouseover", function(E)
			{
				E.setPngBackground(this.images + "close_hover.png")
			}
.bind(this, this.closeButton)).observe("mouseout", function(E)
			{
				E.setPngBackground(this.images + "close.png")
			}
.bind(this, this.closeButton))
		}
		var C = {
			element: this.eventToggle ? [] : [this.element],
			target: this.eventToggle ? [] : [this.target],
			tip: this.eventToggle ? [] : [this.wrapper],
			closeButton: [],
			none: []
		}, A = this.options.hideOn.element;
		this.hideElement = A || (!this.options.hideOn ? "none" : "element");
		this.hideTargets = C[this.hideElement];
		if (!this.hideTargets && A && Object.isString(A)) 
		{
			this.hideTargets = this.tip.select(A)
		}
		var D = {
			mouseenter: "mouseover",
			mouseleave: "mouseout"
		};
		$w("show hide").each(function(H)
		{
			var G = H.capitalize(), F = (this.options[H + "On"].event || this.options[H + "On"]);
			this[H + "Action"] = F;
			if (["mouseenter", "mouseleave", "mouseover", "mouseout"].include(F)) 
			{
				this[H + "Action"] = (this.useEvent[F] || F);
				this["event" + G] = Prototip.capture(this["event" + G])
			}
		}
.bind(this));
		if (!this.eventToggle) 
		{
			this.element.observe(this.options.showOn, this.eventShow)
		}
		if (this.hideTargets) 
		{
			this.hideTargets.invoke("observe", this.hideAction, this.eventHide)
		}
		if (!this.options.fixed && this.options.showOn == "click") 
		{
			this.eventPosition = this.position.bindAsEventListener(this);
			this.element.observe("mousemove", this.eventPosition)
		}
		this.buttonEvent = this.hide.wrap(function(G, F)
		{
			var E = F.findElement(".close");
			if (E) 
			{
				E.blur();
				F.stop();
				G(F)
			}
		}).bindAsEventListener(this);
		if (this.closeButton) 
		{
			this.wrapper.observe("click", this.buttonEvent)
		}
		if (this.options.showOn != "click" && (this.hideElement != "element")) 
		{
			this.eventCheckDelay = Prototip.capture(function()
			{
				this.clearTimer("show")
			}).bindAsEventListener(this);
			this.element.observe(this.useEvent.mouseout, this.eventCheckDelay)
		}
		var B = [this.element, this.wrapper];
		this.activityEnter = Prototip.capture(function()
		{
			Tips.raise(this);
			this.cancelHideAfter()
		}).bindAsEventListener(this);
		this.activityLeave = Prototip.capture(this.hideAfter).bindAsEventListener(this);
		B.invoke("observe", this.useEvent.mouseover, this.activityEnter).invoke("observe", this.useEvent.mouseout, this.activityLeave);
		if (this.options.ajax && this.options.showOn != "click") 
		{
			this.ajaxHideEvent = Prototip.capture(this.ajaxHide).bindAsEventListener(this);
			this.element.observe(this.useEvent.mouseout, this.ajaxHideEvent)
		}
	},
	deactivate: function()
	{
		if (this.options.showOn == this.options.hideOn) 
		{
			this.element.stopObserving(this.options.showOn, this.eventToggle)
		}
		else 
		{
			this.element.stopObserving(this.options.showOn, this.eventShow);
			if (this.hideTargets) 
			{
				this.hideTargets.invoke("stopObserving")
			}
		}
		if (this.eventPosition) 
		{
			this.element.stopObserving("mousemove", this.eventPosition)
		}
		if (this.eventCheckDelay) 
		{
			this.element.stopObserving("mouseout", this.eventCheckDelay)
		}
		this.wrapper.stopObserving();
		this.element.stopObserving(this.useEvent.mouseover, this.activityEnter).stopObserving(this.useEvent.mouseout, this.activityLeave);
		if (this.ajaxHideEvent) 
		{
			this.element.stopObserving(this.useEvent.mouseout, this.ajaxHideEvent)
		}
	},
	ajaxShow: function(C, B)
	{
		if (!this.tooltip) 
		{
			if (!this.build()) 
			{
				return
			}
		}
		this.position(B);
		if (this.ajaxContentLoading) 
		{
			return
		}
		else 
		{
			if (this.ajaxContentLoaded) 
			{
				C(B);
				return
			}
		}
		this.ajaxContentLoading = true;
		var D = {
			fakePointer: {
				pointerX: Event.pointerX(B),
				pointerY: Event.pointerY(B)
			}
		};
		var A = Object.clone(this.options.ajax.options);
		A.onComplete = A.onComplete.wrap(function(F, E)
		{
			this._update({
				title: this.options.title,
				content: E.responseText
			});
			this.position(D);
			(function()
			{
				F(E);
				var G = (this.loader && this.loader.visible());
				if (this.loader) 
				{
					this.clearTimer("loader");
					this.loader.remove();
					this.loader = null
				}
				if (G) 
				{
					this.show()
				}
				this.ajaxContentLoaded = true;
				this.ajaxContentLoading = null
			}
.bind(this)).delay(0.6)
		}
.bind(this));
		this.loaderTimer = Element.show.delay(this.options.delay, this.loader);
		this.wrapper.hide();
		this.ajaxContentLoading = true;
		this.loader.show();
		this.ajaxTimer = (function()
		{
			new Ajax.Request(this.options.ajax.url, A)
		}
.bind(this)).delay(this.options.delay);
		return false
	},
	ajaxHide: function()
	{
		this.clearTimer("loader")
	},
	showDelayed: function(A)
	{
		if (!this.tooltip) 
		{
			if (!this.build()) 
			{
				return
			}
		}
		this.position(A);
		if (this.wrapper.visible()) 
		{
			return
		}
		this.clearTimer("show");
		this.showTimer = this.show.bind(this).delay(this.options.delay)
	},
	clearTimer: function(A)
	{
		if (this[A + "Timer"]) 
		{
			clearTimeout(this[A + "Timer"])
		}
	},
	show: function()
	{
		if (this.wrapper.visible()) 
		{
			return
		}
		if (Tips.fixIE) 
		{
			this.iframeShim.show()
		}
		if (this.options.hideOthers) 
		{
			Tips.hideAll()
		}
		Tips.addVisibile(this);
		this.tooltip.show();
		this.wrapper.show();
		if (this.stem) 
		{
			this.stem.show()
		}
		this.element.fire("prototip:shown")
	},
	hideAfter: function(A)
	{
		if (this.options.ajax) 
		{
			if (this.loader && this.options.showOn != "click") 
			{
				this.loader.hide()
			}
		}
		if (!this.options.hideAfter) 
		{
			return
		}
		this.cancelHideAfter();
		this.hideAfterTimer = this.hide.bind(this).delay(this.options.hideAfter)
	},
	cancelHideAfter: function()
	{
		if (this.options.hideAfter) 
		{
			this.clearTimer("hideAfter")
		}
	},
	hide: function()
	{
		this.clearTimer("show");
		this.clearTimer("loader");
		if (!this.wrapper.visible()) 
		{
			return
		}
		this.afterHide()
	},
	afterHide: function()
	{
		if (Tips.fixIE) 
		{
			this.iframeShim.hide()
		}
		if (this.loader) 
		{
			this.loader.hide()
		}
		this.wrapper.hide();
		(this.borderFrame || this.tooltip).show();
		Tips.removeVisible(this);
		this.element.fire("prototip:hidden")
	},
	toggle: function(A)
	{
		if (this.wrapper && this.wrapper.visible()) 
		{
			this.hide(A)
		}
		else 
		{
			this.showDelayed(A)
		}
	},
	positionStem: function()
	{
		var C = this.options.stem, B = arguments[0] || this.stemInverse, D = Tips.inverseStem(C.position[0], B[C.orientation]), F = Tips.inverseStem(C.position[1], B[Tips._inverse[C.orientation]]), A = this.radius || 0;
		this.stemImage.setPngBackground(this.images + D + F + ".png");
		if (C.orientation == "horizontal") 
		{
			var E = (D == "left") ? C.height : 0;
			this.stemWrapper.setStyle("left: " + E + "px;");
			this.stemImage.setStyle({
				"float": D
			});
			this.stem.setStyle({
				left: 0,
				top: (F == "bottom" ? "100%" : F == "middle" ? "50%" : 0),
				marginTop: (F == "bottom" ? -1 * C.width : F == "middle" ? -0.5 * C.width : 0) + (F == "bottom" ? -1 * A : F == "top" ? A : 0) + "px"
			})
		}
		else 
		{
			this.stemWrapper.setStyle(D == "top" ? "margin: 0; padding: " + C.height + "px 0 0 0;" : "padding: 0; margin: 0 0 " + C.height + "px 0;");
			this.stem.setStyle(D == "top" ? "top: 0; bottom: auto;" : "top: auto; bottom: 0;");
			this.stemImage.setStyle({
				margin: 0,
				"float": F != "middle" ? F : "none"
			});
			if (F == "middle") 
			{
				this.stemImage.setStyle("margin: 0 auto;")
			}
			else 
			{
				this.stemImage.setStyle("margin-" + F + ": " + A + "px;")
			}
			if (Tips.WebKit419) 
			{
				if (D == "bottom") 
				{
					this.stem.setStyle({
						position: "relative",
						clear: "both",
						top: "auto",
						bottom: "auto",
						"float": "left",
						width: "100%",
						margin: (-1 * C.height) + "px 0 0 0"
					});
					this.stem.style.display = "block"
				}
				else 
				{
					this.stem.setStyle({
						position: "absolute",
						"float": "none",
						margin: 0
					})
				}
			}
		}
		this.stemInverse = B
	},
	position: function(B)
	{
		if (!this.tooltip) 
		{
			if (!this.build()) 
			{
				return
			}
		}
		Tips.raise(this);
		if (Tips.fixIE) 
		{
			var A = this.wrapper.getDimensions();
			if (!this.iframeShimDimensions || this.iframeShimDimensions.height != A.height || this.iframeShimDimensions.width != A.width) 
			{
				this.iframeShim.setStyle({
					width: A.width + "px",
					height: A.height + "px"
				})
			}
			this.iframeShimDimensions = A
		}
		if (this.options.hook) 
		{
			var J, H;
			if (this.mouseHook) 
			{
				var K = document.viewport.getScrollOffsets(), C = B.fakePointer ||
				{};
				var G, I = 2;
				switch (this.mouseHook.toUpperCase())
				{
					case "LEFTTOP":
					case "TOPLEFT":
						G = {
							x: 0 - I,
							y: 0 - I
						};
						break;
					case "TOPMIDDLE":
						G = {
							x: 0,
							y: 0 - I
						};
						break;
					case "TOPRIGHT":
					case "RIGHTTOP":
						G = {
							x: I,
							y: 0 - I
						};
						break;
					case "RIGHTMIDDLE":
						G = {
							x: I,
							y: 0
						};
						break;
					case "RIGHTBOTTOM":
					case "BOTTOMRIGHT":
						G = {
							x: I,
							y: I
						};
						break;
					case "BOTTOMMIDDLE":
						G = {
							x: 0,
							y: I
						};
						break;
					case "BOTTOMLEFT":
					case "LEFTBOTTOM":
						G = {
							x: 0 - I,
							y: I
						};
						break;
					case "LEFTMIDDLE":
						G = {
							x: 0 - I,
							y: 0
						};
						break
				}
				G.x += this.options.offset.x;
				G.y += this.options.offset.y;
				J = Object.extend({
					offset: G
				}, {
					element: this.options.hook.tip,
					mouseHook: this.mouseHook,
					mouse: {
						top: C.pointerY || Event.pointerY(B) - K.top,
						left: C.pointerX || Event.pointerX(B) - K.left
					}
				});
				H = Tips.hook(this.wrapper, this.target, J);
				if (this.options.viewport) 
				{
					var M = this.getPositionWithinViewport(H), L = M.stemInverse;
					H = M.position;
					H.left += L.vertical ? 2 * Prototip.toggleInt(G.x - this.options.offset.x) : 0;
					H.top += L.vertical ? 2 * Prototip.toggleInt(G.y - this.options.offset.y) : 0;
					if (this.stem && (this.stemInverse.horizontal != L.horizontal || this.stemInverse.vertical != L.vertical)) 
					{
						this.positionStem(L)
					}
				}
				H = {
					left: H.left + "px",
					top: H.top + "px"
				};
				this.wrapper.setStyle(H)
			}
			else 
			{
				J = Object.extend({
					offset: this.options.offset
				}, {
					element: this.options.hook.tip,
					target: this.options.hook.target
				});
				H = Tips.hook(this.wrapper, this.target, Object.extend({
					position: true
				}, J));
				H = {
					left: H.left + "px",
					top: H.top + "px"
				}
			}
			if (this.loader) 
			{
				var E = Tips.hook(this.loader, this.target, Object.extend({
					position: true
				}, J))
			}
			if (Tips.fixIE) 
			{
				this.iframeShim.setStyle(H)
			}
		}
		else 
		{
			var F = this.target.cumulativeOffset(), C = B.fakePointer ||
			{}, H = {
				left: ((this.options.fixed) ? F[0] : C.pointerX || Event.pointerX(B)) + this.options.offset.x,
				top: ((this.options.fixed) ? F[1] : C.pointerY || Event.pointerY(B)) + this.options.offset.y
			};
			if (!this.options.fixed && this.element !== this.target) 
			{
				var D = this.element.cumulativeOffset();
				H.left += -1 * (D[0] - F[0]);
				H.top += -1 * (D[1] - F[1])
			}
			if (!this.options.fixed && this.options.viewport) 
			{
				var M = this.getPositionWithinViewport(H), L = M.stemInverse;
				H = M.position;
				if (this.stem && (this.stemInverse.horizontal != L.horizontal || this.stemInverse.vertical != L.vertical)) 
				{
					this.positionStem(L)
				}
			}
			H = {
				left: H.left + "px",
				top: H.top + "px"
			};
			this.wrapper.setStyle(H);
			if (this.loader) 
			{
				this.loader.setStyle(H)
			}
			if (Tips.fixIE) 
			{
				this.iframeShim.setStyle(H)
			}
		}
	},
	getPositionWithinViewport: function(C)
	{
		var E = {
			horizontal: false,
			vertical: false
		}, D = this.wrapper.getDimensions(), B = document.viewport.getScrollOffsets(), A = document.viewport.getDimensions(), G = {
			left: "width",
			top: "height"
		};
		for (var F in G) 
		{
			if ((C[F] + D[G[F]] - B[F]) > A[G[F]]) 
			{
				C[F] = C[F] - (D[G[F]] + (2 * this.options.offset[F == "left" ? "x" : "y"]));
				if (this.stem) 
				{
					E[Tips._stemTranslation[G[F]]] = true
				}
			}
		}
		return {
			position: C,
			stemInverse: E
		}
	}
});
Object.extend(Prototip, {
	createCorner: function(G, H)
	{
		var F = arguments[2] || this.options, B = F.radius, E = F.border, D = new Element("canvas", {
			className: "cornerCanvas" + H.capitalize(),
			width: E + "px",
			height: E + "px"
		}), A = {
			top: (H.charAt(0) == "t"),
			left: (H.charAt(1) == "l")
		};
		if (D && D.getContext && D.getContext("2d")) 
		{
			G.insert(D);
			var C = D.getContext("2d");
			C.fillStyle = F.backgroundColor;
			C.arc((A.left ? B : E - B), (A.top ? B : E - B), B, 0, Math.PI * 2, true);
			C.fill();
			C.fillRect((A.left ? B : 0), 0, E - B, E);
			C.fillRect(0, (A.top ? B : 0), E, E - B)
		}
		else 
		{
			G.insert(new Element("div").setStyle({
				width: E + "px",
				height: E + "px",
				margin: 0,
				padding: 0,
				display: "block",
				position: "relative",
				overflow: "hidden"
			}).insert(new Element("v:roundrect", {
				fillcolor: F.backgroundColor,
				strokeWeight: "1px",
				strokeColor: F.backgroundColor,
				arcSize: (B / E * 0.5).toFixed(2)
			}).setStyle({
				width: 2 * E - 1 + "px",
				height: 2 * E - 1 + "px",
				position: "absolute",
				left: (A.left ? 0 : (-1 * E)) + "px",
				top: (A.top ? 0 : (-1 * E)) + "px"
			})))
		}
	}
});
Element.addMethods({
	setPngBackground: function(C, B)
	{
		C = $(C);
		var A = Object.extend({
			align: "top left",
			repeat: "no-repeat",
			sizingMethod: "scale",
			backgroundColor: ""
		}, arguments[2] ||
		{});
		C.setStyle(Tips.fixIE ? {
			filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + B + "'', sizingMethod='" + A.sizingMethod + "')"
		} : {
			background: A.backgroundColor + " url(" + B + ") " + A.align + " " + A.repeat
		});
		return C
	}
});
Prototip.Methods = {
	show: function()
	{
		Tips.raise(this);
		this.cancelHideAfter();
		var D = {};
		if (this.options.hook) 
		{
			D.fakePointer = {
				pointerX: 0,
				pointerY: 0
			}
		}
		else 
		{
			var A = this.target.cumulativeOffset(), C = this.target.cumulativeScrollOffset(), B = document.viewport.getScrollOffsets();
			A.left += (-1 * (C[0] - B[0]));
			A.top += (-1 * (C[1] - B[1]));
			D.fakePointer = {
				pointerX: A.left,
				pointerY: A.top
			}
		}
		if (this.options.ajax) 
		{
			this.ajaxShow(D)
		}
		else 
		{
			this.showDelayed(D)
		}
		this.hideAfter()
	}
};
Prototip.extend = function(A)
{
	A.element.prototip = {};
	Object.extend(A.element.prototip, {
		show: Prototip.Methods.show.bind(A),
		hide: A.hide.bind(A),
		remove: Tips.remove.bind(Tips, A.element)
	})
};
Prototip.start();
