#include "wx-deviceconfig.h"

#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"

extern "C" {
#include "config.h"
#include "plat-midi.h"
void saveconfig(char *);
void resetpchard();
int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam);
device_t *config_device;
int confirm();
}
#define IDC_CONFIG_BASE 1000

int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) {
        switch (message) {
        case WX_INITDIALOG: {
                int id = IDC_CONFIG_BASE;
                device_config_t *config = config_device->config;
                int c;

                while (config->type != -1) {
                        device_config_selection_t *selection = config->selection;
                        void *h = 0;
                        int val_int;
                        int num;
                        char s[100];

                        switch (config->type) {
                        case CONFIG_BINARY:
                                h = wx_getdlgitem(hdlg, id);
                                val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int);

                                wx_sendmessage(h, WX_BM_SETCHECK, val_int, 0);

                                id++;
                                break;

                        case CONFIG_SELECTION:
                                h = wx_getdlgitem(hdlg, id + 1);
                                val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int);

                                c = 0;
                                while (selection->description[0]) {
                                        wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)selection->description);
                                        if (val_int == selection->value)
                                                wx_sendmessage(h, WX_CB_SETCURSEL, c, 0);
                                        selection++;
                                        c++;
                                }

                                id += 2;
                                break;

                        case CONFIG_MIDI:
                                num = midi_get_num_devs();
                                if (num > 0) {
                                        h = wx_getdlgitem(hdlg, id + 1);
                                        val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int);

                                        for (c = 0; c < num; c++) {
                                                midi_get_dev_name(c, s);
                                                wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s);
                                                if (val_int == c)
                                                        wx_sendmessage(h, WX_CB_SETCURSEL, c, 0);
                                        }
                                        id += 2;
                                }
                                break;
                        }
                        config++;
                }
        }
                return TRUE;

        case WX_COMMAND:
                switch (wParam) {
                case wxID_OK: {
                        int id = IDC_CONFIG_BASE;
                        device_config_t *config = config_device->config;
                        int c;
                        int changed = 0;

                        while (config->type != -1) {
                                device_config_selection_t *selection = config->selection;
                                void *h = 0;
                                int val_int;

                                switch (config->type) {
                                case CONFIG_BINARY:
                                        h = wx_getdlgitem(hdlg, id);
                                        val_int = config_get_int(CFG_MACHINE, config_device->name, config->name,
                                                                 config->default_int);

                                        if (val_int != wx_sendmessage(h, WX_BM_GETCHECK, 0, 0))
                                                changed = 1;

                                        id++;
                                        break;

                                case CONFIG_SELECTION:
                                        h = wx_getdlgitem(hdlg, id + 1);
                                        val_int = config_get_int(CFG_MACHINE, config_device->name, config->name,
                                                                 config->default_int);

                                        c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0);

                                        for (; c > 0; c--)
                                                selection++;

                                        if (val_int != selection->value)
                                                changed = 1;

                                        id += 2;
                                        break;

                                case CONFIG_MIDI:
                                        if (midi_get_num_devs() > 0) {
                                                h = wx_getdlgitem(hdlg, id + 1);
                                                val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int);

                                                c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0);

                                                if (val_int != c)
                                                        changed = 1;
                                                id += 2;
                                        }
                                        break;
                                }
                                config++;
                        }

                        if (!changed) {
                                wx_enddialog(hdlg, 0);
                                return TRUE;
                        }

                        if (has_been_inited && !confirm()) {
                                wx_enddialog(hdlg, 0);
                                return TRUE;
                        }

                        id = IDC_CONFIG_BASE;
                        config = config_device->config;

                        while (config->type != -1) {
                                device_config_selection_t *selection = config->selection;
                                void *h = 0;

                                switch (config->type) {
                                case CONFIG_BINARY:
                                        h = wx_getdlgitem(hdlg, id);
                                        config_set_int(CFG_MACHINE, config_device->name, config->name,
                                                       wx_sendmessage(h, WX_BM_GETCHECK, 0, 0));

                                        id++;
                                        break;

                                case CONFIG_SELECTION:
                                        h = wx_getdlgitem(hdlg, id + 1);
                                        c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0);
                                        for (; c > 0; c--)
                                                selection++;
                                        config_set_int(CFG_MACHINE, config_device->name, config->name, selection->value);

                                        id += 2;
                                        break;

                                case CONFIG_MIDI:
                                        if (midi_get_num_devs() > 0) {
                                                h = wx_getdlgitem(hdlg, id + 1);
                                                c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0);
                                                config_set_int(CFG_MACHINE, NULL, config->name, c);

                                                id += 2;
                                        }
                                        break;
                                }
                                config++;
                        }

                        if (has_been_inited) {
                                saveconfig(NULL);
                                resetpchard();
                        }

                        wx_enddialog(hdlg, 0);
                        return TRUE;
                }
                case wxID_CANCEL:
                        wx_enddialog(hdlg, 0);
                        return TRUE;
                }
                break;
        }
        return FALSE;
}

void deviceconfig_open(void *hwnd, device_t *device) {
        char s[257];
        config_device = device;

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

        device_config_t *config = device->config;

        dialog.SetTitle("Device Configuration");

        wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0);
        root->SetFlexibleDirection(wxBOTH);
        root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
        dialog.SetSizer(root);

        wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 2, 0, 0);
        sizer->SetFlexibleDirection(wxBOTH);
        sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
        sizer->AddGrowableCol(1);
        root->Add(sizer, 1, wxEXPAND, 5);

        int id = IDC_CONFIG_BASE;

        while (config->type != -1) {
                switch (config->type) {
                case CONFIG_BINARY:
                        sizer->Add(0, 0, 1, wxEXPAND, 5);
                        sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL, 5);
                        break;

                case CONFIG_SELECTION:
                case CONFIG_MIDI: {
                        if (config->type == CONFIG_MIDI && midi_get_num_devs() == 0)
                                break;
                        sprintf(s, "%s:", config->description);
                        sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
                        wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL);
                        sizer->Add(comboSizer, 1, wxEXPAND, 5);
                        wxComboBox *cb = new wxComboBox(&dialog, id++);
                        cb->SetEditable(false);
                        comboSizer->Add(cb, 1, wxALL, 5);
                        break;
                }
                }

                config++;
        }

        wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL);
        root->Add(okCancelSizer, 1, wxEXPAND, 5);

        okCancelSizer->Add(0, 0, 1, wxEXPAND, 5);
        okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5);
        okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5);

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