/*
 * jquery.flot.tooltip
 *
 * desc:	create tooltip with values of hovered point on the graph, 
					support many series, time mode, stacking and pie charts
					you can set custom tip content (also with use of HTML tags) and precision of values
 * version:	0.4.4
 * author: 	Krzysztof Urbas @krzysu [myviews.pl] with help of @ismyrnow
 * website:	https://github.com/krzysu/flot.tooltip
 * 
 * released under MIT License, 2012
*/

(function ($) {
    var options = {
        tooltip: false, //boolean
        tooltipOpts: {
            content: "%s | X: %x | Y: %y.2", //%s -> series label, %x -> X value, %y -> Y value, %x.2 -> precision of X value, %p -> percent
            dateFormat: "%y-%0m-%0d",
            shifts: {
                x: 10,
                y: 20
            },
            defaultTheme: true
        }
    };

    var init = function (plot) {

        var tipPosition = { x: 0, y: 0 };
        var opts = plot.getOptions();

        var updateTooltipPosition = function (pos) {
            tipPosition.x = pos.x;
            tipPosition.y = pos.y;
        };

        var onMouseMove = function (e) {

            var pos = { x: 0, y: 0 };

            pos.x = e.pageX;
            pos.y = e.pageY;

            updateTooltipPosition(pos);
        };

        var timestampToDate = function (tmst) {

            var theDate = new Date(tmst);

            return $.plot.formatDate(theDate, opts.tooltipOpts.dateFormat);
        };

        plot.hooks.bindEvents.push(function (plot, eventHolder) {

            var to = opts.tooltipOpts;
            var placeholder = plot.getPlaceholder();
            var $tip;

            if (opts.tooltip === false) return;

            if ($('#flotTip').length > 0) {
                $tip = $('#flotTip');
            }
            else {
                $tip = $('<div />').attr('id', 'flotTip');
                $tip.appendTo('body').hide().css({ position: 'absolute' });

                if (to.defaultTheme) {
                    $tip.css({
                        'background': '#fff',
                        'z-index': '100',
                        'padding': '0.4em 0.6em',
                        'border-radius': '0.5em',
                        'font-size': '0.8em',
                        'border': '1px solid #111'
                    });
                }
            }

            $(placeholder).bind("plothover", function (event, pos, item) {
                if (item) {
                    var tipText;

                    if (opts.xaxis.mode === "time" || opts.xaxes[0].mode === "time") {
                        tipText = stringFormat(to.content, item, timestampToDate);
                    }
                    else {
                        tipText = stringFormat(to.content, item);
                    }

                    $tip.html(tipText).css({ left: tipPosition.x + to.shifts.x, top: tipPosition.y + to.shifts.y }).show();
                }
                else {
                    $tip.hide().html('');
                }
            });

            eventHolder.mousemove(onMouseMove);
        });

        var stringFormat = function (content, item, fnct) {

            var percentPattern = /%p\.{0,1}(\d{0,})/;
            var seriesPattern = /%s/;
            var xPattern = /%x\.{0,1}(\d{0,})/;
            var yPattern = /%y\.{0,1}(\d{0,})/;

            //percent match
            if (typeof (item.series.percent) !== 'undefined') {
                content = adjustValPrecision(percentPattern, content, item.series.percent);
            }
            //series match
            if (typeof (item.series.label) !== 'undefined') {
                content = content.replace(seriesPattern, item.series.label);
            }
            // xVal match
            if (typeof (fnct) === 'function') {
                content = content.replace(xPattern, fnct(item.series.data[item.dataIndex][0]));
            }
            else if (typeof item.series.data[item.dataIndex][0] === 'number') {
                content = adjustValPrecision(xPattern, content, item.series.data[item.dataIndex][0]);
            }
            // yVal match
            if (typeof item.series.data[item.dataIndex][1] === 'number') {
                content = adjustValPrecision(yPattern, content, item.series.data[item.dataIndex][1]);
            }

            return content;
        };

        var adjustValPrecision = function (pattern, content, value) {

            var precision;
            if (content.match(pattern) !== 'null') {
                if (RegExp.$1 !== '') {
                    precision = RegExp.$1;
                    value = value.toFixed(precision)
                }
                content = content.replace(pattern, value);
            }

            return content;
        };
    }

    $.plot.plugins.push({
        init: init,
        options: options,
        name: 'tooltip',
        version: '0.4.4'
    });
})(jQuery);
