/*============================================================================
  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@/ios/fstream>
#include <@KWSYS_NAMESPACE@/Encoding.hxx>

namespace @KWSYS_NAMESPACE@
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
# if defined(_NOEXCEPT)
#  define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
# else
#  define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
# endif
  template<typename CharType,typename Traits>
  class basic_filebuf : public std::basic_filebuf<CharType,Traits>
  {
    public:
      typedef std::basic_filebuf<CharType,Traits> my_base_type;
      basic_filebuf *open(char const *s,std::ios_base::openmode mode)
      {
        return static_cast<basic_filebuf*>(
          my_base_type::open(Encoding::ToWide(s).c_str(), mode)
          );
      }
  };

  template<typename CharType,typename Traits = std::char_traits<CharType> >
  class basic_ifstream : public std::basic_istream<CharType,Traits>
  {
  public:
    typedef basic_filebuf<CharType,Traits> internal_buffer_type;
    typedef std::basic_istream<CharType,Traits> internal_stream_type;

    basic_ifstream() : internal_stream_type(new internal_buffer_type())
    {
      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())
    {
      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)
    {
      if(!buf_->open(file_name,mode | std::ios_base::in))
        {
        this->setstate(std::ios_base::failbit);
        }
      else
        {
        this->clear();
        }
    }
    bool is_open()
    {
      return buf_->is_open();
    }
    bool is_open() const
    {
      return buf_->is_open();
    }
    void close()
    {
      if(!buf_->close())
        {
        this->setstate(std::ios_base::failbit);
        }
      else
      {
        this->clear();
      }
    }

    internal_buffer_type *rdbuf() const
    {
      return buf_;
    }

    ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
    {
      buf_->close();
      delete buf_;
    }

  private:
    internal_buffer_type* buf_;
};

template<typename CharType,typename Traits = std::char_traits<CharType> >
class basic_ofstream : public std::basic_ostream<CharType,Traits>
{
  public:
  typedef basic_filebuf<CharType,Traits> internal_buffer_type;
  typedef std::basic_ostream<CharType,Traits> internal_stream_type;

  basic_ofstream() : internal_stream_type(new internal_buffer_type())
  {
  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())
  {
    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)
  {
    if(!buf_->open(file_name,mode | std::ios_base::out))
    {
    this->setstate(std::ios_base::failbit);
    }
    else
    {
    this->clear();
    }
  }
  bool is_open()
  {
    return buf_->is_open();
  }
  bool is_open() const
  {
    return buf_->is_open();
  }
  void close()
  {
    if(!buf_->close())
      {
      this->setstate(std::ios_base::failbit);
      }
    else
      {
      this->clear();
      }
  }

  internal_buffer_type *rdbuf() const
  {
    return buf_.get();
  }
  ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
  {
    buf_->close();
    delete buf_;
  }

  private:
  internal_buffer_type* buf_;
};

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

# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
#else
  using @KWSYS_NAMESPACE@_ios_namespace::ofstream;
  using @KWSYS_NAMESPACE@_ios_namespace::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
