'use strict';

var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');

module.exports = function setContours(trace, vals) {
    var contours = trace.contours;

    // check if we need to auto-choose contour levels
    if(trace.autocontour) {
        // N.B. do not try to use coloraxis cmin/cmax,
        // these values here are meant to remain "per-trace" for now
        var zmin = trace.zmin;
        var zmax = trace.zmax;
        if(trace.zauto || zmin === undefined) {
            zmin = Lib.aggNums(Math.min, null, vals);
        }
        if(trace.zauto || zmax === undefined) {
            zmax = Lib.aggNums(Math.max, null, vals);
        }

        var dummyAx = autoContours(zmin, zmax, trace.ncontours);
        contours.size = dummyAx.dtick;
        contours.start = Axes.tickFirst(dummyAx);
        dummyAx.range.reverse();
        contours.end = Axes.tickFirst(dummyAx);

        if(contours.start === zmin) contours.start += contours.size;
        if(contours.end === zmax) contours.end -= contours.size;

        // if you set a small ncontours, *and* the ends are exactly on zmin/zmax
        // there's an edge case where start > end now. Make sure there's at least
        // one meaningful contour, put it midway between the crossed values
        if(contours.start > contours.end) {
            contours.start = contours.end = (contours.start + contours.end) / 2;
        }

        // copy auto-contour info back to the source data.
        // previously we copied the whole contours object back, but that had
        // other info (coloring, showlines) that should be left to supplyDefaults
        if(!trace._input.contours) trace._input.contours = {};
        Lib.extendFlat(trace._input.contours, {
            start: contours.start,
            end: contours.end,
            size: contours.size
        });
        trace._input.autocontour = true;
    } else if(contours.type !== 'constraint') {
        // sanity checks on manually-supplied start/end/size
        var start = contours.start;
        var end = contours.end;
        var inputContours = trace._input.contours;

        if(start > end) {
            contours.start = inputContours.start = end;
            end = contours.end = inputContours.end = start;
            start = contours.start;
        }

        if(!(contours.size > 0)) {
            var sizeOut;
            if(start === end) sizeOut = 1;
            else sizeOut = autoContours(start, end, trace.ncontours).dtick;

            inputContours.size = contours.size = sizeOut;
        }
    }
};


/*
 * autoContours: make a dummy axis object with dtick we can use
 * as contours.size, and if needed we can use Axes.tickFirst
 * with this axis object to calculate the start and end too
 *
 * start: the value to start the contours at
 * end: the value to end at (must be > start)
 * ncontours: max number of contours to make, like roughDTick
 *
 * returns: an axis object
 */
function autoContours(start, end, ncontours) {
    var dummyAx = {
        type: 'linear',
        range: [start, end]
    };

    Axes.autoTicks(
        dummyAx,
        (end - start) / (ncontours || 15)
    );

    return dummyAx;
}
