

#ifndef __O_CSPHERE_H
#define __O_CSPHERE_H

#include "Syst.hpp"

#include "CMaths.hpp"
#include "CLog.hpp"

extern CLog c_log;


// connu sous le nom de GL_T2F_N3F_V3F
// pour le vertex array
struct myVertex
{
  float tu, tv;         // texture U,V
  float nx, ny, nz;     // normal (position sur la sphere)
  float vx, vy, vz;     // vertex position !
};


#define PI     3.14159265358979f
#define TWOPI  6.28318530717958f
#define PIDIV2 1.57079632679489f


#define sinf(a) ((float)(m_sin((double)a)))
#define cosf(a) ((float)(m_cos((double)a)))
/*
void cgErrorCallback()
{
    CGerror err = cgGetError();
    if (err != CG_NO_ERROR) {
        c_log << "cgErrorCallback(): ";
        exit(1);
    }
}
*/

class CSphere
{
  float         rayon;

  myVertex     *g_VertArray;// Vertex Array
  unsigned int  g_nVerts;

  unsigned int  id_texture;
  unsigned int  id_nuages ;
  unsigned int  id_normalmap;

  float         r_nuages  ;

  // Cg Parametres

  CGcontext context;
  CGprofile profile;
  CGprogram program;


  // Fonction privée

  void setVertData( int index,
                    float tu, float tv,
                    float nx, float ny, float nz,
                    float vx, float vy, float vz );

public:
    
    CSphere() : g_nVerts(0), r_nuages(0), program(0) {};
   ~CSphere() {if (g_VertArray) delete [] g_VertArray;};

   // Interface publique pour la sphere crée
   void Init(unsigned int id_t,
             float cx, float cy, float cz,
             float r,
             int   n);

   void Clouds    (unsigned int id_texture, float dist);


   void Render    () const;   // Affichage avec VERTEX_ARRAY (glDrawElement)
   void RenderWire() const;   // Affichage en filaire
   void RenderLoop() const;   // Affichage en faisant une boucle de Gl_QUAD_STRIP

   void RenderAll () const;   // On affiche tout ...

   void RenderCg  () const;   // Rendu de la sphere avec bump grâce a Cg
                              // vertex shaders


   // fonctions d'affectations
   void SetNormalMap(unsigned int id)
   {
   	id_normalmap = id;
   }
   
   bool Init_Cg(const char *nom_prog)
   {
    //cgSetErrorCallback(cgErrorCallback);

    context = cgCreateContext();

    profile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
    cgGLSetOptimalOptions(profile);

    program = cgCreateProgramFromFile(
        context,
        CG_SOURCE,
        nom_prog,
        profile,
        "main",    // entry point
        NULL);   // arguments

    cgGLLoadProgram(program);

    
    CGerror err = cgGetError();
    if (err != CG_NO_ERROR) {
        c_log << "CSphere::Init_Cg -- 1";
        return false;
    }


    cgGLBindProgram(program);
    cgGLEnableProfile(profile);
    return true;
   }


};



#endif

