/**
 * @title: JQuery Custom Tooltip
 * @author: Michael Aguiar <michaelaguiar@me.com>
 * @description: Allows you to replace the default tooltip with the style of your choice.
 */

(function($) {
    $.fn.tooltip = function(settings) {
        settings = $.extend({
            id: 'tooltip',
            title: null,
            attrFlag: null,
            className: '',
            fade: true,
            elementDelay: 100,
            left: 15,
            top: 15,
            track: true,
            isStatic: false,
            callback: function() {}
        }, settings || {});
        
        var tooltipTimeout = null;
        var id = '#' + settings.id;
        var interact = false;
                      
        function GetContent(element) {
            var text = null;
            settings.attrFlag = null;
            
            if ($(element).attr('alt') && $(element).attr('alt') !== null) {
                text = $(element).attr('alt');
                settings.title = $(element).attr('alt');
                $(element).attr('alt', '');
                settings.attrFlag = 0;
            } else if ($(element).attr('title') && $(element).attr('title') !== null) {
                text = $(element).attr('title');
                settings.title = $(element).attr('title');
                $(element).attr('title', '');
                settings.attrFlag = 1;
            }
            
            return text;
        }
        
        function GetPosition(e, id, element) {
            var width = $(id).width();
            var height = $(id).height();
            var offset = $(element).offset();

            if (settings.isStatic) {
                if (document.body.clientWidth < (e.pageX + width + settings.left + 15)) {
                    $(id).css({'left' : offset.left - width + 20 + 'px'});
                } else {
                    $(id).css({'left' : offset.left + 'px'});
                }

                if (document.body.clientHeight < (e.pageY + height + settings.top + 15)) {
                    $(id).css({'top' : offset.top - height - settings.top - 5 + 'px'});
                } else {
                    $(id).css({'top' : offset.top - height - settings.top - 15 + 'px'});
                }
            } else {
                if (document.body.clientWidth < (e.pageX + width + settings.left + 15)) {
                    $(id).css({'left' : e.pageX - width - settings.left + 'px'});
                } else {
                    $(id).css({'left' : e.pageX + settings.left - 5 + 'px'});
                }
    
                if (document.body.clientHeight < (e.pageY + height + settings.top + 15)) {
                    $(id).css({'top' : e.pageY - height - settings.top - 10 + 'px'});
                } else {
                    $(id).css({'top' : e.pageY + settings.top + 'px'});
                }
            }
        }
        
        $.each(this, function() {
            var html = $('<div id='+ settings.id +' class='+ settings.className +'></div>');
            
            $(this).unbind('mouseover').unbind('mousemove').unbind('mouseout');
            $(id).unbind('mouseover').unbind('mouseout');
            
            $(this).mouseover(function(e) {
                clearTimeout(tooltipTimeout);                
                var text = GetContent(this);
                
                if (text !== null) {
                	if ($(id).length === 0) {
		            	html.prependTo(document.body);
		            }
                    $(id).html(text);
                }
                
                settings.callback.call(this);
                
                if ($(id).find('a').length !== 0) {
                    interact = true;
                } else {
                    interact = false;
                    $(id).html('<span>'+text+'</span>');
                }
                
                GetPosition(e, id, this);
                
                tooltipTimeout = setTimeout(function() {
                    if (settings.fade) {
                        $(id).fadeIn(settings.elementDelay);
                    } else {
                        $(id).show();
                    }   
                }, 100);
                
                $(id).mouseover(function(e) {
                    if (interact) {
                        clearTimeout(tooltipTimeout);
                        $(id).stop();
                        if (settings.fade) {
                            $(id).animate({'opacity' : '1'}, 150);
                        } else {
                            $(id).show();
                        }   
                    }
                });
            });
            
            $(this).mousemove(function(e) {
                if (settings.track) {
                    GetPosition(e, id, this);
                }
            });
            
            $(this).click(function() {
            	clearTimeout(tooltipTimeout);
                
                tooltipTimeout = setTimeout(function() {
                    if (settings.fade) {
                        if (interact) {
                            $(id).fadeOut(settings.elementDelay + 300);
                        } else {
                            $(id).fadeOut(settings.elementDelay);
                        }
                    } else {
                        $(id).hide();
                    }
                }, 100);
                
                $(id).mouseout(function() {
                    if (interact) {
                        clearTimeout(tooltipTimeout);
                        
                        tooltipTimeout = setTimeout(function() {
                            if (settings.fade) {
                                $(id).fadeOut(settings.elementDelay + 300);
                            } else {
                                $(id).hide();
                            }
                        }, 100);
                    }
                });
                if (settings.attrFlag === 0) {
                    $(this).attr('alt', settings.title);
                } else if (settings.attrFlag == 1) {
                    $(this).attr('title', settings.title);
                }
            });
            
            $(this).mouseout(function() {
                clearTimeout(tooltipTimeout);
                
                tooltipTimeout = setTimeout(function() {
                    if (settings.fade) {
                        if (interact) {
                            $(id).fadeOut(settings.elementDelay + 300);
                        } else {
                            $(id).fadeOut(settings.elementDelay);
                        }
                    } else {
                        $(id).hide();
                    }
                }, 100);
                
                $(id).mouseout(function() {
                    if (interact) {
                        clearTimeout(tooltipTimeout);
                        
                        tooltipTimeout = setTimeout(function() {
                            if (settings.fade) {
                                $(id).fadeOut(settings.elementDelay + 300);
                            } else {
                                $(id).hide();
                            }
                        }, 100);
                    }
                });
                if (settings.attrFlag === 0) {
                    $(this).attr('alt', settings.title);
                } else if (settings.attrFlag == 1) {
                    $(this).attr('title', settings.title);
                }
            });         
        });
    };
}(jQuery));
