/***************************************************************
 * Name:      RoboDudeApp.cpp
 * Purpose:   Code for Application Class
 * Author:    Nils Springob (springob@nicai-systems.de)
 * Created:   2009-10-04
 * Copyright: Nils Springob (http://nibo.nicai-systems.de)
 * License:
 **************************************************************/

#include "BobDudeApp.h"

#include <wx/stdpaths.h>
#include <wx/filename.h>
#include <wx/evtloop.h>


//(*AppHeaders
#include "MainFrame.h"
#include <wx/image.h>
//*)

IMPLEMENT_APP(BobDudeApp);

MainFrame * frame;

extern MainFrame * frame;
void appendLogLine(const char * text) {
    if (frame) {
        frame->appendLogLine(text);
    }
}


bool BobDudeApp::OnInit() {
    bool wxsOK = true;
    if (!wxApp::OnInit()) {
        wxsOK = false;
    }
    
    if (m_one.IsAnotherRunning()) {
        //std::cout << "CALLER: calling other instance..." << std::endl;
        // Create a IPC client and use it to ask the existing process to show itself.
        wxClient *client = new wxClient;
        wxConnectionBase *conn = client->MakeConnection("localhost", "/tmp/bobdude_socket_1351a1bebae7", "restart");
        
        if (files.size()>0) {
            if (autoprog) {
                conn->Execute("--autoprog");
            }
            if (autohide) {
                conn->Execute("--autohide");
            }
            
            for (unsigned int i=0; i< files.size(); i++) {
                conn->Execute(files[i]);
            }
            
        } else {
            conn->Execute(".");
        }
        
        //std::cout << "CALLER: request ACK..." << std::endl;
        //std::cout << "CALLER: finished, cleaning up..." << std::endl;
        conn->Disconnect();
        delete conn;
        delete client;
        // Don't enter the message loop.
        return false;
    } else {
        // Start a IPC server.
        m_server = new CServer;
        m_server->Create("/tmp/bobdude_socket_1351a1bebae7");
    }
    
    wxInitAllImageHandlers();
    if ( wxsOK ) {
        frame = new MainFrame(0);
        frame->Show(true);
        SetTopWindow(frame);
        wxsOK = true;
        
    }
    return wxsOK;
}


void BobDudeApp::OnEventLoopEnter (wxEventLoopBase *loop) {
    if (autoprog) {
        autoprog = false;
        frame->Refresh();
        frame->Update();
        frame->startProgram();
    }
    //std::cout << "DEBUG: OnEventLoopEnter" << std::endl;
}


int BobDudeApp::OnExit() {
    delete m_server;
    return this->wxApp::OnExit();
}


void BobDudeApp::OnInitCmdLine(wxCmdLineParser& parser) {
    parser.SetDesc (g_cmdLineDesc);
    // must refuse '/' as parameter starter or cannot use "/path" style paths
    parser.SetSwitchChars (wxT("-"));
}


bool BobDudeApp::OnCmdLineParsed(wxCmdLineParser& parser) {
    // to get at your unnamed parameters use
    
    for (unsigned int i = 0; i < parser.GetParamCount(); i++) {
        files.Add(parser.GetParam(i));
    }
    
    wxString configFile;
    // and other command line parameters
    if (parser.Found( wxT("c"), &configFile)) {
    } else {
        if (configFile=="") {
#ifdef _WIN32
            configFile = ::wxStandardPaths::Get().GetDataDir() + ::wxFileName::GetPathSeparator() + "bobdude.conf";
#else
            configFile = wxString(SYSCONFDIR) + ::wxFileName::GetPathSeparator() + "bobdude.conf";
#endif
        }
    }
    // then do what you need with them.
    conf = configFile;
    //avrdude = new Avrdude("BobDude", static_cast<const char*>(configFile));
#ifdef AVRDUDE_CONF    
    avrdude = new Avrdude("BobDude", static_cast<const char*>(configFile.mb_str(wxConvUTF8)));
#endif
    
    autoprog = parser.Found( wxT("autoprog"));
    autohide = parser.Found( wxT("autohide"));
    
    return true;
}


void BobDudeApp::MacOpenFile(const wxString &fileName) {
    frame->loadFile(fileName);
}


wxConnectionBase * CServer::OnAcceptConnection(const wxString& topic) {
    //std::cout << "DEBUG: OnAcceptConnection topic='" << topic << "'" << std::endl;
    if (topic.compare("restart") == 0) {
        return new CConnection;
    } else {
        return wxServer::OnAcceptConnection(topic);
    }
}


bool CConnection::OnDisconnect() {
    //std::cout << "DEBUG: caller disconneted" << std::endl;
    wxConnection::OnDisconnect();
    return true;
}


CConnection::~CConnection() {
    //std::cout << "DEBUG: ~CConnection" << std::endl;
}


bool CConnection::OnExec(const wxString& topic, const wxString& data) {
    //std::cout << "DEBUG: onExec topic='" << topic << "' data='" << data << "'" << std::endl;
    if (topic.compare("restart") == 0) {
        frame->Show(true);
        frame->Restore();
        frame->Raise();
        if (data.compare(".") == 0) {
            //appendLogLine("[no file]");
        } else if (data.compare("--autoprog") == 0) {
            wxGetApp().autoprog = true;
        } else if (data.compare("--autohide") == 0) {
            wxGetApp().autohide = true;
        } else {
            appendLogLine("\n----------------------------\n");
            frame->loadFile(data);
            if (wxGetApp().autoprog) {
                wxGetApp().autoprog = false;
                frame->startProgram();
            }
        }
    }
    //wxGetApp().GetMainLoop()->WakeUpIdle();
    //std::cout << "DEBUG: Yield" << std::endl;
    wxGetApp().Yield(true);
    //std::cout << "DEBUG: onExec FINISHED topic='" << topic << "' data='" << data << "'" << std::endl;
    return true;
}


