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

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/detail/generate_to.hpp>
#include <boost/spirit/home/karma/detail/extract_from.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/container.hpp>

namespace boost { namespace spirit
{
    ///////////////////////////////////////////////////////////////////////////
    // Enablers
    ///////////////////////////////////////////////////////////////////////////
    template <>
    struct use_operator<karma::domain, proto::tag::complement> // enables ~
      : mpl::true_ {};

}}

namespace boost { namespace spirit { namespace traits // classification
{
    namespace detail
    {
        BOOST_MPL_HAS_XXX_TRAIT_DEF(char_generator_id)
    }

    template <typename T>
    struct is_char_generator : detail::has_char_generator_id<T> {};
}}}

namespace boost { namespace spirit { namespace karma
{
    ///////////////////////////////////////////////////////////////////////////
    // The base char_parser
    ///////////////////////////////////////////////////////////////////////////
    template <typename Derived, typename CharEncoding, typename Tag
      , typename Char = typename CharEncoding::char_type, typename Attr = Char>
    struct char_generator : primitive_generator<Derived>
    {
        typedef CharEncoding char_encoding;
        typedef Tag tag;
        typedef Char char_type;
        struct char_generator_id;

        // if Attr is unused_type, Derived must supply its own attribute
        // metafunction
        template <typename Context, typename Unused>
        struct attribute
        {
            typedef Attr type;
        };

        template <
            typename OutputIterator, typename Context, typename Delimiter
          , typename Attribute>
        bool generate(OutputIterator& sink, Context& context, Delimiter const& d
          , Attribute const& attr) const
        {
            if (!traits::has_optional_value(attr))
                return false;

            Attr ch = Attr();
            if (!this->derived().test(traits::extract_from<Attr>(attr, context), ch, context))
                return false;

            return karma::detail::generate_to(sink, ch, char_encoding(), tag()) &&
                   karma::delimit_out(sink, d);       // always do post-delimiting
        }

        // Requirement: g.test(attr, ch, context) -> bool
        //
        //  attr:       associated attribute
        //  ch:         character to be generated (set by test())
        //  context:    enclosing rule context
    };

    ///////////////////////////////////////////////////////////////////////////
    // negated_char_generator handles ~cg expressions (cg is a char_generator)
    ///////////////////////////////////////////////////////////////////////////
    template <typename Positive>
    struct negated_char_generator
      : char_generator<negated_char_generator<Positive>
          , typename Positive::char_encoding, typename Positive::tag>
    {
        negated_char_generator(Positive const& positive)
          : positive(positive) {}

        template <typename Attribute, typename CharParam, typename Context>
        bool test(Attribute const& attr, CharParam& ch, Context& context) const
        {
            return !positive.test(attr, ch, context);
        }

        template <typename Context>
        info what(Context& context) const
        {
            return info("not", positive.what(context));
        }

        Positive positive;
    };

    ///////////////////////////////////////////////////////////////////////////
    // Generator generators: make_xxx function (objects)
    ///////////////////////////////////////////////////////////////////////////
    namespace detail
    {
        template <typename Positive>
        struct make_negated_char_generator
        {
            typedef negated_char_generator<Positive> result_type;
            result_type operator()(Positive const& positive) const
            {
                return result_type(positive);
            }
        };

        template <typename Positive>
        struct make_negated_char_generator<negated_char_generator<Positive> >
        {
            typedef Positive result_type;
            result_type operator()(negated_char_generator<Positive> const& ncg) const
            {
                return ncg.positive;
            }
        };
    }

    template <typename Elements, typename Modifiers>
    struct make_composite<proto::tag::complement, Elements, Modifiers>
    {
        typedef typename
            fusion::result_of::value_at_c<Elements, 0>::type
        subject;

        BOOST_SPIRIT_ASSERT_MSG((
            traits::is_char_generator<subject>::value
        ), subject_is_not_negatable, (subject));

        typedef typename
            detail::make_negated_char_generator<subject>::result_type
        result_type;

        result_type operator()(Elements const& elements, unused_type) const
        {
            return detail::make_negated_char_generator<subject>()(
                fusion::at_c<0>(elements));
        }
    };

}}}

#endif
