var Tooltip = Class.create();

Tooltip.prototype = {
    initialize: function(element, tool_tip) {
        var options = Object.extend({
            default_css: false,
            margin: "0px",
            padding: "5px",
            backgroundColor: "#d6d6fc",
            min_distance_x: 15,
            min_distance_y: 15,
            delta_x: 0,
            delta_y: 0,
            zindex: 1000
        }, arguments[2] || {});

        this.element = $(element);

        this.options = options;

        this.tool_tip_contents = tool_tip;

        this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
        this.eventMouseOut   = this.hideTooltip.bindAsEventListener(this);
        this.eventMouseMove  = this.moveTooltip.bindAsEventListener(this);

        this.registerEvents();
    },

    destroy: function() {
        Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
        Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
        Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
    },

    registerEvents: function() {
        Event.observe(this.element, "mouseover", this.eventMouseOver);
        Event.observe(this.element, "mouseout", this.eventMouseOut);
        Event.observe(this.element, "mousemove", this.eventMouseMove);
    },

    moveTooltip: function(event){
        if (typeof(Event.stop) != 'function') {
            return;
        }

        if (!this.tool_tip) {
            return;
        }

        // get Mouse position
        var mouse_x = Event.pointerX(event);
        var mouse_y = Event.pointerY(event);

        // get the scroll position
        var scroll_y = 0;
        if (typeof(window.pageYOffset) == 'number') {
            scroll_y = window.pageYOffset;
        } else if (document.documentElement && document.documentElement.scrollTop) {
            scroll_y = document.documentElement.scrollTop;
        } else if (document.body && document.body.scrollTop) {
            scroll_y = document.body.scrollTop;
        }

        // decide if wee need to switch sides for the tooltip
        var dimensions = Element.getDimensions( this.tool_tip );
        var element_width = dimensions.width;
        var element_height = dimensions.height;

        if ((element_width + mouse_x) >= (this.getWindowWidth() - this.options.min_distance_x - 20)){ // too big for X
            mouse_x = mouse_x - element_width;
            // apply min_distance to make sure that the mouse is not on the tool-tip
            mouse_x = mouse_x - this.options.min_distance_x;
        } else {
            mouse_x = mouse_x + this.options.min_distance_x;
        }
//document.title = 'image h =' + element_height + ' mouse_y =' + mouse_y + ' scroll_y=' + scroll_y + ' screen =' + this.getWindowHeight();
        if ((element_height + mouse_y) >= (scroll_y + this.getWindowHeight() - this.options.min_distance_y)
            && (mouse_y - scroll_y - element_height + this.options.min_distance_y > 0)) {
            mouse_y = Math.min(mouse_y - element_height + this.options.min_distance_y, scroll_y + mouse_y - (element_height - (this.getWindowHeight() - mouse_y)) - this.options.min_distance_y);
        } else if ((element_height + mouse_y) >= (scroll_y + this.getWindowHeight() - this.options.min_distance_y)
            && (scroll_y + mouse_y - element_height + this.options.min_distance_y > 0)) {
            mouse_y = Math.min(scroll_y + mouse_y - element_height + this.options.min_distance_y, scroll_y + mouse_y - (element_height - (this.getWindowHeight() - mouse_y)) - this.options.min_distance_y);
        } else if ((element_height + mouse_y) >= (scroll_y + this.getWindowHeight() - this.options.min_distance_y)){ // bas
            mouse_y = scroll_y + mouse_y - (element_height - (this.getWindowHeight() - mouse_y)) - this.options.min_distance_y;
        } else if ((mouse_y < element_height) && (mouse_y + this.options.min_distance_y > scroll_y + this.getWindowHeight() - this.options.min_distance_y)) { // haut
            mouse_y = mouse_y + (element_height - (element_height + mouse_y)) + this.options.min_distance_y + scroll_y;
        } else {
            mouse_y = mouse_y + this.options.min_distance_y;
        }

        // now set the right styles
        this.setStyles(mouse_x, mouse_y);
    },

    showTooltip: function(event) {
        if (typeof(Event.stop) != 'function') {
            return;
        }

        // use the supplied tooltip element or create our own div
        if (!this.tool_tip) {
            this.tool_tip = $(document.createElement("div"));
            document.body.appendChild(this.tool_tip);

            if (this.options.classname) {
                this.tool_tip.addClassName(this.options.classname);
            } else {
                this.tool_tip.addClassName("tooltip");
            }

            if (this.options.html) {
                this.tool_tip.update(this.tool_tip_contents);
            } else {
                this.tool_tip.appendChild(document.createTextNode(this.tool_tip_contents));
            }

            this.tool_tip.hide();
        }

        Event.stop(event);
        this.moveTooltip(event);
        new Element.show(this.tool_tip);
    },

    setStyles: function(x, y){
        // set the right styles to position the tool tip
        Element.setStyle(this.tool_tip, { position:'absolute',
                top:y + this.options.delta_y + "px",
                left:x + this.options.delta_x + "px",
                zindex:this.options.zindex
        });

        // apply default theme if wanted
        if (this.options.default_css){
            Element.setStyle(this.tool_tip, { margin:this.options.margin,
                    padding:this.options.padding,
                    backgroundColor:this.options.backgroundColor,
                    zindex:this.options.zindex
            });
        }
    },

    hideTooltip: function(event){
        if (typeof(Element.hide) != 'function') {
            return;
        }

        new Element.hide(this.tool_tip);
    },

    getWindowHeight: function(){
        var innerHeight;

        if (typeof(window.innerHeight) == 'number') {
            innerHeight = window.innerHeight;
        } else if(document.documentElement && document.documentElement.clientHeight) {
            innerHeight = document.documentElement.clientHeight;
        } else if(document.body && document.body.clientHeight){
            innerHeight = document.body.clientHeight;
        }

        return innerHeight;
    },

    getWindowWidth: function(){
        var innerWidth;
        if (typeof(window.innerWidth) == 'number') {
            innerWidth = window.innerWidth;
        } else if(document.documentElement && document.documentElement.clientWidth) {
            innerWidth = document.documentElement.clientWidth;
        } else if(document.body && document.body.clientWidth){
            innerWidth = document.body.clientWidth;
        }

        return innerWidth;
    }

}