//  Copyright (c) 2001-2010 Joel de Guzman
//  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_RULE_MAR_05_2007_0455PM)
#define BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/function.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>

#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/as_list.hpp>
#include <boost/fusion/include/as_vector.hpp>

#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/karma/reference.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp>
#include <boost/spirit/home/karma/nonterminal/detail/parameterized.hpp>

#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 karma
{
    BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)

    using spirit::_pass;
    using spirit::_val;
    using spirit::_a;
    using spirit::_b;
    using spirit::_c;
    using spirit::_d;
    using spirit::_e;
    using spirit::_f;
    using spirit::_g;
    using spirit::_h;
    using spirit::_i;
    using spirit::_j;

    using spirit::info;
    using spirit::locals;

    template <
        typename OutputIterator
      , typename T1 = unused_type
      , typename T2 = unused_type
      , typename T3 = unused_type
      , typename T4 = unused_type
    >
    struct rule
      : proto::extends<
            typename proto::terminal<
                reference<rule<OutputIterator, T1, T2, T3, T4> const>
            >::type
          , rule<OutputIterator, T1, T2, T3, T4>
        >
      , generator<rule<OutputIterator, T1, T2, T3, T4> >
    {
        typedef mpl::int_<generator_properties::all_properties> properties;

        typedef OutputIterator iterator_type;
        typedef rule<OutputIterator, T1, T2, T3, T4> this_type;
        typedef reference<this_type const> reference_;
        typedef typename proto::terminal<reference_>::type terminal;
        typedef proto::extends<terminal, this_type> base_type;
        typedef mpl::vector<T1, T2, T3, T4> template_params;

        // the output iterator is always wrapped by karma
        typedef detail::output_iterator<OutputIterator, properties> 
            output_iterator;

        // locals_type is a sequence of types to be used as local variables
        typedef typename
            spirit::detail::extract_locals<template_params>::type
        locals_type;

        // The delimiter-generator type
        typedef typename
            spirit::detail::extract_component<
                karma::domain, template_params>::type
        delimiter_type;

        // The rule's signature
        typedef typename
            spirit::detail::extract_sig<template_params>::type
        sig_type;

        // The rule's encoding type
        typedef typename
            spirit::detail::extract_encoding<template_params>::type
        encoding_type;

        // This is the rule's attribute type
        typedef typename
            spirit::detail::attr_from_sig<sig_type>::type
        attr_type;
        typedef typename add_reference<
            typename add_const<attr_type>::type>::type 
        attr_reference_type;

        // parameter_types is a sequence of types passed as parameters to the rule
        typedef typename
            spirit::detail::params_from_sig<sig_type>::type
        parameter_types;

        static size_t const params_size =
            fusion::result_of::size<parameter_types>::type::value;

        // the context passed to the right hand side of a rule contains
        // the attribute and the parameters for this particular rule invocation
        typedef context<
            fusion::cons<attr_reference_type, parameter_types>
          , locals_type>
        context_type;

        typedef function<
            bool(output_iterator&, context_type&, delimiter_type const&)>
        function_type;

        typedef typename
            mpl::if_<
                is_same<encoding_type, unused_type>
              , unused_type
              , tag::char_code<tag::encoding, encoding_type>
            >::type
        encoding_modifier_type;

        explicit rule(std::string const& name_ = "unnamed-rule")
          : base_type(terminal::make(reference_(*this)))
          , name_(name_)
        {
        }

        rule(rule const& rhs)
          : base_type(terminal::make(reference_(*this)))
          , name_(rhs.name_)
          , f(rhs.f)
        {
        }

        template <typename Expr>
        rule (Expr const& expr, std::string const& name_ = "unnamed-rule")
          : base_type(terminal::make(reference_(*this)))
          , name_(name_)
        {
            // Report invalid expression error as early as possible.
            // If you got an error_invalid_expression error message here, then
            // the expression (expr) is not a valid spirit karma expression.
            BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);

            f = detail::bind_generator<mpl::false_>(
                compile<karma::domain>(expr, encoding_modifier_type()));
        }

        rule& operator=(rule const& rhs)
        {
            // The following assertion fires when you try to initialize a rule
            // from an uninitialized one. Did you mean to refer to the right
            // hand side rule instead of assigning from it? In this case you 
            // should write lhs = rhs.alias();
            BOOST_ASSERT(rhs.f);

            f = rhs.f;
            name_ = rhs.name_;
            return *this;
        }

        std::string const& name() const
        {
            return name_;
        }

        void name(std::string const& str)
        {
            name_ = str;
        }

        template <typename Expr>
        rule& operator=(Expr const& expr)
        {
            // Report invalid expression error as early as possible.
            // If you got an error_invalid_expression error message here, then
            // the expression (expr) is not a valid spirit karma expression.
            BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);

            f = detail::bind_generator<mpl::false_>(
                compile<karma::domain>(expr, encoding_modifier_type()));
            return *this;
        }

// VC7.1 has problems to resolve 'rule' without explicit template parameters
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
        // g++ 3.3 barfs if this is a member function :(
        template <typename Expr>
        friend rule& operator%=(rule& r, Expr const& expr)
        {
            // Report invalid expression error as early as possible.
            // If you got an error_invalid_expression error message here, then
            // the expression (expr) is not a valid spirit karma expression.
            BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);

            r.f = detail::bind_generator<mpl::true_>(
                compile<karma::domain>(expr, encoding_modifier_type()));
            return r;
        }

        // non-const version needed to suppress proto's %= kicking in
        template <typename Expr>
        friend rule& operator%=(rule& r, Expr& expr)
        {
            return r %= static_cast<Expr const&>(expr);
        }
#else
        // both friend functions have to be defined out of class as VC7.1
        // will complain otherwise 
        template <typename OutputIterator_, typename T1_, typename T2_
          , typename T3_, typename T4_, typename Expr>
        friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
            rule<OutputIterator_, T1_, T2_, T3_, T4_>&r, Expr const& expr);

        // non-const version needed to suppress proto's %= kicking in
        template <typename OutputIterator_, typename T1_, typename T2_
          , typename T3_, typename T4_, typename Expr>
        friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
            rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr& expr);
#endif

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

        template <typename Context, typename Delimiter, typename Attribute>
        bool generate(output_iterator& sink, Context&, Delimiter const& delim
          , Attribute const& attr) const
        {
            if (f)
            {
                // Create an attribute if none is supplied. 
                typedef traits::make_attribute<attr_type, Attribute> 
                    make_attribute;
                typedef traits::transform_attribute<
                    typename make_attribute::type, attr_type, domain> 
                transform;

                typename transform::type attr_ = 
                    traits::pre_transform<domain, attr_type>(
                        make_attribute::call(attr));

                // If you are seeing a compilation error here, you are probably
                // trying to use a rule or a grammar which has inherited
                // attributes, without passing values for them.
                context_type context(attr_);

                // If you are seeing a compilation error here stating that the 
                // third parameter can't be converted to a karma::reference
                // then you are probably trying to use a rule or a grammar with 
                // an incompatible delimiter type.
                if (f(sink, context, delim))
                {
                    // do a post-delimit if this is an implied verbatim
                    if (is_same<delimiter_type, unused_type>::value)
                        karma::delimit_out(sink, delim);

                    return true;
                }
            }
            return false;
        }

        template <typename Context, typename Delimiter, typename Attribute
          , typename Params>
        bool generate(output_iterator& sink, Context& caller_context
          , Delimiter const& delim, Attribute const& attr
          , Params const& params) const
        {
            if (f)
            {
                // Create an attribute if none is supplied. 
                typedef traits::make_attribute<attr_type, Attribute> 
                    make_attribute;
                typedef traits::transform_attribute<
                    typename make_attribute::type, attr_type, domain> 
                transform;

                typename transform::type attr_ = 
                    traits::pre_transform<domain, attr_type>(
                        make_attribute::call(attr));

                // If you are seeing a compilation error here, you are probably
                // trying to use a rule or a grammar which has inherited
                // attributes, passing values of incompatible types for them.
                context_type context(attr_, params, caller_context);

                // If you are seeing a compilation error here stating that the 
                // third parameter can't be converted to a karma::reference
                // then you are probably trying to use a rule or a grammar with 
                // an incompatible delimiter type.
                if (f(sink, context, delim))
                {
                    // do a post-delimit if this is an implied verbatim
                    if (is_same<delimiter_type, unused_type>::value)
                        karma::delimit_out(sink, delim);

                    return true;
                }
            }
            return false;
        }

        template <typename Context>
        info what(Context& /*context*/) const
        {
            return info(name_);
        }

        reference_ alias() const
        {
            return reference_(*this);
        }

        typename proto::terminal<this_type>::type copy() const
        {
            typename proto::terminal<this_type>::type result = {*this};
            return result;
        }

        // bring in the operator() overloads
        rule const& get_parameterized_subject() const { return *this; }
        typedef rule parameterized_subject_type;
        #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>

        std::string name_;
        function_type f;
    };

#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
    template <typename OutputIterator_, typename T1_, typename T2_
      , typename T3_, typename T4_, typename Expr>
    rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
        rule<OutputIterator_, T1_, T2_, T3_, T4_>&r, Expr const& expr)
    {
        // Report invalid expression error as early as possible.
        // If you got an error_invalid_expression error message here, then
        // the expression (expr) is not a valid spirit karma expression.
        BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);

        typedef typename 
            rule<OutputIterator_, T1_, T2_, T3_, T4_>::encoding_modifier_type
        encoding_modifier_type;

        r.f = detail::bind_generator<mpl::true_>(
            compile<karma::domain>(expr, encoding_modifier_type()));
        return r;
    }

    // non-const version needed to suppress proto's %= kicking in
    template <typename OutputIterator_, typename T1_, typename T2_
      , typename T3_, typename T4_, typename Expr>
    rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
        rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr& expr)
    {
        return r %= static_cast<Expr const&>(expr);
    }
#endif
}}}

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

#endif
