/* The original version of this program can be found at http://damb.dk */
#include "wx/wx.h"
#include <sstream>
#include <string>

// Two helper template functions
template <typename T>
bool FromString(T &aValue, const std::string &aStr)
{
   std::stringstream ss(aStr);
   return ss >> aValue;
}

template <typename T>
std::string ToString(T aValue)
{
   std::stringstream ss;
   ss << aValue;
   return ss.str();
}

// The panel, a panel is what make it behave as a dialog box
class PanelClass: public wxPanel
{
public:
   PanelClass(wxFrame *frame, int x, int y, int w, int h) : wxPanel(frame, wxID_ANY, wxPoint(x, y), wxSize(w, h))
   {
      Text1 = new wxTextCtrl(this, Text1Id, "", wxPoint(5,  5), wxSize(100, 20));
      Text2 = new wxTextCtrl(this, Text2Id, "", wxPoint(5, 30), wxSize(100, 20));
      Result = new wxTextCtrl(this, ResultId, "", wxPoint(5, 55), wxSize(100, 20), wxTE_READONLY);
      Button1 = new wxButton(this, ButtonId, "Add", wxPoint(5, 80), wxSize(100, 20));
   }
   ~PanelClass()
   {
      delete Text1;
      delete Text2;
      delete Result;
      delete Button1;
   }
private:
   // Some id's for my controls
   enum CtrlId
   {
      Text1Id = 1001,
      Text2Id,
      ResultId,
      ButtonId
   };

   // Resize my Controls when I'm resized
   void OnSize(wxSizeEvent &event)
   {
      wxSize Size = GetClientSize();
      Text1->SetSize(Size.GetWidth() - 10, 20);
      Text2->SetSize(Size.GetWidth() - 10, 20);
      Result->SetSize(Size.GetWidth() - 10, 20);
   }
   wxTextCtrl *Text1;
   wxTextCtrl *Text2;
   wxTextCtrl *Result;
   wxButton *Button1;
   void OnAddButton(wxCommandEvent &event);
   DECLARE_EVENT_TABLE()
};

// The event table for the panel, this routes messages/events to functions
BEGIN_EVENT_TABLE(PanelClass, wxPanel)
   EVT_BUTTON(ButtonId, PanelClass::OnAddButton)
   EVT_SIZE(PanelClass::OnSize)
END_EVENT_TABLE()

// The Frame, this is the topleve windows, which hosts the panel
class FrameClass : public wxFrame
{
public:
   FrameClass(wxFrame *frame, const wxChar *title, int x, int y, int w, int h) :
      wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
   {
      Panel = new PanelClass(this, x, y, w, h);
   }
   ~FrameClass()
   {
      delete Panel;
   }
   PanelClass *Panel;
};

// The application, all applications has one
class AppClass: public wxApp
{
public:
   bool OnInit()
   {
      Frame = new FrameClass(0, "wxCalc", 100, 100, 200, 200);
      Frame->Show(true);
      SetTopWindow(Frame);
      return true;
   }
   FrameClass *Frame;
};

IMPLEMENT_APP(AppClass)

// The function that is called when the user hits the Add button.
void PanelClass::OnAddButton(wxCommandEvent &WXUNUSED(event))
{
   std::string S1;
   S1 = Text1->GetValue();
   std::string S2;
   S2 = Text2->GetValue();
   int I1, I2;
   if(FromString(I1, S1) && FromString(I2, S2))
   {
      std::string Res = ToString(I1 + I2);
      Result->SetValue(Res.c_str());
   }
   else
   {
      wxMessageBox("Failed to convert");
   }
}