/*=============================================================================
    Copyright (c) 2002-2003 Joel de Guzman
    Copyright (c) 2002 Juan Carlos Arevalo-Baeza
    Copyright (c) 2002-2003 Martin Wille
    http://spirit.sourceforge.net/

  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 BOOST_SPIRIT_IF_HPP
#define BOOST_SPIRIT_IF_HPP

#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    namespace impl {

    //////////////////////////////////
    // if-else-parser, holds two alternative parsers and a conditional functor
    // that selects between them.
    template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
    struct if_else_parser
        : public condition_evaluator<typename as_parser<CondT>::type>
        , public binary
        <
            typename as_parser<ParsableTrueT>::type,
            typename as_parser<ParsableFalseT>::type,
            parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
        >
    {
        typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT>  self_t;

        typedef as_parser<ParsableTrueT>            as_parser_true_t;
        typedef as_parser<ParsableFalseT>           as_parser_false_t;
        typedef typename as_parser_true_t::type     parser_true_t;
        typedef typename as_parser_false_t::type    parser_false_t;
        typedef as_parser<CondT>                    cond_as_parser_t;
        typedef typename cond_as_parser_t::type     condition_t;

        typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
        typedef condition_evaluator<condition_t>                       eval_t;

        if_else_parser
        (
            ParsableTrueT  const& p_true,
            ParsableFalseT const& p_false,
            CondT          const& cond_
        )
            : eval_t(cond_as_parser_t::convert(cond_))
            , base_t
                (
                    as_parser_true_t::convert(p_true),
                    as_parser_false_t::convert(p_false)
                )
        { }

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, nil_t>::type type;
        };

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result
                <parser_true_t, ScannerT>::type   then_result_t;
            typedef typename parser_result
                <parser_false_t, ScannerT>::type  else_result_t;

            typename ScannerT::iterator_t const  save(scan.first);

            std::ptrdiff_t length = this->evaluate(scan);
            if (length >= 0)
            {
                then_result_t then_result(this->left().parse(scan));
                if (then_result)
                {
                    length += then_result.length();
                    return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
                }
            }
            else
            {
                else_result_t else_result(this->right().parse(scan));
                if (else_result)
                {
                    length = else_result.length();
                    return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
                }
            }
            return scan.no_match();
        }
    };

    //////////////////////////////////
    // if-else-parser generator, takes the false-parser in brackets
    // and returns the if-else-parser.
    template <typename ParsableTrueT, typename CondT>
    struct if_else_parser_gen
    {
        if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
            : p_true(p_true_)
            , cond(cond_) {}

        template <typename ParsableFalseT>
        if_else_parser
        <
            ParsableTrueT,
            ParsableFalseT,
            CondT
        >
        operator[](ParsableFalseT const& p_false) const
        {
            return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
                (
                    p_true,
                    p_false,
                    cond
                );
        }

        ParsableTrueT const &p_true;
        CondT const &cond;
    };

    //////////////////////////////////
    // if-parser, conditionally runs a parser is a functor condition is true.
    // If the condition is fales, it fails the parse.
    // It can optionally become an if-else-parser through the member else_p.
    template <typename ParsableT, typename CondT>
    struct if_parser
        : public condition_evaluator<typename as_parser<CondT>::type>
        , public unary
        <
            typename as_parser<ParsableT>::type,
            parser<if_parser<ParsableT, CondT> > >
    {
        typedef if_parser<ParsableT, CondT>           self_t;
        typedef as_parser<ParsableT>                  as_parser_t;
        typedef typename as_parser_t::type            parser_t;

        typedef as_parser<CondT>                      cond_as_parser_t;
        typedef typename cond_as_parser_t::type       condition_t;
        typedef condition_evaluator<condition_t>      eval_t;
        typedef unary<parser_t, parser<self_t> >      base_t;

        if_parser(ParsableT const& p, CondT const& cond_)
            : eval_t(cond_as_parser_t::convert(cond_))
            , base_t(as_parser_t::convert(p))
            , else_p(p, cond_)
        {}

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, nil_t>::type type;
        };

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
            typename ScannerT::iterator_t const save(scan.first);

            std::ptrdiff_t length = this->evaluate(scan);
            if (length >= 0)
            {
                t_result_t then_result(this->subject().parse(scan));
                if (then_result)
                {
                    length += then_result.length();
                    return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
                }
                return scan.no_match();
            }
            return scan.empty_match();
        }

        if_else_parser_gen<ParsableT, CondT> else_p;
    };

    //////////////////////////////////
    // if-parser generator, takes the true-parser in brackets and returns the
    // if-parser.
    template <typename CondT>
    struct if_parser_gen
    {
        if_parser_gen(CondT const& cond_) : cond(cond_) {}

        template <typename ParsableT>
        if_parser
        <
            ParsableT,
            CondT
        >
        operator[](ParsableT const& subject) const
        {
            return if_parser<ParsableT, CondT>(subject, cond);
        }

        CondT const &cond;
    };

} // namespace impl

//////////////////////////////////
// if_p function, returns "if" parser generator

template <typename CondT>
impl::if_parser_gen<CondT>
if_p(CondT const& cond)
{
    return impl::if_parser_gen<CondT>(cond);
}

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif // BOOST_SPIRIT_IF_HPP
