/////////////////////////////////////////////////////////////////////////////
// Name:        TitanFrame.cpp
// Purpose:     
// Author:      Vince Harron
// Modified by: 
// Created:     06/07/05 12:57:53
// RCS-ID:      
// Copyright:   2005 Sony Online Entertainment
// Licence:     
/////////////////////////////////////////////////////////////////////////////

#if defined(__GNUG__) && !defined(__APPLE__)
#pragma implementation "TitanFrame.h"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

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

////@begin includes
////@end includes

#include "wx/joystick.h"

#include "TitanFrame.h"
#include "Titan.h"
#include "TitanUI.h"
#include "TitanHUD.h"
#include "TiCharacterWindow.h"
#include "TiActivateWindow.h"
#include "TiMenu.h"
#include "PawnDebug.h"
#include "SyBuildVersion.h"
#include "SyDebug.h"

////@begin XPM images
////@end XPM images

/*!
 * TitanFrame type definition
 */

IMPLEMENT_CLASS( TitanFrame, wxFrame )

/*!
 * TitanFrame event table definition
 */

BEGIN_EVENT_TABLE( TitanFrame, wxFrame )

////@begin TitanFrame event table entries
    EVT_ERASE_BACKGROUND( TitanFrame::OnEraseBackground )
    EVT_KEY_DOWN( TitanFrame::OnKeyDown )
    EVT_KEY_UP( TitanFrame::OnKeyUp )

    EVT_MENU( ID_MENU_NTSC, TitanFrame::OnMenuNtscClick )

    EVT_MENU( ID_MENU_480P, TitanFrame::OnMenu480pClick )

    EVT_MENU( ID_MENU_720P, TitanFrame::OnMenu720pClick )

    EVT_MENU( ID_MENU_1080P, TitanFrame::OnMenu1080pClick )

    EVT_MENU( ID_MENU_960x624, TitanFrame::OnMenu960x624Click )

    EVT_MENU( ID_MENU_1920x1248, TitanFrame::OnMenu1920x1248Click )

    EVT_MENU( ID_MENUITEM_INVISIBLE, TitanFrame::OnMenuitemInvisibleClick )
    EVT_UPDATE_UI( ID_MENUITEM_INVISIBLE, TitanFrame::OnMenuitemInvisibleUpdate )

    EVT_MENU( ID_MENUITEM_GOD, TitanFrame::OnMenuitemGodClick )
    EVT_UPDATE_UI( ID_MENUITEM_GOD, TitanFrame::OnMenuitemGodUpdate )

    EVT_MENU( ID_MENUITEM_LOG, TitanFrame::OnMenuitemLogClick )
    EVT_UPDATE_UI( ID_MENUITEM_LOG, TitanFrame::OnMenuitemLogUpdate )

    EVT_MENU( ID_MENUITEM_LABEL, TitanFrame::OnMenuitemLabelClick )
    EVT_UPDATE_UI( ID_MENUITEM_LABEL, TitanFrame::OnMenuitemLabelUpdate )

    EVT_MENU( ID_MENUITEM_RESTART, TitanFrame::OnMenuitemRestartClick )

    EVT_MENU( ID_MENUITEM_BLOOM, TitanFrame::OnMenuitemBloomClick )
    EVT_UPDATE_UI( ID_MENUITEM_BLOOM, TitanFrame::OnMenuitemBloomUpdate )

    EVT_MENU( ID_MENUITEM_SKY, TitanFrame::OnMenuitemSkyClick )
    EVT_UPDATE_UI( ID_MENUITEM_SKY, TitanFrame::OnMenuitemSkyUpdate )

    EVT_MENU( ID_MENUITEM_MULTI_PASS, TitanFrame::OnMenuitemMultiPassClick )
    EVT_UPDATE_UI( ID_MENUITEM_MULTI_PASS, TitanFrame::OnMenuitemMultiPassUpdate )

    EVT_MENU( ID_MENUITEM_RENDER_STATS, TitanFrame::OnMenuitemRenderStatsClick )
    EVT_UPDATE_UI( ID_MENUITEM_RENDER_STATS, TitanFrame::OnMenuitemRenderStatsUpdate )

    EVT_MENU( ID_MENUITEM_RENDER_DRAWMODE_NORMAL, TitanFrame::OnMenuitemRenderDrawmodeNormalClick )
    EVT_UPDATE_UI( ID_MENUITEM_RENDER_DRAWMODE_NORMAL, TitanFrame::OnMenuitemRenderDrawmodeNormalUpdate )

    EVT_MENU( ID_MENUITEM_RENDER_DRAWMODE_WIRE, TitanFrame::OnMenuitemRenderDrawmodeWireClick )
    EVT_UPDATE_UI( ID_MENUITEM_RENDER_DRAWMODE_WIRE, TitanFrame::OnMenuitemRenderDrawmodeWireUpdate )

    EVT_MENU( ID_MENUITEM_RENDER_DRAWMODE_SOLIDFILL, TitanFrame::OnMenuitemRenderDrawmodeSolidfillClick )
    EVT_UPDATE_UI( ID_MENUITEM_RENDER_DRAWMODE_SOLIDFILL, TitanFrame::OnMenuitemRenderDrawmodeSolidfillUpdate )

    EVT_MENU( ID_MENUITEM_BUILDINFO, TitanFrame::OnMenuitemBuildinfoClick )

    EVT_MENU( ID_MENUITEM_WXCARLO, TitanFrame::OnMenuitemWxcarloClick )

    EVT_MENU( ID_MENUITEM_WXVINCE, TitanFrame::OnMenuitemWxvinceClick )

    EVT_MENU( ID_MENUITEM_MONO, TitanFrame::OnMenuitemMonoClick )
    EVT_UPDATE_UI( ID_MENUITEM_MONO, TitanFrame::OnMenuitemMonoUpdate )

    EVT_MENU( ID_MENUITEM_STEREO, TitanFrame::OnMenuitemStereoClick )
    EVT_UPDATE_UI( ID_MENUITEM_STEREO, TitanFrame::OnMenuitemStereoUpdate )

    EVT_MENU( ID_MENUITEM_SURROUND51, TitanFrame::OnMenuitemSurround51Click )
    EVT_UPDATE_UI( ID_MENUITEM_SURROUND51, TitanFrame::OnMenuitemSurround51Update )

    EVT_MENU( ID_MENUITEM_SURROUND71, TitanFrame::OnMenuitemSurround71Click )
    EVT_UPDATE_UI( ID_MENUITEM_SURROUND71, TitanFrame::OnMenuitemSurround71Update )

////@end TitanFrame event table entries
    EVT_JOY_BUTTON_DOWN( TitanFrame::OnJoyButtonDown )

    EVT_JOY_BUTTON_UP( TitanFrame::OnJoyButtonUp )

    EVT_TIMER( wxID_ANY, TitanFrame::OnTimer )

    EVT_DISPLAY_CHANGED( TitanFrame::OnDisplayChanged )

END_EVENT_TABLE()

/*!
 * TitanFrame constructors
 */

TitanFrame::TitanFrame( ) :
  mbShowPawnOutput(false)
{
    mpHUD = NULL;
    mpCharacterWin = NULL;
    mpActivateWin = NULL;
    mpTitanMenu = NULL;
}

TitanFrame::TitanFrame( const char *netRecordFilename, 
                        const char *netPlaybackFilename, 
                        bool bloomEnabled, 
                        bool multiPass, 
                        bool net, 
                        const char *level_name, 
                        bool showUI, 
                        bool pawnDebug,
                        bool checkArt,
                        int numPlayers,
                        wxWindow* parent, 
                        wxWindowID id, 
                        const wxString& caption, 
                        const wxPoint& pos, 
                        const wxSize& size, 
                        long style ):
 mbShowPawnOutput(false)
{
    mpHUD = NULL; 
    mpCharacterWin = NULL;
    mpActivateWin = NULL;
    mpTitanMenu = NULL;
    Create( netRecordFilename, 
            netPlaybackFilename, 
            bloomEnabled, 
            multiPass, 
            net, 
            level_name, 
            showUI, 
            pawnDebug,
            checkArt,
            numPlayers,
            parent, 
            id, 
            caption, 
            pos, 
            size, 
            style );
}

TitanFrame::~TitanFrame()
{
  mpTitan->Close();
  delete mpTitan;
  delete mpTitanUI;
  delete mpStartMenu;
  delete mpHUD;
  delete mpCharacterWin;
  delete mpActivateWin;
  delete mpTitanMenu;
}

/*!
 * TitanFrame creator
 */

bool TitanFrame::Create( const char *netRecordFilename, 
                         const char *netPlaybackFilename, 
                         bool bloomEnabled, 
                         bool multiPass, 
                         bool net, 
                         const char *level_name, 
                         bool showUI,
                         bool pawnDebug, 
                         bool checkArt,
                         int numPlayers,
                         wxWindow* parent, 
                         wxWindowID id, 
                         const wxString& caption, 
                         const wxPoint& pos, 
                         const wxSize& size, 
                         long style)
{
    mNet = net;
    mbShowUI = showUI;
    mWxTest = false;
    mFramesRendered = 0;

////@begin TitanFrame member initialization
////@end TitanFrame member initialization

////@begin TitanFrame creation
    wxFrame::Create( parent, id, caption, pos, size, style );

    CreateControls();
    Centre();
////@end TitanFrame creation

    mpTitanUI = new TitanUI( this );
    mpTitan = TitanI::Create( mpTitanUI );
    mpTitan->SetMultiPass(multiPass);
    mpTitan->SetBloom(bloomEnabled);
    mpTitan->SetNumLocalPlayers(numPlayers);
    if (pawnDebug)
    {
      mpTitan->ScriptEnableDebugging();
    }


    mTime = wxGetLocalTimeMillis();

    if ( !mpTitan->Init( mTime.GetValue() ) )
    {
      return false;
    }

    if ( mNet )
    {
        // multiplayer startup
        mpTitan->HackStartupNetwork("Kaiser Sose", "Test Game", level_name, netRecordFilename, netPlaybackFilename);
    }
    else
    {
        // standard single-player startup
        mpTitan->LoadLevel(level_name);
    }

    mbShowStats = false;
    mpStatsPanel->Show( mbShowStats );

    // activate message
    mpActivateWin = new TiActivateWindow( this, mpTitan, 0 );

    // wrapper UI for the start menu
    mpTitanMenu = new TiMenu( this, mpTitan, 0 );
    mpTitanMenu->SetCentered( true );
    mpTitanMenu->Close( true );

    Layout();

    return TRUE;                        
}

/*!
 * Control creation for TitanFrame
 */

void TitanFrame::CreateControls()
{    
////@begin TitanFrame content construction
    TitanFrame* itemFrame1 = this;

    wxMenuBar* menuBar = new wxMenuBar;
    wxMenu* itemMenu27 = new wxMenu;
    wxMenu* itemMenu28 = new wxMenu;
    itemMenu28->Append(ID_MENU_NTSC, _("NTSC"), _T(""), wxITEM_NORMAL);
    itemMenu28->Append(ID_MENU_480P, _("480p"), _T(""), wxITEM_NORMAL);
    itemMenu28->Append(ID_MENU_720P, _("720p"), _T(""), wxITEM_NORMAL);
    itemMenu28->Append(ID_MENU_1080P, _("1080p"), _T(""), wxITEM_NORMAL);
    itemMenu28->Append(ID_MENU_960x624, _("960x624 (film gate)"), _T(""), wxITEM_NORMAL);
    itemMenu28->Append(ID_MENU_1920x1248, _("1920x1248 (film gate)"), _T(""), wxITEM_NORMAL);
    itemMenu27->Append(ID_MENU, _("Display Resolution"), itemMenu28);
    wxMenu* itemMenu35 = new wxMenu;
    itemMenu35->Append(ID_MENUITEM_INVISIBLE, _("Invisible"), _T(""), wxITEM_CHECK);
    itemMenu35->Append(ID_MENUITEM_GOD, _("God"), _T(""), wxITEM_CHECK);
    itemMenu35->Append(ID_MENUITEM_LOG, _("Log"), _T(""), wxITEM_CHECK);
    itemMenu35->Append(ID_MENUITEM_LABEL, _("Debug Label"), _T(""), wxITEM_CHECK);
    itemMenu35->AppendSeparator();
    itemMenu35->Append(ID_MENUITEM_RESTART, _("Restart"), _T(""), wxITEM_NORMAL);
    itemMenu27->Append(ID_MENU_DESIGN, _("Design"), itemMenu35);
    wxMenu* itemMenu42 = new wxMenu;
    itemMenu42->Append(ID_MENUITEM_BLOOM, _("Bloom"), _T(""), wxITEM_CHECK);
    itemMenu42->Append(ID_MENUITEM_SKY, _("Sky"), _T(""), wxITEM_CHECK);
    itemMenu42->Append(ID_MENUITEM_MULTI_PASS, _("Multi Pass"), _T(""), wxITEM_CHECK);
    itemMenu42->Append(ID_MENUITEM_RENDER_STATS, _("Display Stats"), _T(""), wxITEM_CHECK);
    wxMenu* itemMenu47 = new wxMenu;
    itemMenu47->Append(ID_MENUITEM_RENDER_DRAWMODE_NORMAL, _("Normal"), _T(""), wxITEM_RADIO);
    itemMenu47->Append(ID_MENUITEM_RENDER_DRAWMODE_WIRE, _("Wireframe"), _T(""), wxITEM_RADIO);
    itemMenu47->Append(ID_MENUITEM_RENDER_DRAWMODE_SOLIDFILL, _("Solid Fill"), _T(""), wxITEM_RADIO);
    itemMenu42->Append(ID_MENUITEM_RENDER_DRAWMODE, _("Draw Mode"), itemMenu47);
    itemMenu27->Append(ID_MENU_RENDER, _("Render"), itemMenu42);
    wxMenu* itemMenu51 = new wxMenu;
    itemMenu51->Append(ID_MENUITEM_BUILDINFO, _("Build Info"), _T(""), wxITEM_NORMAL);
    itemMenu51->Append(ID_MENUITEM_WXCARLO, _("wxCarlo"), _T(""), wxITEM_NORMAL);
    itemMenu51->Append(ID_MENUITEM_WXVINCE, _("wxVince"), _T(""), wxITEM_NORMAL);
    itemMenu27->Append(ID_MENU_PROGRAMMING, _("Programming"), itemMenu51);
    wxMenu* itemMenu55 = new wxMenu;
    itemMenu55->Append(ID_MENUITEM_MONO, _("Mono"), _T(""), wxITEM_RADIO);
    itemMenu55->Append(ID_MENUITEM_STEREO, _("Stereo"), _T(""), wxITEM_RADIO);
    itemMenu55->Append(ID_MENUITEM_SURROUND51, _("5.1 Surround"), _T(""), wxITEM_RADIO);
    itemMenu55->Append(ID_MENUITEM_SURROUND71, _("7.1 Surround"), _T(""), wxITEM_RADIO);
    itemMenu27->Append(ID_MENU_SOUND, _("Sound"), itemMenu55);
    menuBar->Append(itemMenu27, _("Menu"));
    itemFrame1->SetMenuBar(menuBar);

    mpMainSizer = new wxBoxSizer(wxVERTICAL);
    itemFrame1->SetSizer(mpMainSizer);

    mpStatsPanel = new wxPanel( itemFrame1, ID_PANEL, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER|wxTAB_TRAVERSAL );
    mpMainSizer->Add(mpStatsPanel, 0, wxALIGN_RIGHT|wxALL, 5);

    mpStatsGrid = new wxFlexGridSizer(2, 3, 0, 0);
    mpStatsPanel->SetSizer(mpStatsGrid);

    wxStaticText* itemStaticText5 = new wxStaticText( mpStatsPanel, wxID_STATIC, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText5, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    wxStaticText* itemStaticText6 = new wxStaticText( mpStatsPanel, wxID_STATIC, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText6, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    wxStaticText* itemStaticText7 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("Avg"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText7, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    wxStaticText* itemStaticText8 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("FPS"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText8, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    mpFPS = new wxStaticText( mpStatsPanel, ID_FPS, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpFPS, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    mpFPSAvg = new wxStaticText( mpStatsPanel, ID_FPS_AVG, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpFPSAvg, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    wxStaticText* itemStaticText11 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("Batches"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText11, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    mpBatches = new wxStaticText( mpStatsPanel, ID_STATICTEXT, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpBatches, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    mpBatchesAvg = new wxStaticText( mpStatsPanel, ID_STATICTEXT2, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpBatchesAvg, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    wxStaticText* itemStaticText14 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("Vertexes"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    mpVertexes = new wxStaticText( mpStatsPanel, ID_STATICTEXT3, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpVertexes, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    mpVertexesAvg = new wxStaticText( mpStatsPanel, ID_STATICTEXT4, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpVertexesAvg, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    wxStaticText* itemStaticText17 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("Triangles"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText17, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    mpTriangles = new wxStaticText( mpStatsPanel, ID_STATICTEXT5, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpTriangles, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    mpTrianglesAvg = new wxStaticText( mpStatsPanel, ID_STATICTEXT1, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpTrianglesAvg, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    wxStaticText* itemStaticText20 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("Deg Tris"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText20, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    mpDegenerateTriangles = new wxStaticText( mpStatsPanel, ID_STATICTEXT7, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpDegenerateTriangles, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    mpDegenerateTrianglesAvg = new wxStaticText( mpStatsPanel, ID_STATICTEXT6, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpDegenerateTrianglesAvg, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    wxStaticText* itemStaticText23 = new wxStaticText( mpStatsPanel, wxID_STATIC, _("Fill"), wxDefaultPosition, wxDefaultSize, 0 );
    mpStatsGrid->Add(itemStaticText23, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    mpFill = new wxStaticText( mpStatsPanel, ID_STATICTEXT8, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpFill, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

    mpFillAvg = new wxStaticText( mpStatsPanel, ID_STATICTEXT9, _("0000000000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE );
    mpStatsGrid->Add(mpFillAvg, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5);

////@end TitanFrame content construction

    // detach menu
    wxMenuBar* menuBarX = GetMenuBar();
    SetMenuBar(0);
    mpStartMenu = menuBarX->Remove(0);
    delete menuBarX;

    // fix min size of all grid items
    wxSizerItemList& children = mpStatsGrid->GetChildren();
    wxSizerItemList::compatibility_iterator node = children.GetFirst();
    while (node)
    {
      wxSizerItem *item = node->GetData();

      if ( item->IsWindow() )
      {
        wxWindow* window = item->GetWindow();
        window->SetMinSize( window->GetSize() );
      }

      node = node->GetNext();
    }

    // health display
    mpHUD = new TitanHUD( this, mpTitan, 0 );
    mpHUD->SetPosition( wxPoint(100,60) );
    mpHUD->Show( GetShowUI() );
}

/*!
 * Should we show tooltips?
 */

bool TitanFrame::ShowToolTips()
{
    return TRUE;
}

/*
 * CloseCharacterWindow
 *  private method
 */

void TitanFrame::CloseCharacterWindow()
{
  if( mpCharacterWin )
  {
    mpCharacterWin->Destroy();
    mpCharacterWin = NULL;
    this->SetFocus();
  }
  mpTitan->UnpauseGame();
}

/*
* OpenCharacterWindow
*  private method
*/

void TitanFrame::OpenCharacterWindow()
{
  mpCharacterWin = new TiCharacterWindow( this, mpTitan, 0 );
  Connect( ID_TITAN_CHARACTER, TIWINDOW_CLOSE, (wxObjectEventFunction)(TiWindowEventFunction)&TitanFrame::OnCharacterWindowClose );
  mpCharacterWin->Show( true );
  mpCharacterWin->SetFocus();
  mpTitan->PauseGame();
}

/*!
* wxEVT_JOY_BUTTON_DOWN event handler
*/

void TitanFrame::OnJoyButtonDown( wxJoystickEvent& event )
{
  if ( FindFocus() == this && m_eventHandler == this ) // need a different way of figuring out if the main frame has focus
  {
    // this window has keyboard focus 
    // and there are no event handlers intercepting events,
    // go ahead and process joystick buttons
    TitanButton tb = mpTitanUI->GetTitanButton( event.GetButtonChange() );
    if ( tb != ButtonMax && tb != ButtonPause )
    {
      TitanInputHandlerI* inputHandler =  mpTitan->GetInputHandler( event.GetJoystick() );
      inputHandler->OnButtonDown( tb );
    }
    else
    {
      event.Skip();
    }
  }
  else
  {
    // some other window has keyboard focus, don't process joystick buttons
    event.Skip();
  }
}

/*!
* wxEVT_JOY_BUTTON_UP event handler
*/

void TitanFrame::OnJoyButtonUp( wxJoystickEvent& event )
{
  if ( FindFocus() == this && GetEventHandler() == this  )
  {
    TitanButton tb = mpTitanUI->GetTitanButton( event.GetButtonChange() );
    if ( tb != ButtonMax )
    {
      TitanInputHandlerI* inputHandler =  mpTitan->GetInputHandler( event.GetJoystick() );
      inputHandler->OnButtonUp( tb );
    }
  }
  else
  {
    event.Skip();
  }
}

/*!
* wxEVT_ERASE_BACKGROUND event handler
*/

void TitanFrame::OnEraseBackground( wxEraseEvent& event )
{
  static int i = 0;
  if ( mWxTest )
  {
    wxSize client = GetClientSize();
    if ( client.x != 0 && client.y != 0 )
    {
      wxBitmap temp( wxT("test/melee.tga") );
      int x = ( i % client.x );
      int y = ( i/2 % client.y );
#if 0 // alpha test
      event.GetDC()->SetAlpha( 0.5f );
      event.GetDC()->SetTiled( wxHORIZONTAL, true );
      event.GetDC()->DrawBitmap( 
        temp,
        x, y, 
        temp.GetWidth()*2, temp.GetHeight(), 
        0, temp.GetHeight()/2,
        temp.GetWidth(), temp.GetHeight()/2
        );
#elif 0
      event.GetDC()->SetTiled( wxHORIZONTAL, true );
      event.GetDC()->SetTiled( wxVERTICAL, true );
      event.GetDC()->DrawBitmap( 
        temp,
        x, y, 
        temp.GetWidth()*8, temp.GetHeight()*8, 
        0, 0,
        temp.GetWidth(), temp.GetHeight()
        );
      event.GetDC()->SetTiled( wxHORIZONTAL, false );
      event.GetDC()->SetTiled( wxVERTICAL, false );
#else
      event.GetDC()->SetTiled( wxHORIZONTAL, true );
      event.GetDC()->SetTiled( wxVERTICAL, true );
      event.GetDC()->DrawBitmap( 
                                temp,
                                0, 0,
                                temp.GetWidth()*8, temp.GetHeight()*8, 
                                x, y, 
                                temp.GetWidth(), temp.GetHeight()
                                );
      event.GetDC()->SetTiled( wxHORIZONTAL, false );
      event.GetDC()->SetTiled( wxVERTICAL, false );
#endif
      i += 1;
    }
  }
}

/*!
 * Get bitmap resources
 */

wxBitmap TitanFrame::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin TitanFrame bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end TitanFrame bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon TitanFrame::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin TitanFrame icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end TitanFrame icon retrieval
}

/*!
* wxEVT_TIMER event handler for ID_FRAME
*/

void TitanFrame::OnTimer( wxTimerEvent& event )
{
}

/*!
* wxEVT_DISPLAY_CHANGED event handler for ID_FRAME
*/

void TitanFrame::OnDisplayChanged( wxDisplayChangedEvent& event )
{
  wxSize size = wxGetDisplaySize();
  SetSize( size );
}

/*!
 * TIWINDOW_CLOSE event handler for ID_TITAN_CHARACTER
 */

void TitanFrame::OnCharacterWindowClose( TiWindowEvent& event )
{
  CloseCharacterWindow();
}

// Handles the update game event
void TitanFrame::OnUpdateGame()
{
  mpFPS->SetLabel(          wxString::Format( wxT("%i"), mpTitan->GetFPS() ) );
  mpFPSAvg->SetLabel(       wxString::Format( wxT("%i"), mpTitan->GetAverageFPS() ) );
  mpBatches->SetLabel(      wxString::Format( wxT("%i"), mpTitan->GetBatches() ) );
  mpBatchesAvg->SetLabel(   wxString::Format( wxT("%i"), mpTitan->GetAverageBatches() ) );
  mpVertexes->SetLabel(     wxString::Format( wxT("%i"), mpTitan->GetVertexes() ) );
  mpVertexesAvg->SetLabel(  wxString::Format( wxT("%i"), mpTitan->GetAverageVertexes() ) );
  mpTriangles->SetLabel(    wxString::Format( wxT("%i"), mpTitan->GetTriangles() ) );
  mpTrianglesAvg->SetLabel( wxString::Format( wxT("%i"), mpTitan->GetAverageTriangles() ) );
  mpDegenerateTriangles->SetLabel(    wxString::Format( wxT("%i"), mpTitan->GetDegenerateTriangles() ) );
  mpDegenerateTrianglesAvg->SetLabel( wxString::Format( wxT("%i"), mpTitan->GetAverageDegenerateTriangles() ) );
  mpFill->SetLabel( wxString::Format( wxT("%u"), mpTitan->GetPixels() ) );
  mpFillAvg->SetLabel( wxString::Format( wxT("%u"), mpTitan->GetPixels() ) );

  // update health bars
  mpHUD->SetHealthMax( mpTitan->GetPlayerHealthMax() );
  mpHUD->SetHealth( mpTitan->GetPlayerHealth() );
  mpHUD->SetBlockMax( mpTitan->GetPlayerBlockMax() );
  mpHUD->SetBlock( mpTitan->GetPlayerBlock() );
  mpHUD->SetXPMax( mpTitan->GetPlayerNextLevelExp() - mpTitan->GetPlayerPrevLevelExp() );
  mpHUD->SetXP( mpTitan->GetPlayerCurExp() - mpTitan->GetPlayerPrevLevelExp() );
  mpHUD->Show( GetShowUI() );

  // update activate message
  if( GetShowUI() )
  {
    const int BUF_LEN = 256;
    char buf[BUF_LEN];
    buf[0] = 0;

    mpTitan->GetActivateString( buf, BUF_LEN );
    mpActivateWin->SetText( _(buf) );
  }
  else
  {
    mpActivateWin->Show( false );
  }

  mTime = wxGetLocalTimeMillis();
  mpTitan->Update( mTime.GetValue() );

  mFramesRendered++;
}

// Handles the render game event
void TitanFrame::OnRenderGame()
{
  mpTitan->Render();
}

void TitanFrame::OnRenderHUD()
{
  if (mpTitan) 
  {
    mpTitan->RenderHUD();
  }
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_NTSC
 */

void TitanFrame::OnMenuNtscClick( wxCommandEvent& event )
{
  wxSetDisplaySize( wxSize( 640, 480 ) );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_480P
 */

void TitanFrame::OnMenu480pClick( wxCommandEvent& event )
{
  wxSetDisplaySize( wxSize( 852, 480 ) );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_720P
 */

void TitanFrame::OnMenu720pClick( wxCommandEvent& event )
{
  wxSetDisplaySize( wxSize( 1280, 720 ) );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_1080P
 */

void TitanFrame::OnMenu1080pClick( wxCommandEvent& event )
{
  wxSetDisplaySize( wxSize( 1920, 1080 ) );
}


/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_960x624
 */

void TitanFrame::OnMenu960x624Click( wxCommandEvent& event )
{
  wxSetDisplaySize( wxSize( 960, 624 ) );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_1920x1248
 */

void TitanFrame::OnMenu1920x1248Click( wxCommandEvent& event )
{
  wxSetDisplaySize( wxSize( 1920, 1248 ) );
}


/*!
 * wxEVT_KEY_DOWN event handler for ID_FRAME
 */

void TitanFrame::OnKeyDown( wxKeyEvent& event )
{
  int keyCode = event.GetKeyCode();
  switch ( keyCode )
  {
  case 'Z':
    SetShowUI( ! GetShowUI() );
    break;
  case 'S':
    StartPerformanceProfile();
    break;
  case WXK_F2:      // "start" button; see SyJoystick::TranslateButtonToKey()
  case WXK_ESCAPE:
    mpTitanMenu->PopupMenu( mpStartMenu );
    break;

  case WXK_F1:      // "select" button; see SyJoystick::TranslateButtonToKey()
    OpenCharacterWindow();
    break;

  case 'O':
    // dialog test
    mbShowPawnOutput = !mbShowPawnOutput;
    mpTitanUI->PawnDebugShowOutput(mbShowPawnOutput);
    break;

  default:
    mpTitan->CheatKey(keyCode);
  }
}

void TitanFrame::StartPerformanceProfile()
 {
  static int i = 0;
  i++;
 }

/*!
 * wxEVT_KEY_UP event handler for ID_FRAME
 */

void TitanFrame::OnKeyUp( wxKeyEvent& event )
{
}


/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_BLOOM
 */

void TitanFrame::OnMenuitemMultiPassClick( wxCommandEvent& event )
{
  mpTitan->SetMultiPass( event.IsChecked() );
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_BLOOM
 */

void TitanFrame::OnMenuitemMultiPassUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetMultiPass() );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_FRAMETIME
 */

void TitanFrame::OnMenuitemRenderStatsClick( wxCommandEvent& event )
{
  if ( mbShowStats == event.IsChecked() )
  {
    // no change
    return;
  }
  mbShowStats = event.IsChecked();
  mpStatsPanel->Show( mbShowStats );
  Layout();
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_FRAMETIME
 */

void TitanFrame::OnMenuitemRenderStatsUpdate( wxUpdateUIEvent& event )
{
  event.Check( mbShowStats );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_INVISIBLE
 */

void TitanFrame::OnMenuitemInvisibleClick( wxCommandEvent& event )
{
  mpTitan->SetInvisibleMode(event.IsChecked());
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_INVISIBLE
 */

void TitanFrame::OnMenuitemInvisibleUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetInvisibleMode() );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_GOD
 */

void TitanFrame::OnMenuitemGodClick( wxCommandEvent& event )
{
  mpTitan->SetGodMode(event.IsChecked());
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_GOD
 */

void TitanFrame::OnMenuitemGodUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetGodMode() );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_LOG
 */

void TitanFrame::OnMenuitemLogClick( wxCommandEvent& event )
{
  mpTitan->SetLogMode(event.IsChecked());
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_LOG
 */

void TitanFrame::OnMenuitemLogUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetLogMode() );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_RESTART
 */

void TitanFrame::OnMenuitemRestartClick( wxCommandEvent& event )
{
  bool bGodMode = mpTitan->GetGodMode();
  bool bInvisibleMode = mpTitan->GetInvisibleMode();
  mpTitan->Restart();
  
  // player gets recreated, so we need to restore these flags ourselves
  if (bGodMode)
  {
    mpTitan->SetGodMode(true);
  }

  if (bInvisibleMode)
  {
    mpTitan->SetInvisibleMode(true);
  }
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_LABEL
 */

void TitanFrame::OnMenuitemLabelUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetDebugLabel() );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_LABEL
 */

void TitanFrame::OnMenuitemLabelClick( wxCommandEvent& event )
{
  mpTitan->SetDebugLabel(event.IsChecked());
}


/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM
 */

void TitanFrame::OnMenuitemBloomClick( wxCommandEvent& event )
{
  mpTitan->SetBloom( event.IsChecked() );
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM
 */

void TitanFrame::OnMenuitemBloomUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetBloom() );
}


/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_WXTEST
 */

void TitanFrame::OnMenuitemWxcarloClick( wxCommandEvent& event )
{
  // TEMP DEBUG
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_MONO
 */

void TitanFrame::OnMenuitemMonoClick( wxCommandEvent& event )
{
////@begin wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_MONO in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_MONO in TitanFrame. 
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_MONO
 */

void TitanFrame::OnMenuitemMonoUpdate( wxUpdateUIEvent& event )
{
////@begin wxEVT_UPDATE_UI event handler for ID_MENUITEM_MONO in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_UPDATE_UI event handler for ID_MENUITEM_MONO in TitanFrame. 
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_STEREO
 */

void TitanFrame::OnMenuitemStereoClick( wxCommandEvent& event )
{
////@begin wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_STEREO in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_STEREO in TitanFrame. 
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_STEREO
 */

void TitanFrame::OnMenuitemStereoUpdate( wxUpdateUIEvent& event )
{
////@begin wxEVT_UPDATE_UI event handler for ID_MENUITEM_STEREO in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_UPDATE_UI event handler for ID_MENUITEM_STEREO in TitanFrame. 
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SURROUND51
 */

void TitanFrame::OnMenuitemSurround51Click( wxCommandEvent& event )
{
////@begin wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SURROUND51 in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SURROUND51 in TitanFrame. 
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_SURROUND51
 */

void TitanFrame::OnMenuitemSurround51Update( wxUpdateUIEvent& event )
{
////@begin wxEVT_UPDATE_UI event handler for ID_MENUITEM_SURROUND51 in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_UPDATE_UI event handler for ID_MENUITEM_SURROUND51 in TitanFrame. 
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SURROUND71
 */

void TitanFrame::OnMenuitemSurround71Click( wxCommandEvent& event )
{
////@begin wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SURROUND71 in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SURROUND71 in TitanFrame. 
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_SURROUND71
 */

void TitanFrame::OnMenuitemSurround71Update( wxUpdateUIEvent& event )
{
////@begin wxEVT_UPDATE_UI event handler for ID_MENUITEM_SURROUND71 in TitanFrame.
    // Before editing this code, remove the block markers.
    event.Skip();
////@end wxEVT_UPDATE_UI event handler for ID_MENUITEM_SURROUND71 in TitanFrame. 
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_RENDER_DRAWMODE_NORMAL
 */

void TitanFrame::OnMenuitemRenderDrawmodeNormalClick( wxCommandEvent& event )
{
  mpTitan->SetDrawMode( TitanI::DrawModeNormal );
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_RENDER_DRAWMODE_NORMAL
 */

void TitanFrame::OnMenuitemRenderDrawmodeNormalUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetDrawMode() == TitanI::DrawModeNormal );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_RENDER_DRAWMODE_WIRE
 */

void TitanFrame::OnMenuitemRenderDrawmodeWireClick( wxCommandEvent& event )
{
  mpTitan->SetDrawMode( TitanI::DrawModeWire );
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_RENDER_DRAWMODE_WIRE
 */

void TitanFrame::OnMenuitemRenderDrawmodeWireUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetDrawMode() == TitanI::DrawModeWire );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_RENDER_DRAWMODE_SOLIDFILL
 */

void TitanFrame::OnMenuitemRenderDrawmodeSolidfillClick( wxCommandEvent& event )
{
  mpTitan->SetDrawMode( TitanI::DrawModeSolid );
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_RENDER_DRAWMODE_SOLIDFILL
 */

void TitanFrame::OnMenuitemRenderDrawmodeSolidfillUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetDrawMode() == TitanI::DrawModeSolid );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_WXVINCE
 */

void TitanFrame::OnMenuitemWxvinceClick( wxCommandEvent& event )
{
  mWxTest = !mWxTest;
  //::wxGetTextFromUser( wxT("Gimmie text, baby") );
}

/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_BUILDINFO
 */

void TitanFrame::OnMenuitemBuildinfoClick( wxCommandEvent& event )
{
  wxMessageBox(g_buildVersionString , "Build Number", wxOK, this);
}


/*!
 * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENUITEM_SKY
 */

void TitanFrame::OnMenuitemSkyClick( wxCommandEvent& event )
{
  mpTitan->SetEnableSky( event.IsChecked() );
}

/*!
 * wxEVT_UPDATE_UI event handler for ID_MENUITEM_SKY
 */

void TitanFrame::OnMenuitemSkyUpdate( wxUpdateUIEvent& event )
{
  event.Check( mpTitan->GetEnableSky() );
}


