/*
 * 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_PATH_IDENTIFIER_HH_INCLUDED
#define PEEKABOT_PATH_IDENTIFIER_HH_INCLUDED


#include <string>
#include <stdexcept>

#include "Types.hh"
#include "serialization/SerializationInterface.hh"
#include "serialization/DeserializationInterface.hh"


namespace peekabot
{
    class SceneObject;
    class ServerExecutionContext;

    /**
     * \internal
     *
     * \brief PathIdentifier is an auxillary class that provides a single 
     * interface for referring to objects in the scene tree, independent of
     * whether the underlying identifier is an ObjectID, a path or a mixture of
     * a path and an object ID.
     */
    class PathIdentifier
    {
    public:
        PathIdentifier() throw();

        /**
         * \brief Construct a path identifier from a path relative the given
         * object.
         *
         * \param parent_id The object the path (\a rel_path) is specified 
         * relative to.
         * \param rel_path The path to the object relative \a parent_id.
         */
        PathIdentifier(ObjectID parent_id, const std::string &rel_path) 
            throw(std::runtime_error);

        /**
         * \brief Construct a path identifier from an absolute path.
         */
        PathIdentifier(const std::string &path) throw(std::runtime_error);

        /**
         * \brief Construct a path identifier from an object ID.
         */
        PathIdentifier(ObjectID id) throw();

#ifdef __PEEKABOT_SERVER
        SceneObject *get_parent(ServerExecutionContext *context) 
            const throw(std::runtime_error);

        SceneObject *get_leaf(ServerExecutionContext *context) 
            const throw(std::runtime_error);

        std::string get_leaf_name(ServerExecutionContext *context) 
            const throw(std::runtime_error);
#endif


        ObjectID get_parent_id() const throw() { return m_parent_id; }

        const std::string &get_path() const throw() { return m_path; }

        void set_parent_id(ObjectID parent_id) throw()
        {
            m_parent_id = parent_id;
        }

        void set_path(const std::string &path) throw() { m_path = path; }

    private:
        ObjectID m_parent_id;
        std::string m_path;
    };

    void save(
        SerializationInterface &ar, const PathIdentifier &path_ident);

    void load(
        DeserializationInterface &ar, PathIdentifier &path_ident, int version);
}


#endif // PEEKABOT_PATH_IDENTIFIER_HH_INCLUDED
