/***********************************************************************
 *
 * Copyright (C) 2010-2017 Innocent De Marchi <tangram.peces@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ***********************************************************************/
#ifndef FRMPRINCIPAL_H
#define FRMPRINCIPAL_H

#include <QtGui>
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItem>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QUndoStack>
#include <QtWidgets/QMenu>
#include <QtWidgets/QActionGroup>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QMainWindow>
#include <QTranslator>
#include <QtWidgets/QProgressDialog>

#include "frmprincipal.h"
#include "tauler.h"
#include "rellotge.h"

class frmPrincipal : public QMainWindow
{
    Q_OBJECT

public:
    frmPrincipal();

    QFrame *jocFram;

    QTreeWidget *arbreModalitatsJocTreeWidget;
    QTreeWidget *arbreModalitatsJocPersonalitzatsTreeWidget;
    //Llista amb el contingut de l'arxiu data.sol
    QList<QString> dadesArxiuData;

    //Tab pels arbres de jocs i solucions
    QTabWidget *tabArbres;

    Tauler *taulerJoc;

    QUndoStack* movimentsUndoStack;

    Rellotge *rellotgeLabel;

    /* Llegeix i carrega les dades dels jocs
     * de l'arxiu games.dat a la llista
     * dadesArxiuData
     */
    void llegeixArxiuData();    
    void carregaArbreModalitatsJoc();
    /* Retorna el tipus de moviment en text
     * (invers/diagonal)
     */
    QString afageixTipusMovimentNomJoc(QString tipus);

    /* Llegeix i carrega les dades dels jocs personalitzats
     * de l'arxiu /home/Solitari/games-per.dat a la llista
     * dadesArxiuData
     */
    bool llegeixArxiuDataPersonalitzats();
    /*Carrega les dades dels solitaris personalitzats
     */
    void carregaArbreModalitatsJocPersonalitzats();
    /* Posa l'icone OK al ítem de l'arbre si
     * ja hi ha un record
     */
    QString posaIconeOK(QString codiJoc);
    /* Comprova si hi ha un record pel joc
     * i el retorna
     */
    QString hihaRecordJoc(QString codiJoc);

   // int jocResolt;

    QStringList solucionaJocActual_movimentsEliminats;
    QStringList solucionaJocActual_movimentsJaRealitzats;
    QStringList solucionaJocActual_movimentsPosiblesActuals;
    QStringList solucioJocActual_configuracionsEliminades;
    QStringList solucioJocActual_configuracionsEliminadesPerDesar;
    QString solucioJocActual_configuracioInicial;
    QString jocActual_configuracioInicialFitxesMarcades;
    QString solucionaJocActual_darrerMoviment;
    void actualitzaConfiguracionsInicials();

    QStringList solucionsTrobades;

    QAction *iniciSolucioAction;

    int retrocedeixMoviment=0;


    void desaSolucions();
    //Desa la solució actual continguda a movimentsUndoStack
    void desaSolucions1();

    //Mostra les solucions del joc actual
    void veureSolucionsSlot();

    void comprovaArxiuSolucions();
    /* Comprova si hi ha un arxiu amb solucions del joc actual
     * en el directorio /games
     * Es fa servir per saber si el programa aconsegueix resoldre
     * el joc sense fer servir dades de solucions prèvies*/
    bool comprovaDadesSolucions();

    QString missatgeNumeroMoviments(int maxim=0);

    //Visualitzador de solucions
    QTreeWidget *arbreSolucionsTreeWidget;

    //Mostra un missatge passat pel tauler del joc
    void mostraMissatge(int codi);


    //Solitari a l'atzar
    /* Determina si el solitari actual és o no
     * a l'atzar
     */
    bool solitariAtzar_esAtzar(QString joc);

    //Solitari personalitzat
    /* Calcula les dades de les fitxes del solitari personalitzat
     */
    void solitariPersonalitzat_dadesFitxes();
    /* Determina si el solitari actual és o no
     * personalitzat
     */
    bool solitariPersonalitzat_esPersonalitzat(QString joc);
    /* Quan es resol un solitari personalitzat
     * es desa a l'arbre de jocs personalitzats
     * (prèvia comprovació de que no està repetit)
     */
    void solitariPersonalitzat_desarSolitari();

    /* Elimina l'arxiu de la solució del solitari personalitzat
     * actual
     */
    void solitariPersonalitzat_eliminaArxiuSolucio();

    /* Controla si s'està jugat un joc del programa (valor 0)
     * o un joc personalitzat (valor 1)
     */
    int tipusJocActual;

    /* Arbre del joc actual.
     * Es fa servir per saber quin tipus de joc
     * està actiu
     * 0: arbre dels jocs del programa
     * 1: arbre dels jocs personalitzats
     */
    void setArbreJocsActual(int valor);
    int arbreJocsActual() const{
        return p_arbreJocsActual;}

    QString nomArxiuJoc(int tipus);
private slots:

    void closeEvent(QCloseEvent* event);

    /* Gestiona a quin arbre de jocs
     * (del programa o personalitzats)
     * cal seleccionar
     */
    void gestioTipusDeJocASeleccionar();

    /*Gestiona la selecció de la modalitat de joc
     *Conectat al canvi d'ítem de l'arbre de jocs
     */
    void seleccioModalitatJoc();

    /* Gestiona el canvi de la selecció de joc per controlar
     * el tipus de joc de generació a l'atzar
     * elimina les dades del ítem a l'atzar per permetre la
     * generació en tornar a seleccionar
     */
    void canviItemArbreJoc(QTreeWidgetItem *actual, QTreeWidgetItem *anterior);

    /* Gestiona el canvi de selecció
     * de la fulla del tab amb els arbres de jocs
     * i solucions
     */
    void canviTabSeleccionat( int tabSeleccionat);

    QString movimentACoordenades(QString inici,QString final);
    QString coordenadesAMoviment(QString coordenades);

    void veureRecordsPersonals();
    void eliminaRecordsPersonals();

    void canviaIdioma(QAction *action);

    void creditsProgramaSlot();
    void webProgramaSlot();
    void webProgramaPecesSlot();

    void ajudaSlot();
    void agraimentSlot();

    /*Procediments de cerca de solició*/
    void solucionaJocRapid();
    bool comprovaExisteixenMovimentsPossibles();
    void solucionaJocActual_carregaSolucio();
    void solucionaJocActual_carregaSolucio1();
    int solucionaJocActual_numeroDeFitxesDelJoc();
    void solucionaJocActual_Inicia();
    void solucionaJocActual_ControlJocPersonalitzatModificat();
    void solucionaJocActual_CarregaMovimentsInicialsArbre();
    void solucionaJocActual_comencaRecerca();
    void solucionaJocActual_eliminaMovimentsPosteriors();
    void solucionaJocActual_eliminaConfiguracionsPosteriors(QString config);
    void solucionaJocActual_RecercaIterativa_ExhaustivaInici(int numFitxesInicialsJoc, int mantenirMoviment=0);
//    void solucionaJocActual_RecercaIterativa_Exhaustiva(QProgressDialog *progres, int profunditat,
//                                                        int numeroInicialFitxesJoc, variables_recerca_solucio variablesSolucio);

    void solucionaJocActual_RecercaIterativa_Exhaustiva1(QProgressDialog *progres, int numeroFitxesJoc);

//    variables_recerca_solucio solucioJocActual_carregaVariablesCercaSolucio(int numeroInicialFitxesJoc);
    /*cerca solucions per força bruta*/
    void solucionaJoc_ForcaBruta();
    void solucioJocActual_RecercaIterativa_escriuDesaMovimentRealitzat(int tabulacio,QString cadenaMoviment);
    //Desa les dades del joc personalitzat/modificat a l'arxiu games_per.dat
    //i l'afageix a l'arbre de jocs personalitzats
    void solucioJocActual_desarJocPersonalitzat();
    //Aquesta funció no es fa servir
   // void solucionaJocActual_eliminaConfiguracions();


    void desaConfiguracionsEliminades(int tipus=0);
    void carregaConfiguracionsEliminades();
    void eliminaArxiuConfgEliminades();

    /* Escriu a un arxiu el moviment passat
     * per paràmetre. Serveix per seguir els moviments
     * provats de la recerca iterativa de solució*/
    void desaMovimentsJoc(QString moviment);
    /* Retorna el nombre de 1 de la configuració de fitxes del joc
     * passada pel paràmetre*/
    int numeroFitxesConfiguracioActualJoc(QString configuracioActual);
    /*
      Elimina l'arxiu de moviments provats en la recerca
      de iterativa de solució.
      */
    void eliminaArxiuMovimentsJoc();

    /* Elimina l'arxiu adequat segons el codi passat
      1 ".txt"
      2 ".sol"
      4 ".movi"
      5 ".arbre"*/
    void eliminaArxiu(int codi);

    void carregaSolucions();
    bool comprovaArxiuDeSolucions();

    //Carrega al movimentsUndoStack la solució actual
    void carregaSolucio(QTreeWidgetItem*, int);
    //Carrega efectivament la solució
    void carregaSolucio1();

    void iniciSolucioSlot(int pmoviment=0);
    void iniciSolucioSlotIndex(int index=0);
    //Carrega una solució
    void finalSolucioSlot(bool marcaFinal=false);

    //Deixa el joc en pausa
    void pausaJocSlot();

    //Suggereix el següent moviment a l'usuari
    void sugereixMovimentSlot();

  //Ha passat a públic
  //  void iniciSolucioSlot();

/* Gestiona el doble clic sobre l'ítem de la generació
 * a l'atzar de solitaris
 */
    void dobleClickArbreJoc(QTreeWidgetItem *item, int columne);

    /* Gestiona la selecció dels jocs
     * personalitzats
     * arbreModalitatsJocPersonalitzatsTreeWidget
     */
    void seleccioModalitatJocPersonalitzat();

private:

    void creaAcccions();
    void creaMenus();
    void creaIdiomaMenu();
    void creaBarraTasques();

    void comprovaDirectoriHome();

    void comprovaRegistre();

    void tradueixGUI();

    /* Procediments dels solitaris a l'atzar
     */
    void solitariAtzar_generaJoc();
    int solitariAtzar_tipusMovimentGenerador(int tipusMoviementGenerat,
                                             QString &tipusFitxa);
    void solitariAtzar_carregaDadesArbreJoc(QString codi,QString FilesColumnes,
                                            QString dadesFitxes);
    QString solitariAtzar_inverteixSolucioJocGenerat();
    QString solitariAtzar_coordenadesAMoviment(QString coordenades);
    /* Desa a un arxiu la solució del solitari
     * generat a l'atzar
     */
    void solitariAtzar_desaSolucio();
    void solitariAtzar_generaImatge();
    void solitariAtzar_eliminaArxiuSolucio();
    //Cadena amb la solució
    QString solitariAtzar_solucio;

    bool solitariAtzar_CarregaSolucio();
    /********/

    /*  Procediments del solitari personalitzat
     */
    /* Comprova si el solitari personalitzat ja està
     * a l'arbre de solitaris personalitzats
     */
    void solitariPersonalitzat_comprovaArbre();
    /* Afegeix un joc personalitzat a l'arbre
     */
    QString solitariPersonalitzat_afegeixJoc(QStringList dadesJocList);
    /* Afegeix les dades del joc personalitzat a l'arxiu
     * de dades
     */
    void solitariPersonalitzat_desaJocArxiu(QString codi,QStringList dadesFitxes,
                                            QString codiNom);
    /* Retorna el nou codi del solitari personalitzat
     */
    QString solitariPersonalitzat_nouCodiJoc(bool nou);

    /* Conserva el següent codi de joc
     * que s'assignarà al nou joc personalitzat
     */
    QString seguentCodiSolitariPersonalitzat;

    /* Renomena l'arxiu amb la solució del solitari
     * personalitzat nou
     */
    void solitariPersonalitzat_renomenaArxiuSolucio(QString nouCodi);
   //****final solitari personalitzat


    /* Comprova si les dades de les fitxes es corresponen
     * amb una modalitat de final marcat
     */
    bool esSolitariAmbFinalMarcat(QString dadesFitxes);

    /* Comprova si hi ha alguna solució a l'arbre
     * de solucions
     */
    bool noHiHaSolucionsArbreSolucions();

    /* Retorna el nom del joc
     * (sense afegitons segons el paràmetre)
     */
    QString nomDelJoc(QString codi, bool complet=true);

    int p_arbreJocsActual;

   //Accions del programa
    QAction *surtAction; //tanca el programa

    QAction *veureRecordsPersonalsAction;
    QAction *eliminaRecordsPersonalsAction;

    QAction *reiniciaJocActual;

    QAction *undoAction;
    QAction *redoAction;

    QAction *pausaAction;
    QAction *sugereixMovimentAction;


    QAction *ajudaAction;
    QAction *colaboraPrograma;
    QAction *creditsPrograma;
    QAction *agraiment;
    QAction *webProgramaAction;
    QAction *webProgramaPecesAction;

    QAction *solucionaJocActual;
//    QAction *solucionaJocActualRapid;
    QAction *solucionaJocActualForcaBruta;

   //Eliminada 16/12/10 Ara les solucions
  // es veuen directament en el Tab de les
  // modalitats de joc
   // QAction *veureSolucions;

    QTranslator *frm_qt_translator;
    QTranslator *frm_Translator;


    QMenu *aplicacioMenu;
    QMenu *movimentsMenu;
    QMenu *idiomaMenu;
       QActionGroup *idiomaActionGroup;
    QMenu *ajudaMenu;



    QToolBar *aplicacioToolBar;
    QToolBar *veureSolucionsToolBar;
    //rellotge per generar els nombre aleatoris
    QTime rellotgeQTime;

    void actualitzaCodisArxiusDeSolucio();

    protected:

      void resizeEvent ( QResizeEvent * event );


};

#endif // FRMPRINCIPAL_H
