package com.jscape.inet.telnet;


import java.io.IOException;
import java.io.OutputStream;


/**
 * Specialised output stream used to embed Telnet commands
 * in ASCII stream.
 */
public class TelnetOutputStream
        extends OutputStream {
    OutputStream os = null;

    private String characterSet = null;

    /**
     * Creates a new TelnetOutputStream instance.
     *
     * @param out the output stream
     */
    public TelnetOutputStream(OutputStream out) {
        this(out, null);
    }

    public TelnetOutputStream(OutputStream out, String characterSet) {
        os = out;
        this.characterSet = characterSet;
    }

    /**
     * Returns underlying stream.
     *
     * @return the OutputStream used to construct this TelnetOutputStream
     */
    public OutputStream getStream() {
        return os;
    }

    /**
     * Write data to telnet stream with escaping IAC.
     *
     * @param a the data to write
     *
     * @throws IOException if an I/O related error occurs
     */
    public void write(int a)
            throws IOException {
        if (a == Telnet.TSC_IAC) {
            os.write(a);
        }
        os.write(a);
    }

    /**
     * Write data to telnet stream with escaping IAC.
     *
     * @param b the data to write
     *
     * @throws IOException if an I/O related error occurs
     */
    public void write(byte[] b)
            throws IOException {
        os.write(b);
        os.flush();
    }

    /**
     * Write data to telnet stream with escaping IAC.
     *
     * @param b   the data
     * @param off the start offset in the data
     * @param len the number of bytes to write
     *
     * @throws IOException if an I/O related error occurs
     */
    public void write(byte[] b, int off, int len)
            throws IOException {
        byte[] tmp = new byte[len];
        System.arraycopy(b, off, tmp, 0, len);
        write(tmp);
    }

    /**
     * Write line of data with escaping IAC terminated with LF.
     *
     * @param line the data
     *
     * @throws IOException if an I/O related error occurs
     */
    public void println(String line)
            throws IOException {
        println(line, "\n");
    }

    /**
     * Write line of data with escaping IAC terminated with specified line terminator.
     *
     * @param line       the data
     * @param terminator the line terminator used
     *
     * @throws IOException if an I/O related error occurs
     */
    public void println(String line, String terminator)
            throws IOException {
        line = line + terminator;
        if (characterSet == null) {
            write(line.getBytes());
        } else {
            write(line.getBytes(characterSet));
        }
        flush();
    }

    /**
     * Write data to telnet stream without escaping IAC.
     * This method is used by the API internally to control
     * connection/ exchange commands with server.
     *
     * @param a the data to write
     *
     * @throws IOException if an I/O related error occurs
     */
    public void twrite(int a)
            throws IOException {
        os.write(a);
        os.flush();
    }

    /**
     * Write data to telnet stream without escaping IAC.
     * This method is used by the API internally to control
     * connection/ exchange commands with server.
     *
     * @param a the data to write
     *
     * @throws IOException if an I/O related error occurs
     */
    public void twrite(byte[] a)
            throws IOException {
        os.write(a);
        os.flush();
    }
}

