package be.iminds.ilabt.jfed.experimenter_gui.util;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * User: twalcari
 * Date: 3/31/2016
 * Time: 09:07
 */
public class ProgressMonitorInputStream extends FilterInputStream {

    private final IntegerProperty nread = new SimpleIntegerProperty(0);
    private int             size = 0;

    /**
     * Creates a <code>FilterInputStream</code>
     * by assigning the  argument <code>in</code>
     * to the field <code>this.in</code> so as
     * to remember it for later use.
     *
     * @param in the underlying input stream, or <code>null</code> if
     *           this instance is to be created without an underlying stream.
     */
    public ProgressMonitorInputStream(InputStream in) {
        super(in);

        try {
            size = in.available();
        }
        catch(IOException ioe) {
            size = 0;
        }
    }

    /**
     * Overrides <code>FilterInputStream.read</code>
     * to update the progress monitor after the read.
     */
    public int read() throws IOException {
        int c = in.read();
        if (c >= 0) nread.set(nread.get()+1);
        return c;
    }


    /**
     * Overrides <code>FilterInputStream.read</code>
     * to update the progress monitor after the read.
     */
    public int read(byte b[]) throws IOException {
        int nr = in.read(b);
        if (nr > 0) nread.set(nread.get()+ nr);
        return nr;
    }


    /**
     * Overrides <code>FilterInputStream.read</code>
     * to update the progress monitor after the read.
     */
    public int read(byte b[],
                    int off,
                    int len) throws IOException {
        int nr = in.read(b, off, len);
        if (nr > 0) nread.set(nread.get()+ nr);
        return nr;
    }


    /**
     * Overrides <code>FilterInputStream.skip</code>
     * to update the progress monitor after the skip.
     */
    public long skip(long n) throws IOException {
        long nr = in.skip(n);
        if (nr > 0) nread.set(nread.get()+ (int) nr);
        return nr;
    }


    /**
     * Overrides <code>FilterInputStream.close</code>
     * to close the progress monitor as well as the stream.
     */
    public void close() throws IOException {
        in.close();
    }


    /**
     * Overrides <code>FilterInputStream.reset</code>
     * to reset the progress monitor as well as the stream.
     */
    public synchronized void reset() throws IOException {
        in.reset();
        nread.set(size - in.available());
    }

    public int getNread() {
        return nread.get();
    }

    public IntegerProperty nreadProperty() {
        return nread;
    }

    public int getSize() {
        return size;
    }
}
