/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Functor attached to a View that computes view matrix for chase-plane view.
 *//*
 * 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_VIEWPOINT_CHASE_HH
#define VIEW_VIEWPOINT_CHASE_HH 1

namespace object { class Object; }
using namespace object;
#include "view/viewpoint.hh"

namespace view {

////////////////////////////////////////////////////////////////////////////////
/// @brief Functor attached to a View that computes view matrix for chase-plane view.
/// See Viewpoint class.
///
class ChaseViewpoint : public Viewpoint
{
PREVENT_COPYING(ChaseViewpoint)
public:
                        ChaseViewpoint( void );
                        ~ChaseViewpoint( void );
protected:
    virtual Matrix      ComputeViewMatrix( shptr<View> view );

public:
    enum { AXIS_CHASE_PLANE_HORZ = ZZ,
           AXIS_CHASE_PLANE_VERT = XX };
private:
    struct State
    {
        State( void );
        shptr<Object>   mTarget;            ///< what chase-plane rotates around
        Vector3         mDistance;          ///< vector is transformed thru matrix to rotate chase-plane
        Vector3         mDistanceUnrotated; ///< unrotated vector
        Radian          mHorzAngle;
        Radian          mVertAngle;
    };

// Chase-plane methods:
public:
    void            Save( void );
    void            Reset( void );
    void            SetTarget( shptr<Object> target );
    shptr<Object>   GetTarget( void );
    void            SetDistance( const Vector3& distance );
    Vector3         GetDistance( void );
    void            Move( const fp inc );
    void            Rotate( const uint axis, const Radian rad );

// Data:
private:
    State           mState;         ///< current orientation of chase view
    State           mSavedState;    ///< saved orientation of chase view
public:
    DECLARE_TYPESIG(TYPESIG_CHASE_VIEWPOINT)
};

} // namespace view

#endif // VIEW_VIEWPOINT_CHASE_HH
