1/////////////////////////////////////////////////////////////////////////////
2// Name:        forty.cpp
3// Purpose:     Forty Thieves patience game
4// Author:      Chris Breeze
5// Modified by:
6// Created:     21/07/97
7// RCS-ID:      $Id: forty.cpp 52452 2008-03-12 13:45:14Z JS $
8// Copyright:   (c) 1993-1998 Chris Breeze
9// Licence:     wxWindows licence
10//---------------------------------------------------------------------------
11// Last modified: 22nd July 1998 - ported to wxWidgets 2.0
12/////////////////////////////////////////////////////////////////////////////
13
14// For compilers that support precompilation, includes "wx/wx.h".
15#include "wx/wxprec.h"
16
17#ifdef __BORLANDC__
18#pragma hdrstop
19#endif
20
21#ifndef WX_PRECOMP
22#include "wx/wx.h"
23#endif
24
25#include "canvas.h"
26#include "forty.h"
27#include "card.h"
28#include "scoredg.h"
29#include "forty.xpm"
30
31#if wxUSE_HTML
32#include "wx/textfile.h"
33#include "wx/html/htmlwin.h"
34#endif
35
36#include "wx/stockitem.h"
37
38BEGIN_EVENT_TABLE(FortyFrame, wxFrame)
39    EVT_MENU(wxID_NEW, FortyFrame::NewGame)
40    EVT_MENU(wxID_EXIT, FortyFrame::Exit)
41    EVT_MENU(wxID_ABOUT, FortyFrame::About)
42    EVT_MENU(wxID_HELP_CONTENTS, FortyFrame::Help)
43    EVT_MENU(wxID_UNDO, FortyFrame::Undo)
44    EVT_MENU(wxID_REDO, FortyFrame::Redo)
45    EVT_MENU(SCORES, FortyFrame::Scores)
46    EVT_MENU(RIGHT_BUTTON_UNDO, FortyFrame::ToggleRightButtonUndo)
47    EVT_MENU(HELPING_HAND, FortyFrame::ToggleHelpingHand)
48    EVT_MENU(LARGE_CARDS, FortyFrame::ToggleCardSize)
49    EVT_CLOSE(FortyFrame::OnCloseWindow)
50END_EVENT_TABLE()
51
52// Create a new application object
53IMPLEMENT_APP (FortyApp)
54
55wxColour* FortyApp::m_backgroundColour = 0;
56wxColour* FortyApp::m_textColour = 0;
57wxBrush*  FortyApp::m_backgroundBrush = 0;
58
59FortyApp::~FortyApp()
60{
61    delete m_backgroundColour;
62    delete m_textColour;
63    delete m_backgroundBrush;
64    delete Card::m_symbolBmap;
65    delete Card::m_pictureBmap;
66
67}
68
69bool FortyApp::OnInit()
70{
71    bool largecards = false;
72#ifndef __WXWINCE__
73    m_helpFile = wxGetCwd() + wxFILE_SEP_PATH + wxT("about.htm");
74    if (!wxFileExists(m_helpFile))
75#endif
76    {
77        m_helpFile = wxPathOnly(argv[0]) + wxFILE_SEP_PATH + wxT("about.htm");
78    }
79
80    wxSize size(668,510);
81
82    if ((argc > 1) && (!wxStrcmp(argv[1],_T("-L"))))
83    {
84        largecards = true;
85        size = wxSize(1000,750);
86    }
87
88    FortyFrame* frame = new FortyFrame(
89            0,
90            _T("Forty Thieves"),
91            wxDefaultPosition,
92            size,
93            largecards
94    );
95
96     // Show the frame
97    frame->Show(true);
98
99    frame->GetCanvas()->ShowPlayerDialog();
100
101    return true;
102}
103
104const wxColour& FortyApp::BackgroundColour()
105{
106    if (!m_backgroundColour)
107    {
108        m_backgroundColour = new wxColour(0, 128, 0);
109    }
110
111    return *m_backgroundColour;
112}
113
114const wxBrush& FortyApp::BackgroundBrush()
115{
116    if (!m_backgroundBrush)
117    {
118        m_backgroundBrush = new wxBrush(BackgroundColour(), wxSOLID);
119    }
120
121    return *m_backgroundBrush;
122}
123
124const wxColour& FortyApp::TextColour()
125{
126    if (!m_textColour)
127    {
128        m_textColour = new wxColour(*wxBLACK);
129    }
130
131    return *m_textColour;
132}
133
134// My frame constructor
135FortyFrame::FortyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size, bool largecards):
136    wxFrame(frame, wxID_ANY, title, pos, size)
137{
138#ifdef __WXMAC__
139    wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
140#endif
141    // set the icon
142#ifdef __WXMSW__
143    SetIcon(wxIcon(_T("CardsIcon")));
144#else
145    SetIcon(wxIcon(forty_xpm));
146#endif
147
148    // Make a menu bar
149    wxMenu* gameMenu = new wxMenu;
150    gameMenu->Append(wxID_NEW, wxGetStockLabel(wxID_NEW), _T("Start a new game"));
151    gameMenu->Append(SCORES, _T("&Scores..."), _T("Displays scores"));
152    gameMenu->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT), _T("Exits Forty Thieves"));
153
154    wxMenu* editMenu = new wxMenu;
155    editMenu->Append(wxID_UNDO, wxGetStockLabel(wxID_UNDO), _T("Undo the last move"));
156    editMenu->Append(wxID_REDO, wxGetStockLabel(wxID_REDO), _T("Redo a move that has been undone"));
157
158    wxMenu* optionsMenu = new wxMenu;
159    optionsMenu->Append(RIGHT_BUTTON_UNDO,
160            _T("&Right button undo"),
161            _T("Enables/disables right mouse button undo and redo"),
162            true
163            );
164    optionsMenu->Append(HELPING_HAND,
165            _T("&Helping hand"),
166            _T("Enables/disables hand cursor when a card can be moved"),
167            true
168            );
169    optionsMenu->Append(LARGE_CARDS,
170            _T("&Large cards"),
171            _T("Enables/disables large cards for high resolution displays"),
172            true
173            );
174    optionsMenu->Check(HELPING_HAND, true);
175    optionsMenu->Check(RIGHT_BUTTON_UNDO, true);
176    optionsMenu->Check(LARGE_CARDS, largecards ? true : false);
177
178    wxMenu* helpMenu = new wxMenu;
179    helpMenu->Append(wxID_HELP_CONTENTS, _T("&Help Contents"), _T("Displays information about playing the game"));
180    helpMenu->Append(wxID_ABOUT, _T("&About..."), _T("About Forty Thieves"));
181
182    m_menuBar = new wxMenuBar;
183    m_menuBar->Append(gameMenu,    _T("&Game"));
184    m_menuBar->Append(editMenu,    _T("&Edit"));
185    m_menuBar->Append(optionsMenu, _T("&Options"));
186    m_menuBar->Append(helpMenu,    _T("&Help"));
187
188    SetMenuBar(m_menuBar);
189
190    if (largecards)
191        Card::SetScale(1.3);
192
193    m_canvas = new FortyCanvas(this, wxDefaultPosition, size);
194
195    wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
196    topsizer->Add( m_canvas, 1, wxEXPAND | wxALL, 0);
197    SetSizer( topsizer );
198
199#if wxUSE_STATUSBAR
200    CreateStatusBar();
201#endif // wxUSE_STATUSBAR
202
203    topsizer->SetSizeHints( this );
204}
205
206void FortyFrame::OnCloseWindow(wxCloseEvent& event)
207{
208    if (m_canvas->OnCloseCanvas() )
209    {
210        this->Destroy();
211    }
212    else
213        event.Veto();
214}
215
216void
217FortyFrame::NewGame(wxCommandEvent&)
218{
219    m_canvas->NewGame();
220}
221
222void
223FortyFrame::Exit(wxCommandEvent&)
224{
225    Close(true);
226}
227
228void
229FortyFrame::Help(wxCommandEvent& event)
230{
231#if wxUSE_HTML
232    if (wxFileExists(wxGetApp().GetHelpFile()))
233    {
234        FortyAboutDialog dialog(this, wxID_ANY, wxT("Forty Thieves Instructions"));
235        if (dialog.ShowModal() == wxID_OK)
236        {
237        }
238    }
239    else
240#endif
241    {
242        About(event);
243    }
244}
245
246void
247FortyFrame::About(wxCommandEvent&)
248{
249        wxMessageBox(
250            _T("Forty Thieves\n\n")
251            _T("A free card game written with the wxWidgets toolkit\n")
252            _T("Author: Chris Breeze (c) 1992-2004\n")
253            _T("email: chris@breezesys.com"),
254            _T("About Forty Thieves"),
255            wxOK|wxICON_INFORMATION, this
256            );
257}
258
259
260void
261FortyFrame::Undo(wxCommandEvent&)
262{
263    m_canvas->Undo();
264}
265
266void
267FortyFrame::Redo(wxCommandEvent&)
268{
269    m_canvas->Redo();
270}
271
272void
273FortyFrame::Scores(wxCommandEvent&)
274{
275    m_canvas->UpdateScores();
276    ScoreDialog scores(this, m_canvas->GetScoreFile());
277    scores.Display();
278}
279
280void
281FortyFrame::ToggleRightButtonUndo(wxCommandEvent& event)
282{
283    bool checked = m_menuBar->IsChecked(event.GetId());
284    m_canvas->EnableRightButtonUndo(checked);
285}
286
287void
288FortyFrame::ToggleHelpingHand(wxCommandEvent& event)
289{
290    bool checked = m_menuBar->IsChecked(event.GetId());
291    m_canvas->EnableHelpingHand(checked);
292}
293
294void
295FortyFrame::ToggleCardSize(wxCommandEvent& event)
296{
297        bool checked = m_menuBar->IsChecked(event.GetId());
298        Card::SetScale(checked ? 1.3 : 1);
299        m_canvas->LayoutGame();
300        m_canvas->Refresh();
301}
302
303//----------------------------------------------------------------------------
304// stAboutDialog
305//----------------------------------------------------------------------------
306
307FortyAboutDialog::FortyAboutDialog( wxWindow *parent, wxWindowID id, const wxString &title,
308    const wxPoint &position, const wxSize& size, long style ) :
309    wxDialog( parent, id, title, position, size, style )
310{
311    AddControls(this);
312
313    Centre(wxBOTH);
314}
315
316bool FortyAboutDialog::AddControls(wxWindow* parent)
317{
318#if wxUSE_HTML
319    wxString htmlText;
320    wxString htmlFile = wxGetApp().GetHelpFile();
321
322    {
323        wxTextFile file(htmlFile);
324        if (file.Exists())
325        {
326            file.Open();
327            for ( htmlText = file.GetFirstLine();
328                  !file.Eof();
329                  htmlText << file.GetNextLine() << _T("\n") ) ;
330        }
331    }
332
333    if (htmlText.empty())
334    {
335        htmlText.Printf(wxT("<html><head><title>Warning</title></head><body><P>Sorry, could not find resource for About dialog<P></body></html>"));
336    }
337
338    // Customize the HTML
339    htmlText.Replace(wxT("$DATE$"), _T(__DATE__));
340
341    wxSize htmlSize(400, 290);
342
343    // Note: in later versions of wxWin this will be fixed so wxRAISED_BORDER
344    // does the right thing. Meanwhile, this is a workaround.
345#ifdef __WXMSW__
346    long borderStyle = wxDOUBLE_BORDER;
347#else
348    long borderStyle = wxRAISED_BORDER;
349#endif
350
351    wxHtmlWindow* html = new wxHtmlWindow(this, ID_ABOUT_HTML_WINDOW, wxDefaultPosition, htmlSize, borderStyle);
352    html -> SetBorders(10);
353    html -> SetPage(htmlText);
354
355    //// Start of sizer-based control creation
356
357    wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
358
359    wxWindow *item1 = parent->FindWindow( ID_ABOUT_HTML_WINDOW );
360    wxASSERT( item1 );
361    item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 );
362
363    wxButton *item2 = new wxButton( parent, wxID_CLOSE );
364    item2->SetDefault();
365    item2->SetFocus();
366    SetAffirmativeId(wxID_CLOSE);
367
368    item0->Add( item2, 0, wxALIGN_RIGHT|wxALL, 5 );
369
370    parent->SetSizer( item0 );
371    parent->Layout();
372    item0->Fit( parent );
373    item0->SetSizeHints( parent );
374#endif
375
376    return true;
377}
378