// 2011, Mathieu Turcotte
// www.mathieuturcotte.ca

#ifndef TTYM_WIN_HPP_
#define TTYM_WIN_HPP_

#include <windows.h>

namespace ttym {

namespace details {
// Saving the initial terminal attributes
// to build the reset value.
WORD SaveOriginalConsoleAttrs() {
    HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
    if (!stdout_handle || stdout_handle == INVALID_HANDLE_VALUE)
        return 0;
    CONSOLE_SCREEN_BUFFER_INFO buffer_info;
    GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
    return buffer_info.wAttributes;
}
const static WORD RESET_ATTRS = SaveOriginalConsoleAttrs();
}

// To save some typing.
#define COLOR_MANIPULATOR(name, color) \
template<typename Char> \
inline std::basic_ostream<Char>& \
name(std::basic_ostream<Char>& out) { \
    HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); \
    if (stdout_handle && stdout_handle != INVALID_HANDLE_VALUE) { \
        out.flush(); \
        SetConsoleTextAttribute(stdout_handle, color); \
    } \
    return out; \
}

#define NOP_MANIPULATOR(name) \
template<typename Char> \
inline std::basic_ostream<Char>& \
name(std::basic_ostream<Char>& out) { \
    return out; \
}

COLOR_MANIPULATOR(reset, details::RESET_ATTRS)
COLOR_MANIPULATOR(black, 0)
COLOR_MANIPULATOR(red, FOREGROUND_RED | FOREGROUND_INTENSITY)
COLOR_MANIPULATOR(green, FOREGROUND_GREEN | FOREGROUND_INTENSITY)
COLOR_MANIPULATOR(yellow, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
COLOR_MANIPULATOR(blue, FOREGROUND_BLUE | FOREGROUND_INTENSITY)
COLOR_MANIPULATOR(magenta, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
COLOR_MANIPULATOR(cyan, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
COLOR_MANIPULATOR(white, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY)

NOP_MANIPULATOR(bold)

#undef COLOR_MANIPULATOR
#undef NOP_MANIPULATOR

} // namespace ttym

#endif // TTYM_WIN_HPP_