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

#include "wx/file.h"
#include "wx/cmdline.h"
#include "wx/html/htmlwin.h"

#include "LanzadorApp.h"

IMPLEMENT_APP(LanzadorApp)

#define APP "LanzATE"
#define VERSION "1.3.1"
#define COPYRIGHT "©2003-2004 Login:"
#define URL "http://www.w3jsj.com/"

bool LanzadorApp::OnInit() {
    SetAppName(APP);
    locale.Init();
    wxApp::OnInit();
    
    if(fichero.IsEmpty()) return FALSE;
    
    frame = new wxFrame((wxFrame*) NULL, -1, APP, wxDefaultPosition, wxSize(600, 400));
    frame->Centre();
    frame->CreateStatusBar();
    frame->SetStatusBarPane(0);
    frame->SetStatusText(APP " " VERSION);
    frame->SetIcon(wxIcon("LANZADOR_ICONO", wxBITMAP_TYPE_ICO_RESOURCE));
    
    lanzador = new DlgLanzador(frame);
    
    lanzador->logo->SetBitmap(wxBitmap("LANZADOR_LOGO", wxBITMAP_TYPE_BMP_RESOURCE));
    lanzador->htmlAcercaDe->SetPage("<h3>" \
      APP "</h3><strong>Versión " VERSION "</strong><br><em>" \
      COPYRIGHT \
      "</em><br><br><u><font color=\"#0000FF\">" URL "</font></u>");

    // atributos de texto
    attrCabecera = wxTextAttr(wxColour(0, 0, 100), *wxWHITE, wxFont(12, wxSWISS, wxNORMAL, wxBOLD));
    attrTexto = wxTextAttr(*wxBLACK, *wxWHITE, wxFont(10, wxSWISS, wxNORMAL, wxNORMAL));
    attrTextoNegrita = wxTextAttr(*wxBLACK, *wxWHITE, wxFont(10, wxSWISS, wxNORMAL, wxBOLD));
    attrTextoGris = wxTextAttr(wxColour(100, 100, 100), *wxWHITE, wxFont(10, wxSWISS, wxNORMAL, wxNORMAL));
    attrTextoRojo = wxTextAttr(*wxRED, *wxWHITE, wxFont(10, wxSWISS, wxNORMAL, wxNORMAL));
    
    // cabecera informativa
    ImpTxt(attrCabecera);
    ImpTxt(APP " " VERSION "\n");
    ImpTxt(COPYRIGHT "\n");
    ImpTxt(attrTextoNegrita);
    ImpTxt("\nModo: ");
    ImpTxt(attrTexto);
    ImpTxt(wxString(glulx ? "Glulx" : "máquina-z"));
    ImpTxt(attrTextoNegrita);
    ImpTxt("    Debug: ");
    ImpTxt(attrTexto);
    ImpTxt(wxString(debug ? "SI" : "NO") + "\n");
    ImpTxt(attrTextoNegrita);
    ImpTxt("Fichero: ");
    ImpTxt(attrTexto);
    ImpTxt(fichero + "\n");
    wxString sep;
    sep.Pad(100, '-');
    ImpTxt(sep + "\n");
    
    rutaEXE = wxPathOnly(argv[0]);
    rutaInform = rutaEXE + "\\inform.exe";
    rutaBRES = rutaEXE + "\\bres.exe";
    rutaBLC = rutaEXE + "\\blc.exe";
    int n = rutaEXE.Find('\\', TRUE);
    wxString rutaLIB;
    if(n != -1) rutaLIB = rutaEXE.Left(n) + "\\lib";
    else rutaLIB = rutaEXE;
    rutaModulos = ".\\,\"" + rutaLIB + "\"";
    
    lanzador->Show(TRUE);
    frame->Show(TRUE);
    SetTopWindow(frame);
    
    Compilar();
    
    return TRUE;
}

// parámetros de línea de comandos
static const wxCmdLineEntryDesc cmdLineDesc[] = {
    { wxCMD_LINE_SWITCH, "h", "help", "muestra este mensaje de ayuda", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
    { wxCMD_LINE_SWITCH, "z", "zmachine", "compilar para máquina-Z" },
    { wxCMD_LINE_SWITCH, "g", "glulx", "compilar para Glulx" },
    { wxCMD_LINE_SWITCH, "d", "debug", "compilar en modo 'debug'" },
    { wxCMD_LINE_PARAM,  NULL, NULL, "fichero de entrada", wxCMD_LINE_VAL_STRING },
    { wxCMD_LINE_NONE }
};

void LanzadorApp::OnInitCmdLine(wxCmdLineParser& parser) {
    parser.SetDesc(cmdLineDesc);
    parser.SetLogo(APP " " VERSION "\n" COPYRIGHT " (" URL ")\n");
}

bool LanzadorApp::OnCmdLineParsed(wxCmdLineParser& parser) {
    glulx = parser.Found("g");
    debug = parser.Found("d");
    fichero = parser.GetParam();
    return TRUE;
}

void LanzadorApp::Salir() {
    frame->Close(TRUE);
}

void LanzadorApp::ImpTxt(wxString txt) {
    lanzador->txtCompilar->AppendText(txt);
}
void LanzadorApp::ImpTxt(wxTextAttr attr) {
    lanzador->txtCompilar->SetDefaultStyle(attr);
}

void LanzadorApp::Compilar() {
    wxString cmd;
    wxString par = "";
    if(glulx) par += " -G";
    if(!debug) par += " -~D -~S";
    
    wxFileName f = wxFileName(fichero);
    wxString ruta = f.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    wxString nombre = f.GetName();
    
    int resultado = 0;
    
    // ejecutar BRES (sólo si es modo Glulx)
    if(glulx) {
        if(f.FileExists(ruta + nombre + ".res")) {
            cmd = rutaBRES + " \"" + ruta + nombre + "\"";
            resultado = Ejecutar("<BRES>", cmd);
        }
    }
    
    // compilar con Inform
    if(resultado == 0) {
        cmd = rutaInform + par + " +" + rutaModulos + " \"" + fichero + "\"";
        resultado = Ejecutar("<INFORM>", cmd);
    }
    
    // ejecutar BLC (sólo si es modo Glulx)
    if(resultado == 0) {
        if(glulx) {
            if(f.FileExists(ruta + nombre + ".blc")) {
                cmd = rutaBLC + " \"" + ruta + nombre + ".blc\" \"" + ruta + nombre + ".blb\"";
                Ejecutar("<BLC>", cmd);
            }
        }
    }

    // nos posicionamos al inicio de la lista de mensajes
    ScrollInicio();
}

int LanzadorApp::Ejecutar(wxString tit, wxString cmd) {
    ImpTxt(attrTextoNegrita);
    ImpTxt("\n" + tit + "\n");
    ImpTxt(attrTextoGris);
    ImpTxt(cmd + "\n");
    ImpTxt(attrTexto);
    
    wxArrayString salida, errores;
    int r = wxExecute(cmd, salida, errores);
    
    ImpTxt(attrTexto);
    size_t lng = salida.GetCount();
    for(size_t i = 0; i < lng; i++) ImpTxt(salida[i] + "\n");
    
    /*
    ImpTxt(attrTextoRojo);
    lng = errores.GetCount();
    for(size_t i = 0; i < lng; i++) ImpTxt(errores[i] + "\n");
    */
    
    // NOTA: inform.exe devuelve -1 si hay avisos
    if((r == 0) || (r == -1)) {
        ImpTxt(attrTextoGris);
        ImpTxt("[PROCESO FINALIZADO CORRECTAMENTE]\n");
        r = 0;
    }
    else {
        ImpTxt(attrTextoRojo);
        ImpTxt("[SE HAN PRODUCIDO ERRORES (cod=" + wxString::Format("%d", r) + ")]\n");
    }
    
    return r;
}

void LanzadorApp::ScrollInicio() {
    lanzador->txtCompilar->SetInsertionPoint(0);
}
