//  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_OUTPUT_ITERATOR_MAY_26_2007_0506PM)
#define BOOST_SPIRIT_KARMA_OUTPUT_ITERATOR_MAY_26_2007_0506PM

#if defined(_MSC_VER)
#pragma once
#endif

#include <iterator>
#include <vector>
#include <algorithm>

#include <boost/config.hpp>
#include <boost/noncopyable.hpp>
#include <boost/mpl/if.hpp>

#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/support/iterators/ostream_iterator.hpp>
#include <boost/spirit/home/support/unused.hpp>

namespace boost { namespace spirit { namespace karma { namespace detail 
{
    ///////////////////////////////////////////////////////////////////////////
    //  This class is used to keep track of the current position in the output.
    ///////////////////////////////////////////////////////////////////////////
    class position_sink 
    {
    public:
        position_sink() : count(0), line(1), column(1) {}
        void tidy() { count = 0; line = 1; column = 1; }

        template <typename T>
        void output(T const& value) 
        {
            ++count; 
            if (value == '\n') {
                ++line;
                column = 1;
            }
            else {
                ++column;
            }
        }
        std::size_t get_count() const { return count; }
        std::size_t get_line() const { return line; }
        std::size_t get_column() const { return column; }

    private:
        std::size_t count;
        std::size_t line;
        std::size_t column;
    };

    ///////////////////////////////////////////////////////////////////////////
    struct position_policy
    {
        position_policy() {}
        position_policy(position_policy const& rhs) 
          : track_position_data(rhs.track_position_data) {}

        template <typename T>
        void output(T const& value) 
        { 
            // track position in the output 
            track_position_data.output(value);
        }

        // return the current count in the output
        std::size_t get_out_count() const
        {
            return track_position_data.get_count();
        }

    private:
        position_sink track_position_data;            // for position tracking
    };

    struct no_position_policy
    {
        no_position_policy() {}
        no_position_policy(no_position_policy const&) {}

        template <typename T>
        void output(T const& /*value*/) {}
    };

    ///////////////////////////////////////////////////////////////////////////
    //  This class is used to count the number of characters streamed into the 
    //  output.
    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator>
    class counting_sink : boost::noncopyable
    {
    public:
        counting_sink(OutputIterator& sink_, std::size_t count_ = 0
              , bool enabled = true) 
          : count(count_), initial_count(count), prev_count(0), sink(sink_)
        {
            prev_count = sink.chain_counting(enabled ? this : NULL);
        }
        ~counting_sink() 
        {
            if (prev_count)           // propagate count 
                prev_count->update_count(count-initial_count);
            sink.chain_counting(prev_count);
        }

        void output() 
        { 
            ++count; 
        }
        std::size_t get_count() const { return count; }

        // propagate count from embedded counters
        void update_count(std::size_t c)
        {
            count += c;
        }

    private:
        std::size_t count;
        std::size_t initial_count;
        counting_sink* prev_count;                // previous counter in chain
        OutputIterator& sink;
    };

    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator>
    struct counting_policy
    {
    public:
        counting_policy() : count(NULL) {}
        counting_policy(counting_policy const& rhs) : count(rhs.count) {}

        // functions related to counting
        counting_sink<OutputIterator>* chain_counting(
            counting_sink<OutputIterator>* count_data)
        {
            counting_sink<OutputIterator>* prev_count = count;
            count = count_data;
            return prev_count;
        }

        template <typename T>
        void output(T const&) 
        { 
            // count characters, if appropriate
            if (NULL != count)
                count->output();
        }

    private:
        counting_sink<OutputIterator>* count;      // for counting
    };

    struct no_counting_policy
    {
        no_counting_policy() {}
        no_counting_policy(no_counting_policy const&) {}

        template <typename T>
        void output(T const& /*value*/) {}
    };

    ///////////////////////////////////////////////////////////////////////////
    //  The following classes are used to intercept the output into a buffer
    //  allowing to do things like alignment, character escaping etc.
    ///////////////////////////////////////////////////////////////////////////
    class buffer_sink : boost::noncopyable
    {
    public:
        buffer_sink()
          : width(0) {}

        ~buffer_sink() 
        { 
            tidy(); 
        }

        void enable(std::size_t width_) 
        { 
            tidy();             // release existing buffer
            width = (width_ == std::size_t(-1)) ? 0 : width_;
            buffer.reserve(width); 
        }

        void tidy() 
        { 
            buffer.clear(); 
            width = 0; 
        }

        template <typename T>
        void output(T const& value)
        {
            BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(wchar_t));
            buffer.push_back(value);
        }

        template <typename OutputIterator_>
        bool copy(OutputIterator_& sink, std::size_t maxwidth) const 
        { 
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable: 4267)
#endif
            typename std::basic_string<wchar_t>::const_iterator end = 
                buffer.begin() + (std::min)(buffer.size(), maxwidth);

#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
            std::copy(buffer.begin(), end, sink);
            return true;
        }
        template <typename RestIterator>
        bool copy_rest(RestIterator& sink, std::size_t start_at) const 
        { 
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable: 4267)
#endif
            typename std::basic_string<wchar_t>::const_iterator begin = 
                buffer.begin() + (std::min)(buffer.size(), start_at);

#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
            std::copy(begin, buffer.end(), sink);
            return true;
        }

        std::size_t buffer_size() const 
        { 
            return buffer.size();
        }

    private:
        std::size_t width;
        std::basic_string<wchar_t> buffer;
    };

    ///////////////////////////////////////////////////////////////////////////
    struct buffering_policy
    {
    public:
        buffering_policy() : buffer(NULL) {}
        buffering_policy(buffering_policy const& rhs) : buffer(rhs.buffer) {}

        // functions related to buffering
        buffer_sink* chain_buffering(buffer_sink* buffer_data)
        {
            buffer_sink* prev_buffer = buffer;
            buffer = buffer_data;
            return prev_buffer;
        }

        template <typename T>
        bool output(T const& value) 
        { 
            // buffer characters, if appropriate
            if (NULL != buffer) {
                buffer->output(value);
                return false;
            }
            return true;
        }

        bool has_buffer() const { return NULL != buffer; }

    private:
        buffer_sink* buffer;
    };

    struct no_buffering_policy
    {
        no_buffering_policy() {}
        no_buffering_policy(no_counting_policy const&) {}

        template <typename T>
        bool output(T const& /*value*/) 
        {
            return true;
        }

        bool has_buffer() const { return false; }
    };

    ///////////////////////////////////////////////////////////////////////////
    //  forward declaration only
    template <typename OutputIterator> 
    struct enable_buffering;

    template <typename OutputIterator, typename Properties
      , typename Derived = unused_type>
    class output_iterator;

    ///////////////////////////////////////////////////////////////////////////
    template <typename Buffering, typename Counting, typename Tracking>
    struct output_iterator_base : Buffering, Counting, Tracking
    {
        typedef Buffering buffering_policy;
        typedef Counting counting_policy;
        typedef Tracking tracking_policy;

        output_iterator_base() {}
        output_iterator_base(output_iterator_base const& rhs) 
          : buffering_policy(rhs), counting_policy(rhs), tracking_policy(rhs)
        {}

        template <typename T>
        bool output(T const& value) 
        { 
            this->counting_policy::output(value);
            this->tracking_policy::output(value);
            return this->buffering_policy::output(value);
        }
    };

    template <typename Buffering, typename Counting, typename Tracking>
    struct disabling_output_iterator : Buffering, Counting, Tracking
    {
        typedef Buffering buffering_policy;
        typedef Counting counting_policy;
        typedef Tracking tracking_policy;

        disabling_output_iterator() : do_output(true) {}
        disabling_output_iterator(disabling_output_iterator const& rhs) 
          : buffering_policy(rhs), counting_policy(rhs), tracking_policy(rhs)
          , do_output(rhs.do_output)
        {}

        template <typename T>
        bool output(T const& value) 
        { 
            if (!do_output) 
                return false;

            this->counting_policy::output(value);
            this->tracking_policy::output(value);
            return this->buffering_policy::output(value);
        }

        bool do_output;
    };

    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator, typename Properties, typename Derived>
    struct make_output_iterator
    {
        // get the most derived type of this class
        typedef typename mpl::if_<
            traits::not_is_unused<Derived>, Derived
          , output_iterator<OutputIterator, Properties, Derived>
        >::type most_derived_type;

        enum { properties = Properties::value };

        typedef typename mpl::if_c<
            (properties & generator_properties::tracking) ? true : false
          , position_policy, no_position_policy
        >::type tracking_type;

        typedef typename mpl::if_c<
            (properties & generator_properties::buffering) ? true : false
          , buffering_policy, no_buffering_policy
        >::type buffering_type;

        typedef typename mpl::if_c<
            (properties & generator_properties::counting) ? true : false
          , counting_policy<most_derived_type>, no_counting_policy
        >::type counting_type;

        typedef typename mpl::if_c<
            (properties & generator_properties::disabling) ? true : false
          , disabling_output_iterator<buffering_type, counting_type, tracking_type>
          , output_iterator_base<buffering_type, counting_type, tracking_type>
        >::type type;
    };

    ///////////////////////////////////////////////////////////////////////////
    //  Karma uses an output iterator wrapper for all output operations. This
    //  is necessary to avoid the dreaded 'scanner business' problem, i.e. the
    //  dependency of rules and grammars on the used output iterator. 
    //
    //  By default the user supplied output iterator is wrapped inside an 
    //  instance of this internal output_iterator class. 
    //
    //  This output_iterator class normally just forwards to the embedded user
    //  supplied iterator. But it is possible to enable additional functionality
    //  on demand, such as counting, buffering, and position tracking.
    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator, typename Properties, typename Derived>
    class output_iterator 
      : public make_output_iterator<OutputIterator, Properties, Derived>::type
    {
    private:
        // base iterator type
        typedef typename make_output_iterator<
            OutputIterator, Properties, Derived>::type base_iterator;

    public:
        typedef std::output_iterator_tag iterator_category;
        typedef void value_type;
        typedef void difference_type;
        typedef void pointer;
        typedef void reference;

        explicit output_iterator(OutputIterator& sink_)
          : sink(&sink_)
        {}
        output_iterator(output_iterator const& rhs)
          : base_iterator(rhs), sink(rhs.sink)
        {}

        output_iterator& operator*() { return *this; }
        output_iterator& operator++() 
        { 
            if (!this->base_iterator::has_buffer())
                ++(*sink);           // increment only if not buffering
            return *this; 
        } 
        output_iterator operator++(int) 
        {
            if (!this->base_iterator::has_buffer()) {
                output_iterator t(*this);
                ++(*sink); 
                return t; 
            }
            return *this;
        }

#if defined(BOOST_MSVC)
// 'argument' : conversion from '...' to '...', possible loss of data
#pragma warning (push)
#pragma warning (disable: 4244)
#endif
        template <typename T>
        void operator=(T const& value) 
        { 
            if (this->base_iterator::output(value))
                *(*sink) = value; 
        }
#if defined(BOOST_MSVC)
#pragma warning (pop)
#endif

        // plain output iterators are considered to be good all the time
        bool good() const { return true; }

    protected:
        // this is the wrapped user supplied output iterator
        OutputIterator* sink;
    };

    ///////////////////////////////////////////////////////////////////////////
    template <typename T, typename Elem, typename Traits, typename Properties>
    class output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties>
      : public output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties
          , output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties> >
    {
    private:
        typedef output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties
          , output_iterator<karma::ostream_iterator<T, Elem, Traits>, Properties> 
        > base_type;
        typedef karma::ostream_iterator<T, Elem, Traits> base_iterator_type;
        typedef std::basic_ostream<Elem, Traits> ostream_type;

    public:
        output_iterator(base_iterator_type& sink)
          : base_type(sink) {}

        ostream_type& get_ostream() { return (*this->sink).get_ostream(); }
        ostream_type const& get_ostream() const { return (*this->sink).get_ostream(); }

        // expose good bit of underlying stream object
        bool good() const { return (*this->sink).get_ostream().good(); }
    };

    ///////////////////////////////////////////////////////////////////////////
    //  Helper class for exception safe enabling of character counting in the
    //  output iterator
    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator>
    struct enable_counting
    {
        enable_counting(OutputIterator& sink_, std::size_t count = 0)
          : count_data(sink_, count) {}

        // get number of characters counted since last enable
        std::size_t count() const
        {
            return count_data.get_count();
        }

    private:
        counting_sink<OutputIterator> count_data;              // for counting
    };

    template <typename OutputIterator>
    struct disable_counting
    {
        disable_counting(OutputIterator& sink_)
          : count_data(sink_, 0, false) {}

    private:
        counting_sink<OutputIterator> count_data;
    };

    ///////////////////////////////////////////////////////////////////////////
    //  Helper class for exception safe enabling of character buffering in the
    //  output iterator
    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator>
    struct enable_buffering
    {
        enable_buffering(OutputIterator& sink_
              , std::size_t width = std::size_t(-1))
          : sink(sink_), prev_buffer(NULL), enabled(false)
        {
            buffer_data.enable(width);
            prev_buffer = sink.chain_buffering(&buffer_data);
            enabled = true;
        }
        ~enable_buffering()
        {
            disable();
        }

        // reset buffer chain to initial state
        void disable()
        {
            if (enabled) {
                BOOST_VERIFY(&buffer_data == sink.chain_buffering(prev_buffer));
                enabled = false;
            }
        }

        // copy to the underlying sink whatever is in the local buffer
        bool buffer_copy(std::size_t maxwidth = std::size_t(-1)
          , bool disable_ = true)
        {
            if (disable_)
                disable();
            return buffer_data.copy(sink, maxwidth) && sink.good();
        }

        // return number of characters stored in the buffer
        std::size_t buffer_size() const
        {
            return buffer_data.buffer_size();
        }

        // copy to the remaining characters to the specified sink
        template <typename RestIterator>
        bool buffer_copy_rest(RestIterator& sink, std::size_t start_at = 0) const
        {
            return buffer_data.copy_rest(sink, start_at);
        }

        // copy the contents to the given output iterator
        template <typename OutputIterator_>
        bool buffer_copy_to(OutputIterator_& sink
          , std::size_t maxwidth = std::size_t(-1)) const
        {
            return buffer_data.copy(sink, maxwidth);
        }

    private:
        OutputIterator& sink;
        buffer_sink buffer_data;    // for buffering
        buffer_sink* prev_buffer;   // previous buffer in chain
        bool enabled;
    };

    ///////////////////////////////////////////////////////////////////////////
    //  Helper class for exception safe disabling of output
    ///////////////////////////////////////////////////////////////////////////
    template <typename OutputIterator>
    struct disable_output
    {
        disable_output(OutputIterator& sink_)
          : sink(sink_), prev_do_output(sink.do_output)
        {
            sink.do_output = false;
        }
        ~disable_output()
        {
            sink.do_output = prev_do_output;
        }

        OutputIterator& sink;
        bool prev_do_output;
    };

    ///////////////////////////////////////////////////////////////////////////
    template <typename Sink>
    bool sink_is_good(Sink const& sink)
    {
        return true;      // the general case is always good
    }

    template <typename OutputIterator, typename Derived>
    bool sink_is_good(output_iterator<OutputIterator, Derived> const& sink)
    {
        return sink.good(); // our own output iterators are handled separately
    }

}}}}

#endif 

