/*
 * Copyright Staffan Gimåker 2008-2010.
 *
 * ---
 *
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef PEEKABOT_CLIENT_CAMERA_PROXY_HH_INCLUDED
#define PEEKABOT_CLIENT_CAMERA_PROXY_HH_INCLUDED


#include "ObjectProxy.hh"


namespace peekabot
{
    namespace client
    {
        /**
         * \brief Base class for CameraProxy.
         */
        class PEEKABOT_API CameraProxyBase : public ObjectProxyBase
        {
        public:
            CameraProxyBase();

            CameraProxyBase(const CameraProxyBase &p);

            /**
             * \brief Set the field of view (FOV) of the camera.
             *
             * \param fov_deg The wanted \emph vertical FOV in degrees.
             */
            DelayedDispatch set_fov(float fov_deg);

            /**
             * \brief Set the zoom distance of the camera.
             *
             * Cameras are focused at their local origins. The viewer position
             * is calculated as the focus point plus the local x-axis multiplied
             * by a <em>zoom distance</em>.
             *
             * \param zoom_distance The distance to offset the viewer from
             * the focus. \a zoom_distance > 0.
             */
            DelayedDispatch set_zoom_distance(float zoom_distance);

            /**
             * \brief Toggles between orthographic and perspective rendering.
             *
             * \param orthographic Set to \c true and \c false for orthographic
             * and perspective rendering respectively.
             */
            DelayedDispatch set_orthographic(bool orthographic);
        };


        /**
         * \brief Proxy class used to add and manipulate cameras.
         */
        class PEEKABOT_API CameraProxy : public CameraProxyBase
        {
        public:
            CameraProxy();

            CameraProxy(const CameraProxyBase &p);

            CameraProxy &operator=(const CameraProxy &p);

            CameraProxy &operator=(const CameraProxyBase &p);

            /**
             * \copydoc ScalableProxy::assign(const ObjectProxyBase&)
             */
            DelayedDispatch assign(const ObjectProxyBase &p);

            /**
             * \copydoc ObjectProxy::assign(PeekabotClient&,const std::string&)
             */
            DelayedDispatch assign(
                PeekabotClient &client,
                const std::string &path);

            /**
             * \copydoc 
             * ObjectProxy::assign(const ObjectProxyBase&,const std::string&)
             */
            DelayedDispatch assign(
                const ObjectProxyBase &parent, 
                const std::string &rel_path);

            /**
             * \brief Add a camera to the scene.
             *
             * Adds a camera to the scene at the given path and assigns 
             * the proxy to point to it. If an object already exists at the 
             * given path the outcome is governed by \a conflict_policy.
             *
             * \param path The path where the object will be added, including 
             * the name of the object.
             * \param conflict_policy Determines how name conflicts are handled.
             */
            DelayedDispatch add(
                PeekabotClient &client,
                const std::string &path,
                NameConflictPolicy conflict_policy = AUTO_ENUMERATE_ON_CONFLICT);

            /**
             * \brief Add a camera to the scene.
             *
             * Adds a camera with the given name under the the object referred 
             * to by \a parent and assigns the proxy to point to it. If an 
             * object already exists at the given path the outcome is governed 
             * by \a conflict_policy.
             *
             * \param parent The parent under which the object will be added.
             * \param name The name to assign to the created object.
             * \param conflict_policy Determines how name conflicts are handled.
             */
            DelayedDispatch add(
                const ObjectProxyBase &parent, 
                const std::string &name,
                NameConflictPolicy conflict_policy = AUTO_ENUMERATE_ON_CONFLICT);
        };
    }
}


#endif // PEEKABOT_CLIENT_CAMERA_PROXY_HH_INCLUDED
