using System;
using System.IO;
using FBPLib;
using System.Threading;


namespace FBPVerbs
{
    /** Component to write data to a file or other output medium, using
* a stream of packets.   The data target is specified as a Stream Writer
* via an InitializationConnection.
* It is specified as "must run" so that the output file will be cleared
* even if no data packets are input.
*/
    [MustRun]
    [InPort("DESTINATION")]
    [InPort("FLUSH")]
    [InPort("CONFIG")]
    [InPort("IN")]
    public class WriteText : Component
    {
        internal static string _copyright =
                "Copyright 2007, 2008, J. Paul Morrison.  At your option, you may copy, " +
                "distribute, or make derivative works under the terms of the Clarified Artistic License, " +
                "based on the Everything Development Company's Artistic License.  A document describing " +
                "this License may be found at http://www.jpaulmorrison.com/fbp/artistic2.htm. " +
                "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";


        IInputPort _inport;
        IInputPort _destination;
        IInputPort _flush;
        IInputPort _cfgp;
        static string _linesep = System.Environment.NewLine;
        double _timeout = 2.0;   // 2 secs

        public override void OpenPorts()
        {

            _inport = OpenInput("IN");
            _inport.SetType(Type.GetType("System.String"));

            _destination = OpenInput("DESTINATION");
            _destination.SetType(Type.GetType("Stream"));
            _flush = OpenInput("FLUSH");
            _cfgp = OpenInput("CONFIG");


        }

        public override void Execute() /*throws Throwable*/ {

            Packet wp = _destination.Receive();
            if (wp == null)
                return;
            _destination.Close();

            Packet fp = _flush.Receive();
            if (fp != null) Drop(fp);
            _flush.Close();

            Packet p = _cfgp.Receive();
            if (p != null)
            {
                string param = p.Content.ToString();
                _timeout = Double.Parse(param);
                Drop(p);
                _cfgp.Close();
            }
            /*
            Object o = wp.Content;
            StreamWriter sw = null;
            if (o is String)
            {
                String st = (String)o;
                sw = new StreamWriter(st);
            }
            else
            {
                Stream str = (Stream)o;
                sw = new StreamWriter(str);
            }*/
            Object dest = wp.Content;
            TextWriter tw;
            if (dest is TextWriter)
                tw = dest as TextWriter;
            else if (dest is string)
                tw = new StreamWriter(dest as string);
            else if (dest is Stream)
                tw = new StreamWriter(dest as Stream);
            else
                tw = new StringWriter();

            Drop(wp);

            while ((p = _inport.Receive()) != null)
            {
                //using (TimeoutHandler t = new TimeoutHandler(_timeout, this))
                //{
                LongWaitStart(_timeout);
                //Thread.Sleep(3000);   // testing only                                                
                tw.WriteLine(p.Content);
                //}
                LongWaitEnd();

                // sw.Write(linesep);
                if (fp != null) tw.Flush();
                Drop(p);
            }
            tw.Close();
        }
        public override System.Object[] Introspect()
        {

            return new Object[] {
        "transmits its input to a Writer as lines, " +
		"optionally flushing the Writer after each line",
		"IN", "input", Type.GetType("System.String"),
			"lines to be written",
        // DESTINATION may either be a Stream or a String, in
        // which case it is a file name 
		"DESTINATION", "parameter", Type.GetType("Stream"),
			"Writer to write lines to",
		"FLUSH", "parameter", null,
			"flush Writer after every line if present",
        "CONFIG", "parameter", null,
			"timeout interval"};
        }

    }

}
