/*
    SiteComponents version:
    6.8.0.1, tag SC_6_8_0_1, created Fri Aug 20 11:18:33 +0200 2010

    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.
    
*/

/*jslint laxbreak: true, sub: true, white: false, browser: true,
onevar: false, nomen: false, noindent: true, eqeqeq: false, plusplus: false,
forin: true */
/*global siteComponentsConfig: false, getSiteComponentsConfig: false,
Ajax: false, $$: false, $: false, Element: false, window: false, Class: false,
Effect: false, lightbox: false, PeriodicalExecuter: false, Event: false,
CtCookie: false, cpKeywords: false, Prototype: false,
cpWriteMediaObject: false, tooltip: false */

/*

    ============================================================================
    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;

        var 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');

        $$("a").each(function(element) {
            this.addTooltipToElement(element);
        }.bind(this));
        
        if(Prototype.Browser.IE && navigator.appVersion.match(/MSIE 6\.0/)) {
            this.tooltip.setStyle({
                position: 'absolute',
                width: '50px',
                whiteSpace: 'nowrap'
            });
        }
    },

    addTooltipToElement: function(element) {
        try {
            var 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(this.positionBy == 'mouse') {
                    element.observe('mousemove', function(event) {
                        tooltip.moveTo(event.pointerX(), event.pointerY());
                    });
                }
            }
        } catch(Exception) { }
    },

    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();
                }
                // 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;
                   default:
                   case 'mouse': // not required, added for readability
                       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: 0.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();

        var scrollOffsets = document.viewport.getScrollOffsets();

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

        var 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
        var 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'
        });
    }
    
});

Event.observe(window, 'load', function() {
    if(!getSiteComponentsConfig('tooltip', 'disable')) {
        window.tooltip = new CtTooltip(getSiteComponentsConfig('tooltip', 'positionby'));
    }
});

