//===========================================================================
/*
    This file is part of the CHAI 3D visualization and haptics libraries.
    Copyright (C) 2003-2009 by CHAI 3D. All rights reserved.

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License("GPL") version 2
    as published by the Free Software Foundation.

    For using the CHAI 3D libraries with software that can not be combined
    with the GNU GPL, and for taking advantage of the additional benefits
    of our support services, please contact CHAI 3D about acquiring a
    Professional Edition License.

    \author    <http://www.chai3d.org>
    \author    Francois Conti
    \version   2.0.0 $Rev: 251 $
*/
//===========================================================================

//---------------------------------------------------------------------------
#ifndef CWorldH
#define CWorldH
//---------------------------------------------------------------------------
#include "extras/CGlobals.h"
#include "scenegraph/CCamera.h"
#include "scenegraph/CGenericObject.h"
#include "graphics/CTriangle.h"
#include "graphics/CTexture2D.h"
#include "graphics/CColor.h"
#include <vector>
//---------------------------------------------------------------------------
class cLight;
//---------------------------------------------------------------------------
//! The maximum number of lights that we expect OpenGL to support
#define CHAI_MAXIMUM_OPENGL_LIGHT_COUNT 8
//---------------------------------------------------------------------------

//===========================================================================
/*!
    \file       CWorld.h

    \brief 
    <b> Scenegraph </b> \n 
    Virtual World.
*/
//===========================================================================

//===========================================================================
/*!
    \class      cWorld
    \ingroup    scenegraph 

    \brief      
    cWorld defines the typical root of the CHAI scene graph. It stores 
    lights,  allocates textures, and serves as the root for scene-wide 
    collision detection.
*/
//===========================================================================
class cWorld : public cGenericObject
{
    
  public:
    
    //-----------------------------------------------------------------------
    // CONSTRUCTOR & DESTRUCTOR:
    //-----------------------------------------------------------------------

    //! Constructor of cWorld.
    cWorld();
    
    //! Destructor of cWorld.
    virtual ~cWorld();


    //-----------------------------------------------------------------------
    // METHODS:
    //-----------------------------------------------------------------------

    //! Set the background color used when rendering.
    void setBackgroundColor(const GLfloat a_red, 
                            const GLfloat a_green,
                            const GLfloat a_blue);

    //! Set the background color used when rendering.
    void setBackgroundColor(const cColorf& a_color);

    //! Get the background color used when rendering.
    cColorf getBackgroundColor() const { return (m_backgroundColor); }

    //! Enable or disable the rendering of this world's light sources.
    void enableLightSourceRendering(bool enable) { m_renderLightSources = enable; }

    //! Create a new bitmap texture.
    cTexture2D* newTexture();

    //! Get a pointer to a texture by passing an index into my texture list.
    cTexture2D* getTexture(unsigned int a_index) { return (m_textures[a_index]); };

    //! Add a texture to my texture list.
    void addTexture(cTexture2D* a_texture);

    //! Remove a texture from my texture list.
    bool removeTexture(cTexture2D* a_texture);

    //! Delete a texture.
    bool deleteTexture(cTexture2D* a_texture);

    //! Delete all textures.
    void deleteAllTextures();

    //! Compute collision detection between a ray segment and all objects in this world.
    virtual bool computeCollisionDetection(cVector3d& a_segmentPointA,
                                           cVector3d& a_segmentPointB,
                                           cCollisionRecorder& a_recorder,
                                           cCollisionSettings& a_settings);

    //! Render OpenGL lights.
    virtual void render(const int a_renderMode=0);

    //! Get access to a particular light source (between 0 and MAXIMUM_OPENGL_LIGHT_COUNT-1).
    virtual cLight* getLightSource(int index);  

    //! Resets textures and displays for the world.
    virtual void onDisplayReset(const bool a_affectChildren = true);
    
    //! It's useful to store the world's modelview matrix, for rendering stuff in "global" coordinates.
    double m_worldModelView[16];
    

protected:

    //-----------------------------------------------------------------------
    // FRIENDS:
    //-----------------------------------------------------------------------
    friend class cLight;


    //-----------------------------------------------------------------------
    // METHODS:
    //-----------------------------------------------------------------------

    //! Add a light source to this world.
    bool addLightSource(cLight* a_light);

    //! Remove a light source from this world.
    bool removeLightSource(cLight* a_light);


    //-----------------------------------------------------------------------
    // MEMBERS:
    //-----------------------------------------------------------------------

    //! Background color. Default color is black.
    cColorf m_backgroundColor;
    
    //! List of textures.
    vector<cTexture2D*> m_textures;
    
    //! List of light sources.
    vector<cLight*> m_lights;
    
    //! Should I render my light sources, or just use the current OpenGL light state?
    bool m_renderLightSources;    
    
    //! Some apps may have multiple cameras, which would cause recursion when resetting the display.
    bool m_performingDisplayReset;
};

//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

