// Minimaler Text File Viewer
//
// Aufruf: viewer
//
// Klaus Kusche, 2011

#include <wx/app.h>
#include <wx/frame.h>
#include <wx/splitter.h> 
#include <wx/textctrl.h> 
#include <wx/dirctrl.h> 
#include <wx/event.h>

// meine Anwendung unterscheidet sich
// von der vordefinierten "leeren" wx-Anwendung nur durch die Init-Funktion
class MyApp: public wxApp
{
  virtual bool OnInit();
};

// generiere ein main für meine Anwendung
IMPLEMENT_APP(MyApp)

// mein Hauptfenster ist ein wx-Frame mit ein paar zusätzlichen Dingen
class MyFrame: public wxFrame
{
  public:
    MyFrame(const wxString &title);

    // Event-Methode für Doppelklick auf File links im Baum
    void OnSel(wxTreeEvent &event);
            
  private:
    // meine Subelemente brauche ich auch in den Event-Methoden,
    // daher müssen sie Member sein
    wxSplitterWindow *Splitter;
    wxGenericDirCtrl *Tree;
    wxTextCtrl *Text;
};

bool MyApp::OnInit()
{
  // das Übliche: Hauptfenster anlegen, anzeigen, zum obersten Fenster machen
  MyFrame *frame = new MyFrame("File Viewer");
  frame->Show(true);
  SetTopWindow(frame);
  return true;
} 

// Konstruktor des Hauptfensters,
// wird beim Start vom OnInit aufgerufen
MyFrame::MyFrame(const wxString &title)
: wxFrame(nullptr, -1, title),  // Aufruf des Konstruktors der Vaterklasse
  // neuer Splitter, Parent: Hauptfenster (ich selbst)
  Splitter(new wxSplitterWindow(this, -1)),
  // neuer Verzeichnis-Baum, Parent: Splitter
  Tree(new wxGenericDirCtrl(Splitter, -1)),
  // neues Multiline-Readonly-Textfeld, initial leerer Text, Parent: Splitter
  Text(new wxTextCtrl(Splitter, -1, "",
       wxDefaultPosition, wxDefaultSize,
       // das sind die Optionen (Style-Flags)
       wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP | wxTE_PROCESS_TAB))    
{
  Splitter->SetMinimumPaneSize(20);  // Mindestbreite einer Hälfte setzen
  Splitter->SplitVertically(Tree, Text, 250); // Teilen und Subfenster einhängen
  
  Tree->SetPath(wxGetCwd());  // aktuelles Verzeichnis im Baum vorselektieren

  // "Wenn der Baum-Doppelklick-Event kommt (egal von welchem Objekt),
  //  dann ruf mein 'OnSel' auf!"
  Bind(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, &MyFrame::OnSel, this);
}

// wird aufgerufen, wenn der Benutzer im Baum einen Doppelklick gemacht hat
void MyFrame::OnSel(wxTreeEvent &WXUNUSED(event))
{
  // frag den Verzeichnisbaum nach dem Filenamen des angeklickten Files
  wxString name = Tree->GetFilePath();
  // ... mach nur etwas, wenn der Name nicht leer ist
  // (wenn man ein Dir doppelklickt, liefert GetFilePath einen Leerstring)
  if (name.Len() != 0) {
    // ... und sag dem Textfeld, es soll diesen File laden
    Text->LoadFile(name);
  }
}
