/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   View class.
 *//*
 * LEGAL:   COPYRIGHT (C) 2008 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef VIEW_VIEW_HH
#define VIEW_VIEW_HH 1

#include "gfx/module.hh"
#include "gfx/graphics.hh"
#include "gfx/rgba.hh"
using namespace gfx;
#include "graph/module.hh"
using namespace graph;
#include "object/module.hh"
using namespace object;
#include "view/viewpoint.hh"
using namespace view;
#if ! DOXYGEN
namespace osg { class Camera; }
#endif

namespace view {

////////////////////////////////////////////////////////////////////////////////
/// @brief View class (data struct).
///
/// View defines both a 2D viewport and 3D viewpoint.
/// The order of rendering Views is the same order Views were attached to Window.
///
/// OSG:
/// The View class abstracts osg::Camera (not osg::View).
/// osg::Camera defines the modelview matrix and viewport
/// which is what this View class is supposed to abstract.
///
class View : public Shared
{
PREVENT_COPYING(View)
public:
                        View( const bool enable,
                              const Rect<int>& rect,
                              shptr<Viewpoint> viewpoint,
                              RefPtr<osg::Camera> camera = new osg::Camera );
    virtual             ~View();

// Enablement:
    void                Enable( const bool enable = true );
    bool                IfEnabled( void ) { return mEnabled; }
    CLASS_METHOD void   EnableObjectInMainView( Object& object, const bool enableInMainView = true );

// View matrix, viewpoint:
    const Matrix&       GetViewMatrix( void ) { return mViewMatrix; }   // modelview
    void                SetViewMatrix( const Matrix& matrix );          // modelview
    void                ComputeViewMatrix( void );  // (for Window)
    WorldVertex         GetPosition( void );
    void                SetViewpoint( shptr<Viewpoint> viewpoint );
    void                LookAt( const Vector3& target, const Vector3& viewpoint );

// Transformation, projection:
    EyeVertex           TransformWorld2Eye( const WorldVertex& wv )
                        { CHECK_TYPESIG(this,TYPESIG_VIEW);
                          return wv * mViewMatrix; }  // transform world --> eye
    Vector2             Project( const WorldVertex& wv );
    bool                IF_Z_FACING( const WorldVertex& wv );

// Dimensions:
    void                SetRect( const Rect<int>& rect );
    Rect<int>           GetRect( void )
                        { CHECK_TYPESIG(this,TYPESIG_VIEW);
                          return mRect; }
// Sprite support:
    Degree              GetRollDegree( void );

// Misc:
    void                SetOutlineColor( const RGBA outlineColor )
                        { CHECK_TYPESIG(this,TYPESIG_VIEW);
                          mOutlineColor = outlineColor; }
    RGBA                GetOutlineColor( void )
                        { CHECK_TYPESIG(this,TYPESIG_VIEW);
                          return mOutlineColor; }

// OSG (LIMITED USE):
    RefPtr<osg::Camera> OsgGetCamera( void )
                        { CHECK_TYPESIG(this,TYPESIG_VIEW);
                          return mCamera; }
// Data:
private:
    bool                mEnabled;               ///< if false, not rendered
    Rect<int>           mRect;                  ///< will change by reshape event
    shptr<Viewpoint>    mViewpoint;             ///< computes view matrix
    RefPtr<osg::Camera> mCamera;                ///< correlates to OpenGL modelview matrix
    Matrix              mViewMatrix;            ///< modelview matrix
    Matrix              mProjectionMatrix;      ///< 3D --> 2D projection
    bool                mComputedViewMatrix;    ///< if ComputeViewMatrix() was ever called
    Degree              mRollDegree;            ///< supports Sprites
    RGBA                mOutlineColor;          ///< outline is draw around 2D viewpoint
public:
    DECLARE_TYPESIG(TYPESIG_VIEW)
};

} // namespace view

#endif // VIEW_VIEW_HH
