#ifndef _MATLAB_DEBUGGER_H_
#define _MATLAB_DEBUGGER_H_

#define ANT_TWEAK_BAR_ACCESS

#include <string>

#include "headers\global_headers.h"
#include "headers\math_headers.h"
#ifdef ANT_TWEAK_BAR_ACCESS
#include "anttweakbar_wrapper.h"
#endif

#ifdef ENABLE_MATLAB_DEBUGGING
#include "engine.h"
#endif

typedef enum 
{
	PLOT_TYPE_PLOT,
	PLOT_TYPE_SEMILOG_X,
	PLOT_TYPE_SEMILOG_Y,
	PLOT_TYPE_LOGLOG

} PlotType;

#ifdef ANT_TWEAK_BAR_ACCESS
// forward declaration
class AntTweakBarWrapper;
#endif

class MatlabDebugger
{
#ifdef ENABLE_MATLAB_DEBUGGING
#ifdef ANT_TWEAK_BAR_ACCESS
	friend class AntTweakBarWrapper;
#endif
public:
	MatlabDebugger();
	~MatlabDebugger();

	void Init();
	void ResetCurrent();
	void Reset();
	void Export();

	void SaveCurrentData(const char* filename);
	void SaveCurrentFigure(const char* filename);

	void SendVector(VectorX &x, char* name, int size);
	void SendSparseMatrixUsingTriplets(std::vector<SparseMatrixTriplet> &triplets, char* name, int d1, int d2);

	void SendPositionIteration(VectorX &x, int size, double iteration);
	void SendPositionIterationTime(VectorX &x, int size, double iteration, double time);
	void SendEnergyIteration(double energy, double iteration);
	void SetLastMatrixToLog(char* name, double iteration);
	void SetLastVectorToLog(char* name, double iteration);

	void PlotDistToSolution();
	void AddNewPlotData();
	void Plot();
	void PlotAll();
	void PlotResidue();

	// specific for this program
	// for matlab solving linear system
	void MatlabSolveLinearSystem(VectorX& x, char* vector_name, char* matrix_name);

	// for matlab sdp solver
	void MatlabResetSDPMosek();
	// yalmip
	void MatlabInitSDPMosekYalmip();
	void MatlabSolveSDPMosekYalmip(int dim, VectorX& x, std::vector<SparseMatrixTriplet>& g_triplets, unsigned int g_dim1, unsigned int g_dim2, VectorX& vectorized_ExR, VectorX& consVIndices, VectorX& exV, ScalarType k = 0, bool has_max_it = false);
	// epigraph
	void MatlabInitSDPMosekEpigraph();
	void MatlabSolveSDPMosekEpigraph(VectorX& x, std::vector<SparseMatrixTriplet>& g_triplets, unsigned int g_dim1, unsigned int g_dim2, VectorX& vectorized_ExR, VectorX& consVIndices, VectorX& exV, ScalarType k = 0);

	void MatlabSetConvergedSolution(VectorX& x_star);
protected:

	// settings for debugger
	bool m_enable;
	PlotType m_plot_type;

	// engine related 
	Engine* m_engine;

	mxArray *m_double1x1_array;
	mxArray *m_triplet_array;
	mxArray *m_vector_array;
	double *m_double1x1;
	double *m_triplet;
	double *m_vector;

	// specific for this program
	// mosek sdp
	int m_mosek_number_of_iterations;
	bool m_yalmip_initialzied;

	VectorX m_x_star;

	char m_legend_string[255];
	std::string m_plot_style[5];
	bool m_plot_x_axis_plot_iterations; // true = iterations, false = time 
	int m_plot_index;
#endif
};

#endif