﻿// Changelog
// v1.1 - Changed tooltip locations to be based off the mouse cursor instead of the parent object.
//        MouseX and MouseY are set outside the class, globally, to be available to any other functions.

var MouseX;
var MouseY;

function getPointerPosition(e) {
    MouseX = Event.pointerX(e);
    MouseY = Event.pointerY(e);
    return true;
}

Event.observe(document, "mousemove", getPointerPosition, false);

var Tooltip = Class.create();
Tooltip.prototype = {
    initialize: function(obj, content, options) {
        this.object = obj;
        this.id = 'tooltip_' + new Date().getTime();
        this.use_shim = 0;
        this.setOptions(options);
        this.buildTooltip(content);
        this.setLocation();
        Effect.Appear(this.tooltip, this.options);

        this.destroyObserver = this.destroy.bind(this);
        this.moveObserver = this.setLocation.bind(this);
        Event.observe(this.object, 'mousemove', this.moveObserver);
        Event.observe(this.object, 'mouseout', this.destroyObserver);
        Event.observe(document, 'keydown', this.destroyObserver);
    },

    buildTooltip: function(content) {
        var tooltip_content = '<div id="' + this.id + '" class="' + this.options.css_class + '" style="display: none; z-index: 1000000;">';
        if (this.options.title) {
            tooltip_content = tooltip_content + '<div class="' + this.options.css_class + '_title">';
            tooltip_content = tooltip_content + this.options.title;
            tooltip_content = tooltip_content + '</div>';
        }
        tooltip_content = tooltip_content + '<div id="' + this.id + '_content" class="' + this.options.css_class + '_content">';
        tooltip_content = tooltip_content + content;
        tooltip_content = tooltip_content + '</div>';
        tooltip_content = tooltip_content + '</div>';

        new Insertion.Bottom(document.body, tooltip_content);
        this.tooltip = $(this.id);

        if ((document.all) && (navigator.userAgent.indexOf("Opera") == -1)) {
            // Yay shim code! Thanks IE!
            new Insertion.Before(this.id, '<iframe src="about: blank;" id="' + this.id + '_shim" class="shim" scrolling="no" frameborder="0" style="display: block;"></iframe>');
            this.shim = $(this.id + '_shim');
            this.use_shim = 1;
        }
    },

    setLocation: function() {
        var window_width = (window.innerWidth || document.body.offsetWidth);
        var window_height = (window.innerHeight || document.body.offsetHeight);

        var parent_offset = Position.cumulativeOffset(this.object);
        var parent_coords = Position.cumulativeOffset(this.object);
        var parent_width = (+Element.getDimensions(this.object).width);
        var parent_height = (+Element.getHeight(this.object));

        this.tooltip.style.position = 'absolute';

        var tooltip_width = this.options.width;
        var tooltip_height = (+Element.getDimensions(this.tooltip).height);
        var tooltip_top = this.options.posY || ((MouseY + tooltip_height > window_height) ? (MouseY - tooltip_height - this.options.offsetV) : (MouseY + this.options.offsetV));
        var tooltip_left = this.options.posX || ((MouseX + tooltip_width > window_width) ? (MouseX - tooltip_width - this.options.offsetH) : (MouseX + this.options.offsetH));

        this.tooltip.style.top = tooltip_top + 'px';
        this.tooltip.style.left = tooltip_left + 'px';
        this.tooltip.style.width = tooltip_width + 'px';

        if (this.use_shim) {
            this.shim.style.position = 'absolute';
            this.shim.style.top = tooltip_top + 'px';
            this.shim.style.left = tooltip_left + 'px';
            this.shim.style.height = (+Element.getDimensions(this.tooltip).height) + 'px';
            this.shim.style.width = tooltip_width + 'px';
        }

    },

    destroy: function() {
        Element.remove(this.tooltip);
        if (this.use_shim) Element.remove(this.shim);
        Event.stopObserving(this.object, 'mousemove', this.moveObserver);
        Event.stopObserving(this.object, 'mouseout', this.destroyObserver);
        Event.stopObserving(document, 'keydown', this.destroyObserver);
    },

    setOptions: function(options) {
        this.options = {
            duration: 0.2,
            to: 0.9,
            css_class: 'tooltip',
            offsetH: 25,
            offsetV: 1,
            width: 250
        }
        Object.extend(this.options, options || {});
    }
}

Ajax.Tooltip = Class.create();
Object.extend(Ajax.Tooltip.prototype, Tooltip.prototype);
Ajax.Tooltip.prototype = Object.extend(Ajax.Tooltip.prototype, {
    initialize: function(obj, url, options) {
        this.object = obj;
        this.id = 'tooltip_' + new Date().getTime();
        this.setOptions(options);
        this.buildTooltip('loading');
        this.setLocation();
        this.createUpdater(url);

        this.destroyObserver = this.destroy.bind(this);
        this.moveObserver = this.setLocation.bind(this);
        Event.observe(this.object, 'mousemove', this.moveObserver);
        Event.observe(this.object, 'mouseout', this.destroyObserver);
        Event.observe(document, 'keydown', this.destroyObserver);
    },

    createUpdater: function(url) {
        o = {
            method: 'get',
            parameters: '',
            onlyLatestOfClass: 'tooltip_loader',
            onComplete: this.completeUpdater.bind(this)
        }
        Object.extend(o, this.options);

        new Ajax.Updater(this.id + '_content', url, o);
    },

    completeUpdater: function() {
        this.setLocation();
        Effect.Appear(this.tooltip, this.options);
    }
});
