/*______________________________________________________________________
 * mastermindSTD
 * par Martin Robinson
 * c'est un frontend pour mastermind
 * ______________________________________________________________________
 * preprocesseur
 */
#pragma once
#ifndef _MMSTD
#define _MMSTD
#include "mastermind.hpp"
#include <string>
#include <iostream>
#include <assert.h>
using namespace std;

/*_______________________________________________________________________
 * constante
 */

#define title "\n"\
"   _____                   __                  _____  .__            .___     \n" \
"  /     \\ _____    _______/  |_  ___________  /     \\ |__| ____    __| _/   \n" \
" /  \\ /  \\\\__  \\  /  ___/\\   __\\/ __ \\_  __ \\/  \\ /  \\|  |/    \\  / __ |\n" \
"/    Y    \\/ __ \\_\\___  \\ |  | \\  ___/|  | \\/    Y    \\  |   |  \\/ /_/ |\n" \
"\\____|__  (____  /____  / |__|  \\___  |__|  \\____|__  /__|___|  /\\____ |    \n" \
"        \\/     \\/     \\/            \\/              \\/        \\/      \\/ \n" \
"\n"

#define perdu "\n" \
" _______  _______  ______    ______   __   __  \n" \
"|       ||       ||    _ |  |      | |  | |  | \n" \
"|    _  ||    ___||   | ||  |  _    ||  | |  | \n" \
"|   |_| ||   |___ |   |_||_ | | |   ||  |_|  | \n" \
"|    ___||    ___||    __  || |_|   ||       | \n" \
"|   |    |   |___ |   |  | ||       ||       | \n" \
"|___|    |_______||___|  |_||______| |_______| \n" \
"\n"

#define gagner "\n" \
" _______  _______  _______  __    _  _______  ______   \n" \
"|       ||   _   ||       ||  |  | ||       ||    _ |  \n" \
"|    ___||  |_|  ||    ___||   |_| ||    ___||   | ||  \n" \
"|   | __ |       ||   | __ |       ||   |___ |   |_||_ \n" \
"|   ||  ||       ||   ||  ||  _    ||    ___||    __  |\n" \
"|   |_| ||   _   ||   |_| || | |   ||   |___ |   |  | |\n" \
"|_______||__| |__||_______||_|  |__||_______||___|  |_|\n" \
"\n" \

/*_______________________________________________________________________
 * defenition d'objet
 */

//-----------------------------objet STD---------------------------------
//il sert à faire le pont entre mastermind et cin cout
//de cette façon le jeux mastermind est completement 
//indépendant de la librairie d'interface
//-----------------------------------------------------------------------
class masterMindSTD : public masterMind{
public:
    masterMindSTD() : masterMind() {}   //constructeur qui appelle 
                                        //le constructeur de sont parent
    friend ostream& operator<<(ostream& out, masterMindSTD& ligne);
                                        //surcharge de cout << this
    friend istream& operator>>(istream& in, masterMindSTD& ligne);
                                        //surcharge de cin >> this
};

//methode

//affichage
ostream& operator<<(ostream& out, masterMindSTD& game)
{
    //effacer l'écran
    for (int i=0;i<25;i++)
        out << endl;
    //afficher l'entête
    //optionelement si le joueur à gagné
    //ou perdu
    out << (game.win()?gagner:(game.done()?perdu:title));
    for (int i=0;i<24;i++)
        out << '_';
    out << "bonne couleur_____bonne place\n";
    //afficher les douze lignes
    for (int i=0;i<12;i++)
    {
        //pour chaque couleur
        for (int j=0;j<5;j++)
            //si elle n'est pas vide affiché là
            if (game[i].getColor(j) != 0)
                out << " [" 
                    << game[i].getColor(j)
                    << "]";
            else
                out << " [ ]";
        //si la ligne est déjà fait afficher les résultat
        if (game[i].done())
            out << "         (" << game[i].matchingColor(game._hidden) 
                << ")             (" << game[i].rightPlace(game._hidden) << ")";
        //et on change de ligne
        out << endl;
    }
#ifdef DEBUG
    //mode debug affiche la ligne caché
    out << "solution =>";
    for (int i=0;i<5;i++)
        out << game._hidden.getColor(i);
    out << endl;
#endif
    return out;
}

//saisie
istream& operator>>(istream& in, masterMindSTD& game)
{
    string buffer;              //tampon temporaire
    in >> buffer;               //sasie d'une string
    if (buffer.length() >=5 )   //s'il n'y a pas assez de charactere
    {
        for (int i=0;i<5;i++)
        {
            //validation des 5 premier charactere
            if (buffer[i] <= 48 || buffer[i] > 56 )
                return in;
            game.currentM().setColor(i,buffer[i]-48);
        }
        //avancer d'une ligne si possible
        game.inc();
    }
    return in;
}

#endif
