// http://www.cplusplus.com/reference/
//
#include <stdio.h> // http://www.cplusplus.com/reference/cstdio/
// #include <conio.h> // // NE FONCTIONNE PAS !!
// Mais c.f. :
// VT100_Terminal_Control_Escape_Sequences_-_ISP_How-To.pdf
// http://ispltd.org/mini_howto:ansi_terminal_codes
#include <iostream> // pour cout et cin  http://www.cplusplus.com/reference/iostream/

//#include <string.h> // http://www.cplusplus.com/reference/cstring/
//#include <string> // http://www.cplusplus.com/reference/string/

// http://stackoverflow.com/questions/9547868/is-there-a-way-to-get-user-input-without-pressing-the-enter-key
// http://shtrom.ssji.net/skb/getc.html
// http://cui.unige.ch/~garg/systinfo/tips/unix/terminal.html
// Pour : tcgetattr(STDIN_FILENO, &old_tio);
#include <termios.h>

//  MARCHE PAS ! #include "conio.h"  // pour kbhit()
//??#include <curses.h>
// c.f. http://pubs.opengroup.org/onlinepubs/7908799/xcurses/curses.h.html
// http://stackoverflow.com/questions/4025891/create-a-function-to-check-for-key-press-in-unix-using-ncurses

#include <unistd.h>  /* only for sleep() */

#include <fcntl.h>

using namespace std;

/*
printf("\e[7A"); // remonte de 7 lignes
printf("\e[7B"); // descend de 7 lignes
printf("\e[7C"); // avance  de 7 colonnes
printf("\e[7D"); // recule  de 7 colonnes
printf("\e[7;9H"); // va en ligne 7 colonne 9
printf("\e[7;9f"); // va en ligne 7 colonne 9

printf("\e[s"); // sauve la position courrante du curseur
printf("\e[u); // restore la position du curseur
printf("\e[); // sauve la position courrante du curseur
printf("\e[8); // restore la position du curseur

printf("\e[r"); // permet le "scrolling" de tout l'affichage
printf("\e[7;9r"); // permet le "scrolling" de la ligne 7 à la 9
printf("\e[D"); // "scroll down one line"
printf("\e[M"); // "scroll up one line"

printf("\ec"); // Reset terminal settings to default
printf("\e[7h"); // Text wraps to next line if longer than the length of the display area.
printf("\e[7l"); //  Disables line wrapping.

printf("\e("); // Set default font.
printf("\e[)"); // Set alternate font.

printf("\e[7h"); //

*/

int test01()
//==========
{
printf("              line 1\n");
printf("              line 2");
printf("\xd line 3");  //  \xd revient en début de ligne.

printf("\e[0;33;44m"); // jaune sur fond bleu
/*
Attribut                foreground     background
0 	Reset all attributes	30 	Black	   40 	Black
1 	Bright               31 	Red	   41 	Red
2 	Dim	               32 	Green	   42 	Green
4 	Underscore	         33 	Yellow	43 	Yellow
5 	Blink	               34 	Blue	   44 	Blue
7 	Reverse	            35 	Magenta	45 	Magenta
8 	Hidden	            36 	Cyan	   46 	Cyan
                        37 	White	   47 	White
*/

// c.f. c
printf("\e[A"); // remonte d'une ligne
printf("line 4\n\n\n");

printf("\e[7C"); // avance le curseur de 7 caractères.
printf("*");
printf("\e[2D"); // recule le curseur de 2 caractères.
printf("#");

printf("\e[7;9f");
printf("7;9");

printf("\e[12;23H"); // positionne le curseur en ligne 12 et col. 23
printf("ligne 12, colone 23");

printf("\e[0;37;40m"); // jaune sur fond bleu

printf("\e[8;1H"); // positionne le curseur en ligne 12 et col. 23
printf("ligne 8, colone 1");

printf("\e[5B"); // descent le curseur de 5 lignes

printf("\e[0;30;47m"); // jaune sur fond bleu

printf("\e[20;1H"); // positionne le curseur
printf("Terminé\n");
return 0;
} // test01

int test02()
//==========
{
int nX = 1; // lignes
int nY = 1; // colonnes

for  (nY=0; nY<=7; nY++) {
  for (nX=0; nX<=7; nX++) {
    printf("\e[%i;%iH", 3+2*nY, 3+2*nX);
    printf("\e[0;%i;%im", 30+nX, 40+nY); // couleur
    printf("*");
    }
  }

for  (nY=0; nY<=7; nY++) {
  for (nX=0; nX<=7; nX++) {
    printf("\e[%i;%iH", 3+2*nY, 20+2*nX);
    printf("\e[7;%i;%im", 30+nX, 40+nY); // couleur
    printf("*");
    }
  }

printf("\e[0;37;40m"); // couleur

for  (nY=0; nY<=7; nY++) {
  for (nX=0; nX<=7; nX++) {
    printf("\e[%i;%iH", 3+2*nY, 40+2*nX);
    printf("\e[1;%i;%im", 30+nX, 40+nY); // couleur
    printf("*");
    }
  }
/*
Attribut                foreground     background
0 	Reset all attributes	30 	Black	   40 	Black
1 	Bright               31 	Red	   41 	Red
2 	Dim	               32 	Green	   42 	Green
4 	Underscore	         33 	Yellow	43 	Yellow
5 	Blink	               34 	Blue	   44 	Blue
7 	Reverse	            35 	Magenta	45 	Magenta
8 	Hidden	            36 	Cyan	   46 	Cyan
                        37 	White	   47 	White
*/

printf("\e[20;1H");
printf("\e[0;37;40m"); // couleur
printf("Terminé\n");
return 0;
} // test02

void Affiche(int nX, int nY, char cDisp) {
//======================================
// Affiche le caractère cDisp en grand à la position nX, nY
string astrS[12];

printf("\e[%i;%iH", nY, nX);

for (int nn=0; nn<=10; nn++) {
  astrS[nn] = "";
  }

if (cDisp == '1') {
   astrS[ 1] = "   **   ";
   astrS[ 2] = " ** *   ";
   astrS[ 3] = "**  *   ";
   astrS[ 4] = "    *   ";
   astrS[ 5] = "    *   ";
   astrS[ 6] = "    *   ";
   astrS[ 7] = "    *   ";
   astrS[ 8] = "    *   ";
   astrS[ 9] = "    *   ";
   astrS[10] = " *******";
   }

if (cDisp == '2') {
   astrS[ 1] = "   **   ";
   astrS[ 2] = "  *  *  ";
   astrS[ 3] = " *    * ";
   astrS[ 4] = " *   *  ";
   astrS[ 5] = "    *   ";
   astrS[ 6] = "   *    ";
   astrS[ 7] = "  *     ";
   astrS[ 8] = " *      ";
   astrS[ 9] = "*       ";
   astrS[10] = "********";
   }

if (cDisp == '3') {
   astrS[ 1] = "   ***  ";
   astrS[ 2] = "  *   **";
   astrS[ 3] = "     ** ";
   astrS[ 4] = "   **   ";
   astrS[ 5] = "  **    ";
   astrS[ 6] = "  **    ";
   astrS[ 7] = "   **   ";
   astrS[ 8] = "     ** ";
   astrS[ 9] = "  *   **";
   astrS[10] = "   ***  ";
   }

for (int nn=0; nn<=9; nn++) {
  printf("\e[%i;%iH", nY+nn, nX);
  cout << astrS[nn+1];
  }

} // Affiche

int test03()
//==========
{
char cDisp; // le caractère à afficher
int nXPos = 1; // position du caractère
int nYPos = 1;

// _kbhit()  _getch() et  sous Windows  // system("stty raw");  sous  OSX
// http://stackoverflow.com/questions/9547868/is-there-a-way-to-get-user-input-without-pressing-the-enter-key
struct termios old_tio, new_tio;

tcgetattr(STDIN_FILENO, &old_tio); // get the terminal settings for stdin
new_tio = old_tio; // we want to keep the old setting to restore them a the end

// disable canonical mode (buffered i/o) and local echo
new_tio.c_lflag &=(~ICANON & ~ECHO);

// set the new settings immediately
tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);

do {
  cDisp = getchar();  // cDisp = getchar(); // cDisp = getc(stdin);
  if ((cDisp < '0') || (cDisp > '9')) break;
  Affiche(nXPos, nYPos, cDisp);
  nXPos += 10;
  if (nXPos > 70) { nXPos = 1; nYPos +=11; }
  } while (true);

printf("\e[20;1H");
printf("\e[0;37;40m"); // couleur
printf("Terminé\n");

// restore the former settings
tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
return 0;
} // test03


int kbhit(void) {
//================
/*
    int ch = getch();
    if (ch != ERR) {
        ungetch(ch);
        return 1;
    } else {
        return 0;
    }
*/
} // kbhit


void test04()
//==========
// Test des fonctions d'input et de timing.
// ch = cin.peek();  lit un caractère, mais ne le sort pas de la liste de lecture.
{
int nn=0, n2=0;
int nTest1=0;
char ch='a';
char c2='a';

for (nn=1; nn<=2; nn++)
for (n2=1; n2<=1; n2++) {
//   nTest1 = kbhit();
   if (nTest1 != 0)  cout << nTest1 << endl;
   }

cin >> ch;
cout << ch;
cin >> c2;
} // test04


void test05()
//==========
// J'aimerais pouvoir tester si un caractère a été tapé ou non
// et que le programme continue dans tous les cas.
{
char cDisp; // le caractère à afficher

// _kbhit()  _getch() et  sous Windows  // system("stty raw");  sous  OSX
// http://stackoverflow.com/questions/9547868/is-there-a-way-to-get-user-input-without-pressing-the-enter-key
struct termios old_tio, new_tio;

tcgetattr(STDIN_FILENO, &old_tio); // get the terminal settings for stdin
new_tio = old_tio; // we want to keep the old setting to restore them a the end

// disable canonical mode (buffered i/o) and local echo
new_tio.c_lflag &=(~ICANON & ~ECHO);

// set the new settings immediately
tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);

do {
  cDisp = getchar();  // cDisp = getchar(); // cDisp = getc(stdin);
  if ((cDisp < '0') || (cDisp > '9')) break;
  cout << cDisp;
  } while (true);

// restore the former settings
tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
} // test05

int main()
{
test05();
return 0;
}
