// ---------------------------------------------------------------------------
// - Output.hpp                                                              -
// - standard object library - output stream base class definition           -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2006 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef AFNIX_OUTPUT_HPP
#define AFNIX_OUTPUT_HPP

#ifndef AFNIX_STREAM_HPP
#include "Stream.hpp"
#endif

#ifndef AFNIX_EXCEPTION_HPP
#include "Exception.hpp"
#endif

namespace afnix {

  /// The Output stream class is a base class which provides a write method for
  /// character in a generic way. There are several ways to create a stream,
  /// including standard Output, file based or socket stream. Various derived 
  /// classes are provided to create an Output stream. The class also provides
  /// support for builtin types serialization.
  /// @author amaury darsch

  class Output : public Stream {
  public:
    /// @return the stream descriptor
    virtual int getsid (void) const;

    /// @return true if the output stream is a tty
    virtual bool istty (void) const;

    /// write one character on the output stream.
    /// @param value the character to write
    virtual void write (const char value) =0;

    /// write a character string to the output stream
    /// @param value the character string to write
    virtual void write (const char* value) =0;

    /// write a unicode character according to the stream mode
    /// @param value the unicode value to write
    virtual void write (const t_quad value);

    /// write a unicode string according to the stream mode
    /// @param value the unicode value to write
    virtual void write (const t_quad* value);

    /// write a character array to the output stream
    /// @param value the character string to write
    /// @param size  the number of character to write
    virtual void write (const char* value, const long size);

    /// write an unicode character array to the output stream
    /// @param value the character string to write
    /// @param size  the number of character to write
    virtual void write (const t_quad* value, const long size);

    /// write a string to the output stream
    /// @param value the character string to write
    virtual void write (const String& value);

    /// write a string as an error string
    /// @param value the character string to write
    virtual void error (const String& value);

    /// write a newline to this output stream
    /// function only. Use write for more error detection.
    /// @param line the line to write
    void newline (void);

    /// write a character string followed by a new line. This is a convenient
    /// function only. Use write for more error detection.
    /// @param line the line to write
    void writeln (const String& line);

    /// write a character string followed by a new line in error mode.
    /// @param line the line to write
    void errorln (const String& line);

    /// write an exception string on this output stream.
    /// @param e the exception to write
    void errorln (const Exception& e);

    /// write a character on the output stream. Just return the stream
    /// @param the character to write
    /// @return the stream  
    Output& operator << (const char value);

    /// write a string on the output stream. Just return the stream.
    /// @param the character to write
    /// @return the stream
    Output& operator << (const String& value);

    /// write an integer on the output stream. Just return the stream.
    /// @param the character to write
    /// @return the stream
    Output& operator << (const long value);

  public:
    /// @return true if the given quark is defined
    bool isquark (const long quark, const bool hflg) const;

    /// apply this output with a set of arguments and a quark
    /// @param robj  the current runnable
    /// @param nset  the current nameset    
    /// @param quark the quark to apply these arguments
    /// @param argv  the argument vector to apply
    Object* apply (Runnable* robj, Nameset* nset, const long quark,
		   Vector* argv);
  };
}

#endif
