;(function ($, Formstone, undefined) {

	"use strict";

	/**
	 * @method private
	 * @name construct
	 * @description Builds instance.
	 * @param data [object] "Instance data"
	 */

	function construct(data) {
		this.on(Events.mouseEnter, data, onMouseEnter);
	}

	/**
	 * @method private
	 * @name destruct
	 * @description Tears down instance.
	 * @param data [object] "Instance data"
	 */

	function destruct(data) {
		removeTooltip();

		this.off(Events.namespace);
	}

	/**
	 * @method private
	 * @name onMouseEnter
	 * @description Handles mouse enter event.
	 * @param e [object] "Event data"
	 */

	function onMouseEnter(e) {
		removeTooltip();

		var data = e.data;

		data.left = e.pageX;
		data.top  = e.pageY;

		buildTooltip(data);
	}

	/**
	 * @method private
	 * @name onMouseLeave
	 * @description Handles mouse leave event.
	 * @param e [object] "Event data"
	 */

	function onMouseLeave(e) {
		var data = e.data;

		Functions.clearTimer(data.timer);

		removeTooltip();
	}

	/**
	 * @method private
	 * @name onMouseLeave
	 * @description Handles mouse move event.
	 * @param e [object] "Event data"
	 */

	function onMouseMove(e) {
		positionTooltip(e.pageX, e.pageY);
	}

	/**
	 * @method private
	 * @name buildTooltip
	 * @description Builds new tooltip instance.
	 * @param data [object] "Instance data"
	 */

	function buildTooltip(data) {
		removeTooltip();

		var html = '';

		html += '<div class="';
		html += [RawClasses.base, RawClasses[data.direction] ].join(" ");
		html += '">';
		html += '<div class="' + RawClasses.content + '">';
		html += data.formatter.call(data.$el, data);
		html += '<span class="' + RawClasses.caret + '"></span>';
		html += '</div>';
		html += '</div>';

		Instance = {
			$tooltip    : $(html),
			$el         : data.$el
		};

		Formstone.$body.append(Instance.$tooltip);

		var $content = Instance.$tooltip.find(Classes.content),
			$caret   = Instance.$tooltip.find(Classes.caret),

			offset = data.$el.offset(),
			height = data.$el.outerHeight(),
			width  = data.$el.outerWidth(),

			tooltipLeft     = 0,
			tooltipTop      = 0,
			contentLeft     = 0,
			contentTop      = 0,
			caretLeft       = false,
			caretTop        = false,

			caretHeight     = $caret.outerHeight(true),
			caretWidth      = $caret.outerWidth(true),
			contentHeight   = $content.outerHeight(true),
			contentWidth    = $content.outerWidth(true);

		// position content
		if (data.direction === "right" || data.direction === "left") {
			caretTop   = (contentHeight - caretHeight) / 2;
			contentTop = -contentHeight / 2;

			if (data.direction === "right") {
				contentLeft = data.margin;
			} else if (data.direction === "left") {
				contentLeft = -(contentWidth + data.margin);
			}
		} else {
			caretLeft = (contentWidth - caretWidth) / 2;
			contentLeft = -contentWidth / 2;

			if (data.direction === "bottom") {
				contentTop = data.margin;
			} else if (data.direction === "top") {
				contentTop = -(contentHeight + data.margin);
			}
		}

		// Modify Dom
		$content.css({
			top:  contentTop,
			left: contentLeft
		});

		$caret.css({
			top:  caretTop,
			left: caretLeft
		});

		// Position tooltip
		if (data.follow) {
			data.$el.on(Events.mouseMove, data, onMouseMove);
		} else {
			if (data.match) {
				if (data.direction === "right" || data.direction === "left") {
					tooltipTop = data.top; // mouse pos

					if (data.direction === "right") {
						tooltipLeft = offset.left + width;
					} else if (data.direction === "left") {
						tooltipLeft = offset.left;
					}
				} else {
					tooltipLeft = data.left; // mouse pos

					if (data.direction === "bottom") {
						tooltipTop = offset.top + height;
					} else if (data.direction === "top") {
						tooltipTop = offset.top;
					}
				}
			} else {
				if (data.direction === "right" || data.direction === "left") {
					tooltipTop = offset.top + (height / 2);

					if (data.direction === "right") {
						tooltipLeft = offset.left + width;
					} else if (data.direction === "left") {
						tooltipLeft = offset.left;
					}
				} else {
					tooltipLeft = offset.left + (width / 2);

					if (data.direction === "bottom") {
						tooltipTop = offset.top + height;
					} else if (data.direction === "top") {
						tooltipTop = offset.top;
					}
				}
			}

			positionTooltip(tooltipLeft, tooltipTop);
		}

		data.timer = Functions.startTimer(data.timer, data.delay, function() {
			Instance.$tooltip.addClass(RawClasses.visible);
		});

		data.$el.one(Events.mouseLeave, data, onMouseLeave);
	}

	/**
	 * @method private
	 * @name positionTooltip
	 * @description Positions active tooltip instance.
	 * @param left [int] "Left position"
	 * @param top [int] "Top position"
	 */

	function positionTooltip(left, top) {
		if (Instance) {
			Instance.$tooltip.css({
				left : left,
				top  : top
			});
		}
	}

	/**
	 * @method private
	 * @name removeTooltip
	 * @description Removes active tooltip instance.
	 */

	function removeTooltip() {
		if (Instance) {
			Instance.$el.off( [Events.mouseMove, Events.mouseLeave].join(" ") );

			Instance.$tooltip.remove();
			Instance = null;
		}
	}

	/**
	 * @method private
	 * @name format
	 * @description Formats tooltip text.
	 * @return [string] "Tooltip text"
	 */

	function format(data) {
		return this.data("title");
	}

	/**
	 * @plugin
	 * @name Tooltip
	 * @description A jQuery plugin for simple tooltips.
	 * @type widget
	 * @dependency core.js
	 */

	var Plugin = Formstone.Plugin("tooltip", {
			widget: true,

			/**
			 * @options
			 * @param delay [int] <0> "Hover delay"
			 * @param direction [string] <'top'> "Tooltip direction"
			 * @param follow [boolean] <false> "Flag to follow mouse"
			 * @param formatter [function] <$.noop> "Text format function"
			 * @param margin [int] <15> "Tooltip margin"
			 * @param match [boolean] <false> "Flag to match mouse position"
			 */

			defaults: {
				delay        : 0,
				direction    : "top",
				follow       : false,
				formatter    : format,
				margin       : 15,
				match        : false
			},

			classes: [
				"content",
				"caret",
				"visible",
				"top",
				"bottom",
				"right",
				"left"
			],

			methods: {
				_construct    : construct,
				_destruct     : destruct
			}
		}),

		// Localize References

		Classes       = Plugin.classes,
		RawClasses    = Classes.raw,
		Events        = Plugin.events,
		Functions     = Plugin.functions,

		// Singleton

		Instance     = null;

})(jQuery, Formstone);