/*=============================================================================
    Copyright (c) 2001-2010 Joel de Guzman

    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)
==============================================================================*/
#if !defined(BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM)
#define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/home/qi/string/detail/tst.hpp>
#include <boost/unordered_map.hpp>
#include <boost/pool/object_pool.hpp>

namespace boost { namespace spirit { namespace qi
{
    struct tst_pass_through; // declared in tst.hpp

    template <typename Char, typename T>
    struct tst_map
    {
        typedef Char char_type; // the character type
        typedef T value_type; // the value associated with each entry
        typedef detail::tst_node<Char, T> node;

        tst_map()
        {
        }

        ~tst_map()
        {
            // Nothing to do here.
            // The pools do the right thing for us
        }

        tst_map(tst_map const& rhs)
        {
            copy(rhs);
        }

        tst_map& operator=(tst_map const& rhs)
        {
            return assign(rhs);
        }

        template <typename Iterator, typename Filter>
        T* find(Iterator& first, Iterator last, Filter filter) const
        {
            if (first != last)
            {
                Iterator save = first;
                typename map_type::const_iterator
                    i = map.find(filter(*first++));
                if (i == map.end())
                {
                    first = save;
                    return 0;
                }
                if (T* p = node::find(i->second.root, first, last, filter))
                {
                    return p;
                }
                return i->second.data;
            }
            return 0;
        }

        template <typename Iterator>
        T* find(Iterator& first, Iterator last) const
        {
            return find(first, last, tst_pass_through());
        }

        template <typename Iterator>
        bool add(
            Iterator first
          , Iterator last
          , typename boost::call_traits<T>::param_type val)
        {
            if (first != last)
            {
                map_data x = {0, 0};
                std::pair<typename map_type::iterator, bool>
                    r = map.insert(std::pair<Char, map_data>(*first++, x));

                if (first != last)
                {
                    return node::add(r.first->second.root
                      , first, last, val, this) ? true : false;
                }
                else
                {
                    if (r.first->second.data)
                        return false;
                    r.first->second.data = this->new_data(val);
                }
                return true;
            }
            return false;
        }

        template <typename Iterator>
        void remove(Iterator first, Iterator last)
        {
            if (first != last)
            {
                typename map_type::iterator i = map.find(*first++);
                if (i != map.end())
                {
                    if (first != last)
                    {
                        node::remove(i->second.root, first, last, this);
                    }
                    else if (i->second.data)
                    {
                        this->delete_data(i->second.data);
                        i->second.data = 0;
                    }
                    if (i->second.data == 0 && i->second.root == 0)
                    {
                        map.erase(i);
                    }
                }
            }
        }

        void clear()
        {
            BOOST_FOREACH(typename map_type::value_type& x, map)
            {
                node::destruct_node(x.second.root, this);
                if (x.second.data)
                    this->delete_data(x.second.data);
            }
            map.clear();
        }

        template <typename F>
        void for_each(F f) const
        {
            BOOST_FOREACH(typename map_type::value_type const& x, map)
            {
                std::basic_string<Char> s(1, x.first);
                node::for_each(x.second.root, s, f);
                if (x.second.data)
                    f(s, *x.second.data);
            }
        }

    private:

        friend struct detail::tst_node<Char, T>;

        struct map_data
        {
            node* root;
            T* data;
        };

        typedef unordered_map<Char, map_data> map_type;

        void copy(tst_map const& rhs)
        {
            BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
            {
                map_data xx = {node::clone_node(x.second.root, this), 0};
                if (x.second.data)
                    xx.data = data_pool.construct(*x.second.data);
                map[x.first] = xx;
            }
        }

        tst_map& assign(tst_map const& rhs)
        {
            if (this != &rhs)
            {
                BOOST_FOREACH(typename map_type::value_type& x, map)
                {
                    node::destruct_node(x.second.root, this);
                }
                map.clear();
                copy(rhs);
            }
            return *this;
        }

        node* new_node(Char id)
        {
            return node_pool.construct(id);
        }

        T* new_data(typename boost::call_traits<T>::param_type val)
        {
            return data_pool.construct(val);
        }

        void delete_node(node* p)
        {
            node_pool.destroy(p);
        }

        void delete_data(T* p)
        {
            data_pool.destroy(p);
        }

        map_type map;
        object_pool<node> node_pool;
        object_pool<T> data_pool;
    };
}}}

#endif
