source: trunk/src/MainFrame.cpp @ 158

Last change on this file since 158 was 158, checked in by guyru, 5 years ago
  • Put all of configuration.h into namespace.
  • save method for Configuration
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.6 KB
Line 
1/***************************************************************************
2 *   Copyright (C) 2006-2008 by Guy Rutenberg   *
3 *   guyrutenberg@gmail.com   *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 *   This program is distributed in the hope that it will be useful,       *
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13 *   GNU General Public License for more details.                          *
14 *                                                                         *
15 *   You should have received a copy of the GNU General Public License     *
16 *   along with this program; if not, write to the                         *
17 *   Free Software Foundation, Inc.,                                       *
18 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19 ***************************************************************************/
20
21 /***********************************************
22 *      This File contains the definitions      *
23 *      of MainFrame's functions                *
24 ***********************************************/
25
26//#define DEBUG
27
28#include <wx/wx.h>
29
30#include "MainFrame.h"
31#include "wxDynamicBitmap.h"
32#include "ObjectsID.h"
33#include "HighScoreDialog.h"
34#include "SettingsDialog.h"
35#include "dice_theme_dialog.h"
36#include "About.h"
37#include "UtilityFunctions.h"
38#include "configuration.h"
39#include <iostream>
40#include <sstream>
41#include <cstdlib>
42#include <wx/version.h>
43
44//include the icon file
45#include "Icon.h"
46
47//default values - design
48#define SPACE_SIZE 1
49#define DICE_SPACE 3
50#ifdef WIN32
51        #define KEEP_SPACE 13
52        #define VERTICAL_ROLL_SIZEX 64
53        #define VERTICAL_ROLL_SIZEY 53
54#else
55        #define KEEP_SPACE 5
56        #define VERTICAL_ROLL_SIZEX 64
57        #define VERTICAL_ROLL_SIZEY 64
58#endif
59#define VER_DICE_SPACER 10
60
61//default values - settings
62#define DEF_HIGHSCORESIZE 20
63#define OY_VERSION "1.8.0"
64
65const wxEventType wxEVT_ENABLE_ROLL = wxNewEventType();
66
67MainFrame::MainFrame(const wxString& title, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE)
68        : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, size, style)
69{
70        //give the frame an icon
71        SetIcon(wxIcon(ICON));
72
73        /* Check if there is configuration file under old-name and
74         * rename it
75         */
76        wxString home_path = wxFileName::GetHomeDir();
77        if (wxFileExists(home_path+wxT("/.OpenYahtzee"))) {
78                // we don't won't to overwrite newer files.
79                wxRenameFile(home_path+wxT("/.OpenYahtzee"),home_path+wxT("/.openyahtzee"),false);
80        }
81        configuration::Configuration config("/home/guy/.openyahtzee.new");
82        config.save();
83        m_settingsdb = new SettingsDB(); //Get the settings database connection
84        m_highscoredb = new HighScoreTableDB();
85
86        m_evt_handler = new MainFrameEvtHandler(this);
87       
88        InitializeDatabase();//this must come _after_ m_settingsdb and m_highscoredb are created
89
90        //bitmap_dices[0] = new wxBitmap(one_xpm);
91        //bitmap_dices[1] = new wxBitmap(two_xpm);
92        //bitmap_dices[2] = new wxBitmap(three_xpm);
93        //bitmap_dices[3] = new wxBitmap(four_xpm);
94        //bitmap_dices[4] = new wxBitmap(five_xpm);
95        //bitmap_dices[5] = new wxBitmap(six_xpm);
96       
97        //randomize the random-number generator based on the time
98        srand( (unsigned)time( NULL ) );
99       
100        AddMenus();
101
102        AddControlsAndLayout();
103       
104        //make the text boxes uneditable to the user   
105        wxTextCtrl *textctrl;
106        for(int i = ID_ACESTEXT;i<=ID_GRANDTOTAL;i++) {
107                textctrl = (wxTextCtrl*) FindWindow(i);
108                textctrl->SetEditable(false);
109        }
110       
111        //disable the undo button
112        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
113
114        ConnectEventTable();
115       
116        ResetRolls();
117        m_yahtzee = false;
118        m_yahtzeebonus = false;
119        m_numofplaysleft = 13;
120
121}
122
123/**
124 * Adds the menus and menu items to the MainFrame.
125 */
126void MainFrame::AddMenus()
127{
128        /*Create the menus*/
129        wxMenu *gameMenu = new wxMenu;  //create Game menu
130        wxMenu *helpMenu = new wxMenu;  //create Help menu
131       
132       
133        //insert menu items into menu Help
134        helpMenu->Append(ID_CHECK_FOR_UPDATES, wxT("&Check for Updates"),
135                        wxT("Check for new version of the game via the web"));
136        helpMenu->AppendSeparator();
137        helpMenu->Append(ID_SENDCOMMENT, wxT("&Send a Comment to Developers"),
138                        wxT("Send a comment to the developers of the game"));
139        helpMenu->AppendSeparator();
140        helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"),
141                        wxT("Show about dialog"));
142
143        //insert menu items into menu Game
144        gameMenu->Append(wxID_NEW,wxT("&New Game\tF2"),wxT("Start a new game"));
145        gameMenu->Append(wxID_UNDO,wxT("&Undo\tCTRL+Z"),wxT("Undo the last move"));
146        gameMenu->Append(ID_SHOWHIGHSCORE,wxT("High &Scores"),wxT("Show high-scores table"));
147        gameMenu->Append(ID_SETTINGS,wxT("Settings"),wxT("Show settings dialog"));
148        gameMenu->Append(ID_THEMES,wxT("Dice Theme..."),wxT("Select a dice theme"));
149        gameMenu->Append(wxID_EXIT);
150       
151        // Declare the menu-bar and append the freshly created menus to the menu bar...
152        wxMenuBar *menuBar = new wxMenuBar();
153        menuBar->Append(gameMenu, wxT("&Game"));
154        menuBar->Append(helpMenu, wxT("&Help"));
155       
156        // ... and attach this menu bar to the frame
157        SetMenuBar(menuBar);
158}
159
160/**
161 * Add the controls to the frame and use sizers to lay them out.
162 */
163void MainFrame::AddControlsAndLayout()
164{
165        wxPanel* panel = new wxPanel(this, ID_PANEL,
166                wxDefaultPosition, wxDefaultSize);
167
168        wxBoxSizer *topSizer;
169        wxFlexGridSizer *diceSizer;
170
171        if (m_settings.horizontal_layout) {
172                topSizer = new wxBoxSizer( wxVERTICAL );
173                sectionsSizer = new wxBoxSizer( wxHORIZONTAL );
174                diceSizer = new wxFlexGridSizer(2, 0, 0, 0);
175        } else {
176                topSizer = new wxBoxSizer( wxHORIZONTAL );
177                sectionsSizer = new wxBoxSizer( wxVERTICAL );
178                diceSizer = new wxFlexGridSizer(1, 0, 0);;
179        }
180
181        uppersection = new wxStaticBoxSizer( new wxStaticBox(
182                panel, wxID_ANY, wxT("Upper Section") ), wxVERTICAL);
183       
184        lowersection = new wxStaticBoxSizer(new wxStaticBox(
185                panel, wxID_ANY, wxT("Lower Section") ), wxVERTICAL);
186       
187        wxFlexGridSizer* uppergrid = new wxFlexGridSizer(2, 0, 10);
188        wxFlexGridSizer* lowergrid = new wxFlexGridSizer(2, 0, 10);
189
190        //BEGIN layout for the upper section of the score board
191        uppergrid->Add(new wxButton(panel,ID_ACES,wxT("Aces")),
192                0, wxALL, SPACE_SIZE);
193        uppergrid->Add(new wxTextCtrl(panel, ID_ACESTEXT),1,wxALL,SPACE_SIZE);
194        uppergrid->Add(new wxButton(panel,ID_TWOS,wxT("Twos")),
195                0, wxALL, SPACE_SIZE);
196        uppergrid->Add(new wxTextCtrl(panel, ID_TWOSTEXT),1,wxALL,SPACE_SIZE);
197        uppergrid->Add(new wxButton(panel,ID_THREES,wxT("Threes")),
198                0, wxALL, SPACE_SIZE);
199        uppergrid->Add(new wxTextCtrl(panel, ID_THREESTEXT),1,wxALL,SPACE_SIZE);
200        uppergrid->Add(new wxButton(panel,ID_FOURS,wxT("Fours")),
201                0, wxALL, SPACE_SIZE);
202        uppergrid->Add(new wxTextCtrl(panel, ID_FOURSTEXT),1,wxALL,SPACE_SIZE);
203        uppergrid->Add(new wxButton(panel,ID_FIVES,wxT("Fives")),
204                0, wxALL, SPACE_SIZE);
205        uppergrid->Add(new wxTextCtrl(panel, ID_FIVESTEXT),1,wxALL,SPACE_SIZE);
206        uppergrid->Add(new wxButton(panel,ID_SIXES,wxT("Sixes")),
207                0, wxALL, SPACE_SIZE);
208        uppergrid->Add(new wxTextCtrl(panel, ID_SIXESTEXT),1,wxALL,SPACE_SIZE);
209        uppergrid->Add(new wxStaticText(panel, wxID_ANY, wxT("Total score:")),
210                0, wxALL, SPACE_SIZE);
211        uppergrid->Add(new wxTextCtrl(panel, ID_UPPERSECTIONTOTAL),
212                1, wxALL, SPACE_SIZE);
213        uppergrid->Add(new wxStaticText(panel, wxID_ANY, wxT("Bonus:")),
214                0, wxALL, SPACE_SIZE);
215        uppergrid->Add(new wxTextCtrl(panel, ID_BONUS),1,wxALL,SPACE_SIZE);
216        uppergrid->Add(new wxStaticText(panel, wxID_ANY,
217                wxT("Total of upper section:")), 0, wxALL, SPACE_SIZE);
218        uppergrid->Add(new wxTextCtrl(panel, ID_UPPERTOTAL),
219                1, wxALL, SPACE_SIZE);
220        //END layout for the upper section of the score board
221
222        //BEGIN layout for the lower section of the score board
223        lowergrid->Add(new wxButton(panel,ID_THREEOFAKIND,wxT("3 of a kind")),
224                0, wxALL, SPACE_SIZE);
225        lowergrid->Add(new wxTextCtrl(panel, ID_THREEOFAKINDTEXT),
226                1, wxALL, SPACE_SIZE);
227        lowergrid->Add(new wxButton(panel,ID_FOUROFAKIND,wxT("4 of a kind")),
228                0, wxALL, SPACE_SIZE);
229        lowergrid->Add(new wxTextCtrl(panel, ID_FOUROFAKINDTEXT),
230                1, wxALL, SPACE_SIZE);
231        lowergrid->Add(new wxButton(panel,ID_FULLHOUSE,wxT("Full House")),
232                0, wxALL, SPACE_SIZE);
233        lowergrid->Add(new wxTextCtrl(panel, ID_FULLHOUSETEXT),
234                1, wxALL, SPACE_SIZE);
235        lowergrid->Add(new wxButton(panel, ID_SMALLSEQUENCE,
236                wxT("Sequence of 4")), 0, wxALL,SPACE_SIZE);
237        lowergrid->Add(new wxTextCtrl(panel, ID_SMALLSEQUENCETEXT),
238                1, wxALL, SPACE_SIZE);
239        lowergrid->Add(new wxButton(panel, ID_LARGESEQUENCE,
240                wxT("Sequence of 5")), 0, wxALL, SPACE_SIZE);
241        lowergrid->Add(new wxTextCtrl(panel, ID_LARGESEQUENCETEXT),
242                1, wxALL, SPACE_SIZE);
243        lowergrid->Add(new wxButton(panel, ID_YAHTZEE, wxT("Yahtzee")),
244                0, wxALL, SPACE_SIZE);
245        lowergrid->Add(new wxTextCtrl(panel,ID_YAHTZEETEXT),1,wxALL,SPACE_SIZE);
246        lowergrid->Add(new wxButton(panel, ID_CHANCE, wxT("Chance")),
247                0, wxALL, SPACE_SIZE);
248        lowergrid->Add(new wxTextCtrl(panel, ID_CHANCETEXT),1,wxALL,SPACE_SIZE);
249        lowergrid->Add(new wxStaticText(panel, wxID_ANY,
250                wxT("Yahtzee Bonus")), 0, wxALL, SPACE_SIZE);
251        lowergrid->Add(new wxTextCtrl(panel, ID_YAHTZEEBONUSTEXT),
252                1, wxALL, SPACE_SIZE);
253        lowergrid->Add(new wxStaticText(panel, wxID_ANY,
254                wxT("Total of lower section:")),0,wxALL,SPACE_SIZE);
255        lowergrid->Add(new wxTextCtrl(panel, ID_LOWERTOTAL),1,wxALL,SPACE_SIZE);
256        lowergrid->Add(new wxStaticText(panel, wxID_ANY, wxT("Grand Total:")),
257                0, wxALL, SPACE_SIZE);
258        lowergrid->Add(new wxTextCtrl(panel, ID_GRANDTOTAL),1,wxALL,SPACE_SIZE);
259        //END layout for the lower section of the score board
260
261        uppersection->Add(uppergrid);
262        lowersection->Add(lowergrid);
263        sectionsSizer->Add(uppersection, 0, wxALL, 5);
264        sectionsSizer->Add(lowersection, 0, wxALL, 5);
265
266        //BEGIN layout for the dice section of the score board
267        if (m_settings.horizontal_layout) {
268                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE1,
269                        m_dice_graphics.GetDice(1)), 0, wxALL, DICE_SPACE);
270                diceSizer->Add(new wxDynamicBitmap(panel,
271                        ID_DICE2, m_dice_graphics.GetDice(2)), 0, wxALL, DICE_SPACE);
272                diceSizer->Add(new wxDynamicBitmap(panel,
273                        ID_DICE3, m_dice_graphics.GetDice(3)), 0, wxALL,DICE_SPACE);
274                diceSizer->Add(new wxDynamicBitmap(panel,
275                        ID_DICE4, m_dice_graphics.GetDice(4)), 0, wxALL,DICE_SPACE);
276                diceSizer->Add(new wxDynamicBitmap(panel,
277                        ID_DICE5, m_dice_graphics.GetDice(5)), 0, wxALL,DICE_SPACE);
278                diceSizer->Add(new wxButton(panel, ID_ROLL, wxT("Roll!"),
279                        wxDefaultPosition, wxSize(64,64)), 0, wxALL,DICE_SPACE);
280                diceSizer->Add(new wxCheckBox(panel, ID_DICE1KEEP,
281                        wxT("Keep")), 0, wxBOTTOM | wxLEFT,KEEP_SPACE);
282                diceSizer->Add(new wxCheckBox(panel, ID_DICE2KEEP,
283                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
284                diceSizer->Add(new wxCheckBox(panel, ID_DICE3KEEP,
285                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
286                diceSizer->Add(new wxCheckBox(panel, ID_DICE4KEEP,
287                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
288                diceSizer->Add(new wxCheckBox(panel, ID_DICE5KEEP,
289                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
290        } else {
291                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE1,
292                        m_dice_graphics.GetDice(1)), 0, wxALL, DICE_SPACE);
293                diceSizer->Add(new wxCheckBox(panel, ID_DICE1KEEP,
294                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
295                diceSizer->AddSpacer(VER_DICE_SPACER);
296                diceSizer->Add(new wxDynamicBitmap(panel,ID_DICE2,
297                        m_dice_graphics.GetDice(2)), 0, wxALL, DICE_SPACE);
298                diceSizer->Add(new wxCheckBox(panel, ID_DICE2KEEP,
299                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
300                diceSizer->AddSpacer(VER_DICE_SPACER);
301                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE3,
302                        m_dice_graphics.GetDice(3)), 0, wxALL, DICE_SPACE);
303                diceSizer->Add(new wxCheckBox(panel, ID_DICE3KEEP,
304                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
305                diceSizer->AddSpacer(VER_DICE_SPACER);
306                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE4,
307                        m_dice_graphics.GetDice(4)), 0, wxALL, DICE_SPACE);
308                diceSizer->Add(new wxCheckBox(panel, ID_DICE4KEEP,
309                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
310                diceSizer->AddSpacer(VER_DICE_SPACER);
311                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE5,
312                        m_dice_graphics.GetDice(5)), 0, wxALL, DICE_SPACE);
313                diceSizer->Add(new wxCheckBox(panel, ID_DICE5KEEP,
314                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
315                diceSizer->AddSpacer(VER_DICE_SPACER);
316                diceSizer->Add(new wxButton(panel, ID_ROLL, wxT("Roll!"),
317                        wxDefaultPosition, wxSize(VERTICAL_ROLL_SIZEX,
318                        VERTICAL_ROLL_SIZEY)), 0, wxALL, DICE_SPACE);
319        }
320        //END layout for the dice section of the score board *******/
321       
322        topSizer->Add(sectionsSizer);
323        topSizer->Add(diceSizer);       
324
325        panel->SetSizer(topSizer);
326       
327        topSizer->Fit(this);
328        topSizer->SetSizeHints(this);
329}
330
331/**
332 * Connects the tables to the event handlers
333 */
334void MainFrame::ConnectEventTable()
335{
336        //BEGIN connecting the menu items' events
337        Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnQuit));
338        Connect(wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnAbout));
339        Connect(ID_CHECK_FOR_UPDATES, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnCheckForUpdates));
340        Connect(ID_SENDCOMMENT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnSendComment));
341        Connect(wxID_NEW, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnNewGame));
342        Connect(wxID_UNDO, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnUndo));
343        Connect(ID_SHOWHIGHSCORE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnShowHighscore));
344        Connect(ID_SETTINGS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnSettings));
345        Connect(ID_THEMES, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnDiceTheme));
346        //END connecting the menu items' events
347
348        Connect(ID_ROLL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnRollButton));
349        Connect(ID_ROLL, wxEVT_ENABLE_ROLL, wxCommandEventHandler (MainFrame::OnRollButton));
350
351        //BEGIN connecting the scoreboard buttons to the events
352        Connect(ID_ACES,ID_SIXES, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnUpperButtons));
353        Connect(ID_THREEOFAKIND, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::On3ofakindButton));
354        Connect(ID_FOUROFAKIND, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::On4ofakindButton));
355        Connect(ID_FULLHOUSE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnFullHouseButton));
356        Connect(ID_SMALLSEQUENCE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnSmallSequenceButton));
357        Connect(ID_LARGESEQUENCE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnLargeSequenceButton));
358        Connect(ID_YAHTZEE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnYahtzeeButton));
359        Connect(ID_CHANCE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnChanceButton));
360        Connect(ID_DICE1,ID_DICE5, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnDiceClick));
361        Connect(ID_DICE1KEEP,ID_DICE5KEEP, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (MainFrame::OnKeepClick));
362        //END connecting the scoreboard buttons to the event
363
364        /* The following code connects the on wxEVT_ENTER_WINDOW and
365         * wxEVT_LEAVE_WINDOW events to the score buttons to handle the score
366         * hints. For some unknown technical problem we have to directly connect
367         * the events, otherwise the wxEVT_LEAVE_WINDOW doesn't get generated.
368         * We have to use event handler other than MainFrame's as the regular
369         * event handler leads to segmantation fault.
370         */
371        wxButton *temp;
372        for (int i = ID_ACES; i<=ID_CHANCE; i++) {
373                temp = ((wxButton *)FindWindow(i));
374                temp->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(MainFrameEvtHandler::OnScoreMouseLeave), NULL, m_evt_handler);
375                temp->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(MainFrameEvtHandler::OnScoreMouseEnter), NULL, m_evt_handler);
376        }
377}
378
379
380/*********EVENT PROCCESSING FUNCTIONS********/
381
382void MainFrame::OnAbout(wxCommandEvent& event)
383{
384#ifdef PORTABLE
385        AboutDialog *about = new AboutDialog(this,wxID_ANY,wxT("About Open Yahtzee PE"));
386#else
387        AboutDialog *about = new AboutDialog(this,wxID_ANY,wxT("About Open Yahtzee"));
388#endif
389        about->ShowModal();
390}
391
392/**
393 * Connects to the Open Yahtzee website on sourceforge.net and checks for
394 * updates to the game.
395 * \param event
396 */
397void MainFrame::OnCheckForUpdates (wxCommandEvent& event)
398{
399       
400        wxString link = wxT("http://openyahtzee.sourceforge.net/download/check-for-updates/");
401       
402        link += wxT(OY_VERSION);
403
404        wxLaunchDefaultBrowser(link);
405}
406
407
408/**
409 * Starts up the user browser and connects to the Open Yahtzee website's
410 * feedback page.
411 * \param event
412 */
413void MainFrame::OnSendComment (wxCommandEvent& event)
414{
415        wxString link = wxT("http://openyahtzee.sourceforge.net/feedback/");
416       
417        wxLaunchDefaultBrowser(link);
418}
419
420void MainFrame::OnQuit(wxCommandEvent& event)
421{
422        // Destroy the frame
423        Close();
424}
425
426/**
427 * This is the event handler of the New Game menu item. It starts a new
428 * game and clears the board from the last game.
429 * \param event
430 */
431void MainFrame::OnNewGame(wxCommandEvent& event)
432{
433        //disable the undo button so it won't be enabled when a new game is started.
434        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
435       
436        ResetRolls();
437        m_yahtzee = false;
438        m_numofplaysleft = 13;
439       
440        for (int i = ID_ACESTEXT; i<= ID_GRANDTOTAL; i++)
441                ((wxTextCtrl*) FindWindow(i))->Clear();
442        for (int i = ID_ACES; i<= ID_CHANCE; i++)
443                ((wxButton*) FindWindow(i))->Enable(true);
444}
445
446/**
447 * This function handles the undo events. It's connected to the Undo menu item.
448 *
449 * Note that the function only allows undoing of scoring actions and not dice
450 * rolls. Also it won't allow the undoing of the last move of the game because
451 * of a technical problem relating to the case an high-score was made and then
452 * the user undo the last move and rescore another high-score and so on.
453 * \param event
454 */
455void MainFrame::OnUndo(wxCommandEvent& event)
456{
457        m_rolls = m_rollsundo;
458
459        //after the user scored the button was enabled, check if it should be disabled
460        if (m_rolls <= 0) //we don't have remaining rolls
461                ((wxButton*) FindWindow(ID_ROLL)) -> Enable(false);
462       
463        // change the displayed roll counter
464        wxString caption = wxString::Format(wxT("Roll! (%i)"),m_rolls);
465        FindWindow(ID_ROLL)->SetLabel(caption);
466
467        //restore the 'keep' checkboxes
468        for (int i=0; i<5; i++)
469                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> Enable(true);
470       
471        //reset the users last choice
472        FindWindow(m_lastmove)->Enable(true);
473
474        //clear the score;
475        ((wxTextCtrl*)FindWindow(ID_ACESTEXT + (m_lastmove - ID_ACES)))->SetValue(wxT(""));
476       
477        //Undo the Yahtzee flag if needed
478        if (m_lastmove == ID_YAHTZEE) {
479                m_yahtzee = false;
480        }
481
482        //undo also the yahtzee bonus if needed
483        if (m_yahtzeebonus) {
484                long temp;
485                wxString tempstr;
486       
487                tempstr = ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> GetValue();
488                tempstr.ToLong(&temp,10);
489                temp -= 100; //this line reduces the points given for the yahtzee bonus
490                tempstr.Printf(wxT("%i"),temp);
491                ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> SetValue(tempstr);
492        }
493
494        //recalculate the subtotals
495        CalculateSubTotal();
496
497        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
498        //cancel the counting for the choice that was canceled
499        m_numofplaysleft++;
500}
501
502/**
503 * This function enables the undo button and stores the last move
504 * \param id
505 */
506inline void MainFrame::EnableUndo(int id)
507{
508        if (m_numofplaysleft) {
509                (GetMenuBar()->FindItem(wxID_UNDO))->Enable(true);
510                m_lastmove = id;
511        }
512}
513
514/**
515 * Shows the high-score dialog. Connected to the Game->"Show High Score" menu item.
516 * \param event
517 */
518void MainFrame::OnShowHighscore(wxCommandEvent& event)
519{
520        HighScoreDialog *dialog = new HighScoreDialog(this,wxID_ANY,m_highscoredb);
521        dialog->ShowModal();
522}
523
524/**
525 * Shows the settings dialog. This event-handler is connected to Game->Settings
526 * menu item.
527 * \param event
528 */
529void MainFrame::OnSettings( wxCommandEvent& event)
530{
531        SettingsDialog *dialog = new SettingsDialog(this,wxID_ANY);
532        SettingsDialogData data;
533        std::ostringstream sstr;
534       
535        data.highscoresize = m_highscoredb->GetSize();
536
537        data.animate = (m_settingsdb->GetKey("animate")=="Yes")?true:false;
538        data.subtotal = (m_settingsdb->GetKey("calculatesubtotal")=="Yes")?true:false;
539        data.score_hints = m_settings.score_hints;
540        data.horizontal = (m_settingsdb->GetKey("horizontallayout")=="Yes")?true:false;
541       
542        dialog->SetData(data);
543       
544        if(dialog->ShowModal()!=wxID_OK)
545                return;
546       
547        data = dialog->GetData();
548
549        if(data.reset)
550                m_highscoredb->SetSize(0);
551       
552        sstr<<data.highscoresize<<std::flush;
553        m_settingsdb->SetKey("highscoresize",sstr.str());
554                       
555        m_highscoredb->SetSize(data.highscoresize);
556       
557        if (data.animate){
558                m_settingsdb->SetKey("animate","Yes");
559                m_settings.animate = true;
560        } else {
561                m_settingsdb->SetKey("animate","No");
562                m_settings.animate = false;
563        }
564
565        if (data.subtotal){
566                m_settingsdb->SetKey("calculatesubtotal","Yes");
567                m_settings.calculate_subtotal = true;
568        } else {
569                m_settingsdb->SetKey("calculatesubtotal","No");
570                m_settings.calculate_subtotal = false;
571        }
572        ((wxTextCtrl*) FindWindow(ID_UPPERSECTIONTOTAL)) -> SetValue(wxT(""));
573        ((wxTextCtrl*) FindWindow(ID_LOWERTOTAL)) -> SetValue(wxT(""));
574        CalculateSubTotal();
575
576        if (data.score_hints){
577                m_settingsdb->SetKey("score_hints","Yes");
578                m_settings.score_hints = true;
579        } else {
580                m_settingsdb->SetKey("score_hints","No");
581                m_settings.score_hints = false;
582        }
583
584        if (data.horizontal){
585                m_settingsdb->SetKey("horizontallayout","Yes");
586                m_settings.horizontal_layout = true;
587                Relayout();                     
588        } else {
589                m_settingsdb->SetKey("horizontallayout","No");
590                m_settings.horizontal_layout = false;
591                Relayout();
592        }
593}
594
595/**
596 * Shows the dice theme selection dialog. This event-handler is connected to
597 * Game->Dice Theme menu item.
598 * \param event
599 */
600void MainFrame::OnDiceTheme( wxCommandEvent& event)
601{
602        DiceThemeDialog *dialog = new DiceThemeDialog(this,wxID_ANY);
603
604        if(dialog->ShowModal()!=wxID_OK)
605                return;
606
607}
608
609/**
610 * Event handler for the Roll button. It checks the settings if it should
611 * animate the dice and then rolls them accordingly. It also checks for the
612 * status of the "keep" checkboxes.
613 * \param event
614 */
615void MainFrame::OnRollButton (wxCommandEvent& event)
616{
617        short int dice[5];      //holds the dices score
618       
619        if (event.GetEventType() == wxEVT_IDLE) {
620                m_skiproll = false;
621                Disconnect(wxEVT_IDLE,  wxCommandEventHandler(MainFrame::OnRollButton));
622                return;
623        }
624       
625        //skip rolling the dice if the user accidently rolled the dice before they finished spinning.
626        if (m_skiproll) return;
627        m_skiproll = true;
628
629        //fill the dice array with the old values
630        dice[0]=m_score_dice.GetDice(1);
631        dice[1]=m_score_dice.GetDice(2);
632        dice[2]=m_score_dice.GetDice(3);
633        dice[3]=m_score_dice.GetDice(4);
634        dice[4]=m_score_dice.GetDice(5);
635        //roll the dice...
636        if (m_settings.animate) {
637                int dice_throws[5] = {0,0,0,0,0};
638                for (int i=0; i<5; i++) { //set the number of rolls for each dice
639                        if (!((wxCheckBox*) FindWindow(i + ID_DICE1KEEP))->IsChecked()) {
640                                dice_throws[i] = (rand()%15)+3; //ensures the number is at least one.
641                        }
642                }
643                while (dice_throws[0] || dice_throws[1] || dice_throws[2] || dice_throws[3] || dice_throws[4]) {
644                        for (int i=0 ; i<5; i++){
645                                if(dice_throws[i]){
646                                        dice_throws[i]--;
647                                        dice[i] = (int)(6.0*rand()/RAND_MAX)+1;
648                                        ((wxDynamicBitmap*) FindWindow(i +
649                                                ID_DICE1)) -> SetBitmap(
650                                                m_dice_graphics.GetDice(dice[i]));
651                                }
652                        }
653                        ::wxMilliSleep(100);
654                }
655        } else {
656                for (int i=0; i<5; i++) {
657                        if (!((wxCheckBox*) FindWindow(i + ID_DICE1KEEP))->IsChecked()) {
658                                dice[i] = (int)(6.0*rand()/RAND_MAX)+1;
659                                ((wxDynamicBitmap*) FindWindow(i + ID_DICE1))->
660                                        SetBitmap(m_dice_graphics.GetDice(dice[i]));
661                        }
662                }
663        }
664
665        m_score_dice.SetDice(dice);
666        m_score_dice.SetYahtzeeJoker(YahtzeeJoker());
667        --m_rolls;
668       
669        // change the displayed roll counter
670        wxString caption = wxString::Format(wxT("Roll! (%i)"),m_rolls);
671        FindWindow(ID_ROLL)->SetLabel(caption);
672
673        #ifndef DEBUG
674        if (m_rolls <= 0) {
675                ((wxButton*) FindWindow(ID_ROLL)) -> Enable(false);
676                FindWindow(ID_ROLL)->SetLabel(wxT("Roll!"));
677        }
678
679        #endif
680       
681        //enable the keep checkboxes
682        for (int i=0; i<5; i++)
683                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> Enable(true);
684       
685        //we rolled the dices so undoing isn't allowed
686        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
687        m_yahtzeebonus = false; //if we scored yahtzee bonus before we don't care anymore.
688       
689        Connect(wxEVT_IDLE, wxCommandEventHandler(MainFrame::OnRollButton));
690}
691
692/**
693 * This is the event-handler for all of the scoring buttons of the upper section.
694 *
695 * It gets the id of the button that called the event handler by comparing it
696 * to the id of the aces button it figures what button was pressed, And updates
697 * the suiting score textbox (again by comparing the id to the one of the aces
698 * checbox).
699 * \param event
700 */
701void MainFrame::OnUpperButtons (wxCommandEvent& event)
702{
703        wxString out;
704        short int temp;
705        if(m_rolls < 3){
706                YahtzeeBonus();
707                switch(event.GetId()) {
708                case ID_ACES:
709                        temp = m_score_dice.Aces();
710                        break;
711                case ID_TWOS:
712                        temp = m_score_dice.Twos();
713                        break;
714                case ID_THREES:
715                        temp = m_score_dice.Threes();
716                        break;
717                case ID_FOURS:
718                        temp = m_score_dice.Fours();
719                        break;
720                case ID_FIVES:
721                        temp = m_score_dice.Fives();
722                        break;
723                case ID_SIXES:
724                        temp = m_score_dice.Sixes();
725                        break;
726                }
727       
728                out.Printf(wxT("%i"),temp);
729                ((wxTextCtrl*) FindWindow(event.GetId() - ID_ACES + ID_ACESTEXT))->SetValue(out);
730                ((wxTextCtrl*) FindWindow(event.GetId() - ID_ACES + ID_ACESTEXT))->SetBackgroundColour(*wxWHITE);
731               
732                PostScore(event.GetId());
733        }
734        else
735                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
736}
737
738/**
739 * Event handler for the "3 of a kind" score button.
740 * \param event
741 */
742void MainFrame::On3ofakindButton(wxCommandEvent& event)
743{
744        if(m_rolls>=3) {
745                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
746                return;
747        }
748        YahtzeeBonus();
749        wxString out;
750       
751        out.Printf(wxT("%i"),m_score_dice.ThreeOfAKind());
752        ((wxTextCtrl*) FindWindow(ID_THREEOFAKINDTEXT))->SetValue(out);
753        ((wxTextCtrl*) FindWindow(ID_THREEOFAKINDTEXT))->SetBackgroundColour(*wxWHITE);
754       
755        PostScore(event.GetId());
756}
757
758/**
759 * Event handler for the "4 of a kind" score button.
760 * \param event
761 */
762void MainFrame::On4ofakindButton(wxCommandEvent& event)
763{
764        if(m_rolls>=3) {
765                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
766                return;
767        }
768        YahtzeeBonus();
769        wxString out;
770
771        out.Printf(wxT("%i"),m_score_dice.FourOfAKind());
772        ((wxTextCtrl*) FindWindow(ID_FOUROFAKINDTEXT))->SetValue(out);
773        ((wxTextCtrl*) FindWindow(ID_FOUROFAKINDTEXT))->SetBackgroundColour(*wxWHITE);
774       
775        PostScore(event.GetId());
776}
777
778/**
779 * Event handler for the full-house score button.
780 * \param event
781 */
782void MainFrame::OnFullHouseButton(wxCommandEvent& event)
783{
784        wxString out;
785
786        if(m_rolls>=3) {
787                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
788                return;
789        }
790        YahtzeeBonus();
791
792        out.Printf(wxT("%i"), m_score_dice.FullHouse());
793        ((wxTextCtrl*) FindWindow(ID_FULLHOUSETEXT))->SetValue(out);
794        ((wxTextCtrl*) FindWindow(ID_FULLHOUSETEXT))->SetBackgroundColour(*wxWHITE);
795       
796        PostScore(event.GetId());
797}
798
799/**
800 * Event handler for the small-sequence score button.
801 * \param event
802 */
803void MainFrame::OnSmallSequenceButton(wxCommandEvent& event)
804{
805        wxString out;
806
807        if(m_rolls>=3) {
808                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
809                return;
810        }
811
812        YahtzeeBonus();
813       
814        out.Printf(wxT("%i"), m_score_dice.SmallSequence());
815        ((wxTextCtrl*) FindWindow(ID_SMALLSEQUENCETEXT))->SetValue(out);
816        ((wxTextCtrl*) FindWindow(ID_SMALLSEQUENCETEXT))->SetBackgroundColour(*wxWHITE);
817       
818        PostScore(event.GetId());
819}
820
821/**
822 * Event handler for the large-sequence score button.
823 * \param event
824 */
825void MainFrame::OnLargeSequenceButton(wxCommandEvent& event)
826{
827        wxString out;
828       
829        if(m_rolls>=3) {
830                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
831                return;
832        }
833
834        YahtzeeBonus();
835
836        out.Printf(wxT("%i"), m_score_dice.LargeSequence());
837        ((wxTextCtrl*) FindWindow(ID_LARGESEQUENCETEXT))->SetValue(out);
838        ((wxTextCtrl*) FindWindow(ID_LARGESEQUENCETEXT))->SetBackgroundColour(*wxWHITE);
839       
840        PostScore(event.GetId());
841}
842
843/**
844 * Event handler for the yahtzee score button.
845 * \param event
846 */
847void MainFrame::OnYahtzeeButton(wxCommandEvent& event)
848{
849        wxString out;
850       
851        if(m_rolls>=3) {
852                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
853                return;
854        }
855       
856        if (m_score_dice.IsYahtzee()) m_yahtzee = true;
857        out.Printf(wxT("%i"), m_score_dice.Yahtzee());
858        ((wxTextCtrl*) FindWindow(ID_YAHTZEETEXT))->SetValue(out);
859        ((wxTextCtrl*) FindWindow(ID_YAHTZEETEXT))->SetBackgroundColour(*wxWHITE);
860
861        PostScore(event.GetId());
862}
863
864/**
865 * Evnet handler for the chance score button.
866 * \param event
867 */
868void MainFrame::OnChanceButton (wxCommandEvent& event)
869{
870        wxString out;
871        int temp = 0;
872        if(m_rolls < 3){
873                YahtzeeBonus();
874       
875                out.Printf(wxT("%i"),m_score_dice.Chance());
876                ((wxTextCtrl*) FindWindow(ID_CHANCETEXT))->SetValue(out);
877                ((wxTextCtrl*) FindWindow(ID_CHANCETEXT))->SetBackgroundColour(*wxWHITE);
878               
879                PostScore(event.GetId());
880        }
881        else
882                wxMessageBox(wxT("First you need to roll, and after you roll you may score"), wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
883
884}
885
886/**
887 * Event handler for mouse clicks on the dice.
888 *
889 * When clicking on the dice this event-handler ticks the appropriate "keep" checkbox.
890 * \param event
891 */
892void MainFrame::OnDiceClick (wxCommandEvent& event)
893{
894        //tick the checkbox
895        if (((wxCheckBox*) FindWindow(event.GetId()-ID_DICE1 + ID_DICE1KEEP))->IsEnabled()){
896                bool newvalue = (((wxCheckBox*) FindWindow(event.GetId()-ID_DICE1 + ID_DICE1KEEP))->GetValue())?false:true;
897                ((wxCheckBox*) FindWindow(event.GetId()-ID_DICE1 + ID_DICE1KEEP)) -> SetValue(newvalue);
898        }
899
900        //dispatch a click event on the checkbox
901        wxCommandEvent clickevent((event.GetId()-ID_DICE1 + ID_DICE1KEEP),wxEVT_COMMAND_CHECKBOX_CLICKED);
902        clickevent.SetEventObject( this );
903        clickevent.SetId(event.GetId()-ID_DICE1 + ID_DICE1KEEP);
904        this->OnKeepClick(clickevent); ///\todo find a better way to call the event handler.
905}
906
907void MainFrame::OnKeepClick (wxCommandEvent& event)
908{
909        wxCheckBox *temp = (wxCheckBox*) FindWindow(event.GetId());
910        ((wxDynamicBitmap*) FindWindow(event.GetId()-ID_DICE1KEEP + ID_DICE1))->SetGrayScale(temp->GetValue());
911}
912
913
914//********************************************
915//******        General Functions       ******
916//********************************************
917
918/**
919 * This function handles everything related to reseting the dice rolls after scoring.
920 */
921void MainFrame::ResetRolls()
922{
923        m_rollsundo = m_rolls;
924        m_rolls = 3;
925        ((wxButton*) FindWindow(ID_ROLL)) -> Enable(true);
926
927        // reset the roll count in the caption
928        FindWindow(ID_ROLL)->SetLabel(wxT("Roll! (3)"));
929        for (int i=0; i<5; i++){
930                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> SetValue(false);
931                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> Enable(false);
932                ((wxDynamicBitmap*) FindWindow(i+ID_DICE1)) -> SetGrayScale(false);
933        }
934}
935
936/**
937 * This function checks for a Yahtzee Bonus situation and if one exists it scores accordingly.
938 */
939void MainFrame::YahtzeeBonus()
940{
941        long temp;
942        wxString tempstr;
943       
944        //if the player didn't have any yathzees yet he can't have the bonus;
945        if (!m_yahtzee)
946                return;
947        if (m_score_dice.IsYahtzee()) {
948                tempstr = ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> GetValue();
949                tempstr.ToLong(&temp,10);
950                temp += 100;
951                tempstr.Printf(wxT("%i"),temp);
952                ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> SetValue(tempstr);
953                m_yahtzeebonus = true;
954        }       
955}
956
957/**
958 * This function checks whether we have a Yahtzee Joker situation.
959 * \return true if there is Yahtzee Joker, false otherwise.
960 */
961bool MainFrame::YahtzeeJoker()
962{
963        if (m_score_dice.IsYahtzee() && !(FindWindow(ID_ACES +
964                m_score_dice.GetDice(1)-1)->IsEnabled()) &&
965                !(FindWindow(ID_YAHTZEE)->IsEnabled())) {
966                return true;
967        }
968        return false;
969}
970
971/**
972 * This function handles the end of game.
973 *
974 * When a game ends it calculates the total score and submit it to the high
975 * score list.
976 */
977void MainFrame::EndofGame()
978{
979        if(m_numofplaysleft>0)
980                return;
981       
982        wxString tempstr;
983        long temp;
984        long upperscore = 0;
985        long lowerscore = 0;
986
987        for (int i = ID_ACESTEXT; i<=ID_SIXESTEXT; i++){
988                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
989                tempstr.ToLong(&temp,10);
990                upperscore +=temp;
991        }
992       
993        tempstr.Printf(wxT("%i"),upperscore);
994        ((wxTextCtrl*) FindWindow(ID_UPPERSECTIONTOTAL)) -> SetValue(tempstr);
995       
996        //check for bonus
997        if(upperscore>=63) {
998                ((wxTextCtrl*) FindWindow(ID_BONUS)) -> SetValue(wxT("35"));
999                upperscore +=35;
1000        } else
1001                ((wxTextCtrl*) FindWindow(ID_BONUS)) -> SetValue(wxT("0"));
1002       
1003        tempstr.Printf(wxT("%i"),upperscore);
1004        ((wxTextCtrl*) FindWindow(ID_UPPERTOTAL)) -> SetValue(tempstr);
1005       
1006        //calculate total on lower section
1007        for (int i = ID_THREEOFAKINDTEXT; i<=ID_YAHTZEEBONUSTEXT; i++) {
1008                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
1009                tempstr.ToLong(&temp,10);
1010                lowerscore +=temp;
1011        }
1012       
1013        tempstr.Printf(wxT("%i"),lowerscore);
1014        ((wxTextCtrl*) FindWindow(ID_LOWERTOTAL)) -> SetValue(tempstr);
1015        tempstr.Printf(wxT("%i"),upperscore + lowerscore);
1016        ((wxTextCtrl*) FindWindow(ID_GRANDTOTAL)) -> SetValue(tempstr);
1017
1018        //disable the roll button;
1019        ((wxButton*) FindWindow(ID_ROLL)) -> Enable(false);
1020
1021        tempstr.Printf(wxT("Your final score is %i points!"),lowerscore+upperscore);
1022        wxMessageBox(tempstr, wxT("Game Ended"), wxOK | wxICON_INFORMATION, this);
1023
1024        //submit to high score
1025        HighScoreHandler(lowerscore+upperscore);
1026       
1027}
1028
1029/**
1030 * This function checks if a given score qualifies for the high score list and
1031 * adds it to the list if it does.
1032 * @param score The score submitted to the high score list.
1033 */
1034void MainFrame::HighScoreHandler(int score)
1035{
1036        int place;
1037        std::string name,date;
1038        wxCommandEvent newevent;
1039
1040
1041        place = m_highscoredb->IsHighScore(score);
1042       
1043        if(!place)  //if the score didn't make it to the highscore table do nothing
1044                return;
1045       
1046        wxString msg;
1047        msg.Printf(wxT("Your score made it to the high score table. Your place is number %i.\nPlease enter your name below:"),place);
1048
1049        wxTextEntryDialog infodialog(this,msg,wxT("Please enter your name"),wxT(""),wxOK | wxCENTRE);
1050        infodialog.ShowModal();
1051
1052        name = infodialog.GetValue().mb_str();
1053
1054        //get the date
1055        wxDateTime now = wxDateTime::Now();
1056        date = now.FormatISOTime().mb_str();
1057        date +=" ";
1058        date += now.FormatDate().mb_str();
1059
1060        m_highscoredb->SendHighScore(name,date,score);
1061
1062        //now show the high score table
1063        newevent.SetId(ID_SHOWHIGHSCORE);
1064        newevent.SetEventType(wxEVT_COMMAND_MENU_SELECTED);
1065        ProcessEvent(newevent);
1066
1067}
1068
1069///this function handles all the post scoring stuff such as disabling the right button.
1070/**
1071 * This function is always called after scoring and it handles all the post-score
1072 * stuff such as reseting the dice rolls, enabling the undo button, calculating
1073 * the sub-total scores and ending the game if necessary.
1074 * \param id
1075 */
1076void MainFrame::PostScore(int id)
1077{
1078        //now after the scoring reset the rolls
1079        ResetRolls();
1080
1081        CalculateSubTotal();
1082
1083        //and disable the button
1084        FindWindow(id)->Enable(false);
1085        m_numofplaysleft--;
1086        EnableUndo(id);
1087        EndofGame();
1088}
1089
1090/**
1091 * This function calculates the sub-total scores and should be called after
1092 * every score. It does so only if this feature is requested in the settings
1093 * dialog.
1094 */
1095void MainFrame::CalculateSubTotal()
1096{
1097        if (!m_settings.calculate_subtotal)
1098                return;
1099        long upperscore = 0;
1100        long lowerscore = 0;
1101        wxString tempstr;
1102        long temp;
1103
1104
1105        for (int i = ID_ACESTEXT; i<=ID_SIXESTEXT; i++){
1106                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
1107                tempstr.ToLong(&temp,10);
1108                upperscore +=temp;
1109        }
1110       
1111        tempstr.Printf(wxT("%i"),upperscore);
1112        ((wxTextCtrl*) FindWindow(ID_UPPERSECTIONTOTAL)) -> SetValue(tempstr);
1113        if (upperscore >= 63) {
1114                ((wxTextCtrl*) FindWindow(ID_BONUS))->SetValue(wxT("35"));
1115        } else {
1116                // this is needed in case of an undo
1117                ((wxTextCtrl*) FindWindow(ID_BONUS))->SetValue(wxT(""));
1118        }
1119
1120        for (int i = ID_THREEOFAKINDTEXT; i<=ID_YAHTZEEBONUSTEXT; i++) {
1121                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
1122                tempstr.ToLong(&temp,10);
1123                lowerscore +=temp;
1124        }
1125       
1126        tempstr.Printf(wxT("%i"),lowerscore);
1127        ((wxTextCtrl*) FindWindow(ID_LOWERTOTAL)) -> SetValue(tempstr);
1128}
1129
1130
1131/**
1132 * Initializes the database and stores default settings if needed.
1133 * @return 0 if some error
1134 */
1135int MainFrame::InitializeDatabase()
1136{
1137        std::ostringstream sstr;
1138
1139
1140        if (m_settingsdb->GetKey("highscoresize") == "") { //check if we need to create a new high score table
1141                m_highscoredb->SetSize(DEF_HIGHSCORESIZE);
1142                sstr<<DEF_HIGHSCORESIZE<<std::flush;
1143                m_settingsdb->SetKey("highscoresize", sstr.str());
1144        } else {
1145                int highscoresize = atoi((m_settingsdb->GetKey("highscoresize")).c_str());
1146                //m_highscoredb->SetSize((highscoresize>0)?highscoresize:DEF_HIGHSCORESIZE);
1147                m_highscoredb->SetSize(highscoresize);
1148        }
1149       
1150        if (m_settingsdb->GetKey("animate") == "Yes") {
1151                m_settings.animate = true;
1152        } else if (m_settingsdb->GetKey("animate") == "No") {
1153                m_settings.animate = false;
1154        } else {
1155                m_settingsdb->SetKey("animate", "Yes");
1156                m_settings.animate = true;
1157        }
1158
1159        if (m_settingsdb->GetKey("calculatesubtotal") == "Yes") {
1160                m_settings.calculate_subtotal = true;
1161        } else if (m_settingsdb->GetKey("calculatesubtotal") == "No") {
1162                m_settings.calculate_subtotal = false;
1163        } else {
1164                m_settingsdb->SetKey("calculatesubtotal", "Yes");
1165                m_settings.calculate_subtotal = true;
1166        }
1167
1168        if (m_settingsdb->GetKey("horizontallayout") == "Yes") {
1169                m_settings.horizontal_layout = true;
1170        } else if (m_settingsdb->GetKey("horizontallayout") == "No") {
1171                m_settings.horizontal_layout = false;
1172        } else {
1173                m_settingsdb->SetKey("horizontallayout", "No");
1174                m_settings.horizontal_layout = true;
1175        }
1176
1177        if (m_settingsdb->GetKey("score_hints") == "Yes") {
1178                m_settings.score_hints = true;
1179        } else if (m_settingsdb->GetKey("score_hints") == "No") {
1180                m_settings.score_hints = false;
1181        } else {
1182                m_settingsdb->SetKey("score_hints", "Yes");
1183                m_settings.score_hints = true;
1184        }
1185
1186        return 1;
1187}
1188
1189void MainFrame::Relayout()
1190{
1191        wxBoxSizer *topSizer;
1192        wxFlexGridSizer *diceSizer;
1193        bool roll_button_enabled;
1194
1195        lowersection->GetStaticBox()->Destroy();
1196        uppersection->GetStaticBox()->Destroy();
1197        sectionsSizer->Remove(lowersection);
1198        sectionsSizer->Remove(uppersection);
1199
1200        if (m_settings.horizontal_layout) {
1201                topSizer = new wxBoxSizer( wxVERTICAL );
1202                sectionsSizer = new wxBoxSizer( wxHORIZONTAL );
1203                diceSizer = new wxFlexGridSizer(2, 0, 0, 0);
1204        } else {
1205                topSizer = new wxBoxSizer( wxHORIZONTAL );
1206                sectionsSizer = new wxBoxSizer( wxVERTICAL );
1207                diceSizer = new wxFlexGridSizer(1, 0, 0);;
1208        }
1209
1210        uppersection = new wxStaticBoxSizer( new wxStaticBox( FindWindow(ID_PANEL), wxID_ANY, wxT("Upper Section") ), wxVERTICAL);
1211        lowersection = new wxStaticBoxSizer( new wxStaticBox( FindWindow(ID_PANEL), wxID_ANY, wxT("Lower Section") ), wxVERTICAL);
1212       
1213        wxFlexGridSizer* uppergrid = new wxFlexGridSizer(2, 0, 10);
1214        wxFlexGridSizer* lowergrid = new wxFlexGridSizer(2, 0, 10);
1215
1216        //BEGIN layout for the upper section of the score board
1217        uppergrid->Add(FindWindow(ID_ACES),0,wxALL,SPACE_SIZE);
1218        uppergrid->Add(FindWindow(ID_ACESTEXT),1,wxALL,SPACE_SIZE);
1219        uppergrid->Add(FindWindow(ID_TWOS),0,wxALL,SPACE_SIZE);
1220        uppergrid->Add(FindWindow(ID_TWOSTEXT),1,wxALL,SPACE_SIZE);
1221        uppergrid->Add(FindWindow(ID_THREES),0,wxALL,SPACE_SIZE);
1222        uppergrid->Add(FindWindow(ID_THREESTEXT),1,wxALL,SPACE_SIZE);
1223        uppergrid->Add(FindWindow(ID_FOURS),0,wxALL,SPACE_SIZE);
1224        uppergrid->Add(FindWindow(ID_FOURSTEXT),1,wxALL,SPACE_SIZE);
1225        uppergrid->Add(FindWindow(ID_FIVES),0,wxALL,SPACE_SIZE);
1226        uppergrid->Add(FindWindow(ID_FIVESTEXT),1,wxALL,SPACE_SIZE);
1227        uppergrid->Add(FindWindow(ID_SIXES),0,wxALL,SPACE_SIZE);
1228        uppergrid->Add(FindWindow(ID_SIXESTEXT),1,wxALL,SPACE_SIZE);
1229        uppergrid->Add(FindWindowByLabel(wxT("Total score:")),0,wxALL,SPACE_SIZE);
1230        uppergrid->Add(FindWindow(ID_UPPERSECTIONTOTAL),1,wxALL,SPACE_SIZE);
1231        uppergrid->Add(FindWindowByLabel(wxT("Bonus:")),0,wxALL,SPACE_SIZE);
1232        uppergrid->Add(FindWindow(ID_BONUS),1,wxALL,SPACE_SIZE);
1233        uppergrid->Add(FindWindowByLabel(wxT("Total of upper section:")),0,wxALL,SPACE_SIZE);
1234        uppergrid->Add(FindWindow(ID_UPPERTOTAL),1,wxALL,SPACE_SIZE);
1235        //END layout for the upper section of the score board
1236
1237        //BEGIN layout for the lower section of the score board
1238        lowergrid->Add(FindWindow(ID_THREEOFAKIND),0,wxALL,SPACE_SIZE);
1239        lowergrid->Add(FindWindow(ID_THREEOFAKINDTEXT),1,wxALL,SPACE_SIZE);
1240        lowergrid->Add(FindWindow(ID_FOUROFAKIND),0,wxALL,SPACE_SIZE);
1241        lowergrid->Add(FindWindow(ID_FOUROFAKINDTEXT),1,wxALL,SPACE_SIZE);
1242        lowergrid->Add(FindWindow(ID_FULLHOUSE),0,wxALL,SPACE_SIZE);
1243        lowergrid->Add(FindWindow(ID_FULLHOUSETEXT),1,wxALL,SPACE_SIZE);
1244        lowergrid->Add(FindWindow(ID_SMALLSEQUENCE),0,wxALL,SPACE_SIZE);
1245        lowergrid->Add(FindWindow(ID_SMALLSEQUENCETEXT),1,wxALL,SPACE_SIZE);
1246        lowergrid->Add(FindWindow(ID_LARGESEQUENCE),0,wxALL,SPACE_SIZE);
1247        lowergrid->Add(FindWindow(ID_LARGESEQUENCETEXT),1,wxALL,SPACE_SIZE);
1248        lowergrid->Add(FindWindow(ID_YAHTZEE),0,wxALL,SPACE_SIZE);
1249        lowergrid->Add(FindWindow(ID_YAHTZEETEXT),1,wxALL,SPACE_SIZE);
1250        lowergrid->Add(FindWindow(ID_CHANCE),0,wxALL,SPACE_SIZE);
1251        lowergrid->Add(FindWindow(ID_CHANCETEXT),1,wxALL,SPACE_SIZE);
1252        lowergrid->Add(FindWindowByLabel(wxT("Yahtzee Bonus")),0,wxALL,SPACE_SIZE);
1253        lowergrid->Add(FindWindow(ID_YAHTZEEBONUSTEXT),1,wxALL,SPACE_SIZE);
1254        lowergrid->Add(FindWindowByLabel(wxT("Total of lower section:")),0,wxALL,SPACE_SIZE);
1255        lowergrid->Add(FindWindow(ID_LOWERTOTAL),1,wxALL,SPACE_SIZE);
1256        lowergrid->Add(FindWindowByLabel(wxT("Grand Total:")),0,wxALL,SPACE_SIZE);
1257        lowergrid->Add(FindWindow(ID_GRANDTOTAL),1,wxALL,SPACE_SIZE);
1258        //END layout for the lower section of the score board
1259
1260        uppersection->Add(uppergrid);
1261        lowersection->Add(lowergrid);
1262        sectionsSizer->Add(uppersection,0,wxALL,5);
1263        sectionsSizer->Add(lowersection,0,wxALL,5);
1264
1265        //Change the roll button size if we need to
1266        roll_button_enabled = FindWindow(ID_ROLL)->IsEnabled();
1267        if (m_settings.horizontal_layout) {
1268                FindWindow(ID_ROLL)->Destroy();
1269                new wxButton(FindWindow(ID_PANEL), ID_ROLL, wxT("Roll!"),wxDefaultPosition,wxSize(64,64));
1270        } else {
1271                FindWindow(ID_ROLL)->Destroy();
1272                new wxButton(FindWindow(ID_PANEL), ID_ROLL, wxT("Roll!"),wxDefaultPosition,wxSize(VERTICAL_ROLL_SIZEX,VERTICAL_ROLL_SIZEY));
1273        }
1274        FindWindow(ID_ROLL)->Enable(roll_button_enabled);
1275
1276        // if there are rolls left we should display the count of them
1277        if (roll_button_enabled) {
1278                wxString caption = wxString::Format(wxT("Roll! (%i)"),m_rolls);
1279                FindWindow(ID_ROLL)->SetLabel(caption);
1280        }
1281
1282       
1283        //BEGIN layout for the dice section of the score board
1284        if (m_settings.horizontal_layout) {
1285                diceSizer->Add(FindWindow(ID_DICE1),0,wxALL,DICE_SPACE);
1286                diceSizer->Add(FindWindow(ID_DICE2),0,wxALL,DICE_SPACE);
1287                diceSizer->Add(FindWindow(ID_DICE3),0,wxALL,DICE_SPACE);
1288                diceSizer->Add(FindWindow(ID_DICE4),0,wxALL,DICE_SPACE);
1289                diceSizer->Add(FindWindow(ID_DICE5),0,wxALL,DICE_SPACE);
1290                diceSizer->Add(FindWindow(ID_ROLL),0,wxALL,DICE_SPACE);
1291                diceSizer->Add(FindWindow(ID_DICE1KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1292                diceSizer->Add(FindWindow(ID_DICE2KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1293                diceSizer->Add(FindWindow(ID_DICE3KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1294                diceSizer->Add(FindWindow(ID_DICE4KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1295                diceSizer->Add(FindWindow(ID_DICE5KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1296        } else {
1297                diceSizer->Add(FindWindow(ID_DICE1),0,wxALL,DICE_SPACE);
1298                diceSizer->Add(FindWindow(ID_DICE1KEEP),0,wxLEFT,KEEP_SPACE);
1299                diceSizer->AddSpacer(VER_DICE_SPACER);
1300                diceSizer->Add(FindWindow(ID_DICE2),0,wxALL,DICE_SPACE);
1301                diceSizer->Add(FindWindow(ID_DICE2KEEP),0,wxLEFT,KEEP_SPACE);
1302                diceSizer->AddSpacer(VER_DICE_SPACER);
1303                diceSizer->Add(FindWindow(ID_DICE3),0,wxALL,DICE_SPACE);
1304                diceSizer->Add(FindWindow(ID_DICE3KEEP),0,wxLEFT,KEEP_SPACE);
1305                diceSizer->AddSpacer(VER_DICE_SPACER);
1306                diceSizer->Add(FindWindow(ID_DICE4),0,wxALL,DICE_SPACE);
1307                diceSizer->Add(FindWindow(ID_DICE4KEEP),0,wxLEFT,KEEP_SPACE);
1308                diceSizer->AddSpacer(VER_DICE_SPACER);
1309                diceSizer->Add(FindWindow(ID_DICE5),0,wxALL,DICE_SPACE);
1310                diceSizer->Add(FindWindow(ID_DICE5KEEP),0,wxLEFT,KEEP_SPACE);
1311                diceSizer->AddSpacer(VER_DICE_SPACER);
1312                diceSizer->Add(FindWindow(ID_ROLL),0,wxALL,DICE_SPACE);
1313        }
1314        //END layout for the dice section of the score board *******/
1315
1316       
1317        topSizer->Add(sectionsSizer);
1318        topSizer->Add(diceSizer);       
1319       
1320        topSizer->SetSizeHints(this);
1321
1322        topSizer->Layout();
1323        FindWindow(ID_PANEL)->SetSizerAndFit(topSizer);
1324       
1325        topSizer->Fit(this);
1326       
1327}
1328
1329/**
1330 * Check whether the dice should be rolled or if the user already rolled them.
1331 * \return true if the dice are valid (rolled).
1332 */
1333bool MainFrame::IsValidDice()
1334{
1335        if ( m_rolls < 3 )
1336                return true;
1337        return false;
1338}
1339
1340/**
1341 *
1342 */
1343void MainFrameEvtHandler::OnScoreMouseEnter (wxMouseEvent& event)
1344{
1345        int id;
1346        wxTextCtrl *text_control;
1347        wxString out;
1348        if (! m_main_frame->m_settings.score_hints) {
1349                event.Skip();
1350                return;
1351        }
1352        if (! m_main_frame->IsValidDice()){
1353                event.Skip();
1354                return;
1355        }
1356       
1357        id = ((wxWindow *)event.GetEventObject())->GetId();
1358        text_control = ((wxTextCtrl*)m_main_frame->FindWindow(id-ID_ACES+ID_ACESTEXT));
1359        switch (id) {
1360        case ID_ACES:
1361                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Aces());
1362                break;
1363        case ID_TWOS:
1364                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Twos());
1365                break;
1366        case ID_THREES:
1367                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Threes());
1368                break;
1369        case ID_FOURS:
1370                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Fours());
1371                break;
1372        case ID_FIVES:
1373                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Fives());
1374                break;
1375        case ID_SIXES:
1376                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Sixes());
1377                break;
1378        case ID_THREEOFAKIND:
1379                out.Printf(wxT("%i"), m_main_frame->m_score_dice.ThreeOfAKind());
1380                break;
1381        case ID_FOUROFAKIND:
1382                out.Printf(wxT("%i"), m_main_frame->m_score_dice.FourOfAKind());
1383                break;
1384        case ID_FULLHOUSE:
1385                out.Printf(wxT("%i"), m_main_frame->m_score_dice.FullHouse());
1386                break;
1387        case ID_SMALLSEQUENCE:
1388                out.Printf(wxT("%i"), m_main_frame->m_score_dice.SmallSequence());
1389                break;
1390        case ID_LARGESEQUENCE:
1391                out.Printf(wxT("%i"), m_main_frame->m_score_dice.LargeSequence());
1392                break;
1393        case ID_YAHTZEE:
1394                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Yahtzee());
1395                break;
1396        case ID_CHANCE:
1397                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Chance());
1398                break;
1399        }
1400        text_control->SetValue(out);           
1401        text_control->SetBackgroundColour(wxColour(239,239,239));
1402       
1403        event.Skip(); //allow default proccesing
1404}
1405
1406/**
1407 *
1408 */
1409void MainFrameEvtHandler::OnScoreMouseLeave (wxMouseEvent& event)
1410{
1411        //we dont have the id of the control that generated the event
1412        wxTextCtrl *text_control;
1413       
1414        if (! m_main_frame->IsValidDice()){
1415                event.Skip();
1416                return;
1417        }
1418
1419        for (int i = ID_ACESTEXT; i<=ID_CHANCETEXT; i++) {
1420                text_control = (wxTextCtrl *)m_main_frame->FindWindow(i);
1421                if (text_control->GetBackgroundColour()==wxColour(239,239,239)){
1422                        text_control->Clear();
1423                        text_control->SetBackgroundColour(*wxWHITE);
1424                }
1425        }
1426
1427        event.Skip(); //allow default proccesing
1428}
Note: See TracBrowser for help on using the repository browser.