#include <time.h>
#include "pmMainframe.h"
#include "pmBasicframe.h"
#include "pmBasicdlg.h"
#include "pmCanvas.h"

pmMainframe::pmMainframe
             (  wxWindow * parent,
                const wxChar *title, int xpos, int ypos, int width, int height)
             : wxFrame( parent, -1, title,
                        wxPoint(xpos, ypos),
                        wxSize(width, height))
{
  theText  = (wxTextCtrl *) NULL;
  menuBar  = (wxMenuBar *) NULL;
  CreateStatusBar(3);
  connectStatus = false;
  logFile = "pmLog.txt";
  lastCmd = "select now()";

  theText = new wxTextCtrl(this,-1,wxEmptyString,wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE);

  editMenu = new wxMenu;
  editMenu->Append(MAIN_FONT, "Choose font","Select a font for the text control");
  editMenu->Append(MAIN_NEWFRAME, "Create new text frame");
  editMenu->Append(MAIN_NEWCANVAS, "Create new image frame");
  editMenu->Append(MAIN_SAVE, "Save log","Save log to a text file");
  editMenu->Append(MAIN_EXIT, "Quit");

  dataMenu = new wxMenu;
  dataMenu->Append(MAIN_CONNECT, "Connect...", "Connect to database");
  dataMenu->Append(MAIN_DISCONNECT, "Disconnect...");
  dataMenu->Append(MAIN_QUERY, "SQL...","Execute an SQL statement");

  helpMenu = new wxMenu;
  helpMenu->Append(MAIN_ABOUT, "About");

  menuBar = new wxMenuBar;
  menuBar->Append(editMenu, "&Frames");
  menuBar->Append(dataMenu, "&SQL");
  menuBar->Append(helpMenu, "&Help");
  SetMenuBar(menuBar);
  wxLog  *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl(theText));
  delete old_log;

  time_t curtime = time (NULL);
  wxString currentDate = asctime (localtime (&curtime));
  currentDate.RemoveLast();
  DATABASE = "DSN=PG_DB_PM;UID=david;PWD=nimrodel";
  wxLogMessage("Start session %s Id is %d", currentDate.GetData(), this->GetId());
  SetTitle(GetTitle() + " " + logFile);
}

pmMainframe::~pmMainframe()
{
}

void pmMainframe::OnSaveLog(void)
{
        theText->SaveFile(logFile);
}

void pmMainframe::ChildMessage(wxString s)
{       theText->AppendText(s); }

void pmMainframe::OnExit   (wxCommandEvent & event)
{
        Close();
}

bool  pmMainframe::GetConnectStatus(void)
{
        return connectStatus;
}

void  pmMainframe::SetConnectStatus(bool s)
{
        connectStatus = s;
}

void pmMainframe::OnCloseWindow (wxCloseEvent& event)
{ wxString msg = "Close Warning: the text has changed"
                 "\nSelect OK to ignore changes for\n";
  wxString con = "Connect Warning: still connected.\n"
                 "Please disconnect first.";

  if (GetConnectStatus() == true)
  { wxMessageDialog
                warnDialog (this, con, "Active connection", wxICON_HAND | wxOK | wxCANCEL);
        warnDialog.ShowModal();
  }
  else
        if ( theText->IsModified() == true)
          { wxMessageDialog
                warnDialog ( this, msg, "File changed", wxICON_HAND | wxOK | wxCANCEL);
       if (warnDialog.ShowModal() == wxID_OK)
        { Destroy();
        }
          }
          else
                Destroy();
}


void pmMainframe::OnChooseFont(wxCommandEvent & event)
{ wxFontData fontData;
  wxFont     theFont = theText->GetFont();
  wxColour       colour;
  colour = theText->GetForegroundColour();
  fontData.SetColour(colour);
  fontData.SetInitialFont(theFont);
  fontData.SetShowHelp(true);
  wxFontDialog *dialog = new wxFontDialog(this, &fontData);
  if (dialog->ShowModal() == wxID_OK)
   { fontData = dialog->GetFontData();
     theFont =  fontData.GetChosenFont();
     theText->SetFont(theFont);
     theText->SetForegroundColour(fontData.GetColour());
   }
  dialog->Destroy();

}

void pmMainframe::OnNewCanvas (wxCommandEvent & event)
{
    wxString theTitle;
    theTitle =
     wxGetTextFromUser("Enter a title", "Input text", "NO NAME", this, -1,-1,TRUE);
        pmCanvasframe * win = new pmCanvasframe(this);
        win->Show(TRUE);
}

void pmMainframe::OnNewFrame (wxCommandEvent & event)
{
    wxString theTitle;
    theTitle =
     wxGetTextFromUser("Enter a title", "Input text", "NO NAME", this, -1,-1,TRUE);
        pmBasicframe * win = new pmBasicframe(this, theTitle, 150, 150, 450, 300);
        win->Show(TRUE);
}

void pmMainframe::OnAbout(wxCommandEvent & event)
{
  pmBasicdialog
   aboutDialog ( this, -1,this->GetTitle(),wxPoint(100,100),wxSize(250, 300),
                                        wxRESIZE_BORDER |  wxDEFAULT_DIALOG_STYLE );
  aboutDialog.ShowModal();
}

SQLRETURN pmMainframe::dbConnect(wxString connectString)
{ SQLRETURN retCode;

  retCode = theDatabase.connect(connectString.c_str());
  if (retCode == SQL_SUCCESS)
     SetConnectStatus(true);
  else
   SetConnectStatus(false);
  if (GetConnectStatus())
   this->SetStatusText("Connected " + connectString, 2);
  else
   this->SetStatusText("Unable to connect", 2);
  return retCode;

}

//Takes two hits to register disconnect
//Skip() added??
SQLRETURN pmMainframe::OnDBDisconnect(wxCommandEvent & event)
{ event.Skip();                 //???? Why ????
  return dbDisconnect();
}

SQLRETURN pmMainframe::dbDisconnect(void)
{ SQLRETURN retCode = SQL_SUCCESS;

  if (GetConnectStatus())
   { retCode = theDatabase.disconnect();
     SetConnectStatus(false);
   }
  else
   this->SetStatusText("Not connected", 2);
  return retCode;
}

SQLRETURN pmMainframe::OnExecSQLGrid(wxCommandEvent & event)
{ SQLRETURN retCode = SQL_SUCCESS;
  wxString cmd;

  if ( GetConnectStatus() )
   {    pmSQLdlg * getSQL =
                new pmSQLdlg (this,-1,"SQL Command",lastCmd, wxPoint(100,100), wxSize(450, 300),
                                                wxRESIZE_BORDER |  wxDEFAULT_DIALOG_STYLE);
                if (getSQL->ShowModal() == wxID_OK)
                {       cmd = getSQL->GetValue();
                        lastCmd = cmd;
                        retCode = theDatabase.execSQL(cmd.c_str(), theTable);
                if (retCode == SQL_SUCCESS)
                {       attribs = theTable.getAttribs();
                        wxLogMessage("%d rows, %d columns", attribs.cRows, attribs.cColumns);
                        if (attribs.cRows > 0)
                        {       pmGridframe * x = new pmGridframe(this, "testing", theTable, 20,20,200,200);
                                x->Show(TRUE);
                        }
                        else
                                wxLogMessage("SQL returned zero rows");
                        }
                }
                else wxLogMessage("Failed - SQL return code %d", retCode);
   }
  else
   wxLogMessage("Cannot execute SQL - we are disconnected.");
  return retCode;
}

void pmMainframe::OnDBStart(wxCommandEvent & event)
{       SQLRETURN rc;
        pmSRCdlg * getLogon =
        new pmSRCdlg (this,-1,"Log on (dsn,uid,pwd)", wxPoint(100,100), wxSize(450, 300),
                                        wxRESIZE_BORDER |  wxDEFAULT_DIALOG_STYLE);
        if (getLogon->ShowModal() == wxID_OK)
        {       wxString connectStr = getLogon->GetValue();
                wxLogMessage("Connecting to %s", connectStr.c_str());
                rc = dbConnect(connectStr);
                if (rc == SQL_SUCCESS)
                        wxLogMessage("Connect OK");
                else
                        wxLogMessage("Connect failed. SQL return code %d", rc);
        }
        else
                wxLogMessage("Connect declined");
}


BEGIN_EVENT_TABLE (pmMainframe, wxFrame)
  EVT_MENU ( MAIN_EXIT,         pmMainframe::OnExit)
  EVT_MENU ( MAIN_FONT,         pmMainframe::OnChooseFont)
  EVT_MENU ( MAIN_NEWFRAME,     pmMainframe::OnNewFrame)
  EVT_MENU ( MAIN_NEWCANVAS,    pmMainframe::OnNewCanvas)
  EVT_MENU ( MAIN_ABOUT,        pmMainframe::OnAbout)
  EVT_MENU ( MAIN_CONNECT,      pmMainframe::OnDBStart)
  EVT_MENU ( MAIN_DISCONNECT,   pmMainframe::OnDBDisconnect)
  EVT_MENU ( MAIN_QUERY,        pmMainframe::OnExecSQLGrid)
  EVT_MENU ( MAIN_SAVE,         pmMainframe::OnSaveLog)
  EVT_CLOSE(                    pmMainframe::OnCloseWindow)
END_EVENT_TABLE()