//  Copyright (c) 2001-2010 Hartmut Kaiser
// 
//  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_KARMA_SYMBOLS_NOV_23_2009_1251PM)
#define BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM

#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/reference.hpp>
#include <boost/spirit/home/karma/generate.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/detail/get_casetag.hpp>
#include <boost/spirit/home/karma/detail/string_generate.hpp>
#include <boost/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/mpl/if.hpp>
#include <map>
#include <set>

#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
    template <typename T, typename Attribute, typename Enable = void>
    struct symbols_lookup
    {
        typedef 
            mpl::eval_if<fusion::traits::is_sequence<T>
              , detail::value_at_c<T, 0>
              , detail::add_const_ref<T> > sequence_type;
        typedef typename 
            mpl::eval_if<traits::is_container<T>
              , traits::container_value<T>
              , sequence_type>::type type;

        // fusion sequence
        template <typename T_>
        static type call(T_ const& t, mpl::false_, mpl::true_)
        {
            return fusion::at_c<0>(t);
        }

        // container
        template <typename T_, typename IsSequence>
        static type call(T_ const& t, mpl::true_, IsSequence)
        {
            return t[0];
        }

        // not a container and not a fusion sequence
        template <typename T_>
        static type call(T_ const& t, mpl::false_, mpl::false_)
        {
            return t;
        }

        static type call(T const& t)
        {
            typedef typename traits::is_container<T>::type is_container;
            typedef typename fusion::traits::is_sequence<T>::type is_sequence;

            return call(t, is_container(), is_sequence());
        }
    };

    template <typename Attribute>
    struct symbols_lookup<Attribute, Attribute>
    {
        typedef Attribute const& type;

        static type call(Attribute const& t)
        {
            return t;
        }
    };

    template <typename Attribute, typename T, typename Enable = void>
    struct symbols_value
    {
        typedef 
            mpl::eval_if<fusion::traits::is_sequence<T>
              , detail::value_at_c<T, 1>
              , mpl::identity<unused_type> > sequence_type;
        typedef typename 
            mpl::eval_if<traits::is_container<T>
              , traits::container_value<T>
              , sequence_type>::type type;

        // fusion sequence
        template <typename T_>
        static type call(T_ const& t, mpl::false_, mpl::true_)
        {
            return fusion::at_c<1>(t);
        }

        // container
        template <typename T_, typename IsSequence>
        static type call(T_ const& t, mpl::true_, IsSequence)
        {
            return t[1];
        }

        // not a container nor a fusion sequence
        template <typename T_>
        static type call(T_ const& t, mpl::false_, mpl::false_)
        {
            return unused;
        }

        static type call(T const& t)
        {
            typedef typename traits::is_container<T>::type is_container;
            typedef typename fusion::traits::is_sequence<T>::type is_sequence;

            return call(t, is_container(), is_sequence());
        }
    };

    template <typename Attribute>
    struct symbols_value<Attribute, Attribute>
    {
        typedef unused_type type;

        static type call(Attribute const&)
        {
            return unused;
        }
    };
}}}

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
    ///////////////////////////////////////////////////////////////////////////
    template <typename T, typename Attribute>
    struct symbols_lookup
      : mpl::if_<
            traits::not_is_unused<T>
          , std::map<Attribute, T>
          , std::set<Attribute> 
        >
    {};

    ///////////////////////////////////////////////////////////////////////////
    namespace detail
    {
        ///////////////////////////////////////////////////////////////////////
        template <typename CharEncoding, typename Tag>
        struct generate_encoded
        {
            typedef typename 
                proto::terminal<tag::char_code<Tag, CharEncoding> >::type
            encoding_type;

            template <typename OutputIterator, typename Expr, typename Attribute>
            static bool call(OutputIterator& sink, Expr const& expr
              , Attribute const& attr)
            {
                encoding_type const encoding = encoding_type();
                return karma::generate(sink, encoding[expr], attr);
            }
        };

        template <>
        struct generate_encoded<unused_type, unused_type>
        {
            template <typename OutputIterator, typename Expr, typename Attribute>
            static bool call(OutputIterator& sink, Expr const& expr
              , Attribute const& attr)
            {
                return karma::generate(sink, expr, attr);
            }
        };
    }

    template <
        typename Attribute = char, typename T = unused_type
      , typename Lookup = typename symbols_lookup<T, Attribute>::type
      , typename CharEncoding = unused_type, typename Tag = unused_type>
    struct symbols
      : proto::extends<
            typename proto::terminal<
                reference<symbols<Attribute, T, Lookup, CharEncoding, Tag> >
            >::type
          , symbols<Attribute, T, Lookup, CharEncoding, Tag> >
      , primitive_generator<
            symbols<Attribute, T, Lookup, CharEncoding, Tag> >
    {
        typedef T value_type;       // the value associated with each entry

        typedef reference<symbols> reference_;
        typedef typename proto::terminal<reference_>::type terminal;
        typedef proto::extends<terminal, symbols> base_type;

        template <typename Context, typename Unused>
        struct attribute
        {
            typedef Attribute type;
        };

        symbols()
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {}

        symbols(symbols const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(syms.lookup)
        {}

        template <typename CharEncoding_, typename Tag_>
        symbols(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(syms.lookup)
        {}

        template <typename Symbols, typename Data>
        symbols(Symbols const& syms, Data const& data)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {
            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
            typename range_const_iterator<Data>::type di = boost::begin(data);
            while (si != boost::end(syms))
                add(*si++, *di++);
        }

        symbols&
        operator=(symbols const& rhs)
        {
            *lookup = *rhs.lookup;
            return *this;
        }

        template <typename CharEncoding_, typename Tag_>
        symbols&
        operator=(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& rhs)
        {
            *lookup = *rhs.lookup;
            return *this;
        }

        void clear()
        {
            lookup->clear();
        }

        struct adder;
        struct remover;

        template <typename Attr, typename T_>
        adder const&
        operator=(std::pair<Attr, T_> const& p)
        {
            lookup->clear();
            return add(p.first, p.second);
        }

        template <typename Attr, typename T_>
        friend adder const&
        operator+= (symbols& sym, std::pair<Attr, T_> const& p)
        {
            return sym.add(p.first, p.second);
        }

        template <typename Attr>
        friend remover const&
        operator-= (symbols& sym, Attr const& attr)
        {
            return sym.remove(attr);
        }

        // non-const version needed to suppress proto's += kicking in
        template <typename Attr, typename T_>
        friend adder const&
        operator+= (symbols& sym, std::pair<Attr, T_>& p)
        {
            return sym.add(p.first, p.second);
        }

        // non-const version needed to suppress proto's -= kicking in
        template <typename Attr>
        friend remover const&
        operator-= (symbols& sym, Attr& str)
        {
            return sym.remove(attr);
        }

        template <typename F>
        void for_each(F f) const
        {
            std::for_each(lookup->begin(), lookup->end(), f);
        }

        template <typename Attr>
        value_type* find(Attr const& attr)
        {
            typename Lookup::iterator it = lookup->find(attr);
            return (it != lookup->end()) ? &(*it).second : 0;
        }

        template <typename Attr>
        value_type& at(Attr const& attr)
        {
            return (*lookup)[attr];
        }

        ///////////////////////////////////////////////////////////////////////
        template <typename OutputIterator, typename Context, typename Delimiter
          , typename Attr>
        bool generate(OutputIterator& sink, Context&, Delimiter const& d
          , Attr const& attr) const
        {
            typename Lookup::iterator it = lookup->find(
                traits::symbols_lookup<Attr, Attribute>::call(attr));
            if (it == lookup->end())
                return false;

            return karma::detail::generate_encoded<CharEncoding, Tag>::call(
                        sink, (*it).second
                      , traits::symbols_value<Attribute, Attr>::call(attr)) && 
                   karma::delimit_out(sink, d);
        }

        template <typename Context>
        info what(Context&) const
        {
            return info("symbols");
        }

        ///////////////////////////////////////////////////////////////////////
        struct adder
        {
            template <typename, typename = unused_type>
            struct result { typedef adder const& type; };

            adder(symbols& sym)
              : sym(sym)
            {
            }

            template <typename Attr>
            adder const&
            operator()(Attr const& attr, T const& val = T()) const
            {
                sym.lookup->insert(typename Lookup::value_type(attr, val));
                return *this;
            }

            template <typename Attr>
            adder const&
            operator, (Attr const& attr) const
            {
                sym.lookup->insert(typename Lookup::value_type(attr, T()));
                return *this;
            }

            symbols& sym;

        private:
            // silence MSVC warning C4512: assignment operator could not be generated
            adder& operator= (adder const&);
        };

        struct remover
        {
            template <typename>
            struct result { typedef remover const& type; };

            remover(symbols& sym)
              : sym(sym)
            {
            }

            template <typename Attr>
            remover const&
            operator()(Attr const& attr) const
            {
                sym.lookup->erase(attr);
                return *this;
            }

            template <typename Attr>
            remover const&
            operator, (Attr const& attr) const
            {
                sym.lookup->erase(attr);
                return *this;
            }

            symbols& sym;

        private:
            // silence MSVC warning C4512: assignment operator could not be generated
            remover& operator= (remover const&);
        };

        adder add;
        remover remove;
        shared_ptr<Lookup> lookup;
    };

    ///////////////////////////////////////////////////////////////////////////
    // specialization for unused stored type
    template <
        typename Attribute, typename Lookup
      , typename CharEncoding, typename Tag>
    struct symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
      : proto::extends<
            typename proto::terminal<
                spirit::karma::reference<
                    symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
            >::type
          , symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
        >
      , spirit::karma::generator<
            symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
    {
        typedef unused_type value_type;  // the value associated with each entry

        typedef spirit::karma::reference<symbols> reference_;
        typedef typename proto::terminal<reference_>::type terminal;
        typedef proto::extends<terminal, symbols> base_type;

        template <typename Context, typename Unused>
        struct attribute
        {
            typedef Attribute type;
        };

        symbols()
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {}

        symbols(symbols const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(syms.lookup)
        {}

        template <typename CharEncoding_, typename Tag_>
        symbols(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(syms.lookup)
        {}

        template <typename Symbols, typename Data>
        symbols(Symbols const& syms, Data const& data)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {
            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
            typename range_const_iterator<Data>::type di = boost::begin(data);
            while (si != boost::end(syms))
                add(*si++, *di++);
        }

        symbols&
        operator=(symbols const& rhs)
        {
            *lookup = *rhs.lookup;
            return *this;
        }

        template <typename CharEncoding_, typename Tag_>
        symbols&
        operator=(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& rhs)
        {
            *lookup = *rhs.lookup;
            return *this;
        }

        void clear()
        {
            lookup->clear();
        }

        struct adder;
        struct remover;

        template <typename Attr>
        adder const&
        operator=(Attr const& attr)
        {
            lookup->clear();
            return add(attr);
        }

        template <typename Attr>
        friend adder const&
        operator+= (symbols& sym, Attr const& attr)
        {
            return sym.add(attr);
        }

        template <typename Attr>
        friend remover const&
        operator-= (symbols& sym, Attr const& attr)
        {
            return sym.remove(attr);
        }

        // non-const version needed to suppress proto's += kicking in
        template <typename Attr>
        friend adder const&
        operator+= (symbols& sym, Attr& attr)
        {
            return sym.add(attr);
        }

        // non-const version needed to suppress proto's -= kicking in
        template <typename Attr>
        friend remover const&
        operator-= (symbols& sym, Attr& str)
        {
            return sym.remove(attr);
        }

        template <typename F>
        void for_each(F f) const
        {
            std::for_each(lookup->begin(), lookup->end(), f);
        }

        template <typename Attr>
        value_type const* find(Attr const& attr)
        {
            typename Lookup::iterator it = lookup->find(attr);
            return (it != lookup->end()) ? &unused : 0;
        }

        template <typename Attr>
        value_type at(Attr const& attr)
        {
            typename Lookup::iterator it = lookup->find(attr);
            if (it == lookup->end()) 
                add(attr);
            return unused;
        }

        ///////////////////////////////////////////////////////////////////////
        template <typename OutputIterator, typename Context, typename Delimiter
          , typename Attr>
        bool generate(OutputIterator& sink, Context&, Delimiter const& d
          , Attr const& attr) const
        {
            typename Lookup::iterator it = lookup->find(
                traits::symbols_lookup<Attr, Attribute>::call(attr));
            if (it == lookup->end())
                return false;

            return karma::detail::generate_encoded<CharEncoding, Tag>::
                      call(sink
                        , traits::symbols_lookup<Attr, Attribute>::call(attr)
                        , unused) && 
                   karma::delimit_out(sink, d);
        }

        template <typename Context>
        info what(Context&) const
        {
            return info("symbols");
        }

        ///////////////////////////////////////////////////////////////////////
        struct adder
        {
            template <typename, typename = unused_type>
            struct result { typedef adder const& type; };

            adder(symbols& sym)
              : sym(sym)
            {
            }

            template <typename Attr>
            adder const&
            operator()(Attr const& attr) const
            {
                sym.lookup->insert(attr);
                return *this;
            }

            template <typename Attr>
            adder const&
            operator, (Attr const& attr) const
            {
                sym.lookup->insert(attr);
                return *this;
            }

            symbols& sym;

        private:
            // silence MSVC warning C4512: assignment operator could not be generated
            adder& operator= (adder const&);
        };

        struct remover
        {
            template <typename>
            struct result { typedef remover const& type; };

            remover(symbols& sym)
              : sym(sym)
            {
            }

            template <typename Attr>
            remover const&
            operator()(Attr const& attr) const
            {
                sym.lookup->erase(attr);
                return *this;
            }

            template <typename Attr>
            remover const&
            operator, (Attr const& attr) const
            {
                sym.lookup->erase(attr);
                return *this;
            }

            symbols& sym;

        private:
            // silence MSVC warning C4512: assignment operator could not be generated
            remover& operator= (remover const&);
        };

        adder add;
        remover remove;
        shared_ptr<Lookup> lookup;
    };

    ///////////////////////////////////////////////////////////////////////////
    // Generator generators: make_xxx function (objects)
    ///////////////////////////////////////////////////////////////////////////
    template <typename Attribute, typename T, typename Lookup
      , typename CharEnconding, typename Tag, typename Modifiers>
    struct make_primitive<
        reference<symbols<Attribute, T, Lookup, CharEnconding, Tag> >
      , Modifiers>
    {
        static bool const lower = 
            has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
        static bool const upper = 
            has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;

        typedef reference<
            symbols<Attribute, T, Lookup, CharEnconding, Tag> 
        > reference_;

        typedef typename mpl::if_c<
            lower || upper
          , symbols<
                Attribute, T, Lookup
              , typename spirit::detail::get_encoding_with_case<
                    Modifiers, unused_type, lower || upper>::type
              , typename detail::get_casetag<Modifiers, lower || upper>::type>
          , reference_>::type
        result_type;

        result_type operator()(reference_ ref, unused_type) const
        {
            return result_type(ref.ref.get());
        }
    };
}}}

#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif

#endif

