#include <wx/wx.h>
#include <wx/aboutdlg.h>
#include <wx/numdlg.h>

#include "LisaEmFrame.h"

/* A hack so that mem68k_fetch_byte et al. don't get declared */
#define IN_CPU68K_C

extern "C"
{
    /*
     * XXX: I really don't like doing this, but trying to include vars.h
     * causes multiple definitions of various things thanks to it being
     * used in LisaCanvas.cpp too. cops.h would have been nice :)
     */
    extern void presspowerswitch();
    extern void apple_dot();
    extern void apple_S();
    extern void apple_enter();
    extern void apple_renter();
    extern void apple_1();
    extern void apple_2();
    extern void apple_3();
    extern void shift_option_0();
    extern void shift_option_4();
    extern void shift_option_7();
}

enum
{
    // File menu
    ID_RUN = 10000,
    ID_PAUSE,
    ID_FLOPPY,
    ID_NEWFLOPPY,
    ID_SCREENSHOT,
    ID_SCREENSHOT2,
    ID_SCREENSHOT3,

    // Keyboard menu
    ID_POWERKEY,
    ID_KEY_APL_DOT,
    ID_KEY_APL_S,
    ID_KEY_APL_ENTER,
    ID_KEY_APL_RENTER,
    ID_KEY_APL_1,
    ID_KEY_APL_2,
    ID_KEY_APL_3,
    ID_KEY_SHIFT_OPT_0,
    ID_KEY_SHIFT_OPT_4,
    ID_KEY_SHIFT_OPT_7,
    ID_RAWKB,

    // View menu
    ID_UNCORRECTED,
    ID_CORRECTED,
    ID_ENHANCED,
    ID_SKIN,

    // Throttle menu
    ID_THROTTLE5,
    ID_THROTTLE8,
    ID_THROTTLE10,
    ID_THROTTLE15,
    ID_THROTTLE20,
    ID_THROTTLE25,
    ID_THROTTLEOTHER,

    // Help menu
    ID_LISAWEB,
    ID_LISAFAQ,
};

BEGIN_EVENT_TABLE(LisaEmFrame, wxFrame)
    // File menu
    EVT_MENU(wxID_OPEN,          LisaEmFrame::OnOpenPreferences)
    EVT_MENU(wxID_SAVEAS,        LisaEmFrame::OnSavePreferences)
    EVT_MENU(wxID_PREFERENCES,   LisaEmFrame::OnShowPreferences)
    EVT_MENU(ID_RUN,             LisaEmFrame::OnRun)
    EVT_MENU(ID_PAUSE,           LisaEmFrame::OnPause)
    EVT_MENU(ID_FLOPPY,          LisaEmFrame::OnInsertFloppy)
    EVT_MENU(ID_NEWFLOPPY,       LisaEmFrame::OnInsertNewFloppy)
    EVT_MENU(ID_SCREENSHOT,      LisaEmFrame::OnScreenshot)
    EVT_MENU(ID_SCREENSHOT2,     LisaEmFrame::OnScreenshot2)
    EVT_MENU(ID_SCREENSHOT3,     LisaEmFrame::OnScreenshot3)
    EVT_MENU(wxID_EXIT,          LisaEmFrame::OnQuit)

    // Edit menu
    EVT_MENU(wxID_PASTE,         LisaEmFrame::OnPaste)

    // Keyboard menu
    EVT_MENU(ID_POWERKEY,        LisaEmFrame::OnPowerKey)
    EVT_MENU(ID_KEY_APL_DOT,     LisaEmFrame::OnAppleDot)
    EVT_MENU(ID_KEY_APL_S,       LisaEmFrame::OnAppleS)
    EVT_MENU(ID_KEY_APL_ENTER,   LisaEmFrame::OnAppleEnter)
    EVT_MENU(ID_KEY_APL_RENTER,  LisaEmFrame::OnAppleREnter)
    EVT_MENU(ID_KEY_APL_1,       LisaEmFrame::OnApple1)
    EVT_MENU(ID_KEY_APL_2,       LisaEmFrame::OnApple2)
    EVT_MENU(ID_KEY_APL_3,       LisaEmFrame::OnApple3)
    EVT_MENU(ID_KEY_SHIFT_OPT_0, LisaEmFrame::OnShiftOpt0)
    EVT_MENU(ID_KEY_SHIFT_OPT_4, LisaEmFrame::OnShiftOpt4)
    EVT_MENU(ID_KEY_SHIFT_OPT_7, LisaEmFrame::OnShiftOpt7)
    EVT_MENU(ID_RAWKB,           LisaEmFrame::OnRawKeyboard)

    // View menu
    EVT_MENU(ID_UNCORRECTED,     LisaEmFrame::OnUncorrected)
    EVT_MENU(ID_CORRECTED,       LisaEmFrame::OnCorrected)
    EVT_MENU(ID_ENHANCED,        LisaEmFrame::OnEnhanced)
    EVT_MENU(ID_SKIN,            LisaEmFrame::OnSkin)

    // Throttle menu
    EVT_MENU(ID_THROTTLE5,       LisaEmFrame::OnThrottle5)
    EVT_MENU(ID_THROTTLE8,       LisaEmFrame::OnThrottle8)
    EVT_MENU(ID_THROTTLE10,      LisaEmFrame::OnThrottle10)
    EVT_MENU(ID_THROTTLE15,      LisaEmFrame::OnThrottle15)
    EVT_MENU(ID_THROTTLE20,      LisaEmFrame::OnThrottle20)
    EVT_MENU(ID_THROTTLE25,      LisaEmFrame::OnThrottle25)
    EVT_MENU(ID_THROTTLEOTHER,   LisaEmFrame::OnThrottleOther)

    // Help menu
    EVT_MENU(wxID_ABOUT,         LisaEmFrame::OnAbout)
    EVT_MENU(ID_LISAWEB,         LisaEmFrame::OnLisaWeb)
    EVT_MENU(ID_LISAFAQ,         LisaEmFrame::OnLisaFAQ)

    EVT_UPDATE_UI(wxID_ANY,      LisaEmFrame::OnUpdateUI)
END_EVENT_TABLE()


LisaEmFrame::LisaEmFrame() : wxFrame(NULL, wxID_ANY, _T("LisaEm"))
{

    CreateMenus();

    CreateStatusBar(2);

    m_lisa = new LisawCanvas((wxWindow *)this);

    UpdateMenus();

    m_sizer = new wxBoxSizer(wxVERTICAL);
    m_sizer->Add(m_lisa, 1, wxALL | wxEXPAND);
    SetSizer(m_sizer);
}

/* Create the menus objects, but don't set them to the correct state */
void LisaEmFrame::CreateMenus(void)
{
    m_file_menu      = new wxMenu();
    m_edit_menu      = new wxMenu();
    m_keyboard_menu  = new wxMenu();
    m_view_menu      = new wxMenu();
    m_throttle_menu  = new wxMenu();
    m_help_menu      = new wxMenu();

    /* File menu */
    m_file_menu->Append(wxID_OPEN,         _T("Open Lisa Preferences...\tCtrl-O"),   _T("Open a Lisa configuration file"));
    m_file_menu->Append(wxID_SAVEAS,       _T("Save Lisa Preferences...\tCtrl-S"),   _T("Save current Lisa configuration to a new file"));
    m_file_menu->Append(wxID_PREFERENCES,  _T("Preferences..."),                     _T("Configure this Lisa"));
    m_file_menu->AppendSeparator();
    m_file_menu->AppendCheckItem(ID_RUN,   _T("Run\tCtrl-R"),                        _T("Run Emulation") );
    m_file_menu->AppendCheckItem(ID_PAUSE, _T("Pause\tCtrl-Shift-R"),                _T("Pause Emulation") );
    m_file_menu->AppendSeparator();
    m_file_menu->Append(ID_FLOPPY,         _T("Insert Floppy...\tCtrl-F"),           _T("Insert a floppy Image"));
    m_file_menu->Append(ID_NEWFLOPPY,      _T("Insert New Floppy...\tCtrl-Shift-F"), _T("Create and insert a blank floppy Image"));
    m_file_menu->AppendSeparator();
    m_file_menu->Append(ID_SCREENSHOT,     _T("Screenshot...\tCtrl-K"),              _T("Save the current screen as an image"));
    m_file_menu->Append(ID_SCREENSHOT2,    _T("Full Screenshot..."),                 _T("Save a screenshot along with the skin"));
    m_file_menu->Append(ID_SCREENSHOT3,    _T("Raw Screenshot..."),                  _T("Save a raw screenshot"));
    m_file_menu->AppendSeparator();
    m_file_menu->Append(wxID_EXIT,         _T("E&xit\tAlt-X"));


    /* Edit menu */
    m_edit_menu->Append(wxID_PASTE, _T("Paste\tCtrl-V") , _T("Paste clipboard text to keyboard.") );


    /* Keyboard menu */
    m_keyboard_menu->Append(ID_POWERKEY,         _T("Power Button\tCtrl-Shift-P"), _T("Push the Power Button"));
    m_keyboard_menu->AppendSeparator();
    m_keyboard_menu->Append(ID_KEY_APL_DOT,      _T("Apple ."),                    _T("Apple + ."));
    m_keyboard_menu->Append(ID_KEY_APL_S,        _T("Apple S"),                    _T("Apple + S"));
    m_keyboard_menu->Append(ID_KEY_APL_ENTER,    _T("Apple Enter"),                _T("Apple + Enter"));
    m_keyboard_menu->Append(ID_KEY_APL_RENTER,   _T("Apple Right Enter"),          _T("Apple + Numpad Enter"));
    m_keyboard_menu->Append(ID_KEY_APL_1,        _T("Apple 1"),                    _T("Apple + 1"));
    m_keyboard_menu->Append(ID_KEY_APL_2,        _T("Apple 2"),                    _T("Apple + 2"));
    m_keyboard_menu->Append(ID_KEY_APL_3,        _T("Apple 3"),                    _T("Apple + 3"));
    m_keyboard_menu->Append(ID_KEY_SHIFT_OPT_0,  _T("Option 0"),                   _T("Option 0"));
    m_keyboard_menu->Append(ID_KEY_SHIFT_OPT_4,  _T("Option 4"),                   _T("Option 4"));
    m_keyboard_menu->Append(ID_KEY_SHIFT_OPT_7,  _T("Option 7"),                   _T("Option 7"));
    m_keyboard_menu->AppendSeparator();
    m_keyboard_menu->AppendCheckItem(ID_RAWKB,   _T("Raw Keyboard\tCtrl-Shift-K"), _T("Map host keys to Lisa keys directly"));


    /* View menu */
    m_view_menu->AppendRadioItem(ID_UNCORRECTED, _T("Uncorrected Video\tCtrl-Shift-U"), _T("Uncorrected Aspect Ratio"));
    m_view_menu->AppendRadioItem(ID_CORRECTED,   _T("Corected Video\tCtrl-Shift-C"),    _T("Aspect Corrected with Anti Aliasing"));
    m_view_menu->AppendRadioItem(ID_ENHANCED,    _T("Enchanced Video\tCtrl-Shift-E"),   _T("Aspect Corrected with Anti Aliasing and Gray Replacing"));
    m_view_menu->AppendSeparator();
    m_view_menu->AppendCheckItem(ID_SKIN,        _T("Show Skin\tCtrl-Shift-S"));


    /* Throttle menu */
    m_throttle_menu->AppendRadioItem(ID_THROTTLE5,     _T("5 MHz\tCtrl-1"));
    m_throttle_menu->AppendRadioItem(ID_THROTTLE8,     _T("8 MHz\tCtrl-2"));
    m_throttle_menu->AppendRadioItem(ID_THROTTLE10,    _T("10 MHz\tCtrl-3"));
    m_throttle_menu->AppendRadioItem(ID_THROTTLE15,    _T("15 MHz\tCtrl-4"));
    m_throttle_menu->AppendRadioItem(ID_THROTTLE20,    _T("20 MHz\tCtrl-5"));
    m_throttle_menu->AppendRadioItem(ID_THROTTLE25,    _T("25 MHz\tCtrl-6"));
    m_throttle_menu->AppendRadioItem(ID_THROTTLEOTHER, _T("Other...\tCtrl-7"));


    /* Help menu */
    m_help_menu->Append(wxID_ABOUT, _T("&About..."));
#ifndef __WXOSX__
    /*
     * Mac doesn't need a seperator here, because the About item appears on
     * the application menu, not the help menu.
     */
    m_help_menu->AppendSeparator();
#endif
    m_help_menu->Append(ID_LISAWEB, _T("Lisa Emulator Webpage..."), _T("http://lisaem.sunder.net"));
    m_help_menu->Append(ID_LISAFAQ, _T("Lisa FAQ webpage..."),      _T("http://lisafaq.sunder.net"));


    m_menubar = new wxMenuBar();

    m_menubar->Append(m_file_menu,     _T("&File"));
    m_menubar->Append(m_edit_menu,     _T("&Edit"));
    m_menubar->Append(m_keyboard_menu, _T("&Keyboard"));
    m_menubar->Append(m_view_menu,     _T("&View"));
    m_menubar->Append(m_throttle_menu, _T("&Throttle"));
    m_menubar->Append(m_help_menu,     _T("&Help"));

    SetMenuBar(m_menubar);
}

/*
 * Set the state of each menu item to match current emulator state. For
 * example, lots of things aren't possible if the emulator is paused, and
 * the corresponding menu items should be greyed out
 */
void LisaEmFrame::UpdateMenus(void)
{
    if (!m_lisa) return;

    bool paused = m_lisa->IsPaused();
    bool powered = m_lisa->IsPowerOn();
    bool floppy_present = m_lisa->IsFloppyPresent();

    // File menu
    m_file_menu->Check(ID_RUN, powered);
    m_file_menu->Check(ID_PAUSE, paused);

    m_file_menu->Enable(ID_FLOPPY, !floppy_present);
    m_file_menu->Enable(ID_NEWFLOPPY, !floppy_present);

    m_file_menu->Enable(ID_PAUSE, powered);
    m_file_menu->Enable(ID_SCREENSHOT, powered);
    m_file_menu->Enable(ID_SCREENSHOT2, powered);
    m_file_menu->Enable(ID_SCREENSHOT3, powered);

    // Edit menu
    m_file_menu->Enable(wxID_PASTE, powered & !paused);

    // Keyboard menu
    m_keyboard_menu->Enable(ID_POWERKEY, !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_DOT, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_S, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_ENTER, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_RENTER, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_1, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_2, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_APL_3, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_SHIFT_OPT_0, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_SHIFT_OPT_4, powered & !paused);
    m_keyboard_menu->Enable(ID_KEY_SHIFT_OPT_7, powered & !paused);
    m_keyboard_menu->Check(ID_RAWKB, m_lisa->IsRawKeyboard());

    // View menu
    int video_mode = m_lisa->GetVideoMode();
    switch (video_mode) {
        case VIDEO_UNCORRECTED: m_view_menu->Check(ID_UNCORRECTED, true); break;
        case VIDEO_CORRECTED:   m_view_menu->Check(ID_CORRECTED,   true); break;
        case VIDEO_ENHANCED:    m_view_menu->Check(ID_ENHANCED,    true); break;
    }

    m_view_menu->Check(ID_SKIN, m_lisa->IsSkinOn());

    // Throttle menu
    int hertz = m_lisa->GetThrottleSpeed();
    switch (hertz) {
        case  5000000: m_throttle_menu->Check(ID_THROTTLE5,  true); break;
        case  8000000: m_throttle_menu->Check(ID_THROTTLE8,  true); break;
        case 10000000: m_throttle_menu->Check(ID_THROTTLE10, true); break;
        case 15000000: m_throttle_menu->Check(ID_THROTTLE15, true); break;
        case 20000000: m_throttle_menu->Check(ID_THROTTLE20, true); break;
        case 25000000: m_throttle_menu->Check(ID_THROTTLE25, true); break;
        default:       m_throttle_menu->Check(ID_THROTTLEOTHER, true);
    }
}


// File menu
void LisaEmFrame::OnOpenPreferences(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnSavePreferences(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnShowPreferences(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnRun(wxCommandEvent& event)
{
    if (!event.IsChecked()) {
        wxMessageDialog dialog(this,
            _T("The emulation is currently running. If you stop it now, the "
                "Lisa OS will be halted immediately, and any unsaved data "
                "will be lost. To shut down cleanly, use the power key. Are "
                "you sure you wish to stop?"),
            _T("Confirm Stop"),
            wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION);

        if (dialog.ShowModal() == wxID_YES) m_lisa->SetPowerOn(false);
    } else {
        m_lisa->SetPowerOn(true);
    }
}

void LisaEmFrame::OnPause(wxCommandEvent& event)
{
    m_lisa->SetPaused(event.IsChecked());
}

void LisaEmFrame::OnInsertFloppy(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    wxString filename = ::wxFileSelector(
        _T("Open Lisa floppy disc image"),
        _T(""), _T(""), _T(""),
        _T("DiskCopy 4.2 files (*.dc42)|*.dc42|DART files (*.dart)|*.dart"),
        wxOPEN | wxFILE_MUST_EXIST,
        this
        );
    if (!filename.empty()) {
        m_lisa->InsertFloppy(filename);
    }
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnInsertNewFloppy(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnScreenshot(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnScreenshot2(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnScreenshot3(wxCommandEvent& event)
{
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    m_lisa->SetPaused(old_paused);
}

void LisaEmFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    bool quit = true;
    if (m_lisa->IsPowerOn()) {
        wxMessageDialog dialog(this,
            _T("The emulation is currently running. If you quit now, the "
                "Lisa OS will be halted immediately, and any unsaved data "
                "will be lost. To shut down cleanly, use the power key. Are "
                "you sure you wish to quit?"),
            _T("Confirm Quit"),
            wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION);

        quit = (dialog.ShowModal() == wxID_YES);
    }

    if (quit) Close(true);
}


// Edit menu
void LisaEmFrame::OnPaste(wxCommandEvent& event)
{

}


// Keyboard menu
/*
 * Arguably, we shouldn't be generating these keypresses ourselves at
 * all; we're not supposed to meddle with the emulator state directly on
 * our own; m_lisa does that on our behalf.
 */

void LisaEmFrame::OnPowerKey(wxCommandEvent& event)
{
    if (!m_lisa->IsPowerOn()) {
        m_lisa->SetPowerOn(true);
        return;
    }

    presspowerswitch();
}


void LisaEmFrame::OnAppleDot(wxCommandEvent& WXUNUSED(event))
{
    apple_dot();
}

void LisaEmFrame::OnAppleS(wxCommandEvent& WXUNUSED(event))
{
    apple_S();
}

void LisaEmFrame::OnAppleEnter(wxCommandEvent& WXUNUSED(event))
{
    apple_enter();
}

void LisaEmFrame::OnAppleREnter(wxCommandEvent& WXUNUSED(event))
{
    apple_renter();
}

void LisaEmFrame::OnApple1(wxCommandEvent& WXUNUSED(event))
{
    apple_1();
}

void LisaEmFrame::OnApple2(wxCommandEvent& WXUNUSED(event))
{
    apple_2();
}

void LisaEmFrame::OnApple3(wxCommandEvent& WXUNUSED(event))
{
    apple_3();
}

void LisaEmFrame::OnShiftOpt0(wxCommandEvent& WXUNUSED(event))
{
    shift_option_0();
}

void LisaEmFrame::OnShiftOpt4(wxCommandEvent& WXUNUSED(event))
{
    shift_option_4();
}

void LisaEmFrame::OnShiftOpt7(wxCommandEvent& WXUNUSED(event))
{
    shift_option_7();
}

void LisaEmFrame::OnRawKeyboard(wxCommandEvent& event)
{
    m_lisa->SetRawKeyboard(event.IsChecked());
}

// View menu
void LisaEmFrame::OnUncorrected(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetVideoMode(VIDEO_UNCORRECTED);
}

void LisaEmFrame::OnCorrected(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetVideoMode(VIDEO_CORRECTED);
}

void LisaEmFrame::OnEnhanced(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetVideoMode(VIDEO_ENHANCED);
}

void LisaEmFrame::OnSkin(wxCommandEvent& event)
{
    m_lisa->SetSkinOn(event.IsChecked());
}

// Throttle menu
void LisaEmFrame::OnThrottle5(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetThrottleSpeed(5000000);
}

void LisaEmFrame::OnThrottle8(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetThrottleSpeed(8000000);
}

void LisaEmFrame::OnThrottle10(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetThrottleSpeed(10000000);
}

void LisaEmFrame::OnThrottle15(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetThrottleSpeed(15000000);
}

void LisaEmFrame::OnThrottle20(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetThrottleSpeed(20000000);
}

void LisaEmFrame::OnThrottle25(wxCommandEvent& WXUNUSED(event))
{
    m_lisa->SetThrottleSpeed(25000000);
}

void LisaEmFrame::OnThrottleOther(wxCommandEvent & WXUNUSED(event))
{
    int hertz;

    /*
     * wxWindows doesn't mask wxTimer events when a modal dialog is
     * displayed, so we've got to manually remember if the emu is paused,
     * pause it, display the dialog and restore the pause state after the
     * dialog is dismissed.
     */
    bool old_paused = m_lisa->IsPaused();
    m_lisa->SetPaused(true);
    hertz = ::wxGetNumberFromUser(
        _T("Please enter a target clock speed (in Hertz) for the Lisa emulator.\n"
        "Note, if the target is very low (<1 kHz), it may not be simulated accurately.\n"
        "The upper clock speed is limited by the host computer."),
        _T("Clock speed:"),
        _T("Set Throttle Speed"),
        m_lisa->GetThrottleSpeed(),
        1000, 1000000000,
        this);
    m_lisa->SetPaused(old_paused);
    if (hertz != -1) m_lisa->SetThrottleSpeed(hertz);
}

// Help menu
void LisaEmFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxAboutDialogInfo info;
    info.SetName(_T("LisaEm"));
    info.SetVersion(_T("0.9.9 Beta"));
    info.SetDescription(_T("The first fully functional Apple Lisa emulator."));
    info.SetCopyright(_T("\xa9 2007 Ray Arachelian"));
    wxAboutBox(info);
}

void LisaEmFrame::OnLisaWeb(wxCommandEvent& WXUNUSED(event))
{
    ::wxLaunchDefaultBrowser("http://lisaem.sunder.net");
}

void LisaEmFrame::OnLisaFAQ(wxCommandEvent& WXUNUSED(event))
{
    ::wxLaunchDefaultBrowser("http://lisafaq.sunder.net");
}

/*
 * Called when the emulator state has changed in a way that requires us
 * to update our menu settings
 */
void LisaEmFrame::OnUpdateUI(wxUpdateUIEvent& WXUNUSED(event))
{
    UpdateMenus();
}
