#if defined(WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#include "getopt.h"
#endif

#include <wx/wxprec.h>
#include <wx/wx.h>
#include <wx/textctrl.h>
#include <wx/spinctrl.h>
#include <wx/tglbtn.h>
#include <wx/slider.h>
#include <iostream>
#include <wx/brush.h>
#include <sstream>
#include <string.h>
#include <wx/listbox.h>
#include <wx/dynarray.h>
#include <wx/dcclient.h>
#include <wx/gauge.h>
#include <wx/spinctrl.h>

//#include "monicone.xpm"

//#if defined(WIN32) && !defined(__CYGWIN__)
//#include <windows.h>
//extern "C"
//{
//#include "getopt.h"
//}
//#endif

#include "main.h"
#include "TestSlaveGui.h"
extern "C"
{
#include "canfestival.h"
#include "ObjDict.h"
}
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif


wxTextCtrl *textLog;
int node_id_ext;
int to_start = 0;
int openInput = 0;
int openOutput = 0;

MyFrame *frame;
#define MAXLENGTH_BUSNAME 32
#define MAXLENGTH_BAUDRATE 8
char _busname[MAXLENGTH_BUSNAME] = "vcan0";
char _baudrate[MAXLENGTH_BAUDRATE] = "500K";
s_BOARD SlaveBoard = { _busname, _baudrate };

#define MAXLENGTH_LIBPATH 1024
char LibraryPath[MAXLENGTH_LIBPATH] = "libcanfestival_can_virtual.so";

#if defined(WIN32)
#define LIB_EXTENT wxT("*.dll")
#else
#define LIB_EXTENT wxT("*.so")
#endif

// Declare some IDs. These are arbitrary.
const int BOOKCTRL = 100;
const int FILE_QUIT = wxID_EXIT;
const int HELP_ABOUT = wxID_ABOUT;
const int ADD = 105;
const int REMOVE = 108;
const int QUIT = 109;
const int FREQBOX = 110;
const int START = 112;
const int TEXTBOX1 = 113;
const int STOP = 114;
const int LOAD = 115;
const int INBT1 = 118;
const int INBT2 = 119;
const int INBT3 = 120;
const int INBT4 = 121;
const int INBT5 = 122;
const int INBT6 = 123;
const int INBT7 = 124;
const int INBT8 = 125;
const int INS1 = 126;
const int INS2 = 127;
const int INS3 = 128;
const int INS4 = 129;
const int INS5 = 135;
const int INS6 = 136;
const int INS7 = 137;
const int INS8 = 138;
const int TIMER_ID = 130;
const int INST1 = 131;
const int INST2 = 132;
const int INST3 = 133;
const int INST4 = 134;
const int INST5 = 135;
const int INST6 = 136;
const int INST7 = 137;
const int INST8 = 138;

// Attach the event handlers. Put this after MyFrame declaration.
BEGIN_EVENT_TABLE (MyFrame, wxFrame)
EVT_BUTTON (STOP, MyFrame::OnStop)
EVT_BUTTON (LOAD, MyFrame::OnLoad)
EVT_BUTTON (START, MyFrame::OnStart)
EVT_TOGGLEBUTTON (INBT1, MyFrame::OnInbt1)
EVT_TOGGLEBUTTON (INBT2, MyFrame::OnInbt2)
EVT_TOGGLEBUTTON (INBT3, MyFrame::OnInbt3)
EVT_TOGGLEBUTTON (INBT4, MyFrame::OnInbt4)
EVT_TOGGLEBUTTON (INBT5, MyFrame::OnInbt5)
EVT_TOGGLEBUTTON (INBT6, MyFrame::OnInbt6)
EVT_TOGGLEBUTTON (INBT7, MyFrame::OnInbt7)
EVT_TOGGLEBUTTON (INBT8, MyFrame::OnInbt8)
EVT_COMMAND_SCROLL (INS1, MyFrame::OnIns1)
EVT_COMMAND_SCROLL (INS2, MyFrame::OnIns2)
EVT_COMMAND_SCROLL (INS3, MyFrame::OnIns3)
EVT_COMMAND_SCROLL (INS4, MyFrame::OnIns4)
EVT_COMMAND_SCROLL (INS5, MyFrame::OnIns5)
EVT_COMMAND_SCROLL (INS6, MyFrame::OnIns6)
EVT_COMMAND_SCROLL (INS7, MyFrame::OnIns7)
EVT_COMMAND_SCROLL (INS8, MyFrame::OnIns8)
EVT_SPINCTRL (INST1, MyFrame::OnInst1)
EVT_SPINCTRL (INST2, MyFrame::OnInst2)
EVT_SPINCTRL (INST3, MyFrame::OnInst3)
EVT_SPINCTRL (INST4, MyFrame::OnInst4)
EVT_SPINCTRL (INST5, MyFrame::OnInst5)
EVT_SPINCTRL (INST6, MyFrame::OnInst6)
EVT_SPINCTRL (INST7, MyFrame::OnInst7)
EVT_SPINCTRL (INST8, MyFrame::OnInst8)
EVT_LISTBOX (FREQBOX, MyFrame::OnFreqBoxClick)
EVT_MENU (FILE_QUIT, MyFrame::OnQuit)
EVT_BUTTON (QUIT, MyFrame::OnQuit) EVT_MENU (HELP_ABOUT, MyFrame::OnAbout)
EVT_TIMER (TIMER_ID, MyFrame::OnTimer)
END_EVENT_TABLE ()IMPLEMENT_APP_NO_MAIN (MyApp);
IMPLEMENT_WX_THEME_SUPPORT;

     void
     help ()
{
  printf ("**************************************************************\n");
  printf ("*  DS-401 Slave GUI                                          *\n");
  printf ("*                                                            *\n");
  printf ("*   Usage:                                                   *\n");
  printf ("*   ./DS401_Slave_Gui [OPTIONS]                              *\n");
  printf ("*                                                            *\n");
  printf ("*   OPTIONS:                                                 *\n");
  printf
    ("*     -l : Can library [\"libcanfestival_can_virtual.so\"]     *\n");
  printf ("*                                                            *\n");
  printf ("*    Slave:                                                  *\n");
  printf ("*     -i : Node id format [0x01 , 0x7F]                      *\n");
  printf ("*                                                            *\n");
  printf ("*    CAN bus:                                                *\n");
  printf
    ("*     -b : bus name [\"1\"]                                    *\n");
  printf ("*     -B : 1M,500K,250K,125K,100K,50K,20K,10K                *\n");
  printf ("*                                                            *\n");
  printf ("**************************************************************\n");
}


int
main (int argc, char **argv)
{

  int c;
  extern char *optarg;
  char *snodeid;
  while ((c = getopt (argc, argv, "-b:B:l:i:sIO")) != EOF)
    {
      switch (c)
	{
	case 'b':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  SlaveBoard.busname = optarg;
	  break;
	case 'B':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  SlaveBoard.baudrate = optarg;
	  break;
	case 'l':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  strncpy (LibraryPath, optarg, MAXLENGTH_LIBPATH);
	  break;
	case 'i':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  snodeid = optarg;
	  sscanf (snodeid, "%x", &node_id_ext);
	  break;
	case 's':
	  to_start = 1;
	  break;
	case 'I':
	  openInput = 1;
	  break;
	case 'O':
	  openOutput = 1;
	  break;
	default:
	  help ();
	  exit (1);
	}
    }
  wxEntry (argc, argv);
}


bool
MyApp::OnInit ()
{
  frame = new MyFrame (wxString::Format(wxT("CanOpen virtual DS-401 - Id : %d"),node_id_ext));
  frame->Show (true);
  if(openInput) frame->book->SetSelection(2);
  else if(openOutput) frame->book->SetSelection(3);
  return true;
}

MyFrame::MyFrame (const wxString & title):wxFrame (NULL, wxID_ANY, title, wxDefaultPosition, wxSize (800, 740),
	 wxDEFAULT_FRAME_STYLE, wxT ("frame")), m_timer (this,
							 TIMER_ID)
{
  wxMenu *
    fileMenu = new wxMenu;
  wxMenu *
    helpMenu = new wxMenu;
  wxPanel *
    panel;
  wxButton *
    quit;
  wxButton *
    load;
  wxBoxSizer *
    mysizer;
  wxBoxSizer *
    mysssizer;
  wxBoxSizer *
    myhsizer;
  wxBoxSizer *
    mybsizer;
  wxBoxSizer *
    myentrysizer;
  wxListBox *
    freqlist;
  wxStaticBox *
    namebox;
  wxStaticBox *
    freqbox;

// SetIcon(wxICON(monicone));
  SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNFACE));
  helpMenu->Append (HELP_ABOUT, _T ("&About...\tF1"),
		    _T ("Show about dialog"));
  fileMenu->Append (FILE_QUIT, _T ("E&xit\tAlt-X"), _T ("Quit this program"));
  wxMenuBar *
    menuBar = new wxMenuBar ();
  menuBar->Append (fileMenu, _T ("&File"));
  menuBar->Append (helpMenu, _T ("&Help"));
  SetMenuBar (menuBar);
  CreateStatusBar (2);
  SetStatusText (_T ("DS-401 GUI."), 0);
  SetStatusText (_T ("Welcome."), 1);

  book = new wxNotebook (this, BOOKCTRL);

  panel = new wxPanel (book);
  book->AddPage (panel, _T ("Configuration"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  wxString
    choices[] = {
    _T ("10K"), _T ("20K"), _T ("50K"), _T ("100K"),
    _T ("125K"), _T ("250K"), _T ("500K"), _T ("1M")
  };

  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY, _T ("Bus driver")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 5);
  load = new wxButton (panel, LOAD, _T ("Load can driver"));
  myhsizer->Add (load, 0, wxLEFT, 5);
  drivername =
    new wxTextCtrl (panel, wxID_ANY,
		    wxString ((const char *) LibraryPath, wxConvLocal));
  myhsizer->Add (drivername, 1, wxEXPAND | wxALL, 5);
  myentrysizer = new wxBoxSizer (wxHORIZONTAL);
  mysizer->Add (myentrysizer, 0, wxEXPAND | wxALL, 5);
  myhsizer =
    new wxStaticBoxSizer (new wxStaticBox (panel, wxID_ANY, _T ("Bus name")),
			  wxHORIZONTAL);
  myentrysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 5);
  busname =
    new wxTextCtrl (panel, wxID_ANY,
		    wxString ((const char *) SlaveBoard.busname,
			      wxConvLocal));
  myhsizer->Add (busname, 0, wxLEFT, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Node ID (Decimal)")), wxHORIZONTAL);
  myentrysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 5);
  node_id =
    new wxSpinCtrl (panel, wxID_ANY, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, 1, 127, node_id_ext,
		    _T ("wxSpinCtrl"));
  myhsizer->Add (node_id, 0, wxRIGHT, 5);
  myhsizer =
    new wxStaticBoxSizer (new wxStaticBox (panel, wxID_ANY, _T ("Baudrate")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  freqlist =
    new wxListBox (panel, FREQBOX, wxDefaultPosition, wxDefaultSize, 8,
		   choices, wxLB_SINGLE | wxLB_HSCROLL);
  myhsizer->Add (freqlist, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);


  panel = new wxPanel (book);
  book->AddPage (panel, wxT ("Inputs"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Read Inputs UNSIGNED8")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 30);
  inbt1 = new wxToggleButton (panel, INBT1, wxT ("1"));
  inbt2 = new wxToggleButton (panel, INBT2, wxT ("2"));
  inbt3 = new wxToggleButton (panel, INBT3, wxT ("3"));
  inbt4 = new wxToggleButton (panel, INBT4, wxT ("4"));
  inbt5 = new wxToggleButton (panel, INBT5, wxT ("5"));
  inbt6 = new wxToggleButton (panel, INBT6, wxT ("6"));
  inbt7 = new wxToggleButton (panel, INBT7, wxT ("7"));
  inbt8 = new wxToggleButton (panel, INBT8, wxT ("8"));
  myhsizer->Add (inbt1, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt2, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt3, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt4, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt5, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt6, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt7, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt8, wxEXPAND | wxALL, 0, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Analogue Inputs INTEGER16")),
			  wxVERTICAL);
  mysizer->Add (myhsizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 30);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, 0, wxEXPAND | wxALL, 0);
  inst1 =
    new wxSpinCtrl (panel, INST1, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst2 =
    new wxSpinCtrl (panel, INST2, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst3 =
    new wxSpinCtrl (panel, INST3, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst4 =
    new wxSpinCtrl (panel, INST4, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst5 =
    new wxSpinCtrl (panel, INST5, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst6 =
    new wxSpinCtrl (panel, INST6, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst7 =
    new wxSpinCtrl (panel, INST7, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst8 =
    new wxSpinCtrl (panel, INST8, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  mysssizer->Add (inst1, wxALL, 0, 5);
  mysssizer->Add (inst2, wxALL, 0, 5);
  mysssizer->Add (inst3, wxALL, 0, 5);
  mysssizer->Add (inst4, wxALL, 0, 5);
  mysssizer->Add (inst5, wxALL, 0, 5);
  mysssizer->Add (inst6, wxALL, 0, 5);
  mysssizer->Add (inst7, wxALL, 0, 5);
  mysssizer->Add (inst8, wxALL, 0, 5);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 0);
  ins1 =
    new wxSlider (panel, INS1, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins2 =
    new wxSlider (panel, INS2, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins3 =
    new wxSlider (panel, INS3, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins4 =
    new wxSlider (panel, INS4, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins5 =
    new wxSlider (panel, INS5, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins6 =
    new wxSlider (panel, INS6, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins7 =
    new wxSlider (panel, INS7, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins8 =
    new wxSlider (panel, INS8, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  mysssizer->Add (ins1, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins2, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins3, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins4, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins5, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins6, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins7, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins8, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);

  panel = new wxPanel (book);
  book->AddPage (panel, wxT ("Outputs"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Write Outputs UNSIGNED8")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 30);
  outbt1 = new wxToggleButton (panel, wxID_ANY, wxT ("1"));
  outbt2 = new wxToggleButton (panel, wxID_ANY, wxT ("2"));
  outbt3 = new wxToggleButton (panel, wxID_ANY, wxT ("3"));
  outbt4 = new wxToggleButton (panel, wxID_ANY, wxT ("4"));
  outbt5 = new wxToggleButton (panel, wxID_ANY, wxT ("5"));
  outbt6 = new wxToggleButton (panel, wxID_ANY, wxT ("6"));
  outbt7 = new wxToggleButton (panel, wxID_ANY, wxT ("7"));
  outbt8 = new wxToggleButton (panel, wxID_ANY, wxT ("8"));
  myhsizer->Add (outbt1, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt2, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt3, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt4, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt5, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt6, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt7, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt8, wxEXPAND | wxALL, 0, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Analogue Output INTEGER16")),
			  wxVERTICAL);
  mysizer->Add (myhsizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 30);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, 0, wxEXPAND | wxALL, 0);
  outst1 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  outst2 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  outst3 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  outst4 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  mysssizer->Add (outst1, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer->Add (outst2, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer->Add (outst3, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer->Add (outst4, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 0);
  outs1 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  outs2 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  outs3 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  outs4 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  mysssizer->Add (outs1, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (outs2, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (outs3, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (outs4, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);

  wxString
    choice[] = {
    _T ("Analogue Out 1"), _T ("Analogue Out 2"),
    _T ("Analogue Out 3"), _T ("Analogue Out 4"),
    _T ("Bool Out 1"), _T ("Bool Out 2"),
    _T ("Bool Out 3"), _T ("Bool Out 4"),
    _T ("Bool Out 5"), _T ("Bool Out 6"),
    _T ("Bool Out 7"), _T ("Bool Out 8"),
    _T ("Analogue Input 1"), _T ("Analogue Input 2"),
    _T ("Analogue Input 3"), _T ("Analogue Input 4"),
    _T ("Analogue Input 5"), _T ("Analogue Input 6"),
    _T ("Analogue Input 7"), _T ("Analogue Input 8"),
    _T ("Bool Input 1"), _T ("Bool Input 2"),
    _T ("Bool Input 3"), _T ("Bool Input 4"),
    _T ("Bool Input 5"), _T ("Bool Input 6"),
    _T ("Bool Input 7"), _T ("Bool Input 8"),
  };

  panel = new wxPanel (book);
  book->InsertPage (0, panel, wxT ("Control"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  myhsizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Control your node")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxALL, 5);
  start = new wxButton (panel, START, _T ("START"));
  stop = new wxButton (panel, STOP, _T ("STOP"));
  stop->Enable (false);
  myhsizer->Add (start, 0, wxRIGHT, 5);
  myhsizer->Add (stop, 0, wxLEFT, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY, _T ("Operation log")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, wxALL, wxEXPAND | wxALL, 5);
  textLog =
    new wxTextCtrl (panel, TEXTBOX1, _T (""), wxDefaultPosition,
		    wxDefaultSize, wxTE_MULTILINE, wxDefaultValidator,
		    wxTextCtrlNameStr);
  myhsizer->Add (textLog, wxALL, wxEXPAND | wxALL, 5);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);

  m_timer.Start (100);
  if (to_start)
    {
      Start ();
    }
}

void
MyFrame::OnQuit (wxCommandEvent & WXUNUSED (event))
{
  Close (true);
}

void
MyFrame::Start ()
{
  if (main_can (SlaveBoard, LibraryPath))
    {
      printf ("[KO]\n");
      fflush(stdout);
      *textLog <<
	wxT
	("----------------------------------------------------Initialization [KO]\n");
    }
  else
    {
      printf ("[OK]\n");
      fflush(stdout);
      *textLog <<
	wxT
	("----------------------------------------------------Initialization [OK]\n");
      stop->Enable (true);
      start->Enable (false);
    }
}

void
MyFrame::OnStart (wxCommandEvent & WXUNUSED (event))
{
  wxString s;
  
  node_id_ext = node_id->GetValue ();
  s = busname->GetValue ();
  strncpy (SlaveBoard.busname, s.mb_str (), MAXLENGTH_BUSNAME);
  *textLog << wxT ("-- Bus name: ------> ") << s << wxT ("\n");
  *textLog << wxT ("-- Node ID: -------> ") << node_id->
    GetValue () << wxT ("\n");
  SetTitle(wxString::Format(wxT("CanOpen virtual DS-401 - Id : %d"),node_id->
		    GetValue ()));
  Start ();
}


void
MyFrame::OnStop (wxCommandEvent & WXUNUSED (event))
{

  *textLog <<
    wxT
    ("----------------------------------------------------Slave [STOPPED]") <<
    wxT ("\n");
  stop_slave ();
  stop->Enable (false);
  start->Enable (true);
}

void
MyFrame::OnLoad (wxCommandEvent & WXUNUSED (event))
{
  wxFileDialog fd (this, wxT ("Choose a can driver library"), wxT (""),
		   wxT (""), LIB_EXTENT);

  if (fd.ShowModal () == wxID_OK)
    {
      drivername->Clear ();
      drivername->AppendText (fd.GetPath ());
      *textLog << wxT ("LibraryPath: ") << fd.GetPath () << wxT ("\n");
      strncpy (LibraryPath, fd.GetPath ().mb_str (), MAXLENGTH_LIBPATH);
      printf ("path=%s", LibraryPath);
    }
}

void
MyFrame::OnInbt1 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x1;
}

void
MyFrame::OnInbt2 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x2;
}

void
MyFrame::OnInbt3 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x4;
}

void
MyFrame::OnInbt4 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x8;
}

void
MyFrame::OnInbt5 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x10;
}

void
MyFrame::OnInbt6 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x20;
}

void
MyFrame::OnInbt7 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x40;
}

void
MyFrame::OnInbt8 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x80;
}



void
MyFrame::OnIns1 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[0] = ins1->GetValue ();
  inst1->SetValue (ins1->GetValue ());
}

void
MyFrame::OnIns2 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[1] = ins2->GetValue ();
  inst2->SetValue (ins2->GetValue ());
}

void
MyFrame::OnIns3 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[2] = ins3->GetValue ();
  inst3->SetValue (ins3->GetValue ());
}

void
MyFrame::OnIns4 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[3] = ins4->GetValue ();
  inst4->SetValue (ins4->GetValue ());
}

void
MyFrame::OnIns5 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[4] = ins5->GetValue ();
  inst5->SetValue (ins5->GetValue ());
}

void
MyFrame::OnIns6 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[5] = ins6->GetValue ();
  inst6->SetValue (ins6->GetValue ());
}

void
MyFrame::OnIns7 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[6] = ins7->GetValue ();
  inst7->SetValue (ins7->GetValue ());
}

void
MyFrame::OnIns8 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[7] = ins8->GetValue ();
  inst8->SetValue (ins8->GetValue ());
}


void
MyFrame::OnInst1 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[0] = inst1->GetValue ();
  ins1->SetValue (inst1->GetValue ());
}

void
MyFrame::OnInst2 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[1] = inst2->GetValue ();
  ins2->SetValue (inst2->GetValue ());
}

void
MyFrame::OnInst3 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[2] = inst3->GetValue ();
  ins3->SetValue (inst3->GetValue ());
}

void
MyFrame::OnInst4 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[3] = inst4->GetValue ();
  ins4->SetValue (inst4->GetValue ());
}

void
MyFrame::OnInst5 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[4] = inst5->GetValue ();
  ins5->SetValue (inst5->GetValue ());
}

void
MyFrame::OnInst6 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[5] = inst6->GetValue ();
  ins6->SetValue (inst6->GetValue ());
}

void
MyFrame::OnInst7 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[6] = inst7->GetValue ();
  ins7->SetValue (inst7->GetValue ());
}

void
MyFrame::OnInst8 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[7] = inst8->GetValue ();
  ins8->SetValue (inst8->GetValue ());
}


void
MyFrame::OnAbout (wxCommandEvent & WXUNUSED (event))
{
  wxString msg;
  msg.Printf (_T ("About.\n\n")
	      _T
	      ("Input-Output simulation by GRANDEMANGE Nicolas for CanFestival!!"));

  wxMessageBox (msg, _T ("About !!!"), wxOK | wxICON_INFORMATION, this);
}


void
MyFrame::OnFreqBoxClick (wxCommandEvent & event)
{
  wxString wxstr;

  wxstr = event.GetString ();
  strncpy (SlaveBoard.baudrate, wxstr.mb_str (), MAXLENGTH_BAUDRATE);
  *textLog << wxT ("Baudrate:") << event.GetString () << wxT ("\n");
}

static int
is_set (int i, wxListBox * inlist, wxArrayInt in)
{
  inlist->GetSelections (in);
  for (int j = 0; j < in.GetCount (); j++)
    {
      if (i == (in[j] + 1))
	{
	  return (i);
	}
    }
  return (0);
}

static int
get_bit (UNS8 input, int bit)
{
  return input & (((UNS8) 1) << bit - 1) ? 1 : 0;
}

void
actu_output (void)
{
  wxString tmp;

  frame->outbt1->SetValue (get_bit (Write_Outputs_8_Bit[0], 1));
  frame->outbt2->SetValue (get_bit (Write_Outputs_8_Bit[0], 2));
  frame->outbt3->SetValue (get_bit (Write_Outputs_8_Bit[0], 3));
  frame->outbt4->SetValue (get_bit (Write_Outputs_8_Bit[0], 4));
  frame->outbt5->SetValue (get_bit (Write_Outputs_8_Bit[0], 5));
  frame->outbt6->SetValue (get_bit (Write_Outputs_8_Bit[0], 6));
  frame->outbt7->SetValue (get_bit (Write_Outputs_8_Bit[0], 7));
  frame->outbt8->SetValue (get_bit (Write_Outputs_8_Bit[0], 8));

  frame->outs1->SetValue (Write_Analogue_Output_16_Bit[0] + 32768);
  frame->outs2->SetValue (Write_Analogue_Output_16_Bit[1] + 32768);
  frame->outs3->SetValue (Write_Analogue_Output_16_Bit[2] + 32768);
  frame->outs4->SetValue (Write_Analogue_Output_16_Bit[3] + 32768);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[0]);
  frame->outst1->SetLabel (tmp);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[1]);
  frame->outst2->SetLabel (tmp);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[2]);
  frame->outst3->SetLabel (tmp);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[3]);
  frame->outst4->SetLabel (tmp);
}

void
actu (void)
{
  actu_output ();
}

void
MyFrame::OnTimer (wxTimerEvent & event)
{
  actu ();			// do whatever you want to do every second here
}

void
MyFrame::OnPaint (wxPaintEvent & event)
{
  //Paint();
}
