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