/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#ifndef @KWSYS_NAMESPACE@_FStream_hxx
#define @KWSYS_NAMESPACE@_FStream_hxx

#include <@KWSYS_NAMESPACE@/Configure.hxx>
#include <@KWSYS_NAMESPACE@/Encoding.hxx>
#include <fstream>
#if defined(_WIN32)
# if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
#  include <ext/stdio_filebuf.h>
# endif
#endif

namespace @KWSYS_NAMESPACE@
{
#if defined(_WIN32) && (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H)
# if defined(_NOEXCEPT)
#  define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
# else
#  define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
# endif

#if defined(_MSC_VER)

  template<typename CharType,typename Traits>
  class basic_filebuf : public std::basic_filebuf<CharType,Traits>
  {
# if _MSC_VER >= 1400
    public:
      typedef std::basic_filebuf<CharType,Traits> my_base_type;
      basic_filebuf *open(char const *s,std::ios_base::openmode mode)
      {
        const std::wstring wstr = Encoding::ToWide(s);
        return static_cast<basic_filebuf*>(
          my_base_type::open(wstr.c_str(), mode)
          );
      }
# endif
  };

#else

  inline std::wstring getcmode(const std::ios_base::openmode mode) {
    std::wstring cmode;
    bool plus = false;
    if (mode & std::ios_base::app) {
      cmode += L"a";
      plus = mode & std::ios_base::in ? true : false;
    } else if (mode & std::ios_base::trunc ||
                (mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) {
      cmode += L"w";
      plus = mode & std::ios_base::in ? true : false;
    } else {
      cmode += L"r";
      plus = mode & std::ios_base::out ? true : false;
    }
    if (plus) {
      cmode += L"+";
    }
    if (mode & std::ios_base::binary) {
      cmode += L"b";
    } else {
      cmode += L"t";
    }
    return cmode;
  };

#endif

  template<typename CharType,typename Traits = std::char_traits<CharType> >
  class basic_efilebuf
  {
    public:
#if defined(_MSC_VER)
      typedef basic_filebuf<CharType,Traits> internal_buffer_type;
#else
      typedef __gnu_cxx::stdio_filebuf<CharType,Traits> internal_buffer_type;
#endif

      basic_efilebuf() : file_(0)
      {
        buf_ = 0;
      }

      bool _open(char const *file_name,std::ios_base::openmode mode)
      {
        if (is_open() || file_) {
          return false;
        }
#if defined(_MSC_VER)
        const bool success = buf_->open(file_name,mode) != 0;
#else
        const std::wstring wstr = Encoding::ToWide(file_name);
        bool success = false;
        std::wstring cmode = getcmode(mode);
        file_ = _wfopen(wstr.c_str(), cmode.c_str());
        if (file_) {
          if (buf_) {
            delete buf_;
          }
          buf_ = new internal_buffer_type(file_, mode);
          success = true;
        }
#endif
        return success;
      }

      bool is_open()
      {
        if (!buf_) {
          return false;
        }
        return buf_->is_open();
      }

      bool is_open() const
      {
        if (!buf_) {
          return false;
        }
        return buf_->is_open();
      }

      bool _close()
      {
        bool success = false;
        if (buf_) {
          success = buf_->close() != 0;
#if !defined(_MSC_VER)
          if (file_) {
            success = fclose(file_) == 0 ? success : false;
            file_ = 0;
          }
#endif
        }
        return success;
      }

      static void _set_state(bool success, std::basic_ios<CharType,Traits> *ios, basic_efilebuf* efilebuf)
      {
#if !defined(_MSC_VER)
        ios->rdbuf(efilebuf->buf_);
#endif
        if (!success) {
          ios->setstate(std::ios_base::failbit);
        } else {
          ios->clear();
        }
      }

      ~basic_efilebuf()
     {
       if (buf_) {
         delete buf_;
       }
     }

    protected:
      internal_buffer_type* buf_;
      FILE *file_;
  };

template<typename CharType,typename Traits = std::char_traits<CharType> >
class basic_ifstream : public std::basic_istream<CharType,Traits>,
                       public basic_efilebuf<CharType,Traits>
{
  using basic_efilebuf<CharType,Traits>::is_open;

  public:
    typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type internal_buffer_type;
    typedef std::basic_istream<CharType,Traits> internal_stream_type;

    basic_ifstream() : internal_stream_type(new internal_buffer_type())
    {
      this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
    }
    explicit basic_ifstream(char const *file_name,
                            std::ios_base::openmode mode = std::ios_base::in)
      : internal_stream_type(new internal_buffer_type())
    {
      this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
      open(file_name,mode);
    }

    void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in)
    {
      mode = mode | std::ios_base::in;
      this->_set_state(this->_open(file_name, mode), this, this);
    }

    void close()
    {
      this->_set_state(this->_close(), this, this);
    }

    internal_buffer_type *rdbuf() const
    {
      return this->buf_;
    }

    ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
    {
      close();
    }
};

template<typename CharType,typename Traits = std::char_traits<CharType> >
class basic_ofstream : public std::basic_ostream<CharType,Traits>,
                       public basic_efilebuf<CharType,Traits>
{
  using basic_efilebuf<CharType,Traits>::is_open;

  public:
  typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type internal_buffer_type;
  typedef std::basic_ostream<CharType,Traits> internal_stream_type;

  basic_ofstream() : internal_stream_type(new internal_buffer_type())
  {
    this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
  }
  explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) :
  internal_stream_type(new internal_buffer_type())
  {
    this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
    open(file_name,mode);
  }
  void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out)
  {
    mode = mode | std::ios_base::out;
    this->_set_state(this->_open(file_name, mode), this, this);
  }

  void close()
  {
    this->_set_state(this->_close(), this, this);
  }

  internal_buffer_type *rdbuf() const
  {
    return this->buf_;
  }

  ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
  {
    close();
  }
};

  typedef basic_ifstream<char> ifstream;
  typedef basic_ofstream<char> ofstream;

# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
#else
  using std::ofstream;
  using std::ifstream;
#endif

  namespace FStream
  {
    enum BOM
    {
      BOM_None,
      BOM_UTF8,
      BOM_UTF16BE,
      BOM_UTF16LE,
      BOM_UTF32BE,
      BOM_UTF32LE
    };

    // Read a BOM, if one exists.
    // If a BOM exists, the stream is advanced to after the BOM.
    // This function requires a seekable stream (but not a relative
    // seekable stream).
    BOM ReadBOM(std::istream& in);
  }
}

#endif
