Changed the section to user/hidden as required for Nokia Store
[ghostsoverboard] / seascene.cpp
1 /**************************************************************************
2         Ghosts Overboard - a game for 'Meego 1.2 Harmattan'
3
4         Copyright (C) 2011  Heli Hyvättinen
5
6         This file is part of Ghosts Overboard
7
8         Ghosts Overboard is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 **************************************************************************/
22
23 #include "seascene.h"
24 #include "octopus.h"
25 #include "ship.h"
26 #include <QGraphicsPixmapItem>
27 #include <QDebug>
28 #include <QMessageBox>
29 #include <QTime>
30 #include <QApplication>
31 #include <QAction>
32 #include <QPushButton>
33 #include <QLabel>
34 #include <QVBoxLayout>
35 #include <QSettings>
36 #include <QPixmap>
37
38
39 const QString ghostImageFilename_ = ":/pix/aave.png";
40 const QString rockImageFilename_ =":/pix/kari.png";
41 const QString octopusImageFilename_= ":/pix/tursas.png";
42
43
44 SeaScene::SeaScene(QObject *parent) :
45     QGraphicsScene(parent)
46 {
47
48     setItemPointersNull();
49
50     paused_ = false;
51     screenLitKeeper_.keepScreenLit(true);
52
53     QSettings settings;
54
55     //set background
56
57     QPixmap waves (":/pix/meri.png");
58     waves.scaled(20,20);
59     setBackgroundBrush(QBrush(waves));
60
61     //set random seed
62
63     qsrand(QTime::currentTime().msec()+2);  //+2 to avoid setting it to 1
64
65
66
67 //Setup level sets
68
69     QList<Level> levelList;
70     Level level1(5,10);
71     levelList.append(level1);
72     Level level2(5,10,2,50);
73     levelList.append(level2);
74     Level level3(5,15,2,50);
75     levelList.append(level3);
76     Level level4(5,15,4,50);
77     levelList.append(level4);
78     Level level5(5,15,5,100);
79     levelList.append(level5);
80
81     Levelset set ("Original",levelList);
82     availableLevelsets_.append(set);
83
84
85     //Create another set of levels and place it in the available levelsets list
86     levelList.clear();
87     Level set2level1(8,15,4,50);
88     levelList.append(set2level1);
89     Level set2level2(8,20,4,50);
90     levelList.append(set2level2);
91     Level set2level3(8,20,5,80);
92     levelList.append(set2level3);
93     Level set2level4(8,20,6,120);
94     levelList.append(set2level4);
95     Level set2level5(8,25,8,150);
96     levelList.append(set2level5);
97
98     Levelset set2("Difficult",levelList);
99     availableLevelsets_.append(set2);
100
101
102     //Setup starting levelset
103
104     QString levelname = settings.value("levelset","Original").toString();
105     bool found = false;
106     foreach (Levelset levelset, availableLevelsets_)
107     {
108         if (levelset.getName() == levelname)
109         {
110             levelset_ = levelset;
111             found = true;
112             break;
113         }
114     }
115
116     if (!found)  //The last used level is not available
117     {
118         levelset_ = availableLevelsets_.value(0);
119     }
120
121     currentLevel_ = 0;
122
123     totalScore_ = 0;
124
125
126     //This ensures that nextlevel will not be called until its safe to delete the Ship object.
127     //Leaving out Qt::QueuedConnection or calling nextlevel directly instead of emitting the signal will CRASH
128     connect(this,SIGNAL(allGhostsPicked()),this,SLOT(nextLevel()),Qt::QueuedConnection);
129
130
131
132     pVibrateAction_ = new QAction(tr("Vibration effects"),this);
133     pVibrateAction_->setCheckable(true);
134     connect(pVibrateAction_,SIGNAL(toggled(bool)),this,SLOT(vibrationActivate(bool)));
135
136     pVibrateAction_->setChecked(settings.value("vibration",false).toBool());
137
138
139     pPauseAction_ = new QAction(tr("Pause"),this);
140     pPauseAction_->setCheckable(true);
141     connect(pPauseAction_,SIGNAL(toggled(bool)),this,SLOT(pause(bool)));
142
143
144     autopauseTimer.setSingleShot(true);
145     autopauseTimer.setInterval(15*60*1000);
146     connect(&autopauseTimer,SIGNAL(timeout()),this,SLOT(turnPauseOn()));
147
148     vibrationAllowed_ = false;
149     pResourceSet_ = new ResourcePolicy::ResourceSet("game",this);
150     ResourcePolicy::VibraResource * pVibraResource = new ResourcePolicy::VibraResource();
151     pVibraResource->setOptional(false); //The only resource of the set, so no sense for it to be optional
152     pResourceSet_->addResourceObject(pVibraResource);
153
154     connect(pResourceSet_,SIGNAL(resourcesGranted(const QList< ResourcePolicy::ResourceType >)),this,SLOT(resourcesAvailable()));
155     connect(pResourceSet_,SIGNAL(lostResources()),this,SLOT(resourcesLost()));
156
157     //To test whether resources were succesfully asked but not given
158     connect(pResourceSet_,SIGNAL(resourcesDenied()),this,SLOT(resourcesLost()));
159     pResourceSet_->setAlwaysReply();
160
161     if (pVibrateAction_->isChecked()) //ask for the resource only if its used
162     {
163         pResourceSet_->acquire();
164     }
165
166 }
167
168 SeaScene::~SeaScene()
169 {
170     pResourceSet_->release();
171     pResourceSet_->deleteLater();
172 }
173
174 void SeaScene::setupMap(int ghosts, int rocks, int octopuses, int octopusSpeed)
175 {
176     //empty the map
177
178     clear();
179
180     setItemPointersNull();
181
182     createMenuItems();
183
184     createAboutBoxItems();
185
186     createSelectLevelsetFromListItems();
187
188     createVictoryItems();
189
190     createLevelCompletedItems();
191
192
193     //empty the list of moving items
194
195     movingItems_.clear();
196
197     //empty the list of free slots
198     freeTiles_.clear();
199
200     //fill the list of free slots
201
202     int numberOfXTiles  = width() / 40;
203     int numberOfYTiles = height() /40;
204
205 //    qDebug() << numberOfXTiles << " slots in x direction";
206 //    qDebug() << numberOfYTiles << " slots in y rirection";
207
208     for (int i = 0; i < numberOfXTiles; i++ )
209     {
210         for (int j = 0; j < numberOfYTiles; j++)
211         {
212             freeTiles_.append(QPointF(i*40,j*40));
213         }
214     }
215
216
217     //spread the rocks
218
219     for (int i = 0; i < rocks; i++)
220     {
221         QPointF * pPosition = findRandomFreeSlot();
222
223         //If there was no room no point to continue
224         if (pPosition == NULL)
225             break;
226
227         QPixmap rockPixmap (":/pix/kari.png");
228         QGraphicsPixmapItem * pRock = addPixmap(rockPixmap);
229         pRock->setData(0,"rock");
230         pRock->setPos(*pPosition);
231         delete pPosition;
232
233     }
234
235     //spread the ghosts
236
237     ghostsLeft_ = ghosts;
238     spreadGhosts(ghosts);
239
240
241
242     //spread the octopuses
243
244     QList <Octopus*> octopusList;
245
246     for (int i=0; i < octopuses; i++)
247     {
248         QPointF * pPosition = findRandomFreeSlot();
249
250         //If there was no room no point to continue
251         if (pPosition == NULL)
252             break;
253
254     QPixmap octopusPixmap (":/pix/tursas.png");
255     Octopus * pOctopus = new Octopus(octopusPixmap,octopusSpeed);
256     pOctopus->setData(0,"octopus");
257     pOctopus->setPos(*pPosition);
258     addItem(pOctopus);
259     pOctopus->startMoving();
260     movingItems_.append(pOctopus);
261     connect(this,SIGNAL(pauseOn()),pOctopus,SLOT(stopMoving()));
262     connect(this,SIGNAL(pauseOff()),pOctopus,SLOT(startMoving()));
263     octopusList.append(pOctopus);
264     delete pPosition;
265
266     }
267
268
269     //place the ship
270
271     QPointF * pPosition = findRandomFreeSlot();
272     if (pPosition == NULL)
273     {
274         // Game cannot begin without a free position for ship, so give an error message and return
275
276         QMessageBox::critical(NULL,"Error! Too many objects on screen","No free space to place the ship. The game cannot start. Please choose another level.");
277         return;
278     }
279
280     QList<QPixmap> shipImages;
281     shipImages.append(QPixmap(":/pix/laiva.png"));
282     shipImages.append(QPixmap(":/pix/laiva_1aave.png"));
283     shipImages.append(QPixmap(":/pix/laiva_2aave.png"));
284     shipImages.append(QPixmap(":/pix/laiva_3aave.png"));
285     shipImages.append(QPixmap(":/pix/laiva_4aave.png"));
286     shipImages.append(QPixmap(":/pix/laiva_5aave.png"));
287     shipImages.append(QPixmap(":/pix/laiva_6aave.png"));
288     shipImages.append(QPixmap(":/pix/laiva_7aave.png"));
289     shipImages.append(QPixmap(":/pix/laiva_8aave.png"));
290     shipImages.append(QPixmap(":/pix/laiva_9aave.png"));
291     shipImages.append(QPixmap(":/pix/laiva_10aave.png"));
292
293     Ship * pShip = new Ship (shipImages);
294     pShip->setData(0,"ship");
295     pShip->setPos(*pPosition);
296     addItem(pShip);
297     connect(pShip,SIGNAL(pickingGhost(QGraphicsItem*)),this, SLOT(removeGhost(QGraphicsItem*)) );
298     connect(pShip,SIGNAL(droppingGhosts(int)),this,SLOT(ghostsDropped(int)));
299     connect(this,SIGNAL(vibrationActivated(bool)),pShip,SLOT(setVibrationActivate(bool)));
300     if (vibrationAllowed_)
301         pShip->allowVibration(); //Vibration is disallowed by default so only allowing needs to be done explicitly
302     connect(this,SIGNAL(vibrationGranted()),pShip,SLOT(allowVibration()));
303     connect(this,SIGNAL(vibrationDenied()),pShip,SLOT(disallowVibration()));
304     pShip->startMoving();
305     movingItems_.append(pShip);
306     connect(this,SIGNAL(pauseOn()),pShip,SLOT(stopMoving()));
307     connect(this,SIGNAL(pauseOff()),pShip,SLOT(startMoving()));
308     foreach (Octopus* pOctopus, octopusList)
309     {
310         connect(pOctopus,SIGNAL(droppingGhosts()),pShip,SLOT(dropAllGhosts()));
311     }
312     delete pPosition;
313 }
314
315 void SeaScene::setupMap(Level level)
316 {
317     setupMap(level.getNumberOfGhosts(),level.getNumberOfRocks(),level.getNumberOfOctopuses(),level.getOctopusSpeed());
318 }
319
320 void SeaScene::spreadGhosts(int ghosts)
321 {
322
323
324     //the octopuses and the ship may have moved from their original positions,
325     //so the list of free slots must be adjusted to exclude their current positions
326
327     QList<QPointF> temporarilyReservedSlots;
328
329     foreach (QGraphicsItem* pItem, movingItems_)
330     {
331         if (pItem == NULL)
332         {
333  //           qDebug() << "NULL item in movingItems_";
334             continue;
335         }
336
337         //round x and y down to fit the slot size
338         int x = pItem->x();
339         x = x/40;
340         x = x*40;
341
342         int y = pItem->y();
343         y = y/40;
344         y=y*40;
345
346
347         QPointF position (x,y);
348
349         //remove the tiles (potentially) occupied by the item from free slots and place in temp list if was in the list before
350
351         if (freeTiles_.removeOne(position))
352             temporarilyReservedSlots.append(position);
353
354
355         position.setX(x+40);
356
357         if (freeTiles_.removeOne(position))
358             temporarilyReservedSlots.append(position);
359
360         position.setY(y+40);
361
362         if (freeTiles_.removeOne(position))
363             temporarilyReservedSlots.append(position);
364
365         position.setX(x);
366
367         if (freeTiles_.removeOne(position))
368             temporarilyReservedSlots.append(position);
369
370     }
371
372
373     //spread ghosts in random free slots
374
375     for (int i=0; i < ghosts; i++)
376     {
377         QPointF * pPosition = findRandomFreeSlot();
378
379         //If there was no room no point to continue
380         if (pPosition == NULL)
381             return;
382
383         QPixmap ghostPixmap(":/pix/aave.png");
384         QGraphicsPixmapItem * pGhost = addPixmap(ghostPixmap);
385         pGhost->setData(0,"ghost");
386         pGhost->setPos(*pPosition);
387         delete pPosition;
388     }
389
390     //return the slots occupied by moving items to free slots
391     freeTiles_.append(temporarilyReservedSlots);
392
393     //clear temp for the next round
394     temporarilyReservedSlots.clear();
395 }
396
397 QPointF* SeaScene::findRandomFreeSlot()
398 {
399     if (freeTiles_.isEmpty())
400         return NULL;
401
402     int index = qrand()%freeTiles_.size();
403
404 //    qDebug()  << index << " index";
405     return new QPointF (freeTiles_.takeAt(index));
406
407 }
408
409 void SeaScene::removeGhost(QGraphicsItem *pGhost)
410 {
411     removeItem(pGhost);  //remove the item from scene
412     freeTiles_.append(pGhost->scenePos()); //add the item's position to free slots
413     delete pGhost;
414     ghostsLeft_--;
415     if (ghostsLeft_ == 0)
416     {
417         emit allGhostsPicked();
418  //       qDebug() << "All ghosts picked!";
419     }
420 }
421
422 void SeaScene::ghostsDropped(int ghosts)
423 {
424     ghostsLeft_ += ghosts;
425
426     spreadGhosts(ghosts);
427 }
428
429 void SeaScene::pause(bool paused)
430 {
431     //    qDebug() << "pause pressed " << paused;
432         if (paused_ == paused)
433                 return;
434
435         paused_ = paused;
436
437         if (paused == false)
438         {
439      //       qDebug() << "starting to move again";
440 //            emit fullscreenRequested();   fremantle specific (since no "show statusbar" action in harmattan version)
441             emit pauseOff();
442             screenLitKeeper_.keepScreenLit(true);
443             if (pPausetextItem_)
444                 pPausetextItem_->hide();
445
446             scoreCounter_.start();
447
448             autopauseTimer.start(); //Start counting towards autopause
449
450
451             if (pVibrateAction_->isChecked())
452             {
453                pResourceSet_->acquire(); //Ask to get the vibration resource back
454             }
455          }
456
457         else
458         {
459 //         qDebug("about to stop movement");
460             emit pauseOn();
461             screenLitKeeper_.keepScreenLit(false);
462             if (pPausetextItem_ != NULL)
463             {
464 //                qDebug() << "about to show the pause text";
465                 pPausetextItem_->show();
466 //                qDebug() << "showing pause text";
467             }
468 //                else qDebug() << "No pause text available";
469
470             levelScore_ += scoreCounter_.elapsed();
471
472             autopauseTimer.stop(); //No need to count toward autopause when already paused
473
474             pResourceSet_->release(); //Release the vibration resource
475             vibrationDenied(); //Tell the ship not to vibrate before resource is granted again
476
477         }
478 }
479
480 void SeaScene::vibrationActivate(bool on)
481 {
482     emit vibrationActivated(on);
483 }
484
485 void SeaScene::handleScreenTapped()
486 {
487
488     //If the game is going just pause it
489     if (!paused_)
490     {
491         pPauseAction_->setChecked(true);
492         return;
493     }
494
495     //If the game is paused and about box is shown, close it and show the pause text and menu again
496
497     if(pAboutBoxItem_)
498     {
499         if(pAboutBoxItem_->isVisible())
500         {
501             pAboutBoxItem_->hide();
502             pPausetextItem_->show();
503             return;
504         }
505     }
506
507     //If the game is paused, check if the level completed item is shown
508
509     if (pLevelCompletedItem_)
510     {
511         if (pLevelCompletedItem_->isVisible())
512         {
513             pLevelCompletedItem_->hide();
514             restartLevel(); //Current level has already been set to the next one before showing the level completed item
515             pPauseAction_->setChecked(false); //unpause
516             return;
517         }
518     }
519    
520     //If the game is paused, check if the victory item is being shown
521     if(pVictoryCongratulationsItem_)
522     {
523         if (pVictoryCongratulationsItem_->isVisibleTo(NULL)) //returns visibility to scene
524         {
525             pVictoryCongratulationsItem_->hide();
526             restartGame();
527             pPauseAction_->setChecked(false); // unpause
528             return;
529         }
530     }
531
532
533     //If the game is paused and no victory or about box, check if menu item was selected
534
535     QList<QGraphicsItem *> items = selectedItems();
536
537     //if nothing selected resume play
538
539     if (items.isEmpty())
540     {
541         pSelectLevelsetFromListItem_->hide();
542         pPauseAction_->setChecked(false);
543
544         return;
545
546     }
547
548     //If something was selected check if it was one of the menu items and act on it
549     //(Nothing else should be made selectable anyway)
550
551     //Menu functions
552
553     QGraphicsItem* pItem = items.at(0); //Selecting an item brings here, thus only selecting one item should be possible
554                                        //... so we can just take the first one
555
556     //Selection is just used to get notice of a menu item being clicked, removed after use
557
558     clearSelection();
559
560
561     //Act upon the selected item
562
563
564     if (pItem == pRestartGameItem_)
565     {
566 //        qDebug() << "game restart requested";
567         restartGame();
568         pPauseAction_->setChecked(false); //unpause game
569
570     }
571
572     else if (pItem == pRestartLevelItem_)
573     {
574 //        qDebug() << "Level restart requested";
575         restartLevel();
576         pPauseAction_->setChecked(false); //unpause game
577
578     }
579
580     else if (pItem == pSettingsItem_)
581     {
582         pVibrateAction_->toggle();
583
584         QSettings settings;
585         settings.setValue("vibration",pVibrateAction_->isChecked());
586
587         QString text = pSettingsItem_->toHtml();
588         if (pVibrateAction_->isChecked())
589             text.replace(" on"," off"); //don't remove spaces or you get vibratioff...
590         else
591             text.replace(" off"," on");
592         pSettingsItem_->setHtml(text);
593     }
594
595     else if (pItem == pAboutItem_)
596     {
597         about();
598     }
599
600     else if (pItem == pQuitItem_)
601     {
602         qApp->quit();
603     }
604
605     else if (pItem == pChooseLevelsetItem_)
606     {
607         pPausetextItem_->hide();
608         pSelectLevelsetFromListItem_->show();
609     }
610
611     else
612     {
613         foreach (QGraphicsItem* pLevelItem, levelsetItems_)
614         {
615             if (pItem == pLevelItem)
616             {
617                 QVariant variant = pLevelItem->data(0);
618
619                 if (variant.canConvert<Levelset>())
620                 {
621                     levelset_ = variant.value<Levelset>();
622
623                     QSettings settings;
624                     settings.setValue("levelset",levelset_.getName());
625
626                     restartGame();
627                     pPauseAction_->setChecked(false); //unpause game
628                 }
629             }
630         }
631     }
632
633 }
634
635
636
637 void SeaScene::createMenuItems()
638 {
639
640     QFont font;
641     font.setPixelSize(35);
642
643
644
645     pPausetextItem_ = new QGraphicsTextItem;
646
647  // This is for fremantle
648 //    pPausetextItem_->setHtml("<font size = \"5\" color = darkorange> Game paused. Tap to continue.");
649
650 //Harmattan needs bigger font
651     pPausetextItem_->setHtml("<font size = \"7\" color = darkorange> Game paused. Tap to continue.");
652
653
654     pPausetextItem_->setZValue(1000);
655     pPausetextItem_->setPos(200,50);
656     addItem(pPausetextItem_);
657     pPausetextItem_->hide();
658
659     menuItemCount_ = 0;
660
661   // This is for fremantle
662  //   QString menufonthtml = "<font size = \"4\" color = darkorange>";
663
664
665  //Harmattan needs bigger font
666         QString menufonthtml = "<font size = \"6\" color = darkorange>";
667
668
669     pRestartGameItem_ = new QGraphicsTextItem;
670     pRestartGameItem_->setHtml(tr("Restart <br> game").prepend(menufonthtml));
671     prepareForMenu(pRestartGameItem_);
672
673     pRestartLevelItem_ = new QGraphicsTextItem;
674     pRestartLevelItem_->setHtml(tr("Restart <br> level").prepend(menufonthtml));
675     prepareForMenu(pRestartLevelItem_);
676
677     pChooseLevelsetItem_ = new QGraphicsTextItem;
678     pChooseLevelsetItem_->setHtml(tr("Choose <br> levelset").prepend(menufonthtml));
679     prepareForMenu(pChooseLevelsetItem_);
680
681     pSettingsItem_ = new QGraphicsTextItem;
682     QString vibraText(tr("Turn vibration <br> effects "));
683     QString statusText;
684     if (pVibrateAction_->isChecked())
685     {
686         statusText = "off";
687     }
688     else
689     {
690         statusText = "on";
691     }
692     vibraText.append(statusText);
693     pSettingsItem_->setHtml(vibraText.prepend(menufonthtml));
694     prepareForMenu(pSettingsItem_);
695
696     pAboutItem_ = new QGraphicsTextItem;
697     pAboutItem_->setHtml(tr("About <br> game").prepend(menufonthtml));
698     prepareForMenu(pAboutItem_);
699
700     pQuitItem_ = new QGraphicsTextItem;
701     pQuitItem_->setHtml(tr("Quit <br> game").prepend(menufonthtml));
702     prepareForMenu(pQuitItem_);
703
704 }
705
706 void SeaScene::prepareForMenu(QGraphicsItem * pItem)
707 {
708
709     //Menu items have pause text item as their parent and are thus added to scene automatically
710     //They are also shown and hidden with it, resulting in the menu being visble when the game is paused
711     //Their coordinates are given relative to the parent.
712
713     int itemsPerRow = 3;
714
715     pItem->setParentItem(pPausetextItem_);
716     pItem->setZValue(1000);
717     pItem->setFlag(QGraphicsItem::ItemIsSelectable);
718
719     if (menuItemCount_< itemsPerRow)
720     {
721         pItem->setY(120);
722     }
723     else pItem->setY(240);
724
725
726     pItem->setX((menuItemCount_++%itemsPerRow)*180-10);
727  }
728
729
730 void SeaScene::about()
731 {
732     pPausetextItem_->hide();
733     pAboutBoxItem_->show();
734 }
735
736
737 void SeaScene::restartLevel()
738 {
739
740     levelScore_ = 0;
741
742     setupMap(levelset_.getLevel(currentLevel_));  //getLevel() returns default constructor Level if index is invalid, so no risk of crash
743
744     scoreCounter_.start();
745
746     vibrationActivate(pVibrateAction_->isChecked());  //Vibration effects are lost without this
747    // qDebug() << pVibrateAction_->isChecked();
748
749     autopauseTimer.start();  //reset counting towards autopause
750
751
752 }
753
754
755
756 void SeaScene::nextLevel()
757 {
758
759     //get score for previous level
760     levelScore_ += scoreCounter_.elapsed();
761     totalScore_ += levelScore_;
762     int highscore = levelset_.getLevelHighScore(currentLevel_);
763
764     qDebug() << highscore;
765
766     QString scoretext;
767
768     if (levelScore_ >= highscore)
769     {
770         scoretext = tr("<font size=\"7\" color = darkorange>Your time: %1.%2 s<br>Best time: %3.%4 s").arg(levelScore_/1000).arg((levelScore_%1000)/100).arg(highscore/1000).arg((highscore%1000)/100);
771     }
772
773     else //New high score!
774
775     {
776         scoretext = tr("<font size=\"7\" color = darkorange>Your time %1.%2 s is<br>the new best time!").arg(levelScore_/1000).arg((levelScore_%1000)/100);
777         levelset_.setLevelHighScore(currentLevel_,levelScore_);
778     }
779
780     //pause to show the highscore or victory screen
781
782     turnPauseOn();
783     pPausetextItem_->hide();
784
785
786     //Go to the next level if available
787     currentLevel_++;
788
789     if ( currentLevel_ < levelset_.numberOfLevels() )
790     {
791
792        pLevelCompletedItem_->setHtml(scoretext);
793        pLevelCompletedItem_->show();
794 //       restartLevel();
795     }
796
797     else //Victory!
798     {
799         int totalHighsore = levelset_.getTotalHighScore();
800         if (totalScore_ >= totalHighsore)
801         {
802             scoretext.append(tr("<br>Your total time: %1.%2 s<br>Best total time: %3.%4 s").arg(totalScore_/1000).arg((totalScore_%1000)/100).arg(totalHighsore/1000).arg((totalHighsore%1000)/100));
803         }
804         else //new total high score
805         {
806             scoretext.append(tr("<br>Your total time %1.%2 s is<br>the new best time").arg(totalScore_/1000).arg((totalScore_%1000)/100));
807             levelset_.setTotalHighScore(totalScore_);
808         }
809
810         pVictoryScoreItem_->setHtml(scoretext);
811         pVictoryCongratulationsItem_->show();
812     }
813 }
814
815
816 void SeaScene::restartGame()
817 {
818     currentLevel_ = 0;
819     totalScore_ = 0;
820     restartLevel();
821 }
822
823
824 void SeaScene::forcePause()
825 {
826     //Pause without setting the pause action state
827     pause(true);
828 }
829
830 void SeaScene::softContinue()
831 {
832     //Continue if not being paused by the user
833     // Reverts forcePause()
834
835     pause(pPauseAction_->isChecked());
836 }
837
838
839 void SeaScene::createVictoryItems()
840 {
841     pVictoryCongratulationsItem_ = new QGraphicsTextItem;
842     pVictoryCongratulationsItem_->setHtml("<font size=\"7\" color = darkorange> <b> Victory!");
843     pVictoryCongratulationsItem_->hide();
844     pVictoryCongratulationsItem_->setPos(370,30);
845     pVictoryCongratulationsItem_->setZValue(1000);
846     addItem(pVictoryCongratulationsItem_);
847
848
849     //coordinates are relative to the parent
850
851     QGraphicsTextItem * pTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
852     pTextItem->setHtml("<font size=\"7\" color = darkorange> Congratulations!");
853     pTextItem->setPos(-50,80);
854     pTextItem->setZValue(1000);
855
856     QGraphicsTextItem * pMiddleTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
857     pMiddleTextItem->setHtml("<font size=\"7\" color = darkorange> You have saved all the ghosts.");
858     pMiddleTextItem->setPos(-145,120);
859     pMiddleTextItem->setZValue(1000);
860
861
862     pVictoryScoreItem_ = new QGraphicsTextItem(pVictoryCongratulationsItem_);
863     pVictoryScoreItem_->setPos(-50,180);
864     pMiddleTextItem->setZValue(1000);
865     //Text is set at usetime!
866
867     QGraphicsTextItem * pLowestTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
868     pLowestTextItem->setHtml("<font size=\"7\" color = darkorange> Tap to play again");
869     pLowestTextItem->setPos(-50,360);
870     pLowestTextItem->setZValue(1000);
871 }
872
873
874 void SeaScene::createAboutBoxItems()
875 {
876     pAboutBoxItem_ = new QGraphicsTextItem;
877     addItem(pAboutBoxItem_);
878     pAboutBoxItem_->setPos(25,50);
879     pAboutBoxItem_->setZValue(1000);
880     pAboutBoxItem_->hide();
881
882     pAboutBoxItem_->setHtml(tr("<font color = darkorange size = \"7\"><b>"
883                           "%1 Version %2</b>"
884                           "<p><font size = \"6\"> Copyright 2011 Heli Hyv&auml;ttinen"
885                           "<p><font size = \"6\"> License: GNU General Public License v2"
886                           "<p><font size = \"6\">  The source code of this game is available trough its web pages."
887                           "<p><font size = \"6\"> Web: http://ghostsoverboard.garage.maemo.org/"
888                           "<p><font size = \"6\">Bug Reports: <br> https://bugs.maemo.org/"
889                           "enter_bug.cgi?product=Ghosts%20Overboard"
890                           ).arg(QApplication::applicationName(),QApplication::applicationVersion()));
891
892 }
893
894 void SeaScene::setItemPointersNull()
895 {
896     pPausetextItem_ = NULL;
897     pRestartLevelItem_ = NULL;
898     pRestartGameItem_ = NULL;
899     pSettingsItem_ = NULL;
900     pAboutItem_ = NULL;
901     pQuitItem_ = NULL ;
902 //    pMinimizeItem_ = NULL; //Fremantle spesific
903     pChooseLevelsetItem_ = NULL;
904
905     pAboutBoxItem_ = NULL;
906     pLevelCompletedItem_ = NULL;
907     pVictoryCongratulationsItem_ = NULL;
908     pVictoryScoreItem_ = NULL;
909
910 }
911
912 void SeaScene::turnPauseOn()
913 {
914     pPauseAction_->setChecked(true);
915 }
916
917
918
919 void SeaScene::createLevelCompletedItems()
920 {
921     pLevelCompletedItem_ = new QGraphicsTextItem;
922     addItem(pLevelCompletedItem_);
923     pLevelCompletedItem_->setPos(310,100);
924     pLevelCompletedItem_->setZValue(1000);
925     pLevelCompletedItem_->hide();
926     //The text is set at usetime
927
928     QGraphicsTextItem * pTapForNextLevelItem = new QGraphicsTextItem(pLevelCompletedItem_);
929     pTapForNextLevelItem->setPos(-60,100);
930     pTapForNextLevelItem->setZValue(1000);
931     pTapForNextLevelItem->setHtml("<font size=\"7\" color = darkorange>Tap to start the next level");
932 }
933
934 void SeaScene::createSelectLevelsetFromListItems()
935 {
936
937     if (availableLevelsets_.isEmpty()) //Something is badly wrong in code if this is true...
938             return;
939
940
941     pSelectLevelsetFromListItem_ = new QGraphicsTextItem;
942     addItem(pSelectLevelsetFromListItem_);
943     pSelectLevelsetFromListItem_->setPos(295,60);
944     pSelectLevelsetFromListItem_->setZValue(1000);
945     pSelectLevelsetFromListItem_->hide();
946
947
948     QString fontstring ("<font color = darkorange size = \"7\">");
949
950     pSelectLevelsetFromListItem_->setHtml(tr("Choose a levelset").prepend(fontstring));
951
952     int yPos = 100;
953
954     levelsetItems_.clear();
955
956
957     foreach (Levelset set, availableLevelsets_)
958     {
959         QGraphicsTextItem * pItem = new QGraphicsTextItem(pSelectLevelsetFromListItem_);
960         QString text (fontstring);
961         if (levelset_.getName() == set.getName())
962             text.append("<b>");
963         text.append(set.getName());
964         pItem->setHtml(text);
965         pItem->setPos(65,yPos);
966         yPos+=80;
967         pItem->setZValue(1000);
968         pItem->setFlag(QGraphicsItem::ItemIsSelectable);
969         pItem->setData(0,QVariant::fromValue(set));
970         levelsetItems_.append(pItem);
971
972     }
973
974   }
975
976
977     void SeaScene::resourcesAvailable()
978     {
979 //        qDebug() << "Resources available";
980         vibrationAllowed_ = true;
981         emit vibrationGranted();
982     }
983
984
985     void SeaScene::resourcesLost()
986     {
987         qDebug() << "Resources lost";
988         vibrationAllowed_ = false;
989         emit vibrationDenied();
990     }