/* copyright 2010 Kirowski Zrt. */

(function($){
    
    if (typeof $.parseJSON !== 'function') {
        // JSON RegExp
        var rvalidchars = /^[\],:{}\s]*$/, 
            rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 
            rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 
            rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
        
        $.extend({
            parseJSON: function(data){
                if (typeof data !== "string" || !data) {
                    return null;
                }
                
                // Make sure leading/trailing whitespace is removed (IE can't handle it)
                data = jQuery.trim(data);
                
                // Make sure the incoming data is actual JSON
                // Logic borrowed from http://json.org/json2.js
                if (rvalidchars.test(data.replace(rvalidescape, "@").replace(rvalidtokens, "]").replace(rvalidbraces, ""))) {
                
                    // Try to use the native JSON parser first
                    return window.JSON && window.JSON.parse ? window.JSON.parse(data) : (new Function("return " + data))();
                    
                }
                else {
                    //jQuery.error("Invalid JSON: " + data);
                }
            }
        });
    }
    
    var counter = 0;
    
    $.fn.extend({
        tooltip: function(options){
            
            var tt_defaults = {
                    delay: 200,
                    track: false,
                    fade: 500,
                    trigger: 'mouseenter',
                    hook: 'center-bottom',
                    cls: '',
                    autoHide: false,
                    tpl: '<div class="tooltip"><div class="ttCont"></div></div>',
                    cont: '',
                    pushX: 15,
                    pushY: 15,
                    width: 0,
                    height: 0,
                    opacity: 1,
                    closeTpl: '<a href="#" class="ttClose">X</a>',
                    pointer: '<div class="ttPointer"></div>',
                    displayOnce: false,
                    onlyOneVisible: true,
                }
            
            function showTooltipBox(tt,box,settings,e){
                
                var tt_props = {};
                tt_props.width = box.outerWidth();
                tt_props.height = box.outerHeight();
                
                // a hook legyen [] vagy {}
                if(settings.track){
                    if(settings.hook=='right-bottom' || settings.hook=='right-center' || settings.hook=='right-top'){
                        var ttLeft = e.pageX + settings.pushX;
                    }else if(settings.hook=='center-bottom' || settings.hook=='center-center' || settings.hook=='center-top'){
                        var ttLeft = e.pageX - (tt_props.width/2) + settings.pushX;
                    }else if(settings.hook=='left-bottom' || settings.hook=='left-center' || settings.hook=='left-top'){
                        var ttLeft = e.pageX - settings.pushX - tt_props.width;
                    }
                    
                    if(settings.hook=='right-top' || settings.hook=='center-top' || settings.hook == 'left-top'){
                        var ttTop = e.pageY - tt_props.height - settings.pushY;
                    }else if(settings.hook=='right-center' || settings.hook=='center-center' || settings.hook == 'left-center'){
                        var ttTop = e.pageY - (tt_props.height/2) + settings.pushY;
                    }else if(settings.hook=='right-bottom' || settings.hook=='center-bottom' || settings.hook=='left-bottom'){
                        var ttTop = e.pageY + settings.pushY;
                    }
                } else {
                    var elem_props = {
                        left: tt.offset().left,
                        top: tt.offset().top,
                        height: tt.outerHeight(),
                        width: tt.outerWidth()
                    }
                    if(settings.hook=='right-bottom' || settings.hook=='right-center' || settings.hook=='right-top'){
                        var ttLeft = elem_props.left + elem_props.width + settings.pushX;
                    }else if(settings.hook=='center-bottom' || settings.hook=='center-center' || settings.hook=='center-top'){
                        var ttLeft = elem_props.left + (elem_props.width/2) - (tt_props.width/2) + settings.pushX;
                    }else if(settings.hook=='left-bottom' || settings.hook=='left-center' || settings.hook=='left-top'){
                        var ttLeft = elem_props.left - settings.pushX - tt_props.width;
                    }
                    
                    if(settings.hook=='right-top' || settings.hook=='center-top' || settings.hook == 'left-top'){
                        var ttTop = elem_props.top - settings.pushY - tt_props.height;
                    }else if(settings.hook=='right-center' || settings.hook=='center-center' || settings.hook == 'left-center'){
                        var ttTop = elem_props.top + (elem_props.height/2) - (tt_props.height/2) + settings.pushY;
                    }else if(settings.hook=='right-bottom' || settings.hook=='center-bottom' || settings.hook=='left-bottom'){
                        var ttTop = elem_props.top + elem_props.height + settings.pushY;
                    }
                }
                
                box.css({
                    left: ttLeft + 'px',
                    top: ttTop + 'px'
                });
                
                if(settings.fade)box.stop(true,true).fadeIn(settings.fade)
                else box.show();
                
                if (settings.autoHide !== false) {
                    hTimer = setTimeout(function(){
                        hideTooltipBox(tt,box,settings);
                    }, settings.fade+settings.delay+settings.autoHide);
                }
            }
            
            function hideTooltipBox(tt,box,settings){
                if(settings.fade)box.stop(true,true).fadeOut(settings.fade, function(){
                    if(settings.displayOnce){
                        tt.unbind('mouseenter.showTT').unbind('mouseleave.hideTT').unbind('mousemove.moveTT').unbind('click.clickShowTT');
                        box.remove();
                    }    
                });
                else box.hide();
            }
            
            $(this).filter(':not(hasTooltip)').each(function(i){
                
                var settings = $.extend({}, tt_defaults, options), ttTimer, hTimer;
                
                var $tt = $(this).addClass('hasTooltip').data('tTitle',$(this).attr('title')).removeAttr('title').attr('id','tt-'+counter++),
                    content,
                    attrRel = $tt.attr('rel'),
                    relSettings = (attrRel && attrRel != '') ? $.parseJSON(attrRel.replace(/'/g,'"')) : {},
                    hook = relSettings.hook || settings.hook,
                    boxClass = relSettings.boxClass;
                    
                $.extend(settings,relSettings);

                if(typeof settings.cont === 'function'){
                    content = settings.cont($tt);
                } else {
                    if(settings.cont==''){
                        content = $tt.data('tTitle');
                    } else {
                        content = settings.cont;
                    }
                }
                
                var $tpl = $(settings.tpl).appendTo('body').addClass(settings.boxClass).addClass(hook || settings.hook).attr('id',$tt.attr('id')+'_ttb').hide().css({
                    opacity: settings.opacity,
                }).find('.ttCont').append(content).end();
                
                if(settings.width)$tpl.css('width',settings.width);
                if(settings.height)$tpl.css('height',settings.height);
                
                if($.browser.msie)$tpl.addClass('ttIE_'+parseInt(jQuery.browser.version));
                
                if(!$tpl.find('.ttPointer').length){
                    $tpl.after(settings.pointer)
                }
                
                if(settings.trigger=='mouseenter'){
                    $tt.bind('mouseenter.showTT',function(e){
                        var $t = $(this);
                        
                        if(settings.delay){
                            ttTimer = setTimeout(function(){
                                showTooltipBox($t, $('#' + $t.attr('id')+'_ttb'),settings, e);
                            },settings.delay);
                        } else {
                            showTooltipBox($t, $('#' + $t.attr('id')+'_ttb'),settings, e);
                        }
                    }).bind('mouseleave.hideTT',function(){
                        var $t = $(this);
                        $t.attr('title',$t.data('tTitle'));
                        clearTimeout(ttTimer);
                        hideTooltipBox($t,$('#' + $t.attr('id')+'_ttb'),settings);
                    });
                    
                    if(settings.track){
                        $tt.bind('mousemove.moveTT',function(e){
                            
                            var $ttBox = $('#' + $(this).attr('id')+'_ttb'),
                                ttWidth = $ttBox.outerWidth(),
                                ttHeight = $ttBox.outerHeight();
                            
                            if(settings.hook=='right-bottom' || settings.hook=='right-center' || settings.hook=='right-top'){
                                var ttLeft = e.pageX + settings.pushX;
                            }else if(settings.hook=='center-bottom' || settings.hook=='center-center' || settings.hook=='center-top'){
                                var ttLeft = e.pageX - (ttWidth/2) + settings.pushX;
                            }else if(settings.hook=='left-bottom' || settings.hook=='left-center' || settings.hook=='left-top'){
                                var ttLeft = e.pageX - settings.pushX - ttWidth;
                            }
                            
                            if(settings.hook=='right-top' || settings.hook=='center-top' || settings.hook == 'left-top'){
                                var ttTop = e.pageY - ttHeight - settings.pushY;
                            }else if(settings.hook=='right-center' || settings.hook=='center-center' || settings.hook == 'left-center'){
                                var ttTop = e.pageY - (ttHeight/2) + settings.pushY;
                            }else if(settings.hook=='right-bottom' || settings.hook=='center-bottom' || settings.hook=='left-bottom'){
                                var ttTop = e.pageY + settings.pushY;
                            }
                            
                            $ttBox.css({
                                left: ttLeft + 'px',
                                top: ttTop + 'px'
                            });
                        });
                    }
                }
                else if(settings.trigger=='click'){
                    
                    var $link;
                    
                    $tt.bind('click.clickShowTT',function(e){
                       
                        $link = $(this);
                        
                        if (settings.onlyOneVisible) $('.ttCloseBox').trigger('click');
                        
                        $link.data('tTitle',$link.attr('title')).attr('title','');
                        if(settings.delay){
                            ttTimer = setTimeout(function(){
                                showTooltipBox($link, $('#' + $link.attr('id')+'_ttb'),settings)
                            },settings.delay);
                        } else {
                            showTooltipBox($link, $('#' + $link.attr('id')+'_ttb'),settings);
                        }
                        
                        if (!$('#' + $link.attr('id')+'_ttb').find('.ttCloseBox').length) {
                            var $close = $('<div class="ttCloseBox"></div>').appendTo($('#' + $link.attr('id')+'_ttb')).html(settings.closeTpl).bind('click',function(e){
                                $link.attr('title', $link.data('tTitle'));
                                clearTimeout(ttTimer);
                                hideTooltipBox($link, $('#' + $link.attr('id')+'_ttb'),settings);
                                e.preventDefault();
                                e.stopPropagation();
                            });
                        }
                        e.preventDefault();
                        e.stopPropagation();
                    });
                }
            }); 
            
            $(function(){
                $(document).click(function(){
                    $('.ttCloseBox').trigger('click');
                });
            });
            
            return $(this);
        }
    });
})(jQuery);
