/**
 * @file VectorLoggable.h
 * @author Bartosz Janiak
 * 
 * @brief Contains the definition of VectorLoggable class.
 *
 * Copyright © 2009 NVIDIA Corporation. All rights reserved.
 *
 * NVIDIA Corporation and its licensors retain all intellectual property and proprietary
 * rights in and to this software, related documentation and any modifications thereto. Any
 * use, reproduction, disclosure or distribution of this software and related documentation
 * without express license agreement from NVIDIA Corporation is strictly prohibited.
 */

#pragma once

#include "CompositeLoggable.h"
#include "LogContentsPrinter.h"
#include "StreamOperators.h"

#include "TStd.h"
#include <vector>

#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <boost/iterator/iterator_traits.hpp>

namespace Nvidia {
namespace Logging {

/**
 * @brief Used to wrap std::vector as a Loggable.
 *
 * @tparam T Type of the values stored in the wrapped vector.
 */
template <typename T>
class VectorLoggable : public CompositeLoggable
{
protected:
    /// @brief Begin iterator - where to start logging the vector from
    T m_begin;
    /// @brief End iterator - where to end the logging 
    T m_end;

public:

    /// @brief Constructor. Sets the wrapped vector using begin and end
    VectorLoggable(T begin, T end) : m_begin(begin), m_end(end) {}

    /**
     * @brief Passes all the elements of the wrapped vector to the LogContentsPrinter instance
       via LogContent() method.
     */
    virtual void LogContentsOn(LogContentsPrinter& logContentsPrinter) const
    {
        std::pair<T,T> tempPair = std::make_pair(m_begin, m_end);

        BOOST_FOREACH(typename boost::iterator_value<T>::type item, tempPair)
        {
            logContentsPrinter.LogContent(_T(""), item);
        }
    }

    /// @brief Returns the type of wrapped vector.
    virtual std::tstring GetTypeName() const
    {
        return _T("vector<") + boost::lexical_cast<std::tstring>(typeid(boost::iterator_value<T>::type).name()) + _T(">");
    }

    virtual std::tstring GetHumanReadableTypeName() const
    {
        return _T("vector");
    }

    /// @brief Returns 
    virtual std::tstring GetStringValue() const
    {
        return GetTypeName();
    }
};

template<typename T>
VectorLoggable<T> MakeVectorLoggable(T begin, T end)
{
    return VectorLoggable<T>(begin, end);
}

}
}