
#ifndef TINYSTL_OSTREAM
#define TINYSTL_OSTREAM

// fread/fwrite
#include <stdio.h>

// strlen
#include <memory.h>

// fprintf ...
#include <stdio.h>

#include <ios>

namespace std {
  
  /* This is just the start */
  
  class basic_ostream : virtual public basic_ios {
  public:
    
    basic_ostream () {};
    
    basic_ostream (FILE* f) {
      m_f = f;
    }

    basic_ostream (basic_streambuf* sb) {
      // TODO: streambuf = sb;
    }
    
    virtual ~basic_ostream () {};
    
    basic_ostream& operator<< (const char* cstr) {
      write (cstr, strlen (cstr));
      return *this;
    }

    basic_ostream& operator<< (char c) {
      put (c);
      return *this;
    }
    
    basic_ostream& operator<< (bool n) {
      fprintf (m_f, "%c", n ? '1' : '0');
      return *this;
    }

    basic_ostream& operator<< (short n) {
      const char* fmt;
      if (flags() & dec)
	fmt = "%d";
      else
	fmt = "%x";
      fprintf (m_f, fmt, n);
      return *this;
    }

    basic_ostream& operator<< (unsigned short n) {
      const char* fmt;
      if (flags() & dec)
	fmt = "%d";
      else
	fmt = "%x";
      fprintf (m_f, fmt, n);
      return *this;
    }
    
    basic_ostream& operator<< (int n) {
      const char* fmt;
      if (flags() & dec)
	fmt = "%d";
      else
	fmt = "%x";
      fprintf (m_f, fmt, n);
      return *this;
    }
    
    basic_ostream& operator<< (unsigned int n) {
      const char* fmt;
      if (flags() & dec)
	fmt = "%d";
      else
	fmt = "%x";
      fprintf (m_f, fmt, n);
      return *this;
    }

    basic_ostream& operator<< (long n) {
      const char* fmt;
      if (flags() & dec)
	fmt = "%ld";
      else
	fmt = "%lx";
      fprintf (m_f, fmt, n);
      return *this;
    }
    
    basic_ostream& operator<< (unsigned long n) {
      const char* fmt;
      if (flags() & dec)
	fmt = "%ld";
      else
	fmt = "%lx";
      fprintf (m_f, fmt, n);
      return *this;
    }
    
    basic_ostream& operator<< (float f) {
      fprintf (m_f, "%f", f);
      return *this;
    }
    
    basic_ostream& operator<< (double f) {
      fprintf (m_f, "%lf", f);
      return *this;
    }

    basic_ostream& operator<< (long double f) {
      fprintf (m_f, "%Lf", f);
      return *this;
    }

    basic_ostream& operator<< (void* p) {
      fprintf (m_f, "%p", p);
      return *this;
    }

    basic_ostream& operator << (basic_ostream& (*pf)(basic_ostream&)) {
      return pf(*this);
    }
    
    basic_ostream& put (char c) {
      fputc (c, m_f);
      return *this;
    }

    inline basic_ostream& flush () {
      fflush (m_f);
      return *this;
    }
    
    basic_ostream& write (const char* s, streamsize n) {
      fwrite (s, n, 1, m_f);
      return *this;
    }
    
    // TODO
    /*
      pos_type tellp();
      seekp(offset);
      seekp(offset,ros);
    */
       
  protected:
    FILE* m_f;
  };
  
  typedef basic_ostream ostream;
}

#endif // TINYSTL_OSTREAM
