/**
* @file SimpleTextLogPrinter.h
* @author Bartosz Janiak
* 
* @brief Contains the definitions of ostream::operator<< overloads for various objects used in the logging system.
*
* 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 "TStd.h"
#include "Utils.h"
#include "LogLevel.h"
#include "Loggable.h"
#include <vector>

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/replace.hpp>

namespace Nvidia {
namespace Logging {

class Loggable;

}
}

//TODO: invalid w/ regards to C++ standard, needs fix
namespace std {

template<typename T>
std::tostream& operator<<(std::tostream& os, const std::vector<T>&)
{
    // We don't really want to create an instance of T.
    // Creating a pointer and cutting the " *" part from the type name instead.
    T *t;
    t = NULL;
    std::tstring typeName = boost::lexical_cast<std::tstring>(typeid(t).name());

    os << _T("vector<") << Nvidia::Logging::Utils::GenerateHumanReadableTypeName(typeName) << _T(">") ;
    return os;
}

inline std::tostream& operator<<(std::tostream& os, const Nvidia::Logging::Loggable& loggable)
{
    os << loggable.GetStringValue();
    return os;
}

inline std::tostream& operator<<(std::tostream& os, const Nvidia::Logging::LogLevel& logLevel)
{
    switch ( logLevel )
    {
    case Nvidia::Logging::LogLevel_System:
        os << _T("System"); 
        break;
    case Nvidia::Logging::LogLevel_Critical:
        os << _T("Critical"); 
        break;
    case Nvidia::Logging::LogLevel_Error:
        os << _T("Error"); 
        break;
    case Nvidia::Logging::LogLevel_Warning:
        os << _T("Warning"); 
        break;
    case Nvidia::Logging::LogLevel_Debug:
        os << _T("Debug"); 
        break;
    case Nvidia::Logging::LogLevel_Info:
        os << _T("Info"); 
        break;
    default:
        //this should not happen
        break;
    }

    return os;
}

}