/***************************************************************************
                          gamedesigner.cpp  -  description
                             -------------------
    begin                : Mit Sep 25 13:11:41 CEST 2002
    copyright            : (C) 2002 by Harald Krippel
    email                : neuro.harald@surfeu.at
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>

#include <math.h>

// plib
#include <plib/ssg.h>
#include <plib/ssgAux.h>
#include <plib/ssgaSky.h>
#include <plib/js.h>
#include <puQT.h>

#include <qtimer.h>
#include <qcursor.h>
#include <qsound.h>
#include <qurl.h>

// open-al
#ifdef KCOPENAL

 #include "audioenv.h"
 #include "alsound.h"

#endif

// ODE
#include <ode/ode.h>

// shader
#include "shader.h"


#include "glcontrol.h"
#include "main.h"
#include "qcake.h"
#include "phthread.h"

#include "spl_prg.h"

#include "mycatalogdlg.h"
#include "guitext.h"
#include "guibutton.h"
#include "guiosbutton.h"
#include "guiinput.h"
#include "netclient.h"
#include "tribarrier.h"
#include "terrain.h"
#include "copydir.h"
#include "loadMD2.h"
#include "usercamera.h"
#include "cursor3d.h"

#ifndef GL_VERSION_1_3
// ARB_multitexture
#define GL_TEXTURE0      GL_TEXTURE0_ARB
#define GL_TEXTURE1      GL_TEXTURE1_ARB
#define glActiveTexture  glActiveTextureARB
#endif

// Shader
  int gl_shader_num;
  shader *gl_shader_obj[MAX_SHADER];

// Global Sky move it to a new Sky Class
  #define MAX_BODIES  2
  #define MAX_CLOUDS  3

  int        nplanets       = 0 ;
  sgdVec3    *planet_data   = NULL ;
  int        nstars         = 1000 ;
  sgdVec3    *star_data     = NULL ;
  ssgaCelestialBody  *bodies[MAX_BODIES] = {NULL} ;
//  ssgaCloudLayer     *clouds[MAX_CLOUDS] = {NULL} ;

  static const double m_log01 = -log( 0.01 );
  static const double sqrt_m_log01 = sqrt( m_log01 );

  static sgVec4 myblack             = { 0.0, 0.0, 0.0, 1.0 } ;
  static sgVec4 mywhite             = { 1.0, 1.0, 1.0, 1.0 } ;
//static sgVec4 translucent_white = { 1.0, 1.0, 1.0, 0.8 } ;

static sgVec4 base_sky_color    = { 0.39, 0.5, 0.74, 1.0 } ;
static sgVec4 base_fog_color    = { 0.84, 0.87, 1.0, 1.0 } ;

static sgVec4 base_ambient      = { 0.2, 0.2, 0.2, 1.0 } ;
static sgVec4 base_diffuse      = { 1.0, 1.0, 1.0, 1.0 } ;
static sgVec4 base_specular     = { 1.0, 1.0, 1.0, 1.0 } ;

static sgVec4 sky_color ;
static sgVec4 fog_color ;
static sgVec4 cloud_color ;

static sgVec4 scene_ambient ;
static sgVec4 scene_diffuse ;
static sgVec4 scene_specular ;

double sun_angle = 0;

//*********PUI********************************
  
#define VIEW_GUI_BASE 20
#define FONT_COLOUR   1,1,1,1

 static puText      *timeText           = (puText      *) NULL ;
 static puText      *phText             = (puText      *) NULL ;

//*****************************************

// #define  CONTINUOUS_DISPLAY_SURFACE 1

    /* ode */
static    dWorldID odworld;
static    dSpaceID odspace;
static    dJointGroupID odcontactgroup;
static    dGeomID odground;

// this is called by dSpaceCollide when two objects in space are
// potentially colliding.



static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  int i,n;
  int a; // g1, g2;


  // only collide things with the ground
    for(a=0;a<MAX_LIST_ITEMS;a++)
    {
      if(g_ListItem[a] != NULL)
      {
        if(g_ListItem[a]->text(1) == "BODY")
        {
          if(g_ListItem[a]->body !=NULL)
          {
            if(g_ListItem[a]->body->odgeom[0] !=NULL)
            {
              if(o1 == g_ListItem[a]->body->odgeom[0] || o2 == g_ListItem[a]->body->odgeom[0] )
              {
                if( o1 == odground || o2 == odground )
                {
                  g_ListItem[a]->groundcollision=1;
                }
                else
                {
                  g_ListItem[a]->collision=1;
                }
              }
            }
          }
        }
      }
    }

  const int N = 10;
  dContact contact[N];
  n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
  if (n > 0)
  {
    for (i=0; i<n; i++)
    {
      contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
	    dContactSoftERP | dContactSoftCFM | dContactApprox1;
      contact[i].surface.mu = dInfinity;
      contact[i].surface.slip1 = 0.1;     // 0.1
      contact[i].surface.slip2 = 0.1;     // 0.1
      contact[i].surface.soft_erp = 0.7;  // 0.5
      contact[i].surface.soft_cfm = 0.1;  // 0.3
      dJointID c = dJointCreateContact (odworld,odcontactgroup,&contact[i]);
      dJointAttach (c,
		  dGeomGetBody(contact[i].geom.g1),
		  dGeomGetBody(contact[i].geom.g2));
    }
  }
}

// Wavesys Callbacks

int Glcontrol::enableTexGen ( ssgEntity * )
{


#ifdef GL_ARB_multitexture
  GLint tx ;
  glGetIntegerv ( GL_TEXTURE_BINDING_2D, &tx ) ;
  glActiveTexture ( GL_TEXTURE1 ) ;
#endif
  glTexGeni ( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ) ;
  glTexGeni ( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ) ;
  glEnable ( GL_TEXTURE_GEN_S ) ;
  glEnable ( GL_TEXTURE_GEN_T ) ;
#ifdef GL_ARB_multitexture
  glEnable ( GL_TEXTURE_2D ) ;  /* Enables the second texture map. */
  glBindTexture ( GL_TEXTURE_2D, tx ) ;
  glActiveTexture ( GL_TEXTURE0 ) ;
#endif
  // Shader @@@ testcode !!!!!!!!!!!!!!!!
  // turn Shader ON
  if(gl_shader_obj[0] != NULL)
  {
//    gl_shader_obj[0]->TurnOn();
  }
  return TRUE ;
}

int Glcontrol::disableTexGen ( ssgEntity * )
{
#ifdef GL_ARB_multitexture
  glActiveTexture ( GL_TEXTURE1 ) ;
#endif
  glDisable ( GL_TEXTURE_GEN_S ) ;
  glDisable ( GL_TEXTURE_GEN_T ) ;
#ifdef GL_ARB_multitexture
  glDisable ( GL_TEXTURE_2D ) ; /* Disables the second texture map */
  glActiveTexture ( GL_TEXTURE0 ) ;
#endif
  // Shader @@@ testcode !!!!!!!!!!!!!!!!
  // turn Shader ON
  if(gl_shader_obj[0] != NULL)
  {
//    gl_shader_obj[0]->TurnOff();
  }
  return TRUE ;
}

// 3D-Object Callbacks  uuugggssssss @@@ H.K.
// Shader @@@ testcode !!!!!!!!!!!!!!!!
int Glcontrol::objprecall  ( ssgEntity * )
{
  // turn Shader ON
  if(gl_shader_obj[0] != NULL)
  {
//    gl_shader_obj[0]->TurnOn();
  }
  return TRUE ;
}
int Glcontrol::objpostcall ( ssgEntity * )
{
  // turn Shader ON
  if(gl_shader_obj[0] != NULL)
  {
//    gl_shader_obj[0]->TurnOff();
  }
  return TRUE ;
}

Glcontrol::Glcontrol(QWidget *parent, const char *name)
  : QGLWidget(parent, name)
{
  scene=NULL;
  initVariables();
  makeCurrent();
    
  focusitem=NULL;
  mouse_mode=0;
  gllook=0;
  keylook=1;
  xRot=0;
  yRot=0;
  zRot=0;

  xTrans=0, yTrans=0, zTrans=0;
  scale=10;

  cxTrans=0;
  cyTrans=0;
  czTrans=0;
  cxRot=0;
  cyRot=0;
  czRot=0;
  
    setCursor( pointingHandCursor  );

    // graphic timer
    gtimer = new QTimer( this );
    connect( gtimer, SIGNAL(timeout()), this, SLOT(gtimerDone()) );
    gtimer->start(TIMER_INTERVAL);

    // Physik & SPL thread
    phthread = new phThread();
    phthread->gl = this;
    phthread->go = 1;
    phthread->start();

    // Shader @@ testcode !!!
//    gl_shader[0] = new shader();

}

void    Glcontrol::gtimerDone()
{
    int a;
    
    my_context->makeCurrent();
      
    updateGL();

    if(g_playmode)
    {
      // SPL get3DMouse Update
      QPoint mpoint = mapFromGlobal(QCursor::pos());
      my_context->setPOI(mpoint.x(), mpoint.y());
      my_context->getPOI(&g_poi);
      g_mouse_x = mpoint.x();
      g_mouse_y = mpoint.y();

      // SPL Cursor Update
      for(a=0;a<MAX_CURSOR;a++)
      {
        if(gl_cursor_obj[a] != NULL)
        {
          gl_cursor_obj[a] -> update () ;
        }
      }
    }

    // spl switch scene
    if( g_switch==1 && g_switchScene != NULL)
    {
         g_switch = 0;
         switchScene(g_switchScene);
         g_switchScene = NULL;
    }
}

void Glcontrol::initVariables()
{
  int a;
  
  globj=NULL;
  g_usercam = NULL;

  // fire
  for(a=0;a<MAX_FIRE;a++)
  {
    gl_fire_obj[a]=NULL;
  }
  gl_fire_num=0;

  // partsys
  for(a=0;a<MAX_PARTSYS;a++)
  {
    gl_partsys_obj[a]=NULL;
  }
  gl_partsys_num=0;

  // wavesys
  for(a=0;a<MAX_WAVESYS;a++)
  {
    gl_wavesys_obj[a]=NULL;
  }
  gl_wavesys_num=0;

  gl_fog=0;

  // player
  for(a=0;a<MAX_PLAYER;a++)
  {
    gl_player[a]=NULL;
  }
  gl_player_num=0;
  
  // barrier
  for(a=0;a<MAX_BARRIER;a++)
  {
    gl_barrier[a]=NULL;
  }
  gl_barrier_num=0;

  // body
  for(a=0;a<MAX_BODY;a++)
  {
    gl_body[a]=NULL;
  }
  gl_body_num=0;

  // sky
  for(a=0;a<MAX_SKY;a++)
  {
    gl_sky_obj[a]=NULL;
  }
  gl_sky_num=0;

  // spl
  for(a=0;a<MAX_SPL;a++)
  {
    gl_spl_obj[a]=NULL;
  }
  gl_spl_num=0;

  // shader
  for(a=0;a<MAX_SHADER;a++)
  {
    gl_shader_obj[a]=NULL;
  }
  gl_shader_num=0;

  // cursor
  for(a=0;a<MAX_CURSOR;a++)
  {
    gl_cursor_obj[a]=NULL;
  }
  gl_cursor_num=0;

}

void Glcontrol::phDelete()
{
//    int a;

    dWorldDestroy (odworld);
   // ODE create world
   odworld = dWorldCreate();
   odspace = dHashSpaceCreate(0);
   odcontactgroup = dJointGroupCreate(0);
   dWorldSetGravity(odworld,0,0,-1.0);       // 0,0,-9.81 !!!

  // Test ODE
//   odground = dCreatePlane(odspace,0,0,1,0);
   odground = NULL;
}


void Glcontrol::DeleteScene()
{
  int a;

  if ( scene )
  {
    puDelete ();
    phDelete ();
    ssgDelete ( scene ) ;
    scene = NULL;
    initVariables();
    for(a=0;a<MAX_LIST_ITEMS;a++)
    {
      if(g_ListItem[a] != NULL)
      {

          if(g_ListItem[a]->text(1) == "OBJECT")
          {
            g_ListItem[a]->objtrans = NULL;
            if(g_ListItem[a]->tribarrier != NULL)
            {
              g_ListItem[a]->tribarrier->~TriBarrier();
              g_ListItem[a]->tribarrier = NULL;
            }
          }
          if(g_ListItem[a]->text(1) == "SHADER")
          {
            if(g_ListItem[a]->gshader != NULL)
            {
              g_ListItem[a]->gshader->~shader();
            }
          }
//          g_ListItem[a] = NULL;
      }
    }

    scene = new ssgRoot ;
    globj=NULL;
    splaInit ();
  }
}

void Glcontrol::puDelete()
{
  int a;

    for(a=0;a<MAX_LIST_ITEMS;a++)
    {
      if(g_ListItem[a] != NULL)
      {
        if(g_ListItem[a]->text(1) == "GUI-TXT")
        {
          if(g_ListItem[a]->guitext != NULL)
          {
            puDeleteObject(g_ListItem[a]->guitext);
            g_ListItem[a]->guitext = NULL;
          }        
        }
        if(g_ListItem[a]->text(1) == "GUI-INPUT")
        {
          if(g_ListItem[a]->guiinput != NULL)
          {
            puDeleteObject(g_ListItem[a]->guiinput);
            g_ListItem[a]->guiinput = NULL;
          }
        }
        if(g_ListItem[a]->text(1) == "GUI-BUTTON")
        {
          if(g_ListItem[a]->guibutton != NULL)
          {
            puDeleteObject(g_ListItem[a]->guibutton);
            g_ListItem[a]->guibutton = NULL;
          }
        }
        if(g_ListItem[a]->text(1) == "GUI-OSBUTTON")
        {
          if(g_ListItem[a]->guiosbutton != NULL)
          {
            puDeleteObject(g_ListItem[a]->guiosbutton);
            g_ListItem[a]->guiosbutton = NULL;
          }
        }
      }
    }
}

void Glcontrol::puRedraw()
{
  int a;

    for(a=0;a<MAX_LIST_ITEMS;a++)
    {
      if(g_ListItem[a] != NULL)
      {
        if(g_ListItem[a]->text(1) == "GUI-TXT")
        {
          if(g_ListItem[a]->guitext != NULL)
          {
              setFocusGUIText(g_ListItem[a]);
          }
        }
        if(g_ListItem[a]->text(1) == "GUI-INPUT")
        {
          if(g_ListItem[a]->guiinput != NULL)
          {
              setFocusGUIInput(g_ListItem[a]);
          }
        }
        if(g_ListItem[a]->text(1) == "GUI-BUTTON")
        {
          if(g_ListItem[a]->guibutton != NULL)
          {
              setFocusGUIButton(g_ListItem[a]);
          }
        }
        if(g_ListItem[a]->text(1) == "GUI-OSBUTTON")
        {
          if(g_ListItem[a]->guiosbutton != NULL)
          {
              setFocusGUIOSButton(g_ListItem[a]);
          }
        }
      }
    }
}

Glcontrol::~Glcontrol()
{
    makeCurrent();
    phthread->go = 0;
    phthread->wait();
    dCloseODE();             // dellocate some extra memory used by ODE -> at the end of application
}

void Glcontrol::load_database ()
{
  xScale=1.0f;
  yScale=1.0f;
  zScale=1.0f;

  /*
    Set up the path to the data files
  */

  ssgModelPath   ( "data" ) ;
  ssgTexturePath ( "data" ) ;

  /*
    Create a root node - and a transform to position
    the pedestal - and another to position the penguin
    beneath that (in the tree that is).
  */

  scene    = new ssgRoot()      ;

  // ODE create world
  odworld = dWorldCreate();
  odspace = dHashSpaceCreate(0);
  odcontactgroup = dJointGroupCreate(0);
  dWorldSetGravity(odworld,0,0,-1.0);       // 0,0,-9.81 !!!

  // Test ODE
  odground = dCreatePlane(odspace,0,0,1,0);
}


void Glcontrol::init_gui ()
{

/*    
  static puFont     *sorority ;
  static fntTexFont *fnt      ;

  fnt      = new fntTexFont () ;
//  fnt     -> load ( "Courier.txf" ) ;
  fnt     -> load ( "Times-Roman.txf" ) ;
//  fnt     -> load ( "Helvetica.txf" ) ;
  sorority = new puFont ( fnt, 14 ) ;

  puSetDefaultFonts        ( *sorority, *sorority ) ;
  puSetDefaultStyle        ( PUSTYLE_SHADED ) ;
  puSetDefaultColourScheme ( 0.2f, 0.5f, 0.2f, 0.5f ) ;

*/
  timeText = new puText ( 40, 40 ) ;
  timeText->setColour( PUCOL_LABEL, FONT_COLOUR ) ;
  phText = new puText ( 40, 20 ) ;
  phText->setColour( PUCOL_LABEL, FONT_COLOUR ) ;

}

void Glcontrol::init_graphics ()
{
  /*
    Initialise SSG
  */
  puInitQT ();
  ssgInit () ;
  jsInit () ;
  
  my_context = new Camera; 
  my_context->makeCurrent();
  
  /*
    Some basic OpenGL setup
  */

  glClearColor ( 0.2f, 0.7f, 1.0f, 1.0f ) ;
  glColor4f(1.0f,1.0f,1.0f,0.5f);
  glEnable ( GL_DEPTH_TEST ) ;

  glEnable(GL_TEXTURE_2D);
  glEnable(GL_BLEND);
  glEnable(GL_ALPHA_TEST);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

//  glDisable(GL_DEPTH_TEST);        // Turn Depth Testing Off
}

void Glcontrol::updatePH ()
{

  static ulClock ck ;
  static float waitoffs = 20;
  int a;
  float wait;
  static int state=0;

  state++;

  ck . update () ;

//  double t = ck . getAbsTime   () ;

  float dt = ck . getDeltaTime () ;
  
  wait = (waitoffs - dt);
  if(wait > 0)
  {
    ulMilliSecondSleep ( (long)wait ) ;
  }
  
  if(state > 1/dt)
  {
    g_phfps = 1/dt;

    if( g_phfps > 52)
    {
        waitoffs += 0.5 ;
    }
    if( g_phfps < 48)
    {
        waitoffs -= 0.5 ;
    }
    state=0;
  }

  if(g_playmode)
  {
    for(a=0;a<MAX_SPL;a++)
    {
      if(gl_spl_obj[a] != NULL)
      {
        ph_mutex.lock();
        gl_spl_obj[a] -> update () ;
        ph_mutex.unlock();
      }
    }
    ph_mutex.lock();
    dSpaceCollide (odspace,0,&nearCallback);
//    dWorldStep (odworld,dt);
    dWorldStepFast1 (odworld,dt,3); 
    // remove all contact joints
    dJointGroupEmpty(odcontactgroup);
    ph_mutex.unlock();
  }
  
  // Network
  if(g_client != NULL)
  {
     g_client->update();
  }
  // js
  if ( !g_js[0] -> notWorking ())
  {
    g_js[0] -> read ( &g_buttons[0], g_ax[0] ) ;
  }
  if ( !g_js[1] -> notWorking () )
  {
    g_js[1] -> read ( &g_buttons[1], g_ax[1] ) ;
  }  
}

void Glcontrol::update_motion ()
{
  
  sgCoord campos ;
  sgCoord gobjpos ;

  int a=0;
  static int state=0;
  static int frameno = 0 ;
  static ulClock ck ;
  static char buff1[256];
  static char buff2[256];

  frameno++ ;
  state++;

  ck . update () ;

  double t = ck . getAbsTime   () ;

  float dt = ck . getDeltaTime () ;

  if(state > 1/dt)
  {
    g_fps = (1/dt);
    sprintf(buff1," FPS:%.0f",g_fps);
    timeText->setLabel ( buff1 ) ;
    
    sprintf(buff2,"PHPS:%.0f",g_phfps);
    phText->setLabel ( buff2 ) ;

    state=0;
  }
  for(a=0;a<MAX_FIRE;a++)
  {
    if(gl_fire_obj[a] != NULL)
    {
      gl_fire_obj[a] -> update ( dt ) ;
    }
  }

  for(a=0;a<MAX_PARTSYS;a++)
  {
    if(gl_partsys_obj[a] != NULL)
    {
      gl_partsys_obj[a] -> update ( dt ) ;
    }
  }

  for(a=0;a<MAX_WAVESYS;a++)
  {
    if(gl_wavesys_obj[a] != NULL)
    {
      gl_wavesys_obj[a] -> setWindDirn ( 25.0 * sin ( t / 100.0 ) ) ;
      gl_wavesys_obj[a] -> updateAnimation ( t ) ;

    }
  }

#ifdef  KCOPENAL

      sgMat4  cammat;

      my_context->getModelviewMatrix ( cammat );
      Audio->ListenerPosition(cammat);
#endif

  if(g_playmode)
  {
    ph_mutex.lock();
    splaRedraw ();
    ph_mutex.unlock();

    for(a=0;a<MAX_PLAYER;a++)
    {
      if(gl_player[a] != NULL)
      {
        gl_player[a] -> maus (mgox,mgoy) ;
        ph_mutex.lock();
        gl_player[a] -> update (scene, dt ) ;
        ph_mutex.unlock();
        my_context -> setCamera( gl_player[a] -> cmat);
      }
    }
    
    for(a=0;a<MAX_BARRIER;a++)
    {
      if(gl_barrier[a] != NULL)
      {
        ph_mutex.lock();
        gl_barrier[a] -> update (scene, dt ) ;
        ph_mutex.unlock();
      }
    }

    for(a=0;a<MAX_BODY;a++)
    {
      if(gl_body[a] != NULL)
      {
        ph_mutex.lock();
        gl_body[a] -> update (scene, dt ) ;
        ph_mutex.unlock();
      }
    }

    if(g_usercam != NULL)
    {
      g_usercam->update();
      my_context -> setCamera( g_usercam -> cmat);
    }

  }

  
   if(!g_playmode)
   {
  /*
    Set the Camera Key Num Block
  */
    if(keylook)
    {
      switch(gllook)
      {
          case 0:     // Key NumBlock 2
            sgSetCoord ( & campos, 0.0f, -5.0f*scale, 3.0f, 0.0f, -1.0f, 0.0f ) ;
            break;
          case 1:     // Key NumBlock 4
            sgSetCoord ( & campos, -5.0f*scale, 0.0f , 3.0f, -90.0f, -1.0f, 0.0f ) ;
            break;
          case 2:     // Key NumBlock 8
            sgSetCoord ( & campos, 0.0f, 5.0f*scale, 3.0f, 180.0f, -1.0f, 0.0f ) ;
            break;
          case 3:     // Key NumBlock 6
            sgSetCoord ( & campos, 5.0f*scale, 0.0f , 3.0f, 90.0f, -1.0f, 0.0f ) ;
            break;
          case 4:     // Key NumBlock 5
            sgSetCoord ( & campos, 0.0f , 0.0f, 5.0f*scale, 0.0f, -90.0f, 0.0f ) ;
            break;
          case 10:     // Key NumBlock 0
            if(globj == NULL)
            {
                cxTrans=xTrans;
                cyTrans=yTrans;
                czTrans=zTrans;
                cxRot=xRot;
                cyRot=yRot;
                czRot=zRot;
            }
            sgSetCoord ( & campos, cxTrans,  cyTrans, czTrans, cxRot, cyRot, czRot ) ;
            break;
      }
      my_context -> setCamera ( & campos );
      keylook=0;
    }

    /* update Object */

    if(globj != NULL)
    {
      // Translate, Rotate , Scale
      sgSetCoord ( & gobjpos, xTrans,  yTrans, zTrans, xRot, yRot, zRot ) ;
      globj -> setTransform ( & gobjpos,xScale,yScale,zScale) ;
    }

  }

  // Fog
  glFogf ( GL_FOG_DENSITY, fogdensity );

  glFogfv( GL_FOG_COLOR  , skyfogcol ) ;
  glFogf ( GL_FOG_START  , fogstart ) ;
  glFogf ( GL_FOG_END  , fogend  ) ;
  
   switch(fogmode)      // linear , exp , exp2
   {
      case 0:     
        glFogi ( GL_FOG_MODE   , GL_LINEAR   ) ;
        break;
      case 1:
        glFogi ( GL_FOG_MODE   , GL_EXP   ) ;
        break;
      case 2:
        glFogi ( GL_FOG_MODE   , GL_EXP2   ) ;
        break;
   }      

   switch(foghint)      // nicest
   {
      case 0:
        glHint ( GL_FOG_HINT   , GL_DONT_CARE ) ;
        break;
      case 1:
        glHint ( GL_FOG_HINT   , GL_FASTEST ) ;
        break;
      case 2:
        glHint ( GL_FOG_HINT   , GL_NICEST ) ;
        break;
   }
   
   if( gl_sky_obj[0] != NULL)
   {
      my_context->getCameraPosition ( campos.xyz );
      gl_sky_obj[0] -> repositionFlat ( campos.xyz, 0, dt );
      gl_sky_obj[0] -> modifyVisibility ( campos.xyz[SG_Z], dt );

      double sun_angle = bodies[0]->getAngle();
      double sky_brightness = (1.0 + cos(sun_angle))/2.0; // 0.0 - 1.0
      double scene_brightness = pow(sky_brightness,0.5);
        /* set sky color */
      sky_color[0] = base_sky_color[0] * sky_brightness;
      sky_color[1] = base_sky_color[1] * sky_brightness;
      sky_color[2] = base_sky_color[2] * sky_brightness;
      sky_color[3] = base_sky_color[3];

        /* set cloud and fog color */
      cloud_color[0] = fog_color[0] = base_fog_color[0] * sky_brightness;
      cloud_color[1] = fog_color[1] = base_fog_color[1] * sky_brightness;
      cloud_color[2] = fog_color[2] = base_fog_color[2] * sky_brightness;
      cloud_color[3] = fog_color[3] = base_fog_color[3];

        /* repaint the sky */
      gl_sky_obj[0] -> repaint ( sky_color, fog_color, cloud_color, sun_angle, nplanets, planet_data, nstars, star_data );

        /* set light source */
      sgCoord sunpos;
      bodies[0] -> getPosition ( & sunpos );
      ssgGetLight ( 0 ) -> setPosition ( sunpos.xyz ) ;

      scene_ambient[0] = base_ambient[0] * scene_brightness;
      scene_ambient[1] = base_ambient[1] * scene_brightness;
      scene_ambient[2] = base_ambient[2] * scene_brightness;
      scene_ambient[3] = 1.0;

      scene_diffuse[0] = base_diffuse[0] * scene_brightness;
      scene_diffuse[1] = base_diffuse[1] * scene_brightness;
      scene_diffuse[2] = base_diffuse[2] * scene_brightness;
      scene_diffuse[3] = 1.0;

      scene_specular[0] = base_specular[0] * scene_brightness;
      scene_specular[1] = base_specular[1] * scene_brightness;
      scene_specular[2] = base_specular[2] * scene_brightness;
      scene_specular[3] = 1.0;
      // GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
      // we only update GL_AMBIENT for our lights we will never get
      // a completely dark scene.  So, we set GL_LIGHT_MODEL_AMBIENT
      // explicitely to black.
      glLightModelfv( GL_LIGHT_MODEL_AMBIENT, myblack );
      ssgGetLight( 0 ) -> setColour( GL_AMBIENT, scene_ambient );
      ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, scene_diffuse );
      ssgGetLight( 0 ) -> setColour( GL_SPECULAR, scene_specular );
   }
}

/*!
  Paint the box. The actual openGL commands for drawing the box are
  performed here.
*/

void Glcontrol::paintGL()
{
  sgCoord campos ;

  my_context->makeCurrent();

  glClear  ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
  glDisable ( GL_FOG ) ;
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable ( GL_BLEND ) ;

  update_motion () ;

  if(gl_fog)
  { 
    glEnable ( GL_FOG ) ;
  }
  if(gl_sky_obj[0] != NULL)
  {
    // Sky Fog
    /* Adjust fog based on visibility (when in clouds) */
    glClearColor ( fog_color[0], fog_color[1], fog_color[2], fog_color[3] ) ;
    glClear  ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
    GLfloat fog_exp2_density = sqrt_m_log01 / gl_sky_obj[0]->getVisibility();
    glEnable( GL_FOG );
    glFogf  ( GL_FOG_DENSITY, fog_exp2_density);
    glFogi  ( GL_FOG_MODE,    GL_EXP2 );
    glFogfv ( GL_FOG_COLOR,   fog_color );
  
    // we need a white diffuse light for the phase of the moon
    ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, mywhite );
    gl_sky_obj[0] -> preDraw  ( );
    // return to the desired diffuse color
    ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, scene_diffuse );
    
  }
  
  ssgCullAndDraw ( scene ) ;
  if(gl_sky_obj[0] != NULL)
  {
    my_context->getCameraPosition ( campos.xyz );
    gl_sky_obj[0] -> postDraw ( campos.xyz[SG_Z] ); /* altitude */
    glDisable ( GL_FOG ) ;
  }
  if(gl_fog)
  {
    glDisable ( GL_FOG ) ;
  }
  puDisplay () ;
}

/*!
  Set up the OpenGL rendering state, and define display list
*/

void Glcontrol::initializeGL()
{
  makeCurrent();   // test
  init_graphics () ;
  load_database () ;
  init_gui();
}



/*!
  Set up the OpenGL view port, matrix mode, etc.
*/

void Glcontrol::resizeGL( int w, int h )
{
  my_context->setAspect((SGfloat)w/(SGfloat)h);
  glViewport ( 0, 0, w, h ) ;
  g_window_w=w;
  g_window_h=h;
  puRedraw();
}


void Glcontrol::transform()
{

}

/*!
  Set the rotation angle of the object to \e degrees around the X axis.
*/
void Glcontrol::setXRotation( double degrees )
{
    xRot = (GLfloat)fmod(degrees, 360.0);
}

/*!
  Set the rotation angle of the object to \e degrees around the Y axis.
*/
void Glcontrol::setYRotation( double degrees )
{
    yRot = (GLfloat)fmod(degrees, 360.0);
}


/*!
  Set the rotation angle of the object to \e degrees around the Z axis.
*/
void Glcontrol::setZRotation( double degrees )
{
    zRot = (GLfloat)fmod(degrees, 360.0);
}

void Glcontrol::setScale( double s )
{
    scale = s;
}

void Glcontrol::setXTrans( double x )
{
    xTrans = x;
}

void Glcontrol::setYTrans( double y )
{
    yTrans = y;
}

void Glcontrol::setZTrans( double z )
{
    zTrans = z;
}

void Glcontrol::setXScale( double x )
{
    xScale = x;
}

void Glcontrol::setYScale( double y )
{
    yScale = y;
}

void Glcontrol::setZScale( double z )
{
    zScale = z;
}

void Glcontrol::setRotationImpulse( double x, double y, double z )
{
    setXRotation( xRot + 180*x );
    setYRotation( yRot + 180*y );
    setZRotation( zRot - 180*z );
}

void Glcontrol::setTranslationImpulse( double x, double y, double z )
{
    setXTrans( xTrans + 2*x );
    setYTrans( yTrans + 2*y );
    setZTrans( zTrans + 2*z );
}

void Glcontrol::setScaleImpulse( double x, double y, double z )
{
    setXScale( xScale + 2*x );
    setYScale( yScale + 2*y );
    setZScale( zScale + 2*z );
}

void Glcontrol::mousePressEvent( QMouseEvent *e )
{
    e->accept();
    oldPos = e->pos();
    makeCurrent();
    my_context->setPOI(e->pos().x(), e->pos().y());
   if(g_playmode)
   {
      /* PUI */
    
    if (e->button() & QMouseEvent::LeftButton)
    {
      puMouse ( PU_LEFT_BUTTON, PU_DOWN, e->x(), e->y() ) ;
    }
    
    // SPL Mouse Buttons
    if(e->button() & QMouseEvent::LeftButton)
    {
       g_mouse_button |= 0x01;
    }
    if (e->button() & QMouseEvent::MidButton)
    {
       g_mouse_button |= 0x02;
    }
    if (e->button() & QMouseEvent::RightButton)
    {
       g_mouse_button |= 0x04;
    }
   }

}

void Glcontrol::mouseReleaseEvent( QMouseEvent *e )
{
    char mybuff[256];

      mgox = 0;
      mgoy = 0;

   if(g_playmode)
   {
    /* PUI */
     if (LeftButton&e->state())
     {
        puMouse ( PU_LEFT_BUTTON, PU_UP, e->x(), e->y() ) ;
     }
    
     // SPL Mouse Buttons
    if (LeftButton & e->state())
    {
       g_mouse_button &= ~0x01;
    }
    if (MidButton & e->state())
    {
       g_mouse_button &= ~0x02;
    }
    if (RightButton & e->state())
    {
       g_mouse_button &= ~0x04;
    }
    
   }
      
    e->accept();
    oldPos = e->pos();
    // update tree
    if(focusitem && globj && ( !g_playmode ) )
    {
      sprintf(mybuff,"%f",xTrans);
      focusitem->SetValue( "x" , mybuff);
      sprintf(mybuff,"%f",yTrans);
      focusitem->SetValue( "y" , mybuff);
      sprintf(mybuff,"%f",zTrans);
      focusitem->SetValue( "z" , mybuff);

      sprintf(mybuff,"%f",xRot);
      focusitem->SetValue( "rotx" , mybuff);
      sprintf(mybuff,"%f",yRot);
      focusitem->SetValue( "roty" , mybuff);
      sprintf(mybuff,"%f",zRot);
      focusitem->SetValue( "rotz" , mybuff);

      sprintf(mybuff,"%f",xScale);
      focusitem->SetValue( "scax" , mybuff);
      sprintf(mybuff,"%f",yScale);
      focusitem->SetValue( "scay" , mybuff);
      sprintf(mybuff,"%f",zScale);
      focusitem->SetValue( "scaz" , mybuff);
      focusitem->updateDialog();
    }
}

void Glcontrol::mouseMoveEvent( QMouseEvent *e )
{
    
    e->accept();
    mouse_mode = g_mouse_mode;       // wrg !!
      
   if(!g_playmode)
   {
   if(g_mouse_mode == 3)
   {  
    if (LeftButton&e->state()){
      QPoint point = e->pos()-oldPos;
      if (point != QPoint(0,0)) {
//        my_context->tilt((point.x()>0)?1.0:-1.0,Camera::Yaxis);
//        my_context->tilt((point.y()>0)?1.0:-1.0,Camera::Xaxis);
//        my_context->tilt(point.y(),Camera::Xaxis);
        my_context->tilt(point.x(),Camera::Yaxis);
        my_context->tilt(point.y(),Camera::Xaxis);
        updateGL();
        QCursor::setPos(mapToGlobal(oldPos));
      }
    }
    else if (RightButton&e->state()){
      my_context->pan(e->pos().x(), e->pos().y());
      updateGL();
    }
    else if (MidButton&e->state()){
      QPoint point = e->pos()-oldPos;
      if (point != QPoint(0,0)) {
//        my_context->walk((point.y()>0)?1.0:-1.0);
        my_context->walk(point.y());
        updateGL();
        QCursor::setPos(mapToGlobal(oldPos));
        }
    }
    }
    else
    {
    double dx = e->x() - oldPos.x();
    double dy = e->y() - oldPos.y();

    oldPos = e->pos();

    double rx = dx / width();
    double ry = dy / height();

    if ( e->state() == LeftButton )
    {
	if(mouse_mode==0)
  {
   if(gllook==0)
    {
	    setTranslationImpulse( rx*scale, ry*scale * -1, 0 );
    }
  	if(gllook==1)
    {
	    setTranslationImpulse( ry*scale * -1, rx*scale * -1, 0 );
    }
  	if(gllook==2)
    {
	    setTranslationImpulse( rx*scale * -1, ry*scale, 0  );
    }
  	if(gllook==3)
    {
	    setTranslationImpulse( ry*scale, rx*scale, 0 );
    }
  	if(gllook==4)
    {
	    setTranslationImpulse( rx*scale, ry*scale * -1, 0 );
    }
  	if(gllook==10)
    {
	    setTranslationImpulse( rx*scale, ry*scale * -1, 0 );
    }
  }
  if(mouse_mode==1)
	 setRotationImpulse( rx, ry, 0 );
	if(mouse_mode==2)
	 setScaleImpulse( rx*scale/2, rx*scale/2, rx*scale/2 );
    }
    else if ( e->state() == RightButton )
    {
	if(mouse_mode==0)
	 setTranslationImpulse( 0, 0, ry*scale * -1 );
	if(mouse_mode==1)
	 setRotationImpulse( rx, 0, ry );
	if(mouse_mode==2)
	 setScaleImpulse( 0 , rx*scale/2, 0 );
    }
    else if ( e->state() == MidButton )
    {
	if(mouse_mode==0)
	 setTranslationImpulse( rx*scale, ry*scale * -1, 0 );
	if(mouse_mode==1)
	 setRotationImpulse( rx, 0, ry );
	if(mouse_mode==2)
	 setScaleImpulse( 0 , 0, rx*scale/2 );
    }
    else if ( e->state() == ( LeftButton | RightButton ) )
    {
	    setScaleImpulse( rx*scale/2, 0 , 0);
    }

    mgox=0;
    mgoy=0;

    }     

  } // !g_playmode
  else
  {
      puMouse ( e->x(), e->y() ) ;
      mgox = ((float)e->x()-((float)width()/2)) / ((float)width()/2);
      mgoy = ((float)e->y()-((float)height()/2)) / ((float)height()/2);      
  }
}

void Glcontrol::wheelEvent( QWheelEvent *e )
{
    e->accept();

        my_context->walk((e->delta()>0)?(1.0):(-1.0));
        updateGL();
}
/*
void Glcontrol::mouseDoubleClickEvent( QMouseEvent * )
{
    if ( delay <= 0 )
	return;

}
*/
void Glcontrol::keyPressEvent(QKeyEvent *e)
{
   int a;
   
   qWarning("Key: %c ",e->ascii());
   e->accept();


     
   switch(e->key())
   {
      case Key_P:
          if(g_playmode)
          {
            for(a=0;a<MAX_SOUND;a++)
            {

            }
            // start sound
          }
          else
          {

          }
        break;
   }
    
   if(!g_playmode)
   {
    switch(e->key())
    {
      //edit mode
      case Key_0:
          gllook=10;
            xTrans=cxTrans;
            yTrans=cyTrans;
            zTrans=czTrans;
            xRot=cxRot;
            yRot=cyRot;
            zRot=czRot;
          globj=NULL;
          keylook=1;
        break;
      case Key_2:
          gllook=0;
          keylook=1;
        break;
      case Key_4:
          gllook=1;
          keylook=1;
        break;
      case Key_8:
          gllook=2;
          keylook=1;
        break;
      case Key_6:
          gllook=3;
          keylook=1;
        break;
      case Key_5:
          gllook=4;
          keylook=1;
        break;
      }
    }
    else
    {
       // PUI
       if ( ! puKeyboard ( e->ascii(), PU_DOWN ) )
       {
         g_key = e->ascii();
       }

       // PLAYER
       for(int a=0;a<MAX_PLAYER;a++)
       {
          if(gl_player[a] != NULL)
          {
             gl_player[a] -> kbd (e->ascii()) ;
          }
       }
       // Usercam
       if(g_usercam != NULL)
       {
             g_usercam -> kbd (e->ascii()) ;
       }

    }
    e->ignore();
}

//***********************************************************
//    add Elements to a scene
//***********************************************************

//**************** OBJECT *******************************************

void Glcontrol::loadObject(FolderListItem * i, ssgTransform *obj)
{
  QString tmpfile;
  ssgTransform *objtrans = NULL ;

// 3D-Catalog
  MyCatalogEditDlg  *catalog = new  MyCatalogEditDlg();
  if ( catalog->exec() == QDialog::Accepted )
  {
         QString   result = catalog->getfile();
         QString   workingDirectory = catalog->getpath();
         qWarning( result );
         qWarning( workingDirectory );

         // copy the 3d-object folder
#ifdef    Q_OS_LINUX
         QString   copy = "cp -dpR " + workingDirectory + result + ' ' +  g_prjpath + "data/";
         qWarning( "%s",copy.latin1() );
         system (copy.latin1());
#endif

#ifdef    Q_OS_MACX
         QString   copy = "cp -pR " + workingDirectory + result + ' ' +  g_prjpath + "data/";
         qWarning( "%s",copy.latin1() );
         system (copy.latin1());
#endif

#ifdef    Q_OS_WIN32
         copydir mycopy;
         mycopy.copy(workingDirectory + result , g_prjpath + "data/" + result);
#endif
       // find *.3ds or *.ac
         QString meshfile =  g_prjpath + "data/" + result + "/mesh.tri";
         qWarning( g_prjpath + "data/" + result );
         QDir tmpdir (g_prjpath + "data/" + result , "*.3ds *.ac");
         QStringList catlist = tmpdir.entryList();
         for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it )
         {
            tmpfile = *it;
            qWarning( tmpfile );           
         }

         // load the 3d-file from the project folder
         if (! tmpfile.isEmpty() )
         {
           setXRotation( 0 );
           setYRotation( 0 );
           setZRotation( 0 );

           setXScale(1.0f);
           setYScale(1.0f);
           setZScale(1.0f);

           ssgModelPath   ( tmpdir.path().latin1() ) ;
           ssgTexturePath ( tmpdir.path().latin1() ) ;
           ssgEntity *nobj = ssgLoad ( tmpfile.latin1() ); 

//            nobj   -> setCallback ( SSG_CALLBACK_PREDRAW , NULL ) ;
//            nobj   -> setCallback ( SSG_CALLBACK_POSTDRAW, NULL ) ;
//            nobj   -> setCallback ( SSG_CALLBACK_PREDRAW , objprecall ) ;
//            nobj   -> setCallback ( SSG_CALLBACK_POSTDRAW, objpostcall ) ;

           i->SetValue("path","data/" + result);          
           i->SetValue("file",tmpfile);
           i->setText( 0, tmpfile);
           if ( !nobj )
           {
              globj=NULL;
              return;
           }
           // save trimesh
           qWarning( "save trimesh \n" );
           
           ssgSaveTRI(meshfile.latin1(),nobj);
           objtrans = new ssgTransform ;

           objtrans -> addKid ( nobj  ) ;
           ssgFlatten         ( nobj  ) ;
           ssgStripify        ( objtrans ) ;

           if(obj == NULL)
             scene -> addKid ( objtrans ) ;
           else
             obj -> addKid ( objtrans ) ;

           globj=objtrans;
           i->objtrans=objtrans;
           i->gl=this;
         }
         else
         {
            QDir tmpdir (g_prjpath + "data/" + result , "*.md2");
            catlist = tmpdir.entryList();
            for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it )
            {
                tmpfile = *it;
                qWarning( tmpfile );
            }
            
            // load the 3d-file from the project folder
            if (! tmpfile.isEmpty() )
            {
              setXRotation( 0 );
              setYRotation( 0 );
              setZRotation( 0 );

              setXScale(1.0f);
              setYScale(1.0f);
              setZScale(1.0f);

              ssgModelPath   ( tmpdir.path().latin1() ) ;
              ssgTexturePath ( tmpdir.path().latin1() ) ;

              ssgSelector *selector = (ssgSelector *)LoadMD2(tmpfile.latin1(), NULL);
              selector->selectStep ( SSG_MD2_STAND );
              ssgTimedSelector *ts = (ssgTimedSelector *)selector -> getKid( SSG_MD2_STAND );
              ts -> setMode(SSG_ANIM_SHUTTLE);
              ts -> control(SSG_ANIM_START);
              ts -> setDuration ( 0.1 , -1 , SSG_ANIM_CLOCK ) ;

              i->SetValue("path","data/" + result);
              i->SetValue("file",tmpfile);
              i->setText( 0, tmpfile);
              if ( !selector )
              {
                  globj=NULL;
                  return;
              }
              // save trimesh
              //qWarning( "save trimesh \n" );

              //ssgSaveTRI(meshfile.latin1(),nobj);
              objtrans = new ssgTransform ;

              objtrans -> addKid ( selector  ) ;
              //ssgFlatten         ( ts  ) ;
              //ssgStripify        ( objtrans ) ;

              if(obj == NULL)
                scene -> addKid ( objtrans ) ;
              else
                obj -> addKid ( objtrans ) ;

              globj=objtrans;
              i->objtrans=objtrans;
              i->gl=this;
            }
         }
                  
  }
  globj=NULL;

//  slotStatusMsg(i18n("Ready."));
}

void Glcontrol::loadObjectFile(QString path , QString file, ssgTransform *obj)
{
  QString tmpfile;

  ssgEntity *nobj = NULL;
  ssgTransform *objtrans = NULL ;

      setXRotation( 0 );
      setYRotation( 0 );
      setZRotation( 0 );

      setXScale(1.0f);
      setYScale(1.0f);
      setZScale(1.0f);

      ssgModelPath   ( path.latin1() ) ;
      ssgTexturePath ( path.latin1() ) ;


      if(file.findRev( ".3ds" )!= -1 || file.findRev( ".ac" ) != -1)
      {
          qWarning(  "Load 3D file: " +  path + "/" + file); // debug
          nobj = ssgLoad ( file.latin1() );
          if(nobj != NULL)
          {
//            nobj   -> setCallback ( SSG_CALLBACK_PREDRAW , NULL ) ;
//            nobj   -> setCallback ( SSG_CALLBACK_POSTDRAW, NULL ) ;
//            nobj   -> setCallback ( SSG_CALLBACK_PREDRAW , objprecall ) ;
//            nobj   -> setCallback ( SSG_CALLBACK_POSTDRAW, objpostcall ) ;

            objtrans = new ssgTransform ;

            objtrans -> addKid ( nobj  ) ;
            ssgFlatten         ( nobj  ) ;
            ssgStripify        ( objtrans ) ;

            if(obj == NULL)
              scene -> addKid ( objtrans ) ;
            else
              obj -> addKid ( objtrans ) ;

            globj=objtrans;
          }
          else
          {
            qWarning(  "no file " +  path + file);
            globj = NULL;
          }
      }
      if(file.findRev( ".md2" )!= -1)
      {
          qWarning( file );
          ssgSelector *selector = (ssgSelector *)LoadMD2(file.latin1(), NULL);
          selector->selectStep ( SSG_MD2_STAND );
          ssgTimedSelector *ts = (ssgTimedSelector *)selector -> getKid(SSG_MD2_STAND);
          ts -> setMode(SSG_ANIM_SHUTTLE);
          ts -> control(SSG_ANIM_START);
          ts -> setDuration ( 0.1 , -1 , SSG_ANIM_CLOCK ) ;
          if(ts != NULL)
          {
            objtrans = new ssgTransform ;

            objtrans -> addKid ( selector  ) ;
//            ssgFlatten         ( nobj  ) ;
//            ssgStripify        ( objtrans ) ;

            if(obj == NULL)
              scene -> addKid ( objtrans ) ;
            else
              obj -> addKid ( objtrans ) ;

            globj=objtrans;
          }
          else
          {
            qWarning(  "no file " +  path + file);
            globj = NULL;
          }
      }
}

// ************* PLAYER ********************

void  Glcontrol::addPlayer(FolderListItem * i, ssgTransform *obj)
{
   

   i->gl=this;
   i->player = new Player();

   i->SetValue("file","box.3ds");
   loadObjectFile("data" , "box.3ds", NULL);
   i->objtrans=globj;
   i->player->objtrans[0]=globj;
   loadObjectFile("data" , "buggyradlv.3ds", NULL);
   i->player->objtrans[1]=globj;
   loadObjectFile("data" , "buggyradrv.3ds", NULL);
   i->player->objtrans[2]=globj;
   loadObjectFile("data" , "buggyradlh.3ds", NULL);
   i->player->objtrans[3]=globj;
   loadObjectFile("data" , "buggyradrh.3ds", NULL);
   i->player->objtrans[4]=globj;

   gl_player[gl_player_num]=i->player;

   // ode
   i->player->createOdeBody(odworld, odspace);
   dWorldStepFast1 (odworld,0.1,5);
   i->player->update (scene, 0.1 );

   if(gl_player_num < MAX_PLAYER-1 )
   {
    gl_player_num++;
   }
   setFocusPlayer(i);
}

void  Glcontrol::addPlayerFile(FolderListItem * i,QString path , QString file, ssgTransform *obj)
{
   i->player = new Player();

   loadObjectFile( path , file, NULL);

   i->player->objtrans[0] = globj;
   i->objtrans = globj;

   loadObjectFile("data" , "buggyradlv.3ds", NULL);
   i->player->objtrans[1]=globj;
   loadObjectFile("data" , "buggyradrv.3ds", NULL);
   i->player->objtrans[2]=globj;
   loadObjectFile("data" , "buggyradlh.3ds", NULL);
   i->player->objtrans[3]=globj;
   loadObjectFile("data" , "buggyradrh.3ds", NULL);
   i->player->objtrans[4]=globj;

   gl_player[gl_player_num]=i->player;

   // ode
   i->player->createOdeBody(odworld, odspace);
   dWorldStepFast1 (odworld,0.1,5);
   i->player->update (scene, 0.1 );

   if(gl_player_num < MAX_PLAYER-1 )
   {
    gl_player_num++;
   }
}

// ************** BARRIER ********************

void  Glcontrol::addBarrier(FolderListItem * i, ssgTransform *obj)
{

   i->gl=this;
   i->barrier = new Barrier();
   i->SetValue("file","minibox.ac");
   loadObjectFile("data" , "minibox.ac", NULL);
   i->objtrans=globj;
   i->barrier->objtrans[0]=globj;

   loadObjectFile("data" , "linebox.ac", i->barrier->objtrans[0]);
   i->barrier->boxobjtrans=globj;

   gl_barrier[gl_barrier_num]=i->barrier;

   // ode
   i->barrier->createOdeBody(odworld, odspace);

   if(gl_barrier_num < MAX_BARRIER-1 )
   {
    gl_barrier_num++;
   }
   setFocusBarrier(i);

}
void  Glcontrol::addBarrierFile(FolderListItem * i,QString path , QString file, ssgTransform *obj)
{
   i->barrier = new Barrier();

   loadObjectFile( path , file, NULL);

   i->barrier->objtrans[0] = globj;
   i->objtrans = globj;

   loadObjectFile("data" , "linebox.ac", i->barrier->objtrans[0]);
   i->barrier->boxobjtrans=globj;

   gl_barrier[gl_barrier_num]=i->barrier;

   // ode
   i->barrier->createOdeBody(odworld, odspace);

   if(gl_barrier_num < MAX_BARRIER-1 )
   {
    gl_barrier_num++;
   }
   globj=i->barrier->objtrans[0];
}

// ************** BODY ********************

void  Glcontrol::addBody(FolderListItem * i, ssgTransform *obj)
{
  int typ=0;

   i->gl=this;
   i->body = new Body();
   i->SetValue("file","minibox.ac");
   loadObjectFile("data" , "minibox.ac", NULL);
   i->objtrans=globj;
   i->body->objtrans[0]=globj;

   loadObjectFile("data" , "linebox.ac", i->body->objtrans[0]);
   i->body->boxobjtrans=globj;

   gl_body[gl_body_num]=i->body;

   // ode
   i->body->createOdeBody(odworld, odspace, typ);

   if(gl_body_num < MAX_BODY-1 )
   {
    gl_body_num++;
   }
   setFocusBody(i);

}
void  Glcontrol::addBodyFile(FolderListItem * i,QString path , QString file, ssgTransform *obj)
{
   int typ=0;
   
   if(i->GetValue("box").toInt() == 1)
   {
      typ=0;
   }
   if(i->GetValue("cylinder").toInt() == 1)
   {
      typ=1;
   }
   if(i->GetValue("sphere").toInt() == 1)
   {
      typ=2;
   }

   i->body = new Body();

   loadObjectFile( path , file, NULL);

   i->body->objtrans[0] = globj;
   i->objtrans = globj;

   loadObjectFile("data" , "linebox.ac", i->body->objtrans[0]);
   i->body->boxobjtrans=globj;

   gl_body[gl_body_num]=i->body;

   // ode
   i->body->createOdeBody(odworld, odspace, typ);

   if(gl_body_num < MAX_BODY-1 )
   {
    gl_body_num++;
   }
   globj=i->body->objtrans[0];
}

// ************** SKY ********************

void    Glcontrol::addSky(FolderListItem * i, ssgTransform *obj)
{
  ssgaCloudLayer     *clouds[MAX_CLOUDS] = {NULL} ;
                    
  star_data = new sgdVec3[nstars] ;
  for ( int a = 0; a < nstars; a++ )
  {
    star_data[a][0] = ssgaRandom() * SGD_PI ;
	  star_data[a][1] = ssgaRandom() * SGD_PI ;
	  star_data[a][2] = ssgaRandom() ;
  }
  
  ssgaSky *sky_obj = NULL ;
  /* sky */
  sky_obj       =  new ssgaSky ;
  sky_obj       -> build ( 80000, 80000, nplanets, planet_data, nstars, star_data );
  /* sun */
  bodies[0] =  sky_obj -> addBody (
                  NULL,                 // body texture
				  "data/halo.rgba",     // halo texture
				  5000,                 // size
				  80000,                // distance
				  true );               // is sun - dome painted based on this
  bodies[0] -> setDeclination  ( 20*SGD_DEGREES_TO_RADIANS );
  /* moon */
  bodies[1] =  sky_obj -> addBody (
                  "data/moon.rgba",     // body texture
				  NULL,                 // halo texture
				  5000,                 // size
				  80000 );              // distance
  bodies[1] -> setDeclination  ( 65*SGD_DEGREES_TO_RADIANS );
  /* clouds */
  clouds[0] =  sky_obj -> addCloud (
				 "data/scattered.rgba", // texture
                 80000,                 // span
				 2000,                  // elevation,
				 100,                   // thickness
				 100 );                 // transition
  clouds[0] -> setSpeed ( 50 ) ;
  clouds[0] -> setDirection ( 45 ) ;
  clouds[1] =  sky_obj -> addCloud (
				 "data/scattered.rgba", // texture
                 80000,                 // span
				 3000,                  // elevation,
				 100,                   // thickness
				 100 );                 // transition
  clouds[1] -> setSpeed ( 20 ) ;
  clouds[1] -> setDirection ( 30 ) ;
  clouds[2] =  sky_obj -> addCloud (
				 "data/scattered.rgba", // texture
                 80000,                 // span
				 1000,                  // elevation,
				 100,                   // thickness
				 100 );                 // transition
  clouds[2] -> setSpeed ( 5 ) ;
  clouds[2] -> setDirection ( 20 ) ;

  gl_sky_obj[0]= sky_obj;
  i->sky = sky_obj;
  i->gl=this;

  setFocusSky(i);
}

void    Glcontrol::addSkyFile(FolderListItem * i, QString path , QString file, ssgTransform *obj)
{

}

// ************** FIRE ********************


void Glcontrol::addFire(FolderListItem * i, ssgTransform *obj)
{
    char mybuff[256];
    unsigned int colorr;
    unsigned int colorg;
    unsigned int colorb;
    sgVec4  firecol;
    QString tmpfile;

  ssgTransform *objtrans = NULL ;
  ssgaFire *fire_obj = NULL ;

      setXRotation( 0 );
      setYRotation( 0 );
      setZRotation( 0 );

      setXScale(1.0f);
      setYScale(1.0f);
      setZScale(1.0f);

  fire_obj =  new ssgaFire ( MAX_FIRE_TRIS, i->GetValue("radius").toFloat(), i->GetValue("height").toFloat(), i->GetValue("speed").toFloat() );

  strncpy(mybuff,i->GetValue("hotcolor"),8);
  sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
  sgSetVec4 ( firecol, (float)colorr/255,(float)colorg/255,(float)colorb/255, 1.0f ) ;
  fire_obj->setHotColour(firecol);


  i->fire = fire_obj;
  i->gl=this;
  objtrans = new ssgTransform ;
  objtrans-> addKid ( fire_obj ) ;


        if(obj == NULL)
          scene -> addKid ( objtrans ) ;
        else
          obj -> addKid ( objtrans ) ;

        globj=objtrans;
        i->objtrans=objtrans;
        gl_fire_obj[gl_fire_num]=fire_obj;
        if(gl_fire_num < MAX_FIRE-1 )
        {
            gl_fire_num++;
        }
        globj=NULL;

//  slotStatusMsg(i18n("Ready."));
}

//**************** LENSFLARE *******************************************


void Glcontrol::addLensflare(FolderListItem * i, ssgTransform *obj)
{

  ssgTransform *objtrans = NULL ;
  ssgaLensFlare *lensflare_obj = NULL ;

      setXRotation( 0 );
      setYRotation( 0 );
      setZRotation( 0 );

      setXScale(1.0f);
      setYScale(1.0f);
      setZScale(1.0f);

  lensflare_obj =  new ssgaLensFlare ();



  i->gl=this;
  objtrans = new ssgTransform ;
  objtrans-> addKid ( lensflare_obj ) ;


        if(obj == NULL)
          scene -> addKid ( objtrans ) ;
        else
          obj -> addKid ( objtrans ) ;

        i->objtrans=objtrans;
        globj=NULL;

//  slotStatusMsg(i18n("Ready."));
}

//**************** PARTSYS *******************************************

void Glcontrol::addPartSys(FolderListItem * i, ssgTransform *obj)
{

  ssgTransform *objtrans = NULL ;
  ssgaParticleSystem  *partsys_obj = NULL ;
  static ssgSimpleState     *splash_state = NULL ;


      setXRotation( 0 );
      setYRotation( 0 );
      setZRotation( 0 );

      setXScale(1.0f);
      setYScale(1.0f);
      setZScale(1.0f);

  splash_state = new ssgSimpleState () ;
  splash_state -> setTexture        ( "data/droplet.rgb" ) ;
  splash_state -> setTranslucent    () ;
  splash_state -> enable            ( GL_TEXTURE_2D ) ;
  splash_state -> setShadeModel     ( GL_SMOOTH ) ;
  splash_state -> enable            ( GL_CULL_FACE ) ;
  splash_state -> enable            ( GL_BLEND ) ;
  splash_state -> enable            ( GL_LIGHTING ) ;
  splash_state -> setColourMaterial ( GL_EMISSION ) ;
  splash_state -> setMaterial       ( GL_AMBIENT, 0, 0, 0, 1 ) ;
  splash_state -> setMaterial       ( GL_DIFFUSE, 0, 0, 0, 1 ) ;
  splash_state -> setMaterial       ( GL_SPECULAR, 0, 0, 0, 1 ) ;
  splash_state -> setShininess      (  0 ) ;
  
  partsys_obj =  new  ssgaParticleSystem ( 1000, 100, 500, TRUE,
                                      0.2f, 1000,
                                      Glcontrol::droplet_create );
                                      
  partsys_obj -> setState ( splash_state );
  


  i->gl=this;
  objtrans = new ssgTransform ;
  objtrans-> addKid ( partsys_obj );

        gl_partsys_obj[gl_partsys_num]=partsys_obj;
        if(gl_partsys_num < MAX_PARTSYS-1 )
        {
            gl_partsys_num++;
        }

        if(obj == NULL)
          scene -> addKid ( objtrans );
        else
          obj -> addKid ( objtrans );
          
        i->objtrans=objtrans;
        globj=NULL;

//  slotStatusMsg(i18n("Ready."));
}

void Glcontrol::droplet_create ( ssgaParticleSystem *, int, ssgaParticle *p )
{
  float c = ((float)(rand()%100)/100.0f) * (256.0f-163.0f)/255.0f ;

  sgSetVec4 ( p -> col, 96.0f/255.0f+c, 147.0f/255.0f+c, 163.0f/255.0f+c, 0.5);
  sgSetVec3 ( p -> pos, -2.4f, -0.1f, 1.9f ) ;
  sgSetVec3 ( p -> vel,
             -(float)(rand()%1000)/200.0f,
              (float)(rand()%1000 - 500)/400.0f,
              (float)(rand()%1000)/1000.0f + 3.0f ) ;
  sgAddScaledVec3 ( p -> pos, p -> vel, (float)(rand()%1000)/20000.0f ) ;
  sgSetVec3 ( p -> acc, 0, 0, -9.8f ) ;
  p -> time_to_live = 1 ;
}


//**************** WAVESYS *******************************************

void Glcontrol::addWaveSys(FolderListItem * i, ssgTransform *obj)
{

  ssgTransform    *objtrans    = NULL ;
  ssgaWaveSystem  *wavesys_obj = NULL ;
  ssgSimpleState  *sea_state   = NULL ;
  ssgaWaveTrain   *wtrains     = NULL ;
  
  sgVec4  TRANSLUCENT_WHITE  = { 1.0f, 1.0f, 1.0f, 0.8f } ;
  sgVec3  pos    = { 0, 0, 0 } ;


      setXRotation( 0 );
      setYRotation( 0 );
      setZRotation( 0 );

      setXScale(1.0f);
      setYScale(1.0f);
      setZScale(1.0f);

  sea_state = new ssgSimpleState () ;
  sea_state -> setTexture        ( "data/seawaterfull3.bmp" ) ;
  sea_state -> setTranslucent    () ;
  sea_state -> enable            ( GL_TEXTURE_2D ) ;
  sea_state -> setShadeModel     ( GL_SMOOTH ) ;
  sea_state -> enable            ( GL_CULL_FACE ) ;
  sea_state -> enable            ( GL_BLEND ) ;
  sea_state -> enable            ( GL_LIGHTING ) ;
  sea_state -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;
  sea_state -> setMaterial       ( GL_EMISSION, 0, 0, 0, 1 ) ;
  sea_state -> setMaterial       ( GL_SPECULAR, 1, 1, 1, 1 ) ;
  sea_state -> setShininess      (  5 ) ;


  wavesys_obj   =  new ssgaWaveSystem ( 10000 ) ;  // 10000
  wavesys_obj   -> setColour        ( TRANSLUCENT_WHITE ) ;
  wavesys_obj   -> setSize          ( i->GetValue("size").toFloat() );
  wavesys_obj   -> setTexScale      ( i->GetValue("texsx").toFloat(), i->GetValue("texsx").toFloat());
  wavesys_obj   -> setCenter        ( pos ) ;
  wavesys_obj   -> setDepthCallback ( NULL ) ;
  wavesys_obj   -> setKidState      ( sea_state ) ;
  wavesys_obj   -> setWindSpeed     ( i->GetValue("wspeed").toFloat());

  wtrains = new  ssgaWaveTrain();
  wtrains-> setSpeed      (  3.1f ) ;
  wtrains-> setLength     (  0.8f ) ;
  wtrains-> setLambda     (  0.6f ) ;
  wtrains-> setHeading    ( 47.0f ) ;
  wtrains-> setWaveHeight (  0.2f ) ;
  
  wavesys_obj   -> setWaveTrain     ( 0,wtrains );
  
  wtrains = new  ssgaWaveTrain();
  wtrains-> setSpeed      (  4.6f ) ;
  wtrains-> setLength     (  0.8f ) ;
  wtrains-> setLambda     (  1.0f ) ;
  wtrains-> setHeading    ( 36.0f ) ;
  wtrains-> setWaveHeight (  0.1f ) ;

  wavesys_obj   -> setWaveTrain     ( 1,wtrains );
  
  wtrains = new  ssgaWaveTrain();
  wtrains-> setSpeed      (  8.5f ) ;
  wtrains-> setLength     (  0.6f ) ;
  wtrains-> setLambda     (  1.0f ) ;
  wtrains-> setHeading    ( 65.0f ) ;
  wtrains-> setWaveHeight (  0.1f ) ;

  wavesys_obj   -> setWaveTrain     ( 2,wtrains );

  wavesys_obj   -> setKidCallback   ( SSG_CALLBACK_PREDRAW , NULL ) ;
  wavesys_obj   -> setKidCallback   ( SSG_CALLBACK_POSTDRAW, NULL ) ;
  wavesys_obj   -> regenerate       () ;



  i->gl=this;
  i->wavesys=wavesys_obj;
  objtrans = new ssgTransform ;
  objtrans-> addKid ( wavesys_obj );

        gl_wavesys_obj[gl_wavesys_num]=wavesys_obj;
        if(gl_wavesys_num < MAX_WAVESYS-1 )
        {
            gl_wavesys_num++;
        }

        if(obj == NULL)
          scene -> addKid ( objtrans );
        else
          obj -> addKid ( objtrans );

        i->objtrans=objtrans;
        globj=NULL;

        
   setFocusWaveSys(i);
//  slotStatusMsg(i18n("Ready."));
}

//**************** CAMERA *******************************************

void Glcontrol::addCamera(FolderListItem * i, ssgTransform *obj)
{
   loadObjectFile(i->GetValue("path") ,i->GetValue("file"),obj);
   i->usercam = new usercamera();
   i->objtrans=globj;
   i->usercam->objtrans=globj;
   i->gl=this;
   globj=NULL;
}

//**************** FOG *******************************************

void Glcontrol::addFog(FolderListItem * i)
{
   i->gl=this;
   globj=NULL;

   setFocusFog(i);
}

// ************** TERRAIN ********************

void  Glcontrol::addTerrain(FolderListItem * i, ssgTransform *obj)
{

   i->gl=this;
   i->terrain = new Terrain();

   setFocusTerrain(i);

}
void  Glcontrol::addTerrainFile(FolderListItem * i,QString path , QString file, ssgTransform *obj)
{
   i->gl=this;
   i->terrain = new Terrain();

}

//**************** SPL *******************************************

void Glcontrol::addSpl(FolderListItem * i, ssgTransform *obj)
{

  QString tmpfile;
  QString copy;
  QFileDialog FileDialog;
  QFileDialog SFileDialog;

    QString url=FileDialog.getOpenFileName(".",
        "*.spl (*.spl)", this, "Open File...");

    if(!url.isEmpty())
    {
      QString path = FileDialog.dirPath ();
      qWarning( "%s",path.latin1() );

     QString surl=SFileDialog.getSaveFileName(g_prjpath + "data/",
        "*.spl (*.spl)", this, "Save File...");
     if(!surl.isEmpty())
     {
      QFileInfo f(surl);
      QString sname = f.fileName();
      qWarning( "SaveName: %s",sname.latin1() );
      // copy the spl file in the project folder
      copy = "cp " + url + ' ' +  g_prjpath + "data/" + sname ;
      qWarning( "%s",copy.latin1() );
      system (copy.latin1());
      tmpfile = g_prjpath + "data/" + sname ;
      qWarning( "spl: %s",tmpfile.latin1() );
      i->splprog = new splPrg(tmpfile.latin1());
//      i->SetValue("path",path);                       // Test
      i->SetValue("file",sname);
      i->setText( 0, sname);

      gl_spl_obj[gl_spl_num]=i->splprog;
      if(gl_spl_num < MAX_SPL-1 )
      {
          gl_spl_num++;
      }
      setFocusSPL(i);
     }
    }
}

void Glcontrol::addSPLFile(FolderListItem * i, QString path , QString file, ssgTransform *obj)
{
  QString tmpfile;

      tmpfile = path + "/" + file;

      i->splprog = new splPrg(tmpfile.latin1());

      gl_spl_obj[gl_spl_num]=i->splprog;
      if(gl_spl_num < MAX_SPL-1 )
      {
          gl_spl_num++;
      }
      setFocusSPL(i);
}

//**************** SHADER *******************************************

void Glcontrol::addShader(FolderListItem * i, ssgTransform *obj)
{

  QString tmpvfile;
  QString tmpffile;
  QString copy;
  QFileDialog FileDialog;
  QFileDialog SFileDialog;

    QString url=FileDialog.getOpenFileName(".",
        "*.vert (*.vert)", this, "Open File...");

    if(!url.isEmpty())
    {
      QString path = FileDialog.dirPath ();
      qWarning( "%s",path.latin1() );

     QString surl=SFileDialog.getSaveFileName(g_prjpath + "data/",
        "*.vert (*.vert)", this, "Save File...");
     if(!surl.isEmpty())
     {
      QFileInfo f(surl);
      QString sname = f.fileName();
      qWarning( "SaveName: %s",sname.latin1() );
      // copy the spl file in the project folder
      copy = "cp " + url + ' ' +  g_prjpath + "data/" + sname ;
      qWarning( "%s",copy.latin1() );
      system (copy.latin1());
      tmpvfile = g_prjpath + "data/" + sname ;
      qWarning( "vert: %s",tmpvfile.latin1() );
//      i->SetValue("path",path);                       // Test
      i->SetValue("vfile",sname);
      i->setText( 0, sname);

      url=FileDialog.getOpenFileName(".",
          "*.frag (*.frag)", this, "Open File...");
      if(!url.isEmpty())
      {
        path = FileDialog.dirPath ();
        qWarning( "%s",path.latin1() );

        surl=SFileDialog.getSaveFileName(g_prjpath + "data/",
        "*.frag (*.frag)", this, "Save File...");
        if(!surl.isEmpty())
        {
          QFileInfo f(surl);
          QString sname = f.fileName();
          qWarning( "SaveName: %s",sname.latin1() );
          // copy the spl file in the project folder
          copy = "cp " + url + ' ' +  g_prjpath + "data/" + sname ;
          qWarning( "%s",copy.latin1() );
          system (copy.latin1());
          tmpffile = g_prjpath + "data/" + sname ;
          qWarning( "frag: %s",tmpffile.latin1() );
          i->SetValue("ffile",sname);

          i->gshader = new shader();
          i->gshader->initShaders(tmpvfile.latin1(),tmpffile.latin1());
          gl_shader_obj[gl_shader_num]=i->gshader;
          if(gl_shader_num < MAX_SPL-1 )
          {
           gl_shader_num++;
          }
          setFocusShader(i);
        }
     }
    }
  }
}

void Glcontrol::addShaderFile(FolderListItem * i, QString path , QString vfile, QString ffile, ssgTransform *obj)
{
  QString tmpvfile;
  QString tmpffile;

      tmpvfile = path + "/" + vfile;
      tmpffile = path + "/" + ffile;

      i->gshader = new shader();
      i->gshader->initShaders(tmpvfile.latin1(),tmpffile.latin1());
      gl_shader_obj[gl_shader_num]=i->gshader;
      if(gl_shader_num < MAX_SHADER-1 )
      {
          gl_shader_num++;
      }
      setFocusShader(i);
}

//**************** CURSOR *******************************************

void Glcontrol::addCursor(FolderListItem * i)
{

      i->cursor = new cursor3d();
      gl_cursor_obj[gl_cursor_num]=i->cursor;
      if(gl_cursor_num < MAX_CURSOR-1 )
      {
          gl_cursor_num++;
      }
      setFocusCursor(i);
}

//**************** GUITXT *******************************************

void Glcontrol::addGUITXT(FolderListItem * i)
{
   i->gl=this;
   globj=NULL;
   i->guitext = new  GUIText(10,10);
   setFocusGUIText(i);
}

//**************** GUIButton *******************************************

void Glcontrol::addGUIButton(FolderListItem * i)
{
   i->gl=this;
   globj=NULL;
   i->guibutton = new  GUIButton(10,10,"nonamed");
   i->guibutton->setValue     ( FALSE ) ;
   setFocusGUIButton(i);
}

//**************** GUIOSButton *******************************************

void Glcontrol::addGUIOSButton(FolderListItem * i)
{
   i->gl=this;
   globj=NULL;
   i->guiosbutton = new  GUIOSButton(10,10,"nonamed");
   i->guiosbutton->setValue     ( FALSE ) ;
   setFocusGUIOSButton(i);
}

//**************** GUIInput *******************************************

void Glcontrol::addGUIInput(FolderListItem * i)
{
   i->gl=this;
   globj=NULL;
   i->guiinput = new  GUIInput(10,10,90,30);
   setFocusGUIInput(i);
}

//**************** Network *******************************************

void Glcontrol::addNetwork(FolderListItem * i)
{
   i->gl=this;
   globj=NULL;
   i->client = new  netclient();
   g_client = i->client;
}

//**************** SOUND *******************************************

void Glcontrol::addSound(FolderListItem * i, ssgTransform *obj)
{
  QString tmpfile;
  QString copy;
  QFileDialog FileDialog;

    QString url=FileDialog.getOpenFileName(".",
        "*.wav *.ogg", this, "Open File...");
    if(!url.isEmpty())
    {
      QFileInfo f(url);
      QString sname = f.fileName();
      // copy the sound file in the project folder
      copy = "cp " + url + ' ' +  g_prjpath + "data/" ;
      qWarning( "%s",copy.latin1() );
      system (copy.latin1());
      tmpfile = url;
      i->gl=this;
      loadObjectFile("data" , "minibox.ac", obj);
      i->objtrans=globj;

#ifdef KCOPENAL 
   i->sound = new AlSound();
   loadObjectFile("data" , "linebox.ac", i->objtrans);
   i->sound->boxobjtrans=globj;
   i->sound->snd = Audio->LoadFile((char *)(tmpfile.latin1()), false);
#endif
      i->SetValue("file",sname);
      i->setText( 0, sname);
      if(gl_sound_num < MAX_SOUND-1 )
      {
          gl_sound_num++;
      }
      setFocusSound(i);
    }
}

void Glcontrol::addSoundFile(FolderListItem * i, QString path , QString file, ssgTransform *obj)
{
  QString tmpfile;



      ssgModelPath   ( path.latin1() ) ;
      ssgTexturePath ( path.latin1() ) ;

      tmpfile = path + "/" + file;
      i->gl=this;
#ifdef KCOPENAL        // load up radar sound effect and loop until program stops
   i->sound = new AlSound();
   loadObjectFile("data" , "minibox.ac", obj);
   i->objtrans=globj;
   loadObjectFile("data" , "linebox.ac", i->objtrans);
   i->sound->boxobjtrans=globj;
   i->sound->snd = Audio->LoadFile((char *)(tmpfile.latin1()), false);

#endif
      if(gl_sound_num < MAX_SOUND-1 )
      {
          gl_sound_num++;
      }
}

void Glcontrol::setMouseMode(int mode)
{
    //  0 Tanslate
    //  1 Rotate
    //  2 Scale
    
    mouse_mode=mode;
}
void Glcontrol::initFolderListItem(FolderListItem * i,const QString &path)
{
    sgCoord objpos ;
    int number=0;
    float myz=0;
    
       if ( !i )
	      return;
        


    QListViewItem *ichild = i->firstChild();

    while(ichild != NULL)
    {
      if(ichild->text(1) == "LAMP")
      {
        qWarning(  "LAMP OK !" );
        number =  ((FolderListItem *)ichild)->GetValue("number").toInt();
        if(number >= 0 && number <=7)
        {
          ((FolderListItem *)ichild)->light=ssgGetLight(number);
          ((FolderListItem *)ichild)->updategl();
            // Lensflare
            addLensflare((FolderListItem *) ichild, 0);
            globj=((FolderListItem *)ichild)->objtrans;

	    
            if(((FolderListItem *)ichild)->GetValue("lensflare").toInt() == 0 || ((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }

            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());
                              
            setFocusLamp(((FolderListItem *)ichild));
        }
          
      }
      if(ichild->text(1) == "OBJECT")
      {
        qWarning(  "OBJECT OK !" );

        loadObjectFile(path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);
        if(globj != NULL)
        {
            ((FolderListItem *)ichild)->objtrans=globj;
            ((FolderListItem *)ichild)->gl=this;
            setFocusObject((FolderListItem *)ichild);
        }         
      }
      if(ichild->text(1) == "PLAYER")
      {
        qWarning(  "PLAYER OK !" );

            ((FolderListItem *)ichild)->gl=this;
            addPlayerFile((FolderListItem *)ichild,path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);

            setFocusPlayer((FolderListItem *)ichild);
      }
      if(ichild->text(1) == "BARRIER")
      {
        qWarning(  "BARRIER OK !" );

            ((FolderListItem *)ichild)->gl=this;
            addBarrierFile((FolderListItem *)ichild,path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);


            if(((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }


            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());

            setFocusBarrier((FolderListItem *)ichild);
      }
      if(ichild->text(1) == "BODY")
      {
        qWarning(  "BODY OK !" );

            ((FolderListItem *)ichild)->gl=this;
            addBodyFile((FolderListItem *)ichild,path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);

            if(((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }


            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());

            setFocusBody((FolderListItem *)ichild);
      }
      if(ichild->text(1) == "CAMERA")
      {
        qWarning(  "CAMERA OK !" );
            loadObjectFile(path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);
            ((FolderListItem *)ichild)->objtrans=globj;
            ((FolderListItem *)ichild)->gl=this;

            if(((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }


            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());

           ((FolderListItem *)ichild)->usercam = new usercamera();
           ((FolderListItem *)ichild)->usercam->objtrans=globj;
           setFocusCamera(((FolderListItem *)ichild));
           
      }
      if(ichild->text(1) == "FIRE")
      {
        qWarning(  "FIRE OK !" );
        addFire((FolderListItem *) ichild, i->objtrans);
            globj=((FolderListItem *)ichild)->objtrans;
 
            if(((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }
 
            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());

           setFocusFire(((FolderListItem *)ichild));

      }
      if(ichild->text(1) == "PARTSYS")
      {
        qWarning(  "PARTSYS OK !" );
            addPartSys((FolderListItem *) ichild, i->objtrans);
            globj=((FolderListItem *)ichild)->objtrans;

            if(((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }

            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());

      }
      if(ichild->text(1) == "WAVESYS")
      {
        qWarning(  "WAVESYS OK !" );
            addWaveSys((FolderListItem *) ichild, i->objtrans);
            globj=((FolderListItem *)ichild)->objtrans;

            if(((FolderListItem *)ichild)->GetValue("on").toInt() == 0)
            {
               myz = OBJ_OFF;
            }
            else
            {
              myz = ((FolderListItem *)ichild)->GetValue("z").toFloat();
            }

            sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  myz,
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());
          
	   setFocusWaveSys((FolderListItem *)ichild);
      }
      if(ichild->text(1) == "FOG")
      {
        qWarning(  "FOG OK !" );
        addFog((FolderListItem *) ichild);

      }
      
      if(ichild->text(1) == "SKY")
      {
        qWarning(  "SKY OK !" );
        addSky((FolderListItem *) ichild, i->objtrans);
        globj=NULL;
      }

      if(ichild->text(1) == "SPL")
      {
        qWarning(  "SPL OK !" );
        ((FolderListItem *)ichild)->gl=this;
        addSPLFile((FolderListItem *)ichild,path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);
        globj=NULL;
      }

      if(ichild->text(1) == "SHADER")
      {
        qWarning(  "SHADER OK !" );
        ((FolderListItem *)ichild)->gl=this;
        addShaderFile((FolderListItem *)ichild,path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("vfile"),((FolderListItem *)ichild)->GetValue("ffile"),i->objtrans);
        globj=NULL;
      }

      if(ichild->text(1) == "SOUND")
      {
        qWarning(  "SOUND OK !" );
        ((FolderListItem *)ichild)->gl=this;
        addSoundFile((FolderListItem *)ichild,path.latin1()+((FolderListItem *)ichild)->GetValue("path") ,((FolderListItem *)ichild)->GetValue("file"),i->objtrans);

        globj=((FolderListItem *)ichild)->objtrans;
     
	    sgSetCoord ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("x").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("y").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotx").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("roty").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("rotz").toFloat());
            globj -> setTransform ( & objpos,
                  ((FolderListItem *)ichild)->GetValue("scax").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scay").toFloat(),
                  ((FolderListItem *)ichild)->GetValue("scaz").toFloat());

            setFocusSound((FolderListItem *)ichild);
        globj=NULL;
      }

      if(ichild->text(1) == "CURSOR")
      {
        qWarning(  "CURSOR OK !" );
        addCursor((FolderListItem *) ichild);
        globj=NULL;
      }

      if(ichild->text(1) == "GUI-TXT")
      {
        qWarning(  "GUI-TXT OK !" );
        addGUITXT((FolderListItem *) ichild);
      }
      
      if(ichild->text(1) == "GUI-BUTTON")
      {
        qWarning(  "GUI-Button OK !" );
        addGUIButton((FolderListItem *) ichild);
      }

      if(ichild->text(1) == "GUI-OSBUTTON")
      {
        qWarning(  "GUI-OSButton OK !" );
        addGUIOSButton((FolderListItem *) ichild);
      }

      if(ichild->text(1) == "GUI-INPUT")
      {
        qWarning(  "GUI-Input OK !" );
        addGUIInput((FolderListItem *) ichild);
      }

      if(ichild->text(1) == "NETWORK")
      {
        qWarning(  "Network OK !" );
        addNetwork((FolderListItem *) ichild);
      }

      initFolderListItem((FolderListItem *)ichild,path);
      ichild=ichild->nextSibling();
    }
    globj = NULL;
}

//***********************************************************
//    set the focus to a Elements
//***********************************************************

void Glcontrol::setFocus(FolderListItem * i)
{

    if(i->objtrans != NULL)
    {
         globj = i->objtrans;

      setXTrans( i->GetValue("x").toFloat() );
      setYTrans( i->GetValue("y").toFloat() );
      setZTrans( i->GetValue("z").toFloat() );
      

      setXRotation( i->GetValue("rotx").toFloat() );
      setYRotation( i->GetValue("roty").toFloat() );
      setZRotation( i->GetValue("rotz").toFloat() );

      if(i->GetValue("on").toInt() == 0)
      {
        setXScale( 0.0f );
        setYScale( 0.0f );
        setZScale( 0.0f );
      }
      else
      {
        setXScale( i->GetValue("scax").toFloat() );
        setYScale( i->GetValue("scay").toFloat() );
        setZScale( i->GetValue("scaz").toFloat() );
      }
      focusitem = i;

    }
    else
    {
        globj=NULL;
    }
}

void Glcontrol::setFocusObject(FolderListItem * i)
{
  sgCoord       pos ;

    if(i->objtrans != NULL)
    {
      sgSetCoord ( &pos,
                  i->GetValue("x").toFloat(),
                  i->GetValue("y").toFloat(),
                  i->GetValue("z").toFloat(),
                  i->GetValue("rotx").toFloat(),
                  i->GetValue("roty").toFloat(),
                  i->GetValue("rotz").toFloat() ) ;

      if(i->GetValue("barrier").toInt() == 1)
      {
        if(i->tribarrier == NULL)
        {
            QString file = g_prjpath + i->GetValue("path") + "/mesh.tri" ;
            qWarning( "trimesh: " + file );
            i->tribarrier = new TriBarrier();
            i->tribarrier->createTriMesh( odspace , file.latin1());
        }
      }

      if(i->GetValue("on").toInt() == 0)
      {
        i->objtrans->setTransform ( & pos,0.0001f,0.0001f,0.0001f) ;
      }
      else
      {
        i->objtrans->setTransform ( & pos,
                                      i->GetValue("scax").toFloat(),
                                      i->GetValue("scay").toFloat(),
                                      i->GetValue("scaz").toFloat()) ;
        i->objtrans->recalcBSphere();
       if(i->tribarrier != NULL)
       {
        i->tribarrier->pos.xyz[0] = i->GetValue("x").toFloat();
        i->tribarrier->pos.xyz[1] = i->GetValue("y").toFloat();
        i->tribarrier->pos.xyz[2] = i->GetValue("z").toFloat();

        i->tribarrier->pos.hpr[0] = i->GetValue("rotx").toFloat();
        i->tribarrier->pos.hpr[1] = i->GetValue("roty").toFloat();
        i->tribarrier->pos.hpr[2] = i->GetValue("rotz").toFloat();
        i->tribarrier->SetPosition ();
       }
      }
    }
    setFocus(i);
}

void Glcontrol::setFocusScene(FolderListItem * i)
{
    char mybuff[256];
    unsigned int colorr;
    unsigned int colorg;
    unsigned int colorb;

      i->gl->setCaption( tr( i->text(0) ) );
      dWorldSetGravity(odworld,i->GetValue("wgx").toFloat(),i->GetValue("wgy").toFloat(),i->GetValue("wgz").toFloat());  
      strncpy(mybuff,i->GetValue("color_back",i),8);
      sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
      glClearColor ( (float)colorr/255, (float)colorg/255, (float)colorb/255 ,1.0f) ;

      if(i->GetValue("cgplane").toInt() == 0)
      {
        if(odground != NULL)
        {
          dGeomDestroy (odground);
          odground = NULL;
        }   
      }
      else
      {
        if(odground == NULL)
        {
          odground = dCreatePlane(odspace,0,0,1,0);
        }
      }
      globj=NULL;
}

void Glcontrol::setFocusPlayer(FolderListItem * i)
{
     if(i->player != NULL)
     {
        i->player->rotspeed = i->GetValue("rotsp").toFloat();
        i->player->transspeed = i->GetValue("transp").toFloat();
        i->player->fmax2 = i->GetValue("fmax2").toFloat();
        
        // keyboard
        i->player->kbforward =  (i->GetValue("kbforward").at(0)).latin1();
        i->player->kbback = (i->GetValue("kbback").at(0)).latin1();
        i->player->kbleft = (i->GetValue("kbleft").at(0)).latin1();
        i->player->kbright = (i->GetValue("kbright").at(0)).latin1();

        i->player->pos.xyz[0] = i->GetValue("x").toFloat();
        i->player->pos.xyz[1] = i->GetValue("y").toFloat();

        i->player->pos.hpr[0] = i->GetValue("rotx").toFloat();
        i->player->pos.hpr[1] = i->GetValue("roty").toFloat();
        i->player->pos.hpr[2] = i->GetValue("rotz").toFloat();

        i->player->kbcamrotadd = (i->GetValue("kbcamrotadd").at(0)).latin1();
        i->player->kbcamrotsub = (i->GetValue("kbcamrotsub").at(0)).latin1();
        i->player->kbcamradadd = (i->GetValue("kbcamradadd").at(0)).latin1();
        i->player->kbcamradsub = (i->GetValue("kbcamradsub").at(0)).latin1();
        i->player->kbcamheightadd = (i->GetValue("kbcamheightadd").at(0)).latin1();
        i->player->kbcamheightsub = (i->GetValue("kbcamheightsub").at(0)).latin1();

        i->player->camradius = i->GetValue("camradius").toFloat();
        i->player->camrotw = i->GetValue("camrotw").toFloat();
        i->player->camhight = i->GetValue("camhight").toFloat();
        
        i->player->axis[0][0] = i->GetValue("ax1").toInt();
        i->player->axis[0][1] = i->GetValue("ay1").toInt();
        i->player->axis[1][0] = i->GetValue("ax2").toInt();
        i->player->axis[1][1] = i->GetValue("ay2").toInt();
        
      if(i->GetValue("on").toInt() == 0)
      {
        i->player->pos.xyz[2] = OBJ_OFF ;
      }
      else
      {
        i->player->pos.xyz[2] = i->GetValue("z").toFloat() ;
      }
      
      // ode   Test   move to player

      i->player->SetPosition ();
      
      // controller
      if(i->GetValue("kbd").toInt() == 1)
      {
        i->player->controller = 1 ;
      }
      if(i->GetValue("maus").toInt() == 1)
      {
        i->player->controller = 2 ;
      }
      if(i->GetValue("joystick").toInt() == 1)
      {
        i->player->controller = 3 ;
      }
      if(i->GetValue("joystick").toInt() == 2)
      {
        i->player->controller = 4 ;
      }
      if(i->GetValue("network").toInt() == 1)
      {
        i->player->controller = 5 ;
      }
      
      // cameratyp
      if(i->GetValue("camfix").toInt() == 1)
      {
        i->player->camtyp = 1 ;
      }
      if(i->GetValue("cam2d").toInt() == 1)
      {
        i->player->camtyp = 2 ;
      }
      if(i->GetValue("camego").toInt() == 1)
      {
        i->player->camtyp = 3 ;
      }

      qWarning(  "setFocusPlayer Player Object OK %i %i", i->player->controller, i->player->camtyp);
     }
     else
     {
          qWarning(  "setFocusPlayer No Player Object " );
     }
     setFocus(i);
}
void Glcontrol::setFocusBarrier(FolderListItem * i)
{

    sgCoord    boxpos;
    float barrz=0.0f;
    
     if(i->barrier != NULL)
     {
       if(i->barrier->boxobjtrans != NULL)
       {
        sgSetCoord ( & boxpos, 0,  0, 0, 0, 0, 0 ) ;
        if(i->GetValue("viewbox").toInt() == 0)
        {
          i->barrier->boxobjtrans -> setTransform ( & boxpos,0.0f,0.0f,0.0f) ;
        }
        else
        {
          i->barrier->boxobjtrans -> setTransform ( & boxpos,1.0f,1.0f,1.0f) ;
        }
       }

      // ode   Test   move to player
      if(i->GetValue("on").toInt() == 0)
      {
        barrz = OBJ_OFF ;
      }
      else
      {
        barrz = i->GetValue("z").toFloat() ;
      }
      dGeomBoxSetLengths (i->barrier->odbox[0], i->GetValue("scax").toFloat(), i->GetValue("scay").toFloat(), i->GetValue("scaz").toFloat());

        i->barrier->pos.xyz[0] = i->GetValue("x").toFloat();
        i->barrier->pos.xyz[1] = i->GetValue("y").toFloat();
        i->barrier->pos.xyz[2] = barrz;

        i->barrier->pos.hpr[0] = i->GetValue("rotx").toFloat();
        i->barrier->pos.hpr[1] = i->GetValue("roty").toFloat();
        i->barrier->pos.hpr[2] = i->GetValue("rotz").toFloat();
        i->barrier->SetPosition ();
     }
     else
     {
          qWarning(  "setFocusBarrier No Barrier Object " );
     }
     setFocus(i);
}

void Glcontrol::setFocusBody(FolderListItem * i)
{
    sgCoord    boxpos;
    float bodyz=0.0f;
    int typ=0;
    
     // enable or disable VIEWBOX
     if(i->body != NULL)
     {
       
      if(i->body->boxobjtrans != NULL)
      {
        sgSetCoord ( & boxpos, 0,  0, 0, 0, 0, 0 ) ;
        if(i->GetValue("viewbox").toInt() == 0)
        {
          i->body->boxobjtrans -> setTransform ( & boxpos,0.0f,0.0f,0.0f) ;
        }
        else
        {
          i->body->boxobjtrans -> setTransform ( & boxpos,1.0f,1.0f,1.0f) ;
        }
      }

      // ode

      if(i->GetValue("box").toInt() == 1)
      {
        typ=0;
      }
      if(i->GetValue("cylinder").toInt() == 1)
      {
        typ=1;
      }
      if(i->GetValue("sphere").toInt() == 1)
      {
        typ=2;
      }
      i->body->typ(odspace, typ);
   
      if(i->GetValue("on").toInt() == 0)
      {
        bodyz = OBJ_OFF ;
      }
      else
      {
        bodyz = i->GetValue("z").toFloat() ;
      }
      i->body->Scale (i->GetValue("scax").toFloat(), i->GetValue("scay").toFloat(), i->GetValue("scaz").toFloat());
      i->body->adjustMass(i->GetValue("mass").toFloat());

      i->body->pos.xyz[0] = i->GetValue("x").toFloat();
      i->body->pos.xyz[1] = i->GetValue("y").toFloat();
      i->body->pos.xyz[2] = bodyz;

      i->body->pos.hpr[0] = i->GetValue("rotx").toFloat();
      i->body->pos.hpr[1] = i->GetValue("roty").toFloat();
      i->body->pos.hpr[2] = i->GetValue("rotz").toFloat();

      i->body->lvel[0] = i->GetValue("lvx").toFloat();
      i->body->lvel[1] = i->GetValue("lvy").toFloat();
      i->body->lvel[2] = i->GetValue("lvz").toFloat();

      i->body->avel[0] = i->GetValue("avx").toFloat();
      i->body->avel[1] = i->GetValue("avy").toFloat();
      i->body->avel[2] = i->GetValue("avz").toFloat();
      
      i->body->SetPosition ();

     }
     else
     {
          qWarning(  "setFocusBody No Barrier Object " );
     }
     setFocus(i);
}

void Glcontrol::setFocusLamp(FolderListItem * i)
{
    char mybuff[256];
    unsigned int colorr;
    unsigned int colorg;
    unsigned int colorb;
    int number;
    
    if(i->objtrans != NULL)
    {
        number =  i->GetValue("number").toInt();
        if(number >= 0 && number <=7)
        {
            i->light=ssgGetLight(number);   // ? the lamps are Global ????
        
            strncpy(mybuff,i->GetValue("color_amb"),8);
            sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
            i->light->setColour(GL_AMBIENT,(float)colorr/255,(float)colorg/255,(float)colorb/255);

            strncpy(mybuff,i->GetValue("color_dif"),8);
            sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
            i->light->setColour(GL_DIFFUSE,(float)colorr/255,(float)colorg/255,(float)colorb/255);

            strncpy(mybuff,i->GetValue("color_spe"),8);
            sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
            i->light->setColour(GL_SPECULAR,(float)colorr/255,(float)colorg/255,(float)colorb/255);

            i->light->setPosition(i->GetValue("x").toFloat(),i->GetValue("y").toFloat(),i->GetValue("z").toFloat());
            i->light->setSpotDirection(i->GetValue("sx").toFloat(),i->GetValue("sy").toFloat(),i->GetValue("sz").toFloat());
            i->light->setSpotDiffusion(i->GetValue("sdexpo").toFloat(),i->GetValue("sdcut").toFloat());

            if(i->GetValue("on").toInt()==0)
              i->light->off();
            else
              i->light->on();

            if(i->GetValue("spotlight").toInt()==0)
              i->light->setSpotlight(0);
            else
              i->light->setSpotlight(1);

            if(i->GetValue("headlight").toInt()==0)
              i->light->setHeadlight(0);
            else
              i->light->setHeadlight(1);

            globj = i->objtrans;

            setXTrans( i->GetValue("x").toFloat() );
            setYTrans( i->GetValue("y").toFloat() );
            if(i->GetValue("lensflare").toInt() == 0 || i->GetValue("on").toInt() == 0)
            {
                setZTrans( OBJ_OFF );
            }
            else
            {
               setZTrans( i->GetValue("z").toFloat() );
            }

            setXRotation( i->GetValue("rotx").toFloat() );
            setYRotation( i->GetValue("roty").toFloat() );
            setZRotation( i->GetValue("rotz").toFloat() );

            setXScale( i->GetValue("scax").toFloat() );
            setYScale( i->GetValue("scay").toFloat() );
            setZScale( i->GetValue("scaz").toFloat() );

            focusitem = i;
       }
    }
    else
    {
        globj=NULL;
    }
}


void Glcontrol::setFocusFog(FolderListItem * i)
{
    char mybuff[256];
    unsigned int colorr;
    unsigned int colorg;
    unsigned int colorb;

      if(i->GetValue("on").toInt() == 0)
      {
        gl_fog=0;
      }
      else
      {
        gl_fog=1;
      }
      strncpy(mybuff,i->GetValue("color"),8);
      sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
      sgSetVec4 ( skyfogcol, 0.2, (float)colorr/255, (float)colorg/255,(float)colorb/255 ) ;

      fogdensity=i->GetValue("density").toFloat();
      
      fogstart=i->GetValue("start").toFloat();
      fogend=i->GetValue("end").toFloat();


      if(i->GetValue("linear").toInt() == 1)
      {
        fogmode=0;
      }
      if(i->GetValue("exp").toInt() == 1)
      {
        fogmode=1;
      }
      if(i->GetValue("exp2").toInt() == 1)
      {
        fogmode=2;
      }

      if(i->GetValue("dontcare").toInt() == 1)
      {
        foghint=0;
      }
      if(i->GetValue("fastest").toInt() == 1)
      {
        foghint=1;
      }
      if(i->GetValue("nicest").toInt() == 1)
      {
        foghint=2;
      }
      
      globj=NULL;
}

void Glcontrol::setFocusFire(FolderListItem * i)
{
    char mybuff[256];
    unsigned int colorr;
    unsigned int colorg;
    unsigned int colorb;
    sgVec4  firecol;
    
            i->fire->setUpwardSpeed(i->GetValue("speed").toFloat());
            i->fire->setHeight(i->GetValue("height").toFloat());
//            i->fire->setRadius(i->GetValue("radius").toFloat());

            strncpy(mybuff,i->GetValue("hotcolor"),8);
            sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
            sgSetVec4 ( firecol, (float)colorr/255,(float)colorg/255,(float)colorb/255, 1.0f ) ;
            i->fire->setHotColour(firecol);
            setFocus(i);
}

void  Glcontrol::setFocusSky(FolderListItem * i)
{
  ssgaCloudLayer     *cloud = NULL ;

  // sun
  bodies[0]->setRightAscension(i->GetValue("sunrotv").toFloat()*SGD_DEGREES_TO_RADIANS);
  bodies[0]->setDeclination(i->GetValue("sunroth").toFloat()*SGD_DEGREES_TO_RADIANS);
  
  // moon
  bodies[1]->setRightAscension(i->GetValue("moonrotv").toFloat()*SGD_DEGREES_TO_RADIANS);
  bodies[1]->setDeclination(i->GetValue("moonroth").toFloat()*SGD_DEGREES_TO_RADIANS);

  cloud = i->sky->getCloud(0);
  if(i->GetValue("cl1on").toInt() == 0)
      {
        cloud -> disable();
      }
      else
      {
        cloud -> enable();
      }
  cloud -> setElevation ( i->GetValue("cl1h").toFloat() ) ;
  cloud -> setSpeed ( i->GetValue("cl1s").toFloat() ) ;
  cloud -> setDirection ( i->GetValue("cl1d").toFloat() ) ;

  cloud = i->sky->getCloud(1);
  if(i->GetValue("cl2on").toInt() == 0)
      {
        cloud -> disable();
      }
      else
      {
        cloud -> enable();
      }
  cloud -> setElevation ( i->GetValue("cl2h").toFloat() ) ;
  cloud -> setSpeed ( i->GetValue("cl2s").toFloat() ) ;
  cloud -> setDirection ( i->GetValue("cl2d").toFloat() ) ;

  cloud = i->sky->getCloud(2);
  if(i->GetValue("cl3on").toInt() == 0)
      {
        cloud -> disable();
      }
      else
      {
        cloud -> enable();
      }
  cloud -> setElevation ( i->GetValue("cl3h").toFloat() ) ;
  cloud -> setSpeed ( i->GetValue("cl3s").toFloat() ) ;
  cloud -> setDirection ( i->GetValue("cl3d").toFloat() ) ;
}

void Glcontrol::setFocusSound(FolderListItem * i)
{
      sgCoord    boxpos;

#ifdef KCOPENAL

   if(i->GetValue("relativexyz").toInt() == 1)
   {
     i->sound->Relative(1);
   }
   else
   {
     i->sound->Relative(0);
   }
   i->sound->adjustVolume(i->GetValue("volume").toFloat());

       if(i->sound->boxobjtrans != NULL)
       {
        sgSetCoord ( & boxpos, 0,  0, 0, 0, 0, 0 ) ;
        if(i->GetValue("viewbox").toInt() == 0)
        {
          i->sound->boxobjtrans -> setTransform ( & boxpos,0.0f,0.0f,0.0f) ;
        }
        else
        {
          i->sound->boxobjtrans -> setTransform ( & boxpos,1.0f,1.0f,1.0f) ;
        }
       }
   i->sound->pos.xyz[0] = i->GetValue("x").toFloat();
   i->sound->pos.xyz[1] = i->GetValue("y").toFloat();
   i->sound->pos.xyz[2] = i->GetValue("z").toFloat();
   i->sound->SetPosition();

   if(i->GetValue("loop").toInt() == 1)
   {
     i->sound->Loop(1);
   }
   else
   {
     i->sound->Loop(0);
   }


   if(i->GetValue("play").toInt() == 1)
   {
     i->sound->Play();
   }
   if(i->GetValue("play").toInt() == 0)
   {
     i->sound->Stop();
   }

#endif
     setFocus(i);
}

void  Glcontrol::setFocusSPL(FolderListItem * i)
{ 
    if(i->GetValue("on").toInt() == 1)
    {
        i->splprog->TurnOn();
    }
    else
    {
        i->splprog->TurnOff();
    }
}

void  Glcontrol::setFocusShader(FolderListItem * i)
{
    if(i->GetValue("on").toInt() == 1)
    {
        i->gshader->TurnOn();
    }
    else
    {
        i->gshader->TurnOff();
    }
}

void  Glcontrol::setFocusCursor(FolderListItem * i)
{
    if(i->GetValue("on").toInt() == 1)
    {
        i->cursor->TurnOn();
    }
    else
    {
        i->cursor->TurnOff();
    }
    i->cursor->x = i->GetValue("mx").toInt();
    i->cursor->y = i->GetValue("my").toInt();
}

void Glcontrol::setFocusGUIText(FolderListItem * i)
{
   char mybuff[256];
   unsigned int colorr;
   unsigned int colorg;
   unsigned int colorb;

  int w = puGetWindowWidth  () ;
  int h = puGetWindowHeight () ;
  
    if(i->GetValue("on").toInt() == 1)
    {
        i->guitext->reveal();
    }
    else
    {
        i->guitext->hide();
    }

    i->guitext->setText ( i->GetValue("label").latin1() ) ;

    strncpy(mybuff,i->GetValue("colorlabel"),8);
    sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
    i->guitext->setColour( PUCOL_LABEL, (float)colorr/255, (float)colorg/255,(float)colorb/255, 1.0f ) ;

    switch (i->GetValue("place").toInt())
    {
      case 0:
      // upperleft
      i->guitext->setPosition ( i->GetValue("x").toInt(), h - i->GetValue("y").toInt() ) ;
      break;

      case 1:
      // upperright
      i->guitext->setPosition ( w - i->GetValue("x").toInt() , h - i->GetValue("y").toInt() ) ;
      break;

      case 2:
      // lowerright
      i->guitext->setPosition ( w - i->GetValue("x").toInt() ,  i->GetValue("y").toInt() ) ;
      break;

      case 3:
      // lowerleft
      i->guitext->setPosition ( i->GetValue("x").toInt() , i->GetValue("y").toInt() ) ;
      break;

      case 4:
      // center
      i->guitext->setPosition ( (w/2) - i->GetValue("x").toInt() , (h/2) + i->GetValue("y").toInt() ) ;
      break;
    }
}

void Glcontrol::setFocusGUIButton(FolderListItem * i)
{
   char mybuff[256];
   unsigned int colorr;
   unsigned int colorg;
   unsigned int colorb;

  int w = puGetWindowWidth  () ;
  int h = puGetWindowHeight () ;

    if(i->GetValue("on").toInt() == 1)
    {
        i->guibutton->reveal();
    }
    else
    {
        i->guibutton->hide();
    }

    i->guibutton->setText ( i->GetValue("legend").latin1() ) ;
    i->guibutton->setSize ( i->GetValue("maxx").toInt(), i->GetValue("maxy").toInt() ) ;

    strncpy(mybuff,i->GetValue("colorlabel"),8);
    sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
    i->guibutton->setColour( PUCOL_LEGEND, (float)colorr/255, (float)colorg/255,(float)colorb/255, 1.0f ) ;

    switch (i->GetValue("place").toInt())
    {
      case 0:
      // upperleft
      i->guibutton->setPosition ( i->GetValue("x").toInt(), h - i->GetValue("y").toInt() ) ;
      break;

      case 1:
      // upperright
      i->guibutton->setPosition ( w - i->GetValue("x").toInt() , h - i->GetValue("y").toInt() ) ;
      break;

      case 2:
      // lowerright
      i->guibutton->setPosition ( w - i->GetValue("x").toInt() ,  i->GetValue("y").toInt() ) ;
      break;

      case 3:
      // lowerleft
      i->guibutton->setPosition ( i->GetValue("x").toInt() , i->GetValue("y").toInt() ) ;
      break;

      case 4:
      // center
      i->guibutton->setPosition ( (w/2) - i->GetValue("x").toInt() , (h/2) + i->GetValue("y").toInt() ) ;
      break;
    }

}

void Glcontrol::setFocusGUIOSButton(FolderListItem * i)
{
   char mybuff[256];
   unsigned int colorr;
   unsigned int colorg;
   unsigned int colorb;

  int w = puGetWindowWidth  () ;
  int h = puGetWindowHeight () ;

    if(i->GetValue("on").toInt() == 1)
    {
        i->guiosbutton->reveal();
    }
    else
    {
        i->guiosbutton->hide();
    }

    i->guiosbutton->setText ( i->GetValue("legend").latin1() ) ;
    i->guiosbutton->setSize ( i->GetValue("maxx").toInt(), i->GetValue("maxy").toInt() ) ;

    strncpy(mybuff,i->GetValue("colorlabel"),8);
    sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
    i->guiosbutton->setColour( PUCOL_LEGEND, (float)colorr/255, (float)colorg/255,(float)colorb/255, 1.0f ) ;

    switch (i->GetValue("place").toInt())
    {
      case 0:
      // upperleft
      i->guiosbutton->setPosition ( i->GetValue("x").toInt(), h - i->GetValue("y").toInt() ) ;
      break;

      case 1:
      // upperright
      i->guiosbutton->setPosition ( w - i->GetValue("x").toInt() , h - i->GetValue("y").toInt() ) ;
      break;

      case 2:
      // lowerright
      i->guiosbutton->setPosition ( w - i->GetValue("x").toInt() ,  i->GetValue("y").toInt() ) ;
      break;

      case 3:
      // lowerleft
      i->guiosbutton->setPosition ( i->GetValue("x").toInt() , i->GetValue("y").toInt() ) ;
      break;

      case 4:
      // center
      i->guiosbutton->setPosition ( (w/2) - i->GetValue("x").toInt() , (h/2) + i->GetValue("y").toInt() ) ;
      break;
    }
}

void Glcontrol::setFocusGUIInput(FolderListItem * i)
{
   char mybuff[256];
   unsigned int colorr;
   unsigned int colorg;
   unsigned int colorb;

  int w = puGetWindowWidth  () ;
  int h = puGetWindowHeight () ;

    if(i->GetValue("on").toInt() == 1)
    {
        i->guiinput->reveal();
    }
    else
    {
        i->guiinput->hide();
    }

    i->guiinput->setText ( i->GetValue("label").latin1() ) ;
    i->guiinput->setSize ( i->GetValue("maxx").toInt(), i->GetValue("maxy").toInt() ) ;

    strncpy(mybuff,i->GetValue("colorlabel"),8);
    sscanf(mybuff,"%02X%02X%02X",&colorr,&colorg,&colorb);
    i->guiinput->setColour( PUCOL_LABEL, (float)colorr/255, (float)colorg/255,(float)colorb/255, 1.0f ) ;

    switch (i->GetValue("place").toInt())
    {
      case 0:
      // upperleft
      i->guiinput->setPosition ( i->GetValue("x").toInt(), h - i->GetValue("y").toInt() ) ;
      break;

      case 1:
      // upperright
      i->guiinput->setPosition ( w - i->GetValue("x").toInt() , h - i->GetValue("y").toInt() ) ;
      break;

      case 2:
      // lowerright
      i->guiinput->setPosition ( w - i->GetValue("x").toInt() ,  i->GetValue("y").toInt() ) ;
      break;

      case 3:
      // lowerleft
      i->guiinput->setPosition ( i->GetValue("x").toInt() , i->GetValue("y").toInt() ) ;
      break;

      case 4:
      // center
      i->guiinput->setPosition ( (w/2) - i->GetValue("x").toInt() , (h/2) + i->GetValue("y").toInt() ) ;
      break;
    }
}

void Glcontrol::setFocusTerrain(FolderListItem * i)
{
    setFocus(i);
}

void Glcontrol::setFocusCamera(FolderListItem * i)
{

    i->usercam->bind( i->GetValue("bind").toInt() );
    
    i->usercam->camradius = i->GetValue("camradius").toFloat();
    i->usercam->camrotw = i->GetValue("camrotw").toFloat();
    i->usercam->camhight = i->GetValue("camhight").toFloat();

      // cameratyp
      if(i->GetValue("camfix").toInt() == 1)
      {
        i->usercam->camtyp = 1 ;
      }
      if(i->GetValue("cam2d").toInt() == 1)
      {
        i->usercam->camtyp = 2 ;
      }
      if(i->GetValue("camego").toInt() == 1)
      {
        i->usercam->camtyp = 3 ;
      }
    
    setFocus(i);    
}

void Glcontrol::setFocusWaveSys(FolderListItem * i)
{
    if(i->GetValue("envmap").toInt() == 1)
    {
      i->wavesys->setKidCallback   ( SSG_CALLBACK_PREDRAW , enableTexGen ) ;
      i->wavesys->setKidCallback   ( SSG_CALLBACK_POSTDRAW, disableTexGen ) ;
      i->wavesys->regenerate       () ;
    }
    else
    {
      i->wavesys->setKidCallback   ( SSG_CALLBACK_PREDRAW , NULL ) ;
      i->wavesys->setKidCallback   ( SSG_CALLBACK_POSTDRAW, NULL ) ;
      i->wavesys->regenerate       () ;
    }

    i->wavesys->setSize( i->GetValue("size").toFloat() );
    i->wavesys->setTexScale( i->GetValue("texsx").toFloat(), i->GetValue("texsx").toFloat());
    i->wavesys->setWindSpeed( i->GetValue("wspeed").toFloat());

    setFocus(i);
}

void  Glcontrol::viewCamera(FolderListItem * i)
{
    if(i->usercam != NULL)
    {
      i->usercam->view(my_context);
    }
}

void  Glcontrol::switchCamera(FolderListItem * i)
{
    g_usercam = i->usercam;
    globj=NULL;
}

void  Glcontrol::makemyCurrent()
{
    my_context->makeCurrent();
}

void Glcontrol::changeAttribute (FolderListItem * i, char *attr, char *value)
{
    i->SetValue(attr,value);
    if(i->text(1) == "OBJECT")
    {
       setFocusObject(i);
    }
    if(i->text(1) == "BARRIER")
    {
       setFocusBarrier(i);
    }
    if(i->text(1) == "BODY")
    {
       setFocusBody(i);
    }
    if(i->text(1) == "FOG")
    {
       setFocusFog(i);
    }
    if(i->text(1) == "GUI-BUTTON")
    {
       setFocusGUIButton(i);
    }
    if(i->text(1) == "GUI-OSBUTTON")
    {
       setFocusGUIOSButton(i);
    }
    if(i->text(1) == "GUI-INPUT")
    {
       setFocusGUIInput(i);
    }
    if(i->text(1) == "GUI-TXT")
    {
       setFocusGUIText(i);
    }
    if(i->text(1) == "LAMP")
    {
       setFocusLamp(i);
    }
    if(i->text(1) == "PLAYER")
    {
       setFocusPlayer(i);
    }
    if(i->text(1) == "SCENE")
    {
       setFocusScene(i);
    }
    if(i->text(1) == "SKY")
    {
       setFocusSky(i);
    }
    if(i->text(1) == "TERRAIN")
    {
       setFocusTerrain(i);
    }
    if(i->text(1) == "SOUND")
    {
       setFocusSound(i);
    }
    if(i->text(1) == "WAVESYS")
    {
       setFocusWaveSys(i);
    }
    if(i->text(1) == "CURSOR")
    {
       setFocusCursor(i);
    }
}

void  Glcontrol::switchScene(FolderListItem * i)
{
  int a;
  int tmpplaymode;

  StopSound();
  tmpplaymode=g_playmode;
  g_playmode = 0;
  gtimer->stop();
  while(gtimer->isActive() );
         
  // otherwise switch with wavesys will crash but why ??
  ulMilliSecondSleep ( 100 ) ;    
  i->gl=this;
  setCaption( tr( i->text(0) ) );
  DeleteScene();
  initFolderListItem(i,g_prjpath);
  setFocusScene(i);
  
  // compile the spl program

  for(a=0;a<MAX_SPL;a++)
  {
    if(gl_spl_obj[a] != NULL)
    {
      gl_spl_obj[a]->compile();
    }
  }

  gtimer->start(TIMER_INTERVAL);
  g_playmode=tmpplaymode;
  i->gl->globj=NULL;

  qWarning(  "switch Scene OK " );

}

void  Glcontrol::StopSound()
{
  int a;
    // Stop Sounds
    for(a=0;a<MAX_LIST_ITEMS;a++)
    {
      if(g_ListItem[a] != NULL)
      {
          if(g_ListItem[a]->text(1) == "SOUND")
          {
            if(g_ListItem[a]->sound != NULL)
            {
               g_ListItem[a]->sound->Stop();
            }
          }
      }
    }
}

void  Glcontrol::getPoint(int x, int y, sgVec3 *poi)
{
    sgVec3 old_poi;
    sgVec3 my_poi;

    my_context->getPOI(&old_poi);
    my_context->setPOI(x,y);
    my_context->getPOI(&my_poi);
    sgCopyVec3( *poi, my_poi);
    my_context->setPOI(old_poi);

/*  
      qWarning("QC: mx:%i my:%i",g_mouse_x,g_mouse_y);
      qWarning("QC: x:%f y:%f z:%f",g_poi[0],g_poi[1],g_poi[2]);
      qWarning("getPoint: mx:%i my:%i",x,y);
      qWarning("getPoint: x:%f y:%f z:%f",my_poi[0],my_poi[1],my_poi[2]);
*/
}



