class lineChartMedium {

    constructor(div_id, lineData, label, y_ax, x_ax, colours, reference) {
        this.lineData = lineData;
        this.referenceData = [[{x: 0, y: 0}, {x: 300, y: 100000}]];
        this.x_d = label[0];
        this.y_d = label[1];
        this.x_ax = x_ax;
        this.y_ax = y_ax;
        this.margin = {top: 10, right: 10, bottom: 10, left: 10};
        this.axis_w = 55;
        this.ayis_w = 20;
        this.colours = colours;

        this.svg = d3.select("#" + div_id).append("svg")
            .attr("width",  "100%")
            .attr("height", "100%");

        this.width = this.svg.node().getBoundingClientRect().width - this.margin.left - this.margin.right - this.axis_w;
        this.height = this.svg.node().getBoundingClientRect().height - this.margin.top - this.margin.bottom - this.ayis_w;

        this.g0 = this.svg.append("g")
            .attr("transform", "translate(" + (this.margin.left + this.axis_w) + "," + (this.margin.top + this.ayis_w/2) + ")");

        this.g3 = this.svg.append("g")
            .attr("transform", "translate(" + (this.margin.left + this.axis_w) + "," + (this.margin.top + this.ayis_w/2) + ")");

        this.g1 = this.svg.append("g")
            .attr("class", "y axis")
            .attr("transform", "translate(" + this.axis_w + "," + (this.margin.top + this.ayis_w/2) + ")")
            .attr("width",  "95%")
            .attr("height", "100%");

        this.g4 = this.svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(" + this.axis_w + "," + (this.height + this.margin.top + this.ayis_w/2) + ")")
            .attr("width",  "95%")
            .attr("height", "100%");

        this.g2 = this.svg.append("g")
        .attr("transform", "translate(" + (this.width + this.axis_w) + "," + (this.height + this.margin.bottom) + ")")
        //.attr("transform", "translate(" + (this.width + this.axis_w) + "," + (this.height - this.margin.bottom) + ") rotate(-90)")
            .attr("width",  "95%")
            .attr("height", "100%");

        this.g5 = this.svg.append("g")
        .attr("transform", "translate(" + (this.axis_w + 12) + "," + (this.ayis_w + this.margin.bottom + this.margin.top) + ") rotate(-90)")
            .attr("width",  "95%")
            .attr("height", "100%");

        // set the ranges
        this.buildObject(this.x_d, this.y_d, reference);
    };
  
    buildObject(x_d, y_d, ref) {
        var x = d3.scaleLinear().range([0, this.width])
        .domain([0, this.x_d]);


        var y = d3.scaleLinear().range([this.height, 0]);
        //y.domain(d3.extent(this.lineData, function(d, i) { return Math.min(d); }));
        y.domain([0,this.y_d]);
        //this.buildTextLabel(this.level);
        var p = d3.scaleLinear().range(['beige', 'red']);
        p.domain([50,150]);

        this.buildLines(x, y, p);
        this.buildAxis(x, y);
        this.buildTextLabelX(x, y);
        this.buildTextLabelY(x, y);
        if (ref == true) this.buildReference(x, y);
    };
  
    buildLines(x, y, p) {
        this.g0.selectAll("circle")
          .data(this.lineData)
          .attr("cx", function (d) { return x(d.x); } )
          .attr("cy", function (d) { return y(d.y); } )
          .attr("r", 1.5)
          .style("fill", function (d) { return p(d.p); })
          .enter()
          .append("circle")
            .attr("cx", function (d) { return x(d.x); } )
            .attr("cy", function (d) { return y(d.y); } )
            .attr("r", 1.5)
            .style("fill", function (d) { return p(d.p); })
          .exit()
            .remove();

        this.valueline = d3.line()
                .x(function(d, i) { return x(i); })
                .y(function(d) { return y(d);  })
                .curve(d3.curveMonotoneX);

        var colors = this.colours;

        this.g0.selectAll("path")
            .data(this.lineData)
            .attr("class", "line")
            .attr("style", function(d, i) { return "stroke: " + colors[i];})
            .attr("d", this.valueline)
            .enter().append("path")
                .attr("class", "line")  
                .attr("d", this.valueline)
            .exit()
                .remove();
    };
  
    buildReference(x, y) {
        var referenceline = d3.line()
                .x(function(d) { return x(d.x); })
                .y(function(d) { return y(d.y);  })
                .curve(d3.curveMonotoneX);

        var colors = this.colours;

        this.g3.selectAll("path")
            .data(this.referenceData)
            .attr("class", "line")
            .attr("style", function(d, i) { return "stroke: " + colors[i];})
            .attr("d", referenceline)
            .enter().append("path")
                .attr("class", "line")
                .attr("style", function(d, i) { return "stroke: " + colors[i];})
                .attr("d", referenceline)
            .exit()
                .remove();
    };
  
    buildAxis(x, y) {
        this.yAxis_woy = d3.axisLeft(y).ticks(3);
        this.g1.call(this.yAxis_woy);
        this.xAxis_woy = d3.axisBottom(x).ticks(3);
        this.g4.call(this.xAxis_woy); 
    };
  
    buildTextLabelX() {
        this.g2.selectAll("text")
        .data([0])
        .text(this.x_ax)
        .enter()
            .append("text")
            .text(this.x_ax)
            .attr("x", 0)
            .attr("y", 0)
            .attr("font-family", "carbonFont")
            .attr("font-size", this.height*0.05 + "px")
            .attr("text-anchor", "middle")
            .attr("fill", "#ffffff")
        .exit()
            .remove();
    };
  
    buildTextLabelY() {
        this.g5.selectAll("text")
        .data([0])
        .text(this.y_ax)
        .enter()
            .append("text")
            .text(this.y_ax)
            .attr("x", 0)
            .attr("y", 0)
            .attr("font-family", "carbonFont")
            .attr("font-size", this.height*0.05 + "px")
            .attr("text-anchor", "middle")
            .attr("fill", "#ffffff")
        .exit()
            .remove();
    };

    updateLevel(values) {
        var found = false;
        for (var i = 0 ; i < this.lineData.length; i++) {
            if (this.lineData[i].x == values.x) {
                found = true;
                this.lineData[i].y = values.y;
            }
        }
        if (found == false) {
            this.lineData.push(values);
        }
        this.buildObject();
    };

    updateReference(max) {
        var x = d3.scaleLinear().range([0, this.width])
        .domain([0, this.x_d]);


        var y = d3.scaleLinear().range([this.height, 0]);
        //y.domain(d3.extent(this.lineData, function(d, i) { return Math.min(d); }));
        y.domain([0,this.y_d]);
        this.referenceData[0][1].y = this.referenceData[0][1].x*max;
        this.buildReference(x, y);
    }

    updateLabel(data) {
        this.label = data;
        this.buildTextLabel();
    };

    updateColors(colours) {
        this.colours = colours;
    };

    updateData(data) {
        this.lineData = data;
    };
}
  
//Usage
var medlineData = [[],[],[],[]];
var medcharts = [];

var resetMedCharts = function(type)
{
    medlineData = [
        [[0]],
        [[0],[],[]],
        [[0]],
        [[0]],
    ];
    for (var i = 0; i < 4; i++) {
        medcharts[i].updateData(medlineData[i]);
    }
    medcharts[0].updateLabel("INTERRUPT TIME");
    medcharts[1].updateLabel("FLOW RATE");
    medcharts[2].updateLabel("FLOW TARGET");
    medcharts[3].updateLabel("RPM VS TARGET");

    medcharts[0].updateColors(["#ffa600"]);
    medcharts[1].updateColors(["#ffa600", "#ff2100", "#0083ff"]);
    medcharts[2].updateColors(["#ffa600"]);
    medcharts[3].updateColors(["#ffa600"]);
}

medcharts[0] = new lineChartMedium("device-medlinechart-1", medlineData[0], [2300,400000], "INTERRUPT", "STEPS", ["#ffa600", "#ff2100", "#0083ff"], false);
medcharts[1] = new lineChartMedium("device-medlinechart-2", medlineData[1], [2300,8000], "FLOW", "STEPS", ["#ffa600"], false);
medcharts[2] = new lineChartMedium("device-medlinechart-3", medlineData[2], [240,260], "PWM", "RPM", ["#ffa600", "#ff6361", "#bc5090"], false);
medcharts[3] = new lineChartMedium("device-medlinechart-4", medlineData[3], [300,100000], "TARGET FLOW", "RPM", ["#ffa600", "#ff6361", "#bc5090"], true);

