1/////////////////////////////////////////////////////////////////////////////
2// Name:        canvas.cpp
3// Purpose:     Forty Thieves patience game
4// Author:      Chris Breeze
5// Modified by:
6// Created:     21/07/97
7// RCS-ID:      $Id: canvas.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 "forty.h"
26#include "card.h"
27#include "game.h"
28#include "scorefil.h"
29#include "playerdg.h"
30#include "canvas.h"
31
32BEGIN_EVENT_TABLE(FortyCanvas, wxScrolledWindow)
33    EVT_MOUSE_EVENTS(FortyCanvas::OnMouseEvent)
34END_EVENT_TABLE()
35
36FortyCanvas::FortyCanvas(wxWindow* parent, const wxPoint& pos, const wxSize& size) :
37             wxScrolledWindow(parent, wxID_ANY, pos, size, 0),
38             m_helpingHand(true),
39             m_rightBtnUndo(true),
40             m_playerDialog(0),
41             m_leftBtnDown(false)
42{
43    SetScrollbars(0, 0, 0, 0);
44
45#ifdef __WXGTK__
46    m_font = wxTheFontList->FindOrCreateFont(12, wxROMAN, wxNORMAL, wxNORMAL);
47#else
48    m_font = wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxNORMAL);
49#endif
50    SetBackgroundColour(FortyApp::BackgroundColour());
51
52    m_handCursor = new wxCursor(wxCURSOR_HAND);
53    m_arrowCursor = new wxCursor(wxCURSOR_ARROW);
54
55    wxString name = wxTheApp->GetAppName();
56    if (name.Length() <= 0) name = _T("forty");
57    m_scoreFile = new ScoreFile(name);
58    m_game = new Game(0, 0, 0);
59    m_game->Deal();
60}
61
62
63FortyCanvas::~FortyCanvas()
64{
65    UpdateScores();
66    delete m_game;
67    delete m_scoreFile;
68    delete m_handCursor;
69    delete m_arrowCursor;
70}
71
72
73/*
74Write the current player's score back to the score file
75*/
76void FortyCanvas::UpdateScores()
77{
78    if (m_player.Length() > 0 && m_scoreFile && m_game)
79    {
80        m_scoreFile->WritePlayersScore(
81            m_player,
82            m_game->GetNumWins(),
83            m_game->GetNumGames(),
84            m_game->GetScore()
85        );
86    }
87}
88
89
90void FortyCanvas::OnDraw(wxDC& dc)
91{
92    dc.SetFont(* m_font);
93    m_game->Redraw(dc);
94#if 0
95    // if player name not set (and selection dialog is not displayed)
96    // then ask the player for their name
97    if (m_player.Length() == 0 && !m_playerDialog)
98    {
99        m_playerDialog = new PlayerSelectionDialog(this, m_scoreFile);
100        m_playerDialog->ShowModal();
101        m_player = m_playerDialog->GetPlayersName();
102        if (m_player.Length() > 0)
103        {
104            // user entered a name - lookup their score
105            int wins, games, score;
106            m_scoreFile->ReadPlayersScore(m_player, wins, games, score);
107            m_game->NewPlayer(wins, games, score);
108            m_game->DisplayScore(dc);
109            m_playerDialog->Destroy();
110            m_playerDialog = 0;
111            Refresh(false);
112        }
113        else
114        {
115            // user cancelled the dialog - exit the app
116            ((wxFrame*)GetParent())->Close(true);
117        }
118    }
119#endif
120}
121
122void FortyCanvas::ShowPlayerDialog()
123{
124    // if player name not set (and selection dialog is not displayed)
125    // then ask the player for their name
126    if (m_player.Length() == 0 && !m_playerDialog)
127    {
128        m_playerDialog = new PlayerSelectionDialog(this, m_scoreFile);
129        m_playerDialog->ShowModal();
130        m_player = m_playerDialog->GetPlayersName();
131        if (m_player.Length() > 0)
132        {
133            // user entered a name - lookup their score
134            int wins, games, score;
135            m_scoreFile->ReadPlayersScore(m_player, wins, games, score);
136            m_game->NewPlayer(wins, games, score);
137
138            wxClientDC dc(this);
139            dc.SetFont(* m_font);
140            m_game->DisplayScore(dc);
141            m_playerDialog->Destroy();
142            m_playerDialog = 0;
143            Refresh(false);
144        }
145        else
146        {
147            // user cancelled the dialog - exit the app
148            ((wxFrame*)GetParent())->Close(true);
149        }
150    }
151}
152
153/*
154Called when the main frame is closed
155*/
156bool FortyCanvas::OnCloseCanvas()
157{
158    if (m_game->InPlay() &&
159        wxMessageBox(_T("Are you sure you want to\nabandon the current game?"),
160            _T("Warning"), wxYES_NO | wxICON_QUESTION) == wxNO)
161    {
162        return false;
163    }
164    return true;
165}
166
167void FortyCanvas::OnMouseEvent(wxMouseEvent& event)
168{
169    int mouseX = (int)event.GetX();
170    int mouseY = (int)event.GetY();
171
172    wxClientDC dc(this);
173    PrepareDC(dc);
174    dc.SetFont(* m_font);
175
176    if (event.LeftDClick())
177    {
178        if (m_leftBtnDown)
179        {
180            m_leftBtnDown = false;
181            ReleaseMouse();
182            m_game->LButtonUp(dc, mouseX, mouseY);
183        }
184        m_game->LButtonDblClk(dc, mouseX, mouseY);
185    }
186    else if (event.LeftDown())
187    {
188        if (!m_leftBtnDown)
189        {
190            m_leftBtnDown = true;
191            CaptureMouse();
192            m_game->LButtonDown(dc, mouseX, mouseY);
193        }
194    }
195    else if (event.LeftUp())
196    {
197        if (m_leftBtnDown)
198        {
199            m_leftBtnDown = false;
200            ReleaseMouse();
201            m_game->LButtonUp(dc, mouseX, mouseY);
202        }
203    }
204    else if (event.RightDown() && !event.LeftIsDown())
205    {
206        // only allow right button undo if m_rightBtnUndo is true
207        if (m_rightBtnUndo)
208        {
209            if (event.ControlDown() || event.ShiftDown())
210            {
211                m_game->Redo(dc);
212            }
213            else
214            {
215                m_game->Undo(dc);
216            }
217        }
218    }
219    else if (event.Dragging())
220    {
221        m_game->MouseMove(dc, mouseX, mouseY);
222    }
223
224    if (!event.LeftIsDown())
225    {
226        SetCursorStyle(mouseX, mouseY);
227    }
228}
229
230void FortyCanvas::SetCursorStyle(int x, int y)
231{
232    // Only set cursor to a hand if 'helping hand' is enabled and
233    // the card under the cursor can go somewhere
234    if (m_game->CanYouGo(x, y) && m_helpingHand)
235    {
236        SetCursor(* m_handCursor);
237    }
238    else
239    {
240        SetCursor(* m_arrowCursor);
241    }
242
243}
244
245void FortyCanvas::NewGame()
246{
247    m_game->Deal();
248    Refresh();
249}
250
251void FortyCanvas::Undo()
252{
253    wxClientDC dc(this);
254    PrepareDC(dc);
255    dc.SetFont(* m_font);
256    m_game->Undo(dc);
257}
258
259void FortyCanvas::Redo()
260{
261    wxClientDC dc(this);
262    PrepareDC(dc);
263    dc.SetFont(* m_font);
264    m_game->Redo(dc);
265}
266
267void FortyCanvas::LayoutGame()
268{
269       m_game->Layout();
270}
271