// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.procedure;

import bdc.scheme.Scheme;
import bdc.scheme.SchemeException;
import bdc.scheme.Stack;
import bdc.scheme.exception.ParseException;
import bdc.scheme.expression.Procedure1;
import bdc.util.FileUtil;
import bdc.util.IOUtil;
import bdc.util.MultiPrintWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;

/**
    (transcript-on x)

    Transcripts are implemented using MultiPrintWriter. When we turn a
    transcript on we open the transcript file and add its port so that
    it receives output to the output and error ports. The REPL also
    knows to write out any input expressions, although the loader does
    not.

*/
public class TranscriptOn extends Procedure1
{
    public Object apply1 (Stack stack) throws SchemeException
    {
        Object o1 = stack.array[stack.inUse-1];
        File file = new File(FileUtil.fixFileSeparators(Scheme.string(o1, this)));
        try {
            /*
                Open the transcript file
            */
            MultiPrintWriter transcript =
                new MultiPrintWriter(IOUtil.bufferedOutputStream(file));

            /*
                Get the output and error ports
            */
            PrintWriter outPW = stack.currentOutputPort;
            PrintWriter errPW = stack.currentErrorPort;
            if (!((outPW instanceof MultiPrintWriter) &&
                  (errPW instanceof MultiPrintWriter)))
                return Scheme.Unspecified;

            /*
                Add the transcript to catch the output and errors
            */
            MultiPrintWriter out = (MultiPrintWriter)outPW;
            MultiPrintWriter err = (MultiPrintWriter)errPW;
            out.addStream(transcript.stream());
            err.addStream(transcript.stream());
            stack.currentTranscriptPort = transcript;
            return Scheme.Unspecified;

        }
        catch (FileNotFoundException fnfe) {
            throw new ParseException(file.getPath(),
                                     0,
                                     fnfe.toString());
        }
        catch (IOException ioe) {
            throw new ParseException(file.getPath(),
                                     0,
                                     ioe.toString());
        }
    }
}
