All fonts are now bigger (20pt)
[scorecard] / src / stat-model.cpp
1 /*
2  * Copyright (C) 2009 Sakari Poussa
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, version 2.
7  */
8
9 #include <QVariant>
10 #include <QFont>
11
12 #include "score-common.h"
13 #include "stat-model.h"
14
15 StatModel::StatModel(QList<Club *> &cList, QList<Score *> &sList) : clubList(cList), scoreList(sList)
16 {
17   update();
18 }
19
20 int StatModel::rowCount(const QModelIndex & parent) const
21 {
22   Q_UNUSED(parent);
23   return ROWS;
24 }
25
26 int StatModel::columnCount(const QModelIndex & parent) const
27 {
28   Q_UNUSED(parent);
29   return COLS;
30 }
31
32 QVariant StatModel::data(const QModelIndex & index, int role) const
33 {
34   if (!index.isValid())
35     return QVariant();
36
37   int row = index.row();
38   int col = index.column();
39
40   if (col >= stat.size())
41     return QVariant();
42     
43   //
44   // ALIGNMENT
45   //
46   if (role == Qt::TextAlignmentRole ) {
47     return Qt::AlignCenter;
48   }
49
50   //
51   // FONT
52   //
53   if (role == Qt::FontRole) {
54       QFont font;
55       font.setPointSize(fontSize);
56       return font;
57   }
58   //
59   // NUMBERS
60   //
61   if (role == Qt::DisplayRole) {
62     switch (row) {
63     case ROW_ROUNDS: 
64       return stat.at(col)->rounds();
65     case ROW_AVERAGE: 
66       return stat.at(col)->average();
67     case ROW_MIN: 
68       return stat.at(col)->min();
69     case ROW_MAX: 
70       return stat.at(col)->max();
71     case ROW_BIRDIE: 
72       return stat.at(col)->birdies();
73     case ROW_PAR: 
74       return stat.at(col)->pars();
75     case ROW_BOGEY: 
76       return stat.at(col)->bogeys();
77     case ROW_MORE:
78       return stat.at(col)->more();
79     }
80   }
81   return QVariant();
82 }
83
84 QVariant StatModel::headerData(int section, Qt::Orientation orientation, int role) const
85 {
86   // Only vertical header -- horizontal is hidden
87   if (role != Qt::DisplayRole)
88     return QVariant();
89
90   if (orientation == Qt::Horizontal) {
91     // TODO: check when no or less data than cols
92     // HERE CRASH
93
94     if (section < stat.size())
95       return stat.at(section)->year();
96   }
97
98   if (orientation == Qt::Vertical) {
99     switch(section) {
100     case ROW_ROUNDS: 
101       return QString("Rounds");
102     case ROW_AVERAGE: 
103       return QString("Average");
104     case ROW_MIN: 
105       return QString("Best");
106     case ROW_MAX: 
107       return QString("Worst");
108     case ROW_BIRDIE: 
109       return QString("Birdies");
110     case ROW_PAR: 
111       return QString("Pars");
112     case ROW_BOGEY: 
113       return QString("Bogeys");
114     case ROW_MORE:
115       return QString("Double+");
116     }
117   }
118
119   return QVariant();
120 }
121
122 // TODO: dup code from table-model.cpp
123 Course *StatModel::findCourse(const QString &clubName, 
124                               const QString &courseName)
125 {
126   QListIterator<Club *> i(clubList);
127   Club *c;
128
129   while (i.hasNext()) {
130     c = i.next();
131     if (c->getName() == clubName) {
132       return c->getCourse(courseName);
133     }
134   }
135   return 0;
136 }
137
138 void StatModel::update(void)
139 {
140   QListIterator<Score *> iScore(scoreList);
141   QMultiMap<QString, Score *> yearMap;
142
143   // Create multi map with years as keys, scores as values
144   while (iScore.hasNext()) {
145     Score *score = iScore.next();
146     QString year = score->getDate().split("-").at(0);
147     yearMap.insert(year, score);
148   }
149   // Create uniq list of years
150   QList<QString> yearList = yearMap.uniqueKeys();
151
152   // For each year collect the statistics
153   QListIterator<QString> iYear(yearList);
154   while (iYear.hasNext()) {
155     QString year = iYear.next();
156
157     StatItem *item = new StatItem;
158     item->setYear(year);
159
160     QList<Score *> scoresPerYear = yearMap.values(year);
161     QListIterator<Score *> iScoresPerYear(scoresPerYear);
162     
163     item->setRounds(scoresPerYear.count());
164
165     // for each year, add score
166     int sum = 0;
167     int min = 200;
168     int max = 0;
169     int pars = 0;
170     int birdies = 0;
171     int bogeys = 0;
172     int more = 0;
173     while (iScoresPerYear.hasNext()) {
174       Score *s = iScoresPerYear.next();
175       int tot = s->getTotal(Total).toInt();
176       sum += tot;
177
178       if (tot > max)
179         max = tot;
180
181       if (tot < min)
182         min = tot;
183
184       Course *c = findCourse(s->getClubName(), s->getCourseName());
185
186       for (int i = 0; i < 18; i++) {
187         int par = c->getPar(i).toInt();
188         int shots = s->getScore(i).toInt();
189         
190         if (shots == (par - 1))
191           birdies++;
192         else if (shots == par)
193           pars++;
194         else if (shots == (par + 1))
195           bogeys++;
196         else if (shots >= (par + 2))
197           more++;
198       }
199     }
200     item->setBirdies(birdies);
201     item->setPars(pars);
202     item->setBogeys(bogeys);
203     item->setMore(more);
204
205     int avg = sum / scoresPerYear.count();
206     item->setAverage(avg);
207     item->setMin(min);
208     item->setMax(max);
209
210     stat << item;
211   }
212 }