/*=============================================================================
    Copyright (c) 2009 Daniel James

    Use, modification and distribution is subject to 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)
=============================================================================*/

#include <boost/program_options.hpp>
#include <iostream>
#include "input_path.hpp"
#include "utils.hpp"

#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
#include <boost/scoped_ptr.hpp>
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#endif

#if QUICKBOOK_CYGWIN_PATHS
#include <boost/scoped_array.hpp>
#include <boost/program_options/errors.hpp>
#include <sys/cygwin.h>
#endif

namespace quickbook {
    extern bool ms_errors;
}

namespace quickbook {
namespace detail {

// This is used for converting paths to UTF-8 on cygin.
// Might be better not to use a windows 
#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
    namespace {
        std::string to_utf8(std::wstring const& x)
        {
            int buffer_count = WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, 0, 0, 0, 0); 
        
            if (!buffer_count)
                throw conversion_error("Error converting wide string to utf-8.");
    
            boost::scoped_ptr<char> buffer(new char[buffer_count]);
    
            if (!WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count, 0, 0))
                throw conversion_error("Error converting wide string to utf-8.");
            
            return std::string(buffer.get());
        }

        std::wstring from_utf8(std::string const& x)
        {
            int buffer_count = MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, 0, 0); 
        
            if (!buffer_count)
                throw conversion_error("Error converting utf-8 to wide string.");
    
            boost::scoped_ptr<wchar_t> buffer(new wchar_t[buffer_count]);
    
            if (!MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count))
                throw conversion_error("Error converting utf-8 to wide string.");
            
            return std::wstring(buffer.get());
        }
    }
#endif

#if QUICKBOOK_WIDE_PATHS
    std::string input_to_utf8(input_string const& x)
    {
        return to_utf8(x);
    }
#else
    std::string input_to_utf8(input_string const& x)
    {
        return x;
    }
#endif

#if QUICKBOOK_WIDE_PATHS
    fs::path generic_to_path(std::string const& x)
    {
        return fs::path(from_utf8(x));
    }

    std::string path_to_generic(fs::path const& x)
    {
        return to_utf8(x.generic_wstring());
    }
#else
    fs::path generic_to_path(std::string const& x)
    {
        return fs::path(x);
    }

    std::string path_to_generic(fs::path const& x)
    {
        return x.generic_string();
    }

#endif

#if QUICKBOOK_CYGWIN_PATHS
    fs::path input_to_path(input_string const& path)
    {
        cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_W | CCP_RELATIVE;

        ssize_t size = cygwin_conv_path(flags, path.c_str(), NULL, 0);
        
        if (size < 0)
            throw conversion_error("Error converting cygwin path to windows.");

        // TODO: size is in bytes.
        boost::scoped_array<wchar_t> result(new wchar_t[size]);

        if(cygwin_conv_path(flags, path.c_str(), result.get(), size))
            throw conversion_error("Error converting cygwin path to windows.");

        return fs::path(result.get());
    }
    
    stream_string path_to_stream(fs::path const& path)
    {
        cygwin_conv_path_t flags = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;

        ssize_t size = cygwin_conv_path(flags, path.native().c_str(), NULL, 0);
        
        if (size < 0)
            throw conversion_error("Error converting windows path to cygwin.");

        boost::scoped_array<char> result(new char[size]);

        if(cygwin_conv_path(flags, path.native().c_str(), result.get(), size))
            throw conversion_error("Error converting windows path to cygwin.");

        return std::string(result.get());
    }
#else
    fs::path input_to_path(input_string const& path)
    {
        return fs::path(path);
    }

#if QUICKBOOK_WIDE_PATHS && !QUICKBOOK_WIDE_STREAMS
    stream_string path_to_stream(fs::path const& path)
    {
        return path.string();
    }
#else
    stream_string path_to_stream(fs::path const& path)
    {
        return path.native();
    }
#endif

#endif // QUICKBOOK_CYGWIN_PATHS

#if QUICKBOOK_WIDE_STREAMS

    void initialise_output()
    {
        if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT);
        if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT);
    }

    void write_utf8(ostream& out, std::string const& x)
    {
        out << from_utf8(x);
    }

    ostream& out()
    {
        return std::wcout;
    }

    namespace
    {
        inline ostream& error_stream()
        {
            return std::wcerr;
        }
    }

#else

    void initialise_output()
    {
    }

    void write_utf8(ostream& out, std::string const& x)
    {
        out << x;
    }

    ostream& out()
    {
        return std::cout;
    }

    namespace
    {
        inline ostream& error_stream()
        {
            return std::clog;
        }
    }

#endif

    ostream& outerr()
    {
        return error_stream() << "Error: ";
    }

    ostream& outerr(fs::path const& file, int line)
    {
        if (line >= 0)
        {
            if (ms_errors)
                return error_stream() << path_to_stream(file) << "(" << line << "): error: ";
            else
                return error_stream() << path_to_stream(file) << ":" << line << ": error: ";
        }
        else
        {
            return error_stream() << path_to_stream(file) << ": error: ";
        }
    }

    ostream& outwarn(fs::path const& file, int line)
    {
        if (line >= 0)
        {
            if (ms_errors)
                return error_stream() << path_to_stream(file) << "(" << line << "): warning: ";
            else
                return error_stream() << path_to_stream(file) << ":" << line << ": warning: ";
        }
        else
        {
            return error_stream() << path_to_stream(file) << ": warning: ";
        }
    }
}}
