/*
 * @(#)InputWriter.java
 *
 * Copyright (c) 2001-2002 JScape
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JScape. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with JScape.
 */
package com.jscape.inet.bsd;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;


/**
 * InputWriter is an utility class that should be is used to handle user input
 * and write it to the input of  remote bsd process.
 */
public class InputWriter
        extends Thread {
    private InputStream localInput;
    private OutputStream remoteInput;
    private Vector bsdListeners = null;

    /**
     * Constructs the InputWriter thread.
     *
     * @param localInput   the <code>InputStream</code> stream that thread reads
     *                     from.
     * @param remoteInput  the <code>OutputStream</code> stream that thread
     *                     writes to.
     * @param bsdListeners a <code>Vector</code> of <code>BsdListener</code>
     */
    public InputWriter(InputStream localInput, OutputStream remoteInput,
                       Vector bsdListeners) {
        this.localInput = localInput;
        this.remoteInput = remoteInput;
        this.bsdListeners = bsdListeners;
    }

    /**
     * Thread for running InputWriter.
     */
    public void run() {
        int ch;
        long total = 0;

        try {
            while (!interrupted() && ((ch = localInput.read()) != -1)) {
                ++total;
                remoteInput.write(ch);
                remoteInput.flush();
                fireBytesTransmitted(total, 1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Fires <code>BsdBytesTransmittedEvent</code>. This event is fired when
     * data is transmitted to remote host.
     *
     * @param total the total number of bytes transmitted thus far
     * @param bytes the total number of bytes to submit
     *
     * @see BsdBytesTransmittedEvent
     */
    protected void fireBytesTransmitted(long total, int bytes) {
        Vector thisList = new Vector();
        BsdBytesTransmittedEvent thisEvent = new BsdBytesTransmittedEvent(this,
                                                                          total, bytes);

        // Make a copy of the list so potential changes to it by
        // other threads won't affect traversal.
        synchronized (this) {
            thisList = (Vector) bsdListeners.clone();
        }

        // Send a BsdBytesTransmittedEvent to every listener.
        for (int elem = 0; elem < thisList.size(); elem++) {
            ((BsdListener) thisList.elementAt(elem)).bytesTransmitted(thisEvent);
        }
    }
}
