using System;
using System.IO;

namespace bigloo
{
  public class output_stream_port: output_port
  {
    protected Stream stream;

    public output_stream_port( Stream  stream,
                               byte[]  name )
      : base( name )
    {
      this.stream= stream;
    }

    public output_stream_port( Stream  stream )
    {
      this.stream= stream;
    }

    public output_stream_port( byte[]  file )
      : base( file )
    {
      string       file_name= foreign.newstring( file );

      try     // should we keep this try/catch block even when Mono bug will be corrected ?
      {
        if (file_name.ToLower().Equals( "null:" ))
          stream= Stream.Null;
        else
          stream= File.OpenWrite( file_name );
      }
      catch (Exception)
      {
        foreign.fail( "open_output_file", "Could not open file " + file_name, file );
      }
    }

    public output_stream_port( byte[]  file,
                               bool    append )
      : base( file )
    {
      // !!!!! is this try/catch block to be kept or just a protecting against a Mono/PNet bug ?????
      try
      {
        stream= File.Open( foreign.newstring( file ),
                           (append ? FileMode.Append : FileMode.Create),
                           FileAccess.Write );
      }
      catch (Exception e)
      {
        foreign.fail( "append output port", e.Message, file );
      }
    }

    public override Object close()
    {
      try
      {
        stream.Close();
      }
      catch (Exception e)
      {
        if (stream == null)
          return bigloo.foreign.BUNSPEC;
        else
          foreign.fail( "close", e.Message, this );
      }

      return this;
    }

    public override Object flush() 
    {
      try
      {
        stream.Flush();
        return bbool.vrai;
      }
      catch (Exception e)
      {
        if (stream != null)
          foreign.fail( "flush", e.Message, this );
        return bbool.faux;
      }
    }

    public override void write( int  cn ) 
    {
      try
      {
        stream.WriteByte( (byte)cn );
        stream.Flush();
      }
      catch (Exception e)
      {
        if (stream != null)
          foreign.fail( "write", e.Message, this );
      }
    }

    public override void write( byte[]  s ) 
    {
      try
      {
        // CARE pnet bug
        int        n= s.Length;

        if (n == 3294)
          for ( int i= 0 ; i < 3294 ; ++i )
            write( s[i] );
        else
          stream.Write( s, 0, s.Length );
        stream.Flush();
      }
      catch (Exception e)
      {
        if (stream != null)
          foreign.fail( "write", e.Message, this );
      }
    }

    public override void write( String  s )
    {
      try
      {
        int        len= s.Length;

        for ( int i= 0 ; i < len ; ++i )
          stream.WriteByte( (byte)s[i] );
      }
      catch (Exception e)
      {
        if (stream != null)
          foreign.fail( "write", e.Message, this );
      }
    }
  }
}
