// Copyright (C) 2010 MobileOn Services Inc.  All Rights Reserved
// Uses technique outlined by "Scott" at Filament Group for CSS triangles:
// http://www.filamentgroup.com/lab/image_free_css_tooltip_pointers_a_use_for_polygonal_css/
jQuery.fn.autotip = function(options) {

    var _transformIntoTooltip = function(tooltipSelector, pointerDirectionality, pointerPct, jQueryWidgetClass) {
        jQuery(tooltipSelector).html('<div class="tooltip-content">' + jQuery(tooltipSelector).html() + '</div>');
        jQuery(tooltipSelector).append(
                '<div class="tooltip-pointer-' + pointerDirectionality + ' tooltip-pointer-' + pointerDirectionality + '-' + pointerPct + ' ' + jQueryWidgetClass + '">' +
                    '<div class="tooltip-pointer-' + pointerDirectionality + '-inner"></div>' +
                '</div>'
        );
        jQuery(tooltipSelector).addClass('tooltip').addClass('ui-widget').addClass('ui-corner-all').addClass(jQueryWidgetClass);
    }

    var _findFirstWord = function(wordIndexObj) {

        var minimumWord = "";
        var strpos = -1;

        for(var prop in wordIndexObj) {
            if(wordIndexObj[prop] !== false) {
                if(strpos == -1 || wordIndexObj[prop] < strpos) {
                    strpos = wordIndexObj[prop];
                    minimumWord = prop;
                }
            }
        }

        return minimumWord;
    }

    var _locationSanitizer = function(loc) {

        var words = [ 'top', 'bottom', 'center', 'right', 'left' ];
        var placement = { };

        for(var i = 0; i < words.length; i++) {
            var wordloc = loc.indexOf(words[i]);
            if(wordloc >= 0) {
                placement[words[i]] = wordloc;
            } else {
                placement[words[i]] = false;
            }
        }

        var minimumWord = _findFirstWord(placement);
        if(minimumWord == "" || minimumWord == 'center') {
            minimumWord = "bottom";
        }

        if(minimumWord == "top" || minimumWord == "bottom") {
            delete placement['top'];
            delete placement['bottom'];
        } else if(minimumWord == "left" || minimumWord == "right") {
            delete placement['left'];
            delete placement['right'];
        }

        var otherAxisWord = _findFirstWord(placement);
        if(otherAxisWord == "") {
            otherAxisWord = "center";
        }

        return [ minimumWord, otherAxisWord ];
    }

    var _makeTooltip = function(targetSelector, tooltipSelector, rawTooltipLocation, TIP, jQueryWidgetClass) {

        var myLoc;
        var myHorizontal, myVertical;
        var atLoc;
        var targetHorizontal, targetVertical;

        var topOffset = 0;
        var leftOffset = 0;
        var topMainOffset = 0;
        var topSubOffset = 0;
        var leftMainOffset = 0;
        var leftSubOffset = 0;
        var offset;

        var tipPct;

        var tipDirection;


        /*
           Here's how the logic maps work out
           First: tooltipLocation must start with right, left, top, or bottom (AXIS)
                  Following that, for right/left: top,center,bottom (ALIGN)
                                  for top/bottom: left,center,right

              MyHorizontal = f(AXIS):
                f(right) = left
                f(left) = right
                f(top|bottom) = center

              MyVertical = f(AXIS):
                f(right|left) = center
                f(top) = bottom
                f(bottom) = top

              TargetHorizontal,TargetVertical = f(AXIS,ALIGN):
                f(right|left,ALIGN) -> (TH,TV) = (AXIS,ALIGN)
                f(top|bottom,ALIGN) -> (TH,TV) = (ALIGN,AXIS)

              TipPct = f(TIP):
                top|left -> 25%
                center -> 50%
                bottom|right -> 75%

              Left Offset = f(AXIS,ALIGN,TIP):
                f(left,ALIGN,TIP) = -16
                f(right,ALIGN,TIP) = 16

                Left Mainoffset
                f(top|bottom,left,TIP) = +1/4 bw
                f(top|bottom,center,TIP) = 0
                f(top|bottom,right,TIP) = -1/4 bw
                
                Left Suboffset
                f(top|bottom,ALIGN,left) = +1/4 tw
                f(top|bottom,ALIGN,center) = 0
                f(top|bottom,ALIGN,right) = -1/4 tw

              Top Offset = f(AXIS,ALIGN,TIP):

                Top Mainoffset
                f(left|right,top,TIP) = +1/4 bh
                f(left|right,center,TIP) = 0
                f(left|right,bottom,TIP) = -1/4 bh

                Top Suboffset
                f(left|right,ALIGN,top) = +1/4 th
                f(left|right,ALIGN,center) = 0
                f(left|right,ALIGN,bottom) = -1/4 th

                f(top,ALIGN,TIP) = -16
                f(bottom,ALIGN) = 16

         */

        var tooltipLocation = _locationSanitizer(rawTooltipLocation);
        var AXIS = tooltipLocation[0];
        var ALIGN = tooltipLocation[1];

        tipDirection = (AXIS == 'right' ? 'left' :
                         (AXIS == 'left' ? 'right' :
                           (AXIS == 'top' ? 'bottom' : 'top')));

        tipPct = (TIP == 'top' || TIP == 'left' ? "near" : (TIP == 'bottom' || TIP == 'right' ? "far" : "center"));

        _transformIntoTooltip(tooltipSelector, tipDirection, tipPct, jQueryWidgetClass);

        jQuery(tooltipSelector).show();

        var bw = jQuery(targetSelector).outerWidth() / 8;
        var bh = jQuery(targetSelector).outerHeight() / 8;
        var tw = jQuery(tooltipSelector).outerWidth() / 8;
        var th = jQuery(tooltipSelector).outerHeight() / 8;

        // console.log("b = " + bw + "x" + bh + ", tt = "  + tw + ", " + th);

        // console.log("AXIS = " + AXIS + ", ALIGN = " + ALIGN);

        myHorizontal = (AXIS == 'right' ? 'left' : (AXIS == 'left' ? 'right' : 'center'));
        myVertical = (AXIS == 'top' ? 'bottom' : (AXIS == 'bottom' ? 'top' : 'center'));

        targetHorizontal = (AXIS == 'right' || AXIS == 'left' ? AXIS : ALIGN);
        targetVertical = (AXIS == 'right' || AXIS == 'left' ? ALIGN : AXIS);

        if(AXIS == 'left' || AXIS == 'right') {
            leftOffset = (AXIS == 'left' ? -16 : 16);
            if(ALIGN == 'top' || ALIGN == 'bottom') {
                topMainOffset = (ALIGN == 'top' ? bh : -bh);
            }
            if(TIP == 'top' || TIP == 'bottom') {
                topSubOffset = (TIP == 'top' ? th : -th);
            }
            topOffset = topMainOffset + topSubOffset;
        } else {
            topOffset = (AXIS == 'top' ? -16 : 16);
            if(ALIGN == 'left' || ALIGN == 'right') {
                leftMainOffset = (ALIGN == 'left' ? bw : -bw);
            }
            if(TIP == 'left' || TIP == 'right') {
                leftSubOffset = (TIP == 'left' ? tw : -tw);
            }
            // console.log("leftMainOffset = " + leftMainOffset + ", leftSubOffset = " + leftSubOffset);
            leftOffset = leftMainOffset + leftSubOffset;
        }

        myLoc = myHorizontal + " " + myVertical;
        atLoc = targetHorizontal + " " + targetVertical;

        offset = "" + leftOffset + " " + topOffset;

        // console.log("MyLoc = " + myLoc + ", atLoc = " + atLoc + ", tipDir = " + tipDirection + ", Offset = " + offset);


        jQuery(tooltipSelector).position({
            of: targetSelector,
            my: myLoc,
            at: atLoc,
            offset: offset
        });

        jQuery(tooltipSelector).hide();
    }

    var defaults = {
        location: 'bottom right',
        tooltip: false,
        tip: 'left',
        width: false,
        widgetClass: 'ui-state-highlight'
    };

    var options = jQuery.extend(defaults, options);

    if(options.tooltip !== false) {
        _makeTooltip(jQuery(this).first(), jQuery(options.tooltip), options.location, options.tip, options.widgetClass);
    } else {
        // iterate over each supplied source element, grab title="", make tooltips, associate with each element
        this.each(function(n) {
            var element = jQuery(this);
            if(jQuery(element).attr('title').trim() != '') {
                jQuery('<div class="autotip-generated" style="padding: 10px;">' + jQuery(element).attr('title').trim() + '</div>').appendTo('body');
                // grab the width of the parent element
                var width;
                if(options.width !== false && options.width > 0) {
                    width = options.width;
                } else {
                    width = jQuery(element).width() * 1.5;
                }
                jQuery('body > div:last-child').css('width', "" + width + "px");
                _makeTooltip(element, jQuery('body > div:last-child'), options.location, options.tip, options.widgetClass);
                var childElementClosure = jQuery('body > div:last-child');
                if(jQuery(element).is('input[type=text]') ||
                   jQuery(element).is('input[type=password]') ||
                   jQuery(element).is('textarea') ||
                   jQuery(element).is('select')) {
                    jQuery(element).bind('focus', function(ev) {
                        jQuery(childElementClosure).show();
                    });
                    jQuery(element).bind('blur', function(ev) {
                        jQuery(childElementClosure).hide();
                    });
                } else {
                    jQuery(element).hover(
                        function(ev) {
                            jQuery(childElementClosure).fadeIn('fast');
                        },
                        function(ev) {
                            jQuery(childElementClosure).fadeOut('fast');
                        }
                    );
                }
            }
        });
    }

    return this;
}

