#ifndef PLOTERRTIME_H
#define PLOTERRTIME_H

#include <KLib/misc/gnuplot/Gnuplot.h>
#include <KLib/misc/gnuplot/GnuplotPlot.h>
#include <KLib/misc/gnuplot/GnuplotPlotElementLines.h>

#include <Indoor/data/Timestamp.h>

/**
 * plot error behaviour over time
 */
class PlotErrTime {

private:

	K::Gnuplot gp;
	K::GnuplotPlot gpplot;
	K::GnuplotPlotElementLines lineErr[8];
	K::GnuplotPlotElementLines lineB;
	K::GnuplotPlotElementLines lineC;
	std::string codeFile;

public:

	/** empty ctor */
	PlotErrTime() {

	}

	/** ctor */
	PlotErrTime(const std::string& xLabel, const std::string& yLabel, const std::string& y2Label) {

		gpplot.getAxisX().setLabel(xLabel);
		gpplot.getAxisY().setLabel(yLabel);
		gpplot.getAxisY2().setLabel(y2Label);

		gpplot.add(&lineErr[0]);	lineErr[0].getStroke().setWidth(1.5);	lineErr[0].getStroke().getColor().setHexStr("#000000");
		gpplot.add(&lineErr[1]);	lineErr[1].getStroke().setWidth(1.5);	lineErr[1].getStroke().getColor().setHexStr("#FF0000");
		gpplot.add(&lineErr[2]);	lineErr[2].getStroke().setWidth(1.5);	lineErr[2].getStroke().getColor().setHexStr("#00FF00");
		gpplot.add(&lineErr[3]);	lineErr[3].getStroke().setWidth(1.5);	lineErr[3].getStroke().getColor().setHexStr("#0000FF");

		gpplot.add(&lineB);			lineB.getStroke().setWidth(1);			lineB.getStroke().getColor().setHexStr("#0000ff");
		gpplot.add(&lineC);
		gpplot.setGrid(true);

	}

	void setColor(const int idx, const std::string& color) {
		lineErr[idx].getStroke().getColor().setHexStr(color);
	}

	void setLabel(const int idx, const std::string& label) {
		lineErr[idx].setTitle(label);
	}

	void setWidth(const int idx, const float w) {
		lineErr[idx].getStroke().setWidth(w);
	}

	K::GnuplotStroke& getStroke(const int idx) {
		return lineErr[idx].getStroke();
	}

	K::Gnuplot& getGP() {
		return gp;
	}

	/** write the gnuplot commands to file for later re-use */
	void writePlotToFile(const std::string& file) {
		this->gp.writePlotToFile(file);
	}

	void clear() {
		for (int i = 0; i < 8; ++i) {lineErr[i].clear();}
		lineB.clear();
		lineC.clear();
	}

	void writeCodeTo(const std::string& file) {
		this->codeFile = file;
	}

	void writeEpsTex(const std::string file, K::GnuplotSize size = K::GnuplotSize(8.5, 5.1)) {
		gp.setTerminal("epslatex", size);
		gp.setOutput(file);
		gp << "set key\n";
		gp << "set rmargin 0.2\n";
		gp << "set tmargin 0.2\n";
		gp << "set bmargin 1.2\n";
	}

	K::GnuplotPlot& getPlot() {
		return gpplot;
	}

	/** add the give error value to the idx-th error line */
	void addErr(const Timestamp t, const float err, const int idx = 0) {
		K::GnuplotPoint2 pt(t.sec(), err);
		lineErr[idx].add(pt);
	}


	void addB(const Timestamp t, const float something) {
		K::GnuplotPoint2 pt(t.sec(), something);
		lineB.add(pt);
	}

	void addC(const Timestamp t, const float something) {
		K::GnuplotPoint2 pt(t.sec(), something);
		lineC.add(pt);
	}

	void plot() {
		gp.draw(gpplot);
		if (codeFile != "") {
			std::ofstream out(codeFile);
			out << gp.getBuffer();
			out.close();
		}
		gp.flush();
	}

};

#endif // PLOTERRTIME_H
