#include "wx-utils.h"
#include <wx/wxprec.h>

#include "wx-dialogbox.h"

#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include <wx/xrc/xmlres.h>
#include <wx/spinctrl.h>

#include "wx-glslp-parser.h"
#include "wx-shaderconfig.h"

extern "C"
{
#include "config.h"
void saveconfig(char *);
void resetpchard();
int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam);
void write_shader_config(glslp_t *shader);
struct glslp_t *current_glsl;
int confirm();
}
#define IDC_CONFIG_BASE 1000
#define ID_APPLY 500
#define ID_RESET 501
extern int renderer_doreset;

static int shaderconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) {
	int i;
	switch (message) {
	case WX_INITDIALOG: {
		return TRUE;
	}
	case WX_COMMAND:
		switch (wParam) {
		case ID_APPLY: {
			for (i = 0; i < current_glsl->num_parameters; ++i) {
				struct parameter *p = &current_glsl->parameters[i];
				wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i);
				p->value = (float)h->GetValue();
			}
			write_shader_config(current_glsl);
			renderer_doreset = 1;
			return TRUE;
		}
		case wxID_OK: {
			for (i = 0; i < current_glsl->num_parameters; ++i) {
				struct parameter *p = &current_glsl->parameters[i];
				wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i);
				p->value = (float)h->GetValue();
			}
			write_shader_config(current_glsl);
			renderer_doreset = 1;
			wx_enddialog(hdlg, 0);
			return TRUE;
		}
		case wxID_CANCEL:wx_enddialog(hdlg, 0);
			return TRUE;
		case ID_RESET: {
			for (i = 0; i < current_glsl->num_parameters; ++i) {
				struct parameter *p = &current_glsl->parameters[i];
				wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i);
				h->SetValue(p->default_value);
			}
			return TRUE;
		}
		}
	}
	return TRUE;
}

void shaderconfig_open(void *hwnd, struct glslp_t *glsl) {
	int i;
	current_glsl = glsl;

	PCemDialogBox dialog((wxWindow *)hwnd, shaderconfig_dlgproc);
//      dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);

	dialog.SetTitle("Shader Configuration");

	wxBoxSizer *root = new wxBoxSizer(wxVERTICAL);
	dialog.SetSizer(root);

	wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
	root->Add(sizer, 0, wxALL, 5);

	wxPanel *panel = new wxPanel(&dialog, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_SUNKEN);
	sizer->Add(panel);

	wxBoxSizer *panelSizer = new wxBoxSizer(wxVERTICAL);
	panel->SetSizer(panelSizer);

	wxScrolledWindow *win = new wxScrolledWindow(panel, wxID_ANY, wxDefaultPosition, wxSize(300, 350), wxHSCROLL | wxVSCROLL);
	win->SetScrollRate(5, 5);
	panelSizer->Add(win, 1, wxEXPAND | wxALL, 5);

	wxBoxSizer *winSizer = new wxBoxSizer(wxVERTICAL);
	win->SetSizer(winSizer);

	if (glsl->num_parameters > 0) {
		wxPanel *scrollPanel = new wxPanel(win);
		winSizer->Add(scrollPanel);

		wxBoxSizer *scollPanelSizer = new wxBoxSizer(wxVERTICAL);
		scrollPanel->SetSizer(scollPanelSizer);

		for (i = 0; i < glsl->num_parameters; ++i) {
			struct parameter *p = &glsl->parameters[i];
			scollPanelSizer->Add(new wxStaticText(scrollPanel, wxID_ANY, p->description), 0, wxALL);
			wxSpinCtrlDouble *spin = new wxSpinCtrlDouble(scrollPanel, IDC_CONFIG_BASE + i);
			spin->SetRange(p->min, p->max);
			spin->SetIncrement(p->step);
			spin->SetValue(p->value);
			spin->SetDigits(2);

			scollPanelSizer->Add(spin, 0, wxALL);
		}
	} else
		winSizer->Add(new wxStaticText(win, wxID_ANY, "No configuration available."), 0, wxALL);

	wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);

	buttonSizer->Add(new wxButton(&dialog, ID_APPLY, "Apply"));
	buttonSizer->Add(new wxButton(&dialog, wxID_OK));
	buttonSizer->Add(new wxButton(&dialog, wxID_CANCEL));
	buttonSizer->Add(new wxButton(&dialog, ID_RESET, "Reset"));

	sizer->Add(buttonSizer);

	dialog.Fit();
	dialog.OnInit();
	dialog.ShowModal();
	dialog.Destroy();
}
