#ifndef CWINSTREAM_H
#define CWINSTREAM_H

#include <string>
#include <sstream>
#include <GL/glut.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::ostringstream
{
 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 (unsigned int i = 0; i < Chaine.size()/*pcount() - 1*/; i++)
    {
      if (Chaine[i] == '\n')
        SetPos(x, y - Interligne * Hauteur[LaPolice]);
      else
        glutBitmapCharacter(Police[LaPolice], Chaine[i]);
    }

  str("");
}


extern CWinStream wout;



#endif
