class TimelineTooltip {

    private static final int DELAY = 500;
    private TimelineModel model;
    private String position;
    private String min;
    private String max;
    private String y;
    private Timer timer;
    private RichTooltip tooltip;
    private final Lock lock = new ReentrantLock();

    public void setModel(TimelineModel model) {
        this.model = model;
    }

    public void start(final double currentPosition, final Point mousePosition, final JComponent component) {
        stop();
        if (model == null) {
            return;
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                lock.lock();
                try {
                    if (tooltip != null) {
                        tooltip.hideTooltip();
                    }
                    buildData(currentPosition);
                    tooltip = buildTooltip();
                    tooltip.showTooltip(component, mousePosition);
                } finally {
                    lock.unlock();
                }
            }
        }, TimelineTooltip.DELAY);
    }

    public void stop() {
        if (timer != null) {
            timer.cancel();
        }
        lock.lock();
        try {
            if (tooltip != null) {
                tooltip.hideTooltip();
            }
        } finally {
            lock.unlock();
        }
        timer = null;
        tooltip = null;
    }

    private void buildData(double currentPosition) {<FILL_FUNCTION_BODY>}

    private RichTooltip buildTooltip() {
        RichTooltip richTooltip = new RichTooltip();

        //Min
        richTooltip
            .addDescriptionSection(NbBundle.getMessage(TimelineTooltip.class, "TimelineTooltip.min") + ": " + getMin());

        //Max
        richTooltip
            .addDescriptionSection(NbBundle.getMessage(TimelineTooltip.class, "TimelineTooltip.max") + ": " + getMax());

        //Title
        richTooltip.setTitle(getPosition());

        //Img
        richTooltip.setMainImage(ImageUtilities.loadImage("DesktopTimeline/info.png", false));

        //Chart
        if (getY() != null) {
            richTooltip.addFooterSection(model.getChart().getColumn());
            richTooltip
                .addFooterSection(NbBundle.getMessage(TimelineTooltip.class, "TimelineTooltip.chart") + ": " + getY());

            //Img
            richTooltip.setFooterImage(ImageUtilities.loadImage("DesktopTimeline/chart.png", false));
        }

        return richTooltip;
    }

    public String getY() {
        return y;
    }

    public String getPosition() {
        return position;
    }

    public String getMin() {
        return min;
    }

    public String getMax() {
        return max;
    }
}

        switch (model.getTimeFormat()) {
            case DOUBLE:
                int exponentMin = (int) Math.round(Math.log10(model.getCustomMin()));
                DecimalFormat decimalFormat = new DecimalFormat();
                decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
                if (exponentMin > 0) {
                    min = String.valueOf(model.getCustomMin());
                    max = String.valueOf(model.getCustomMax());
                    position = String.valueOf(currentPosition);
                } else {
                    decimalFormat.setMaximumFractionDigits(Math.abs(exponentMin) + 2);
                    min = decimalFormat.format(model.getCustomMin());
                    max = decimalFormat.format(model.getCustomMax());
                    position = decimalFormat.format(currentPosition);
                }
                break;
            case DATE: {
                DateTime minDate = new DateTime((long) model.getCustomMin());
                DateTime maxDate = new DateTime((long) model.getCustomMax());
                DateTime posDate = new DateTime((long) currentPosition);
                DateTimeFormatter formatter = ISODateTimeFormat.date();
                min = formatter.print(minDate);
                max = formatter.print(maxDate);
                position = formatter.print(posDate);
                break;
            }
            default: {
                DateTime minDate = new DateTime((long) model.getCustomMin());
                DateTime maxDate = new DateTime((long) model.getCustomMax());
                DateTime posDate = new DateTime((long) currentPosition);
                DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
                min = formatter.print(minDate);
                max = formatter.print(maxDate);
                position = formatter.print(posDate);
                break;
            }
        }

        if (model.getChart() != null) {
            TimelineChart chart = model.getChart();
            Number yNumber = chart.getY(currentPosition);
            y = yNumber != null ? yNumber.toString() : null;
        } else {
            y = null;
        }
    
<no_super_class>