package com.brackeen.javagamebook.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
    Klasa LoopingByteInputStream dziedziczy po ByteArrayInputStream
    z dodanym zapętleniem. Pętla zostaje przerwana po wywołaniu
    metody close().
    <p>Możliwe rozszerzenia tej klasy:<ul>
    <li>Dodanie opcji wykonywania określonej liczby przebiegów.
    </ul>
*/
public class LoopingByteInputStream extends ByteArrayInputStream {

    private boolean closed;

    /**
        Tworzenie nowego obiektu LoopingByteInputStream z podaną
        tablicą bajtów. Tablica nie jest kopiowana.
    */
    public LoopingByteInputStream(byte[] buffer) {
        super(buffer);
        closed = false;
    }

    /**
        Odczytuje <code>length</code> bajtów z tablicy. Jeżeli
        zostanie osiągnięty koniec tablicy, odczyt zaczyna się ponownie
        od jej początku. Po zamknięciu tablicy zwraca wartość -1.
    */
    public int read(byte[] buffer, int offset, int length) {
        if (closed) {
            return -1;
        }
        int totalBytesRead = 0;

        while (totalBytesRead < length) {
            int numBytesRead = super.read(buffer,
                offset + totalBytesRead,
                length - totalBytesRead);

            if (numBytesRead > 0) {
                totalBytesRead += numBytesRead;
            }
            else {
                reset();
            }
        }
        return totalBytesRead;
    }

    /**
        Zamyka strumień. Kolejne wywołania metody read()
        zwrócą wartość -1.
    */
    public void close() throws IOException {
        super.close();
        closed = true;
    }
}
