#ifndef CWINSTREAM_H
#define CWINSTREAM_H


////////////////////////////////////////////////////////
//                                                    //
//  Classe CWinStream                                 //
//                                                    //
//  Cette classe a été créée pour en instancier un    //
//  seul objet, wout, donc le comportement devrait    //
//  être le même que le même que l'objet cout de la   //
//  classe iostream, mais dans une application        //
//  fenêtre.                                          //
//                                                    //
////////////////////////////////////////////////////////

class CWinStream : public std::ostrstream
{
 protected:
  void * Police[7];
  int Hauteur[7];
  int ScreenWidth, ScreenHeight;

 public:
  int LaPolice;
  int x, y;
  float Couleur[4];
  float Interligne;


  // Constructeur
  CWinStream()
    {
      x = 0; y = 0;

      Police[0] = GLUT_BITMAP_9_BY_15;
      Police[1] = GLUT_BITMAP_8_BY_13;
      Police[2] = GLUT_BITMAP_TIMES_ROMAN_10;
      Police[3] = GLUT_BITMAP_TIMES_ROMAN_24;
      Police[4] = GLUT_BITMAP_HELVETICA_10;
      Police[5] = GLUT_BITMAP_HELVETICA_12;
      Police[6] = GLUT_BITMAP_HELVETICA_18;

      Hauteur[0] = 15;
      Hauteur[1] = 13;
      Hauteur[2] = 10;
      Hauteur[3] = 24;
      Hauteur[4] = 10;
      Hauteur[5] = 12;
      Hauteur[6] = 18;

      ScreenWidth = 100;
      ScreenHeight = 100;

      Couleur[0] = 1;
      Couleur[1] = 1;
      Couleur[2] = 1;
      Couleur[3] = 1;

      LaPolice = 0;

      Interligne = 1.0f;
    }

  inline void SetPos(int xx, int yy)
    {
      x = xx; y = yy;
      glColor4fv(Couleur);
      glRasterPos2i(x, y);
    }
  inline void SetCouleur(float r, float g, float b, float a)
    { 
      Couleur[0] = r;
      Couleur[1] = g;
      Couleur[2] = b;
      Couleur[3] = a;
      glColor4fv(Couleur);
    }
  inline int Length(const unsigned char * Chaine) const
    {
      return glutBitmapLength(Police[LaPolice], Chaine);
    }



  // FONCTIONS SERVANT À INITIALER LES OPÉRATEURS
  inline void Begin(void)
    {
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      glLoadIdentity();
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
      glLoadIdentity();
      glOrtho(0, ScreenWidth, 0, ScreenHeight, -2, 2);
      glColor4fv(Couleur);
      glRasterPos2i(x, y);
    }
  inline void End(void)
    {
      flush();
      glMatrixMode(GL_PROJECTION);
      glPopMatrix();
      glMatrixMode(GL_MODELVIEW);
      glPopMatrix();
    }
  inline void SetToWindow(void)
    {
      ScreenWidth = glutGet(GLUT_WINDOW_WIDTH);
      ScreenHeight = glutGet(GLUT_WINDOW_HEIGHT);
    }

  // flush
  void flush(void);
};


// flush
inline void CWinStream::flush(void)
{
  put(0);
  std::string Chaine = str();

  for (int i = 0; i < pcount() - 1; i++)
    {
      if (Chaine[i] == '\n')
        SetPos(x, y - Interligne * Hauteur[LaPolice]);
      else
        glutBitmapCharacter(Police[LaPolice], Chaine[i]);
    }

  freeze(0);
  seekp(0);
}


extern CWinStream wout;



#endif // CWINSTREAM_H
