/*
 * 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_GRID_PROXY_HH_INCLUDED
#define PEEKABOT_CLIENT_GRID_PROXY_HH_INCLUDED


#include "ScalableProxy.hh"
#include "LineBasedProxy.hh"


namespace peekabot
{
    namespace client
    {
        /**
         * \brief Base class for GridProxy.
         */
        class PEEKABOT_API GridProxyBase : public ScalableProxyBase,
                                           public LineBasedProxyBase
        {
        public:
            GridProxyBase();

            GridProxyBase(GridProxyBase &p);

            /**
             * \brief Change the number of segments in the grid.
             */
            DelayedDispatch set_segment_count(boost::uint32_t n);

            /**
             * \brief Change the grid type (regular, radial or angular) of the
             * remote grid.
             */
            DelayedDispatch set_grid_type(GridType type);

            /**
             * \brief Set the radial extent of the grid, only applicable for
             * radial and angular grids.
             *
             * \param central_angle The desired central angle, in radians. Must
             * be between 0 and 2pi.
             */
            DelayedDispatch set_central_angle(float central_angle);
        };


        /**
         * \brief Proxy class used to add and manipulate grids.
         *
         * The extent of the grids is manipulated by changing the scale, and 
         * altering the number of segments the grids is comprised of.
         */
        class PEEKABOT_API GridProxy : public GridProxyBase
        {
        public:
            GridProxy();

            GridProxy(GridProxyBase &p);

            GridProxy &operator=(const GridProxy &p);

            GridProxy &operator=(const GridProxyBase &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 grid to the scene.
             *
             * Adds a regular 1-segment grid to the scene at the given path and 
             * assigns the proxy to refer to it. If an object already exists at
             * the given path the outcome is governed by \a conflict_policy.
             *
             * Use set_grid_type(), set_segment_count() and set_central_angle()
             * to adjust the grid parameters once it's been created.
             *
             * \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 grid to the scene.
             *
             * Adds a regular 1-segment grid with the given name under the 
             * object referred to by \a parent and assigns the proxy to refer 
             * to it. If an object already exists at the given path the outcome
             * is governed by \a conflict_policy.
             *
             * Use set_grid_type(), set_segment_count() and set_central_angle()
             * to adjust the grid parameters once it's been created.
             *
             * \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_GRID_PROXY_HH_INCLUDED
