/* Flot plugin for computing bottoms for filled line and bar charts.

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

The case: you've got two series that you want to fill the area between. In Flot
terms, you need to use one as the fill bottom of the other. You can specify the
bottom of each data point as the third coordinate manually, or you can use this
plugin to compute it for you.

In order to name the other series, you need to give it an id, like this:

    var dataset = [
        { data: [ ... ], id: "foo" } ,         // use default bottom
        { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
    ];

    $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});

As a convenience, if the id given is a number that doesn't appear as an id in
the series, it is interpreted as the index in the array instead (so fillBetween:
0 can also mean the first series).

Internally, the plugin modifies the datapoints in each series. For line series,
extra data points might be inserted through interpolation. Note that at points
where the bottom line is not defined (due to a null point or start/end of line),
the current line will show a gap too. The algorithm comes from the
jquery.flot.stack.js plugin, possibly some code could be shared.

*/

(function ( $ ) {

    var options = {
        series: {
            fillBetween: null    // or number
        }
    };

    function init( plot ) {

        function findBottomSeries( s, allseries ) {

            var i;

            for ( i = 0; i < allseries.length; ++i ) {
                if ( allseries[ i ].id === s.fillBetween ) {
                    return allseries[ i ];
                }
            }

            if ( typeof s.fillBetween === "number" ) {
                if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
                    return null;
                }
                return allseries[ s.fillBetween ];
            }

            return null;
        }

        function computeFillBottoms( plot, s, datapoints ) {

            if ( s.fillBetween == null ) {
                return;
            }

            var other = findBottomSeries( s, plot.getData() );

            if ( !other ) {
                return;
            }

            var ps = datapoints.pointsize,
                points = datapoints.points,
                otherps = other.datapoints.pointsize,
                otherpoints = other.datapoints.points,
                newpoints = [],
                px, py, intery, qx, qy, bottom,
                withlines = s.lines.show,
                withbottom = ps > 2 && datapoints.format[2].y,
                withsteps = withlines && s.lines.steps,
                fromgap = true,
                i = 0,
                j = 0,
                l, m;

            while ( true ) {

                if ( i >= points.length ) {
                    break;
                }

                l = newpoints.length;

                if ( points[ i ] == null ) {

                    // copy gaps

                    for ( m = 0; m < ps; ++m ) {
                        newpoints.push( points[ i + m ] );
                    }

                    i += ps;

                } else if ( j >= otherpoints.length ) {

                    // for lines, we can't use the rest of the points

                    if ( !withlines ) {
                        for ( m = 0; m < ps; ++m ) {
                            newpoints.push( points[ i + m ] );
                        }
                    }

                    i += ps;

                } else if ( otherpoints[ j ] == null ) {

                    // oops, got a gap

                    for ( m = 0; m < ps; ++m ) {
                        newpoints.push( null );
                    }

                    fromgap = true;
                    j += otherps;

                } else {

                    // cases where we actually got two points

                    px = points[ i ];
                    py = points[ i + 1 ];
                    qx = otherpoints[ j ];
                    qy = otherpoints[ j + 1 ];
                    bottom = 0;

                    if ( px === qx ) {

                        for ( m = 0; m < ps; ++m ) {
                            newpoints.push( points[ i + m ] );
                        }

                        //newpoints[ l + 1 ] += qy;
                        bottom = qy;

                        i += ps;
                        j += otherps;

                    } else if ( px > qx ) {

                        // we got past point below, might need to
                        // insert interpolated extra point

                        if ( withlines && i > 0 && points[ i - ps ] != null ) {
                            intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
                            newpoints.push( qx );
                            newpoints.push( intery );
                            for ( m = 2; m < ps; ++m ) {
                                newpoints.push( points[ i + m ] );
                            }
                            bottom = qy;
                        }

                        j += otherps;

                    } else { // px < qx

                        // if we come from a gap, we just skip this point

                        if ( fromgap && withlines ) {
                            i += ps;
                            continue;
                        }

                        for ( m = 0; m < ps; ++m ) {
                            newpoints.push( points[ i + m ] );
                        }

                        // we might be able to interpolate a point below,
                        // this can give us a better y

                        if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
                            bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
                        }

                        //newpoints[l + 1] += bottom;

                        i += ps;
                    }

                    fromgap = false;

                    if ( l !== newpoints.length && withbottom ) {
                        newpoints[ l + 2 ] = bottom;
                    }
                }

                // maintain the line steps invariant

                if ( withsteps && l !== newpoints.length && l > 0 &&
                    newpoints[ l ] !== null &&
                    newpoints[ l ] !== newpoints[ l - ps ] &&
                    newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
                    for (m = 0; m < ps; ++m) {
                        newpoints[ l + ps + m ] = newpoints[ l + m ];
                    }
                    newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
                }
            }

            datapoints.points = newpoints;
        }

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

    $.plot.plugins.push({
        init: init,
        options: options,
        name: "fillbetween",
        version: "1.0"
    });

})(jQuery);
