/*
 * Copyright Staffan Gimåker 2008-2009.
 *
 * ---
 *
 * 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_VERTEX_BASED_PROXY_HH_INCLUDED
#define PEEKABOT_CLIENT_VERTEX_BASED_PROXY_HH_INCLUDED


#include <vector>

#include "ObjectProxy.hh"
#include "../DelayedDispatch.hh"
#include "../../Vector.hh"


namespace peekabot
{
    namespace client
    {
        /**
         * \brief A set of vertices, that's used to pass vertices to
         * vertex-based object proxies.
         */
        class PEEKABOT_API VertexSet
        {
            friend class VertexBasedProxyBase;

        public:
            void add_vertex(float x, float y, float z) throw();

            void clear() throw();

            size_t size() const throw();

            bool empty() const throw();

        private:
            std::vector<Vector3f> m_verts;
        };


        /**
         * \brief Base class for all proxies to vertex-based objects.
         */
        class PEEKABOT_API VertexBasedProxyBase : virtual public ObjectProxyBase
        {
        public:
            typedef peekabot::client::VertexSet VertexSet;


            VertexBasedProxyBase();

            VertexBasedProxyBase(const VertexBasedProxyBase &p);

            /**
             * \brief Set the vertices of the object.
             *
             * \param vertices The vertices to set the remote object's 
             * vertices to.
             */
            DelayedDispatch set_vertices(const VertexSet &vertices);

            /**
             * \brief Add one or more vertices to the object.
             *
             * \param vertices The vertices to add to the object.
             */
            DelayedDispatch add_vertices(const VertexSet &vertices);

            /**
             * \brief Add a single vertex to the object.
             *
             * \remark If you're adding several vertices, using 
             * add_vertices(const VertexSet &) is a lot more efficient.
             */
            DelayedDispatch add_vertex(float x, float y, float z);

            /**
             * \brief Remove all vertices of the remote object.
             */
            DelayedDispatch clear_vertices();
        };

        /**
         * \brief Proxy class usable with any type of object that is 
         * vertex-based.
         */
        class PEEKABOT_API VertexBasedProxy : public VertexBasedProxyBase
        {
        public:
            VertexBasedProxy();

            VertexBasedProxy(const VertexBasedProxyBase &p);

            VertexBasedProxy &operator=(const VertexBasedProxy &p) throw();

            VertexBasedProxy &operator=(const VertexBasedProxyBase &p) throw();

            /**
             * \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);
        };
    }
}


#endif // PEEKABOT_CLIENT_VERTEX_BASED_PROXY_HH_INCLUDED
