/*
   CVS version:
   $Id: tooltip.js,v 1.4 2009/03/16 07:00:03 john Exp $
   $Name: HEAD $
   
   Disclaimer
   
   While we make every effort to ensure that this code is fit for its intended
   purpose, we make no guarantees as to its functionality. CoreTrek AS will
   accept no responsibility for the loss of data or any other damage or
   financial loss caused by use of this code.
   
   Copyright
   
   This programming code is copyright of CoreTrek AS. Permission to run this
   code is given to approved users of CoreTrek's publishing system CorePublish.
   
   This source code may not be copied, modified or otherwise repurposed for use
   by a third party without the written permission of CoreTrek AS.
   
   Contact webmaster@coretrek.com for information.
  
*/

/*

    ============================================================================
    IMPORTANT! This javascript is dependent on Prototype. If Scriptaculous is
               available the tooltip will use some nice effects.
    ============================================================================

    SiteComponents Tooltip

    Displays a nice looking tooltip instead of browser tooltip. The tooltip will
    be available for all a-tags that has a title attribute. The title attribute
    will be displayed in the tooltip popup.

    Just include this javascript file to enable.

    The script is dependent on Prototype, and optionaly on Scriptaculous.
    Scriptaculous is used to display an Appear effect when showing the tooltip.
    Use CSS to style the tooltip elements.

    The title can contain entity encoded HTML. IE6 behaves a bit off when using
    a absolute positioned div. The div will use all available width. We
    therefore explicitly set tooltip width to 50px and white-space to nowrap.
    Remember to manuallt set linebreaks in your tooltip using entity encoded
    <br>'s, <p>'s or whatever. If your site is using a custom theme, copy the
    IE6 tooltip css to your new theme folder.

    The tooltip is appended to body using using javascript:

    <div id="tooltip">
        <div id="tooltip-top"></div>
        <div id="tooltip-content">
            Content is added here...
        </div>
    </div>

    SiteComponents Configurations

    component:
        tooltip
    parameters:
        string positionby Supported values: 'element', 'mouse'
    example:
        var siteComponentsConfig = { 'tooltip': { 'positionby': 'element' }};
*/

var CtTooltip = Class.create({
    
    /**
     * Initialize function
     *
     * @param string positionBy Valid values are "mouse" (default) and "element"
     */
    initialize: function(positionBy) {
        switch(positionBy) {
            case 'mouse':
                positionBy = 'mouse';
                break;
            default:
            case 'element':
                    positionBy = 'element';
                    break;
        }
        this.positionBy = positionBy;

        objBody = document.getElementsByTagName('body').item(0);

        // Add the tooltip html structure to end of page
        var tooltipObj = document.createElement('div');
        tooltipObj.setAttribute('id', 'tooltip');
        tooltipObj.style.display = 'none';
        tooltipObj.style.position = 'absolute';
        tooltipObj.style.zIndex = '100';
        objBody.appendChild(tooltipObj);

        var tooltipTopObj = document.createElement('div');
        tooltipTopObj.setAttribute('id', 'tooltip-top');
        tooltipObj.appendChild(tooltipTopObj);

        var tooltipContentObj = document.createElement('div');
        tooltipContentObj.setAttribute('id', 'tooltip-content');
        tooltipObj.appendChild(tooltipContentObj);
        
        var tooltipBottomObj = document.createElement('div');
        tooltipBottomObj.setAttribute('id', 'tooltip-bottom');
        tooltipObj.appendChild(tooltipBottomObj);

        this.tooltip = $('tooltip');
        this.content = $('tooltip-content');
        this.topDiv = $('tooltip-top');
        this.bottomDiv = $('tooltip-bottom');

        $$("*.tooltip").each(function(element) {
            try {
                title = element.getAttribute('title');
                if(title != null && title.length > 0) {
		            element.observe('mouseover', function(event) {
		                //event.stop();
		                tooltip.show(element, event);
		            });

		            element.observe('mouseout', function(event) {
		                tooltip.hide();
		            });
		            
                    if(positionBy == 'mouse') {
			            element.observe('mousemove', function(event) {
			                tooltip.moveTo(event.pointerX(), event.pointerY());
			            });
		            }
                }
            } catch(Exception) { }
        });
        
        if(Prototype.Browser.IE && navigator.appVersion.match(/MSIE 6\.0/)) {
	        this.tooltip.setStyle({
	            position: 'absolute',
	            width: '50px',
	            whiteSpace: 'nowrap'
	        });
        }
    },

    show: function(element, event) {
        // If the tooltip source attribute is missing an exception is
        // thrown, catch and release...
        try {
	        if(element.getAttribute('title').length > 0) {
	            // If the tooltip is already visible, hide it
                if(this.visible) {
                    this.hide();
                }

                if (element.hasClassName('tooltip-simple')) {
                    $('tooltip').addClassName('simple');
                    $('tooltip').removeClassName('wide');
                } else if (element.hasClassName('tooltip-wide')) {
                    $('tooltip').addClassName('wide');
                    $('tooltip').removeClassName('simple');
                } else {
                    $('tooltip').removeClassName('simple');
                    $('tooltip').removeClassName('wide');
                }
                
                // Store the title attribute (the tooltip text), then reset the
                // element title to nothing. This prevents the browser tooltip
                // from appearing. The title text is set back to the element
                // when were hiding our tooltip
                this.element = element;
	            this.tooltipText = element.getAttribute('title');
	            element.setAttribute('title', '');
                
	            // Move to mouse or element position, the moveTo contains a small offset
	            switch(this.positionBy) {
	               case 'element':
	                   this.moveTo(element.cumulativeOffset()[0],element.cumulativeOffset()[1]);
	                   break;
	               case 'mouse':
	               default:
	                   this.moveTo(event.pointerX(), event.pointerY());
	                   break;
	            }

		        // Set tooltip content to the element title
		        this.content.update(this.tooltipText);

		        // Try using appear effect if scriptaculous is available,
		        // if not we fallback to just showing the tooltip without any
		        // effects
		        try {
		            this.effect = Effect.Appear('tooltip', {
                        duration: .25,
		                afterFinish: function() {
                            tooltip.effect = null;
                        }
                    });
		        } catch (Exeption) {
		            this.tooltip.show();
		        }
		        this.visible = true;
	        }
        } catch(Exception) { }
    },

    hide: function() {
        if(this.visible) {
            // if there is an ongoing effect, cancel it
            if(this.effect != null) {
                this.effect.cancel();
                this.effect = null;
            }

	        this.tooltip.hide();

	        this.element.setAttribute('title', this.tooltipText);
	        this.tooltipText = null;
	        this.visible = false;
        }
    },

    moveTo: function(x, y) {
        // Move to a given position. The position is the current mouse
        // position, so were adding a small offset so that the mouse cursor
        // is not in the way. Also we check if the tooltip will overflow the
        // visible viewport. If it does, we reposition it so that it will fit

        // add initial offset from pointer
        x -= 10;
        y += 20;
        
        var width = this.tooltip.getWidth();
        var height = this.tooltip.getHeight();

        scrollOffsets = document.viewport.getScrollOffsets();

        var viewportWindow = {
            top: scrollOffsets['top'],
            bottom: scrollOffsets['top'] + document.viewport.getHeight(),
            left: scrollOffsets['left'],
            right: scrollOffsets['left'] + document.viewport.getWidth()
        };

        flipX = false;
        if(x + width > viewportWindow['right']) {
            x = viewportWindow['right'] - width;
            flipX = true;
        }
        
        // If the tooltip extends beyond the bottom of the visible viewport,
        // we reposition it above the pointer. We also hide the top
        flipY = false;
        if(y + height > viewportWindow['bottom']) {
            y = y - height - 30;
            flipY = true;
        }
        
        if(flipY) {
            this.tooltip.addClassName('flipped-y');
        } else {
            this.tooltip.removeClassName('flipped-y');
        }
        
        this.tooltip.setStyle({
            left: x + 'px',
            top: y + 'px'
        });
    }

});

var tooltip;
document.observe('dom:loaded', function(event) {
    tooltip = new CtTooltip("mouse");
});
