#include <qdeclarative.h>
#include <QFile>
#include <QApplication>
#include <QSettings>
#include <QTranslator>

#if defined(Q_EVHUNT_MEEGO)
    #include <MDataUri>
    #include <maemo-meegotouch-interfaces/shareuiinterface.h>
#endif

#include "TileData.h"
#include "EvidenceType.h"
#include "EvidenceInfo.h"
#include "SuspectData.h"
#include "TopPlayerData.h"
#include "Scoreboard.h"

#ifndef EVIDENHUNTGAME_H
#define EVIDENHUNTGAME_H

class EvidencehuntGame : public QObject {

    Q_OBJECT

public:
    EvidencehuntGame(QApplication*);

    Q_PROPERTY(QDeclarativeListProperty<TileData> tiles READ tiles CONSTANT)
    QDeclarativeListProperty<TileData> tiles();

    Q_PROPERTY(QDeclarativeListProperty<SuspectData> suspects READ suspects CONSTANT)
    QDeclarativeListProperty<SuspectData> suspects();

    Q_PROPERTY(QDeclarativeListProperty<TopPlayerData> players READ topPlayers NOTIFY scoreboardLoaded)
    QDeclarativeListProperty<TopPlayerData> topPlayers();

    Q_PROPERTY(EvidenceInfo* evidenceInfo READ evidenceInfo NOTIFY evidenceInfoChanged)
    EvidenceInfo* evidenceInfo() {return _evidenceInfo; }

    Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY isPlayingChanged)
    bool isPlaying() {return playing;}

    Q_PROPERTY(bool hasWon READ hasWon NOTIFY hasWonChanged)
    bool hasWon() {return won;}

    Q_PROPERTY(int numEvidences READ numEvidences NOTIFY numEvidencesChanged)
    int numEvidences() const{return nEvidences;}

    Q_PROPERTY(int foundEvidences READ foundEvidences NOTIFY foundEvidencesChanged)
    int foundEvidences() const{return fEvidences;}

    Q_PROPERTY(int numFlags READ numFlags NOTIFY numFlagsChanged)
    int numFlags() const{return nFlags;}

    Q_PROPERTY(int timeRemaining READ timeRemaining NOTIFY timeRemainingChanged)
    int timeRemaining() const{return remaining;}

    Q_PROPERTY(int streak READ streak NOTIFY wonStreakChanged)
    int streak() const {return wonStreak;}

    Q_PROPERTY(int currentScore READ currentScore NOTIFY currentScoreChanged)
    int currentScore() const {return score;}

    Q_PROPERTY(int lastScore READ lastScore NOTIFY lastScoreChanged)
    int lastScore() const;

    Q_PROPERTY(int totalScore READ totalScore NOTIFY totalScoreChanged)
    int totalScore() const;

    Q_PROPERTY(int maxScore READ maxScore NOTIFY maxScoreChanged)
    int maxScore() const;

    Q_PROPERTY(int maxScoreSubmitted READ maxScoreSubmitted NOTIFY maxScoreSubmittedChanged)
    int maxScoreSubmitted() const;

    Q_PROPERTY(bool solveMode READ solveMode NOTIFY solveModeChanged)
    bool solveMode() {return isSolveMode;}

    Q_PROPERTY(int killer READ killer NOTIFY killerChanged)
    int killer() const{ return killerId; }

    Q_PROPERTY(bool isInfoVisible READ isInfoVisible NOTIFY evidenceInfoChanged())
    bool isInfoVisible() {return _evidenceInfo->visible();}

    Q_PROPERTY(QString emptyString READ getEmptyString NOTIFY languageChanged)
    QString getEmptyString () { return ""; }

    Q_PROPERTY(int selectedLanguage READ currentLanguage NOTIFY languageChanged)
    int currentLanguage () {
        QString langString = _settings->value("lang").toString();
        int ret = 0;
        if (langString=="hu_HU") {
            ret = 1;
        } else if(langString=="sr_RS") {
            ret = 2;
        } else if(langString=="it_IT") {
            ret = 3;
        }
        return ret;
    }

    Q_PROPERTY(QString playerName READ player NOTIFY playerChanged)
    QString player();

    QList<QString> roleTypes;

public slots:
    Q_INVOKABLE bool flip(int row, int col);
    Q_INVOKABLE bool flag(int row, int col);
    Q_INVOKABLE void shareGame() const;
    Q_INVOKABLE bool loadEvidence(int row, int col);
    Q_INVOKABLE bool suspectFlip(int id);
    Q_INVOKABLE bool suspectExclude(int id);
    Q_INVOKABLE bool toggleSolve();
    Q_INVOKABLE bool guessMurderer(int id);
    Q_INVOKABLE void selectLanguage(int lang);
    Q_INVOKABLE void openScoreboard();
    Q_INVOKABLE bool submitScore(QString name, int score);
    void loadLanguage();
    void refreshLanguage(bool loadStartScene = false);
    void setBoard();
    void reset();
    void changeEvidenceInfo() { emit evidenceInfoChanged(); }
    void loadScoreboardPlayers(QList< QHash<QString,QString> >);
    void boardSubmitSuccess(int);

signals:
    void isPlayingChanged();
    void hasWonChanged();
    void numEvidencesChanged();
    void foundEvidencesChanged();
    void numFlagsChanged();
    void timeRemainingChanged();
    void currentScoreChanged();
    void lastScoreChanged();
    void totalScoreChanged();
    void maxScoreChanged();
    void maxScoreSubmittedChanged();
    void evidenceInfoChanged();
    void solveModeChanged();
    void killerChanged();
    void languageChanged();
    void openWelcomeDialog();
    void scoreboardLoaded();
    void openBoardErrorDialog();
    void playerChanged();
    void wonStreakChanged();

private:
    bool onBoard( int r, int c ) const { return r >= 0 && r < numRows && c >= 0 && c < numCols; }
    TileData *tile( int row, int col ) { return onBoard(row, col) ? _tiles[col+numRows*row] : 0; }
    SuspectData *suspect( int id ) { return _suspects[id]; }
    int getHint(int row, int col);
    EvidenceType* getType(int row, int col);
    void setPlaying(bool b){if(b==playing) return; playing=b; emit isPlayingChanged();}

    QList<QString> loadFromXml(QString);

    QList<TileData *> _tiles;
    QList<SuspectData *> _suspects;
    QList<TopPlayerData *> _players;

    QList<EvidenceType *> tileTypes;
    QList<QString> suspectProperties;
    QList<QString> suspectNegativeProperties;
    QList<QString> startScenes;
    EvidenceInfo* _evidenceInfo;

    Scoreboard* _scoreboard;

    int numCols;
    int numRows;
    int nEvidences;
    int fEvidences;
    int numSuspects;
    bool playing;
    bool won;
    int remaining;
    int score;
    int nFlags;
    int defaultScore;
    int scoreMultiplier;
    int wonStreak;

    int startScene;
    int killerId;
    int alibiId;

    bool isSolveMode;

    QSettings* _settings;
    QApplication* _app;
    QTranslator* _translator;

};

#endif // EVIDENCEHUNTGAME_H

