/* Flot plugin for thresholding data.

Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.

The plugin supports these options:

	series: {
		threshold: {
			below: number
			color: colorspec
		}
	}

It can also be applied to a single series, like this:

	$.plot( $("#placeholder"), [{
		data: [ ... ],
		threshold: { ... }
	}])

An array can be passed for multiple thresholding, like this:

	threshold: [{
		below: number1
		color: color1
	},{
		below: number2
		color: color2
	}]

These multiple threshold objects can be passed in any order since they are
sorted by the processing function.

The data points below "below" are drawn with the specified color. This makes
it easy to mark points below 0, e.g. for budget data.

Internally, the plugin works by splitting the data into two series, above and
below the threshold. The extra series below the threshold will have its label
cleared and the special "originSeries" attribute set to the original series.
You may need to check for this in hover events.

*/

(function ($) {
  var options = {
    series: { threshold: null } // or { below: number, color: color spec}
  };

  function init(plot) {
    function thresholdData(plot, s, datapoints, below, color) {
      var ps = datapoints.pointsize, i, x, y, p, prevp,
          thresholded = $.extend({}, s); // note: shallow copy

      thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
      thresholded.label = null;
      thresholded.color = color;
      thresholded.threshold = null;
      thresholded.originSeries = s;
      thresholded.data = [];

      var origpoints = datapoints.points,
          addCrossingPoints = s.lines.show;

      var threspoints = [];
      var newpoints = [];
      var m;

      for (i = 0; i < origpoints.length; i += ps) {
        x = origpoints[i];
        y = origpoints[i + 1];

        prevp = p;
        if (y < below)
          p = threspoints;
        else
          p = newpoints;

        if (addCrossingPoints && prevp != p && x != null
            && i > 0 && origpoints[i - ps] != null) {
          var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
          prevp.push(interx);
          prevp.push(below);
          for (m = 2; m < ps; ++m)
            prevp.push(origpoints[i + m]);

          p.push(null); // start new segment
          p.push(null);
          for (m = 2; m < ps; ++m)
            p.push(origpoints[i + m]);
          p.push(interx);
          p.push(below);
          for (m = 2; m < ps; ++m)
            p.push(origpoints[i + m]);
        }

        p.push(x);
        p.push(y);
        for (m = 2; m < ps; ++m)
          p.push(origpoints[i + m]);
      }

      datapoints.points = newpoints;
      thresholded.datapoints.points = threspoints;

      if (thresholded.datapoints.points.length > 0) {
        var origIndex = $.inArray(s, plot.getData());
        // Insert newly-generated series right after original one (to prevent it from becoming top-most)
        plot.getData().splice(origIndex + 1, 0, thresholded);
      }

      // FIXME: there are probably some edge cases left in bars
    }

    function processThresholds(plot, s, datapoints) {
      if (!s.threshold)
        return;

      if (s.threshold instanceof Array) {
        s.threshold.sort(function(a, b) {
          return a.below - b.below;
        });

        $(s.threshold).each(function(i, th) {
          thresholdData(plot, s, datapoints, th.below, th.color);
        });
      }
      else {
        thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
      }
    }

    plot.hooks.processDatapoints.push(processThresholds);
  }

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