+
+void GameView::setMovingPieces()
+{
+ if(pieces_.isEmpty()) {
+ qDebug() << "Empty list @ GameView::setMovingPieces";
+ return;
+ }
+
+ QPointF point = QPointF();
+ for(int i = 0; i < pieces_.count(); ++i) {
+ point = pieces_.at(i)->currentPlace();
+
+ // Is piece on the left side of the empty space
+ if(emptyPlace_.y() == point.y() && point.x() + horizontalStep_ == emptyPlace_.x()) {
+ pieces_.at(i)->setMovable(true);
+ }
+
+ // Is piece on the right side of the empty space
+ else if(emptyPlace_.y() == point.y() && point.x() - horizontalStep_ == emptyPlace_.x()) {
+ pieces_.at(i)->setMovable(true);
+ }
+
+ // Is piece below the empty space
+ else if(emptyPlace_.x() == point.x() && point.y() - verticalStep_ == emptyPlace_.y()) {
+ pieces_.at(i)->setMovable(true);
+ }
+
+ // Is piece on top of the empty space
+ else if(emptyPlace_.x() == point.x() && point.y() + verticalStep_ == emptyPlace_.y()) {
+ pieces_.at(i)->setMovable(true);
+ }
+
+ // The piece is somewhere else
+ else {
+ pieces_.at(i)->setMovable(false);
+ }
+ }
+}
+
+bool GameView::restoreGame()
+{
+ // Read settings from file
+ QFile file(QString("%1/%2/%3")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY)
+ .arg(RESTORE_FILE));
+
+ if(!file.open(QIODevice::ReadOnly)) {
+ qDebug() << "Failed to open restore file for reading";
+ return false;
+ }
+
+ QTextStream in(&file);
+
+ QStringList list;
+
+ list = in.readLine().split(";;");
+
+ qDebug() << "restore list count: " << list.count();
+
+ if(!list.isEmpty()) {
+ bool ok = false;
+ int pieces = list.at(0).toInt(&ok);
+ if(!ok) {
+ return false;
+ }
+
+ QString im = list.at(1);
+ if(!QFile::exists(im) && im != "default") {
+ return false;
+ }
+
+ int moveCount = list.at(2).toInt(&ok);
+ if(!ok) {
+ return false;
+ }
+
+ Settings::instance()->setPieceCount(pieces);
+ PuzzleItem::setMoveCount(moveCount);
+
+ if(im == "default" || im.isEmpty()) {
+ Settings::instance()->setImage(0);
+ Settings::instance()->setImagePath("default");
+ }
+ else {
+ Settings::instance()->setImagePath(im);
+ Settings::instance()->setImage(QPixmap(im));
+ }
+
+ setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()), false);
+
+ qDebug() << "pieces_ count after restoring image: " << pieces_.count();
+
+ if(list.count() >= pieces_.count() + 3) {
+ for(int j = 0; j < pieces_.count(); ++j) {
+ if(!list.at(j + 3).isNull()) {
+ QStringList points = list.at(j + 3).split("#");
+
+ int x = points.at(0).toInt(&ok);
+ if(!ok) {
+ return false;
+ }
+
+ int y = points.at(1).toInt(&ok);
+ if(!ok) {
+ return false;
+ }
+
+ QPointF point(x, y);
+
+ //qDebug() << "Setting piece " << pieces_.at(j)->pieceNumber();
+ //qDebug() << "x: " << point.x() << " y: " << point.y();
+
+ pieces_.at(j)->setCurrentPlace(point);
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ else {
+ file.close();
+ file.remove();
+ return false;
+ }
+
+ QStringList hidden = list.last().split("#");
+
+ if(hidden.count() == 3) {
+ for(int m = 0; m < pieces_.count(); ++m) {
+ pieces_.at(m)->setPos(pieces_.at(m)->currentPlace());
+ if(pieces_.at(m)->pieceNumber() == hidden.at(2).toInt()) {
+ //qDebug() << "Hiding piece number " << hidden;
+ hiddenIndex_ = m;
+ }
+ }
+
+ setEmptyPlace(QPointF(hidden.at(0).toInt(), hidden.at(1).toInt()));
+
+ pieces_.at(hiddenIndex_)->setVisible(false);
+
+ setMovingPieces();
+ }
+ else {
+ setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()));
+ file.close();
+ file.remove();
+ return false;
+ }
+ }
+ else {
+ qDebug() << "Invalid restore file";
+ file.close();
+ file.remove();
+ return false;
+ }
+
+ QFileInfo fileInfo(file);
+
+ QDateTime created = fileInfo.created();
+ QString infoTxt = QString("Restored game state from %1")
+ .arg(created.toString(Qt::TextDate));
+
+#ifdef Q_WS_MAEMO_5
+ QMaemo5InformationBox::information(this, infoTxt);
+#endif
+
+ file.close();
+ file.remove();
+
+ return true;
+}
+
+void GameView::saveGame()
+{
+ if(pieces_.isEmpty() || pieces_.count() < EASY_PIECE_COUNT) {
+ return;
+ }
+
+ QDir dir;
+ if(!dir.exists(QString("%1/%2")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY))) {
+ dir.mkpath(QString("%1/%2")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY));
+ }
+
+ QFile file(QString("%1/%2/%3")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY)
+ .arg(RESTORE_FILE));
+
+ if(!file.open(QIODevice::WriteOnly)) {
+ qDebug() << "Failed to open restore file for writing";
+ return;
+ }
+
+ QTextStream out(&file);
+
+ out << Settings::instance()->pieceCount();
+ out << QString(";;");
+ if(Settings::instance()->imagePath().isEmpty()) {
+ out << QString("default");
+ }
+ else {
+ out << Settings::instance()->imagePath();
+ }
+ out << QString(";;");
+ out << PuzzleItem::moveCount();
+ out << QString(";;");
+
+ // piece positions
+ int number = 0;
+ int hiddenNo = 0;
+
+ while(number != pieces_.count()) {
+ for(int i = 0; i < pieces_.count(); ++i) {
+ if(pieces_.at(i)->pieceNumber() == number + 1) {
+ out << pieces_.at(i)->currentPlace().x();
+ out << QString("#");
+ out << pieces_.at(i)->currentPlace().y();
+ out << QString(";;");
+ pieces_.at(i)->pieceNumber();
+ if(!pieces_.at(i)->isVisible()) {
+ hiddenNo = number + 1;
+ }
+ number++;
+ break;
+ }
+ }
+ }
+
+ out << QString("%1#%2#%3").arg(emptyPlace().x()).arg(emptyPlace().y()).arg(hiddenNo);
+
+ out << "\n";
+
+ file.close();
+
+ qApp->quit();
+}
+
+int GameView::correctPlaces() const
+{
+ int c = 0;
+
+ for(int i = 0; i < pieces_.count(); ++i) {
+ if(pieces_.at(i)->currentPlace() == pieces_.at(i)->correctPlace()) {
+ c++;
+ }
+ }
+
+ return c;
+}
+
+QList<int> GameView::movingPlaces() const
+{
+ QList<int> m;
+
+ for(int i = 0; i < pieces_.count(); ++i) {
+ if(pieces_.at(i)->movable()) {
+ m.append(i);
+ }
+ }
+
+ return m;
+}