var Sparkline = function(showHigh, config) {
    this.config = config || Sparkline.defaults;
    this.size = {x: this.config.size.x, y: this.config.size.y};
    this.showHigh = showHigh;
};

Sparkline.defaults = {
    pad: 2,
    size: {x: 100, y: 16},
    area: {
        fill: "#D2D7DA"
    },
    line: {
        width: .7,
        stroke: "#474B4D"
    },
    dot: {
        size: 3,
        fill: "#474B4D",
        line: 1,
        stroke: "none"
    },
    high: {
        size: 3,
        fill: "#00B0EB",
        stroke: "none"
    }
};

Sparkline.prototype.render = function(values, container, size) {
    if (!values || values.length < 2) {
        return false;
    }

    while (values.length && isNaN(values[0])) {
        values.shift();
    }
    while (values.length && isNaN(values[values.length - 1])) {
        values.pop();
    }
    /*
    values = values.map(function(v) {
        return isNaN(v) ? 0 : v;
    });
    */

    var config = this.config,
        showHigh = this.showHigh,
        pad = config.pad,
        len = values.length,
        last = len - 1,
        max = pv.max(values),
        max_index = values.indexOf(max);

    $(container).attr("data-values", values.join(","));
    $(container).attr("data-max", max + " @ " + max_index);

    if (!size) size = this.size;

    var x = pv.Scale.linear()
        .domain(0, last)
        .range(pad, size.x - pad);
    var y = pv.Scale.linear()
        .domain(values)
        .range(pad, size.y - pad);

    var graph = new pv.Panel()
        .canvas(container)
        .width(size.x)
        .height(size.y)

    var area = graph.add(pv.Area)
        .data(values)
        .left(function(d) { return x(this.index); })
        .bottom(pad)
        .height(pv.Scale.linear(y.domain()).range(0, size.y - pad * 2))
        .fillStyle(pv.color(config.area.fill).alpha(.25));

    var line = graph.add(pv.Line)
        .data(values)
        .left(function(d) { return x(this.index); })
        .bottom(y)
        .lineWidth(config.line.width)
        .strokeStyle(config.line.stroke);

    var dots = line.add(pv.Dot)
        .visible(function(d) {
            return this.index == 0 || this.index == last || (showHigh && this.index == max_index);
        })
        .lineWidth(0)
        .fillStyle(function(d) {
            return showHigh
                ? this.index == max_index
                    ? config.high.fill
                    : config.dot.fill
                : config.dot.fill;
        })
        .lineWidth(config.dot.line)
        .strokeStyle(function(d) {
            return showHigh
                ? this.index == max_index
                    ? config.high.stroke
                    : config.dot.stroke
                : config.dot.stroke;
        })
        .size(function(d) {
            return showHigh
                ? this.index == max_index
                    ? config.high.size
                    : config.dot.size
                : config.dot.size;
        });

    graph.area = area;
    graph.line = line;
    graph.dots = dots;

    graph.render();
    this.maxIndex = max_index;
    return graph;
};

