/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.sanselan.common;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

import org.apache.commons.sanselan.ImageReadException;

public class BinaryInputStream extends InputStream implements BinaryConstants
{
    protected boolean debug = false;

    public final void setDebug(boolean b)
    {
        debug = b;
    }

    public final boolean getDebug()
    {
        return debug;
    }

    private final InputStream is;

    public BinaryInputStream(byte bytes[], int byteOrder)
    {
        this.byteOrder = byteOrder;
        this.is = new ByteArrayInputStream(bytes);
    }

    public BinaryInputStream(InputStream is, int byteOrder)
    {
        this.byteOrder = byteOrder;
        this.is = is;
    }

    public BinaryInputStream(InputStream is)
    {
        this.is = is;
    }

    // default byte order for Java, many file formats.
    private int byteOrder = BYTE_ORDER_NETWORK;

    protected void setByteOrder(int a, int b) throws ImageReadException
    {
        if (a != b)
            throw new ImageReadException("Byte Order bytes don't match (" + a
                    + ", " + b + ").");

        if (a == BYTE_ORDER_MOTOROLA)
            byteOrder = a;
        else if (a == BYTE_ORDER_INTEL)
            byteOrder = a;
        else
            throw new ImageReadException("Unknown Byte Order hint: " + a);
    }

    protected void setByteOrder(int byteOrder)
    {
        this.byteOrder = byteOrder;
    }

    protected int getByteOrder()
    {
        return byteOrder;
    }

    @Override
    public int read() throws IOException
    {
        return is.read();
    }

    protected final int convertByteArrayToInt(String name, byte bytes[])
    {
        return convertByteArrayToInt(name, bytes, byteOrder);
    }

    public final int convertByteArrayToShort(String name, byte bytes[])
    {
        return convertByteArrayToShort(name, bytes, byteOrder);
    }

    public final int convertByteArrayToShort(String name, int start,
            byte bytes[])
    {
        return convertByteArrayToShort(name, start, bytes, byteOrder);
    }

    public final int read4Bytes(String name, String exception)
            throws IOException
    {
        return read4Bytes(name, exception, byteOrder);
    }

    public final int read3Bytes(String name, String exception)
            throws IOException
    {
        return read3Bytes(name, exception, byteOrder);
    }

    public final int read2Bytes(String name, String exception)
            throws IOException
    {
        return read2Bytes(name, exception, byteOrder);
    }

    protected final void readRandomBytes() throws IOException
    {

        for (int counter = 0; counter < 100; counter++)
        {
            readByte("" + counter, "Random Data");
        }
    }

    public final void debugNumber(String msg, int data)
    {
        debugNumber(msg, data, 1);
    }

    public final void debugNumber(String msg, int data, int bytes)
    {
        System.out.print(msg + ": " + data + " (");
        int byteData = data;
        for (int i = 0; i < bytes; i++)
        {
            if (i > 0)
                System.out.print(",");
            int singleByte = 0xff & byteData;
            System.out.print((char) singleByte + " [" + singleByte + "]");
            byteData >>= 8;
        }
        System.out.println(") [0x" + Integer.toHexString(data) + ", "
                + Integer.toBinaryString(data) + "]");
    }

    public final void readAndVerifyBytes(byte expected[], String exception)
            throws ImageReadException, IOException
    {
        for (int i = 0; i < expected.length; i++)
        {
            int data = is.read();
            byte b = (byte) (0xff & data);

            if ((data < 0) || (b != expected[i]))
            {
                System.out.println("i" + ": " + i);

                this.debugByteArray("expected", expected);
                debugNumber("data[" + i + "]", b);
                // debugNumber("expected[" + i + "]", expected[i]);

                throw new ImageReadException(exception);
            }
        }
    }

    protected final void readAndVerifyBytes(String name, byte expected[],
            String exception) throws ImageReadException, IOException
    {
        byte bytes[] = readByteArray(name, expected.length, exception);

        for (int i = 0; i < expected.length; i++)
        {
            if (bytes[i] != expected[i])
            {
                System.out.println("i" + ": " + i);
                debugNumber("bytes[" + i + "]", bytes[i]);
                debugNumber("expected[" + i + "]", expected[i]);

                throw new ImageReadException(exception);
            }
        }
    }

    public final void skipBytes(int length, String exception)
            throws IOException
    {
        long total = 0;
        while (length != total)
        {
            long skipped = is.skip(length - total);
            if (skipped < 1)
                throw new IOException(exception + " (" + skipped + ")");
            total += skipped;
        }
    }

    protected final void scanForByte(byte value) throws IOException
    {
        int count = 0;
        for (int i = 0; count < 3; i++)
        // while(count<3)
        {
            int b = is.read();
            if (b < 0)
                return;
            if ((0xff & b) == value)
            {
                System.out.println("\t" + i + ": match.");
                count++;
            }
        }
    }

    public final byte readByte(String name, String exception)
            throws IOException
    {
        int result = is.read();

        if ((result < 0))
        {
            System.out.println(name + ": " + result);
            throw new IOException(exception);
        }

        if (debug)
            debugNumber(name, result);

        return (byte) (0xff & result);
    }

    protected final RationalNumber[] convertByteArrayToRationalArray(
            String name, byte bytes[], int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 8;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        RationalNumber result[] = new RationalNumber[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToRational(name, bytes, start + i * 8,
                    byteOrder);
        }

        return result;
    }

    protected final RationalNumber convertByteArrayToRational(String name,
            byte bytes[], int byteOrder)
    {
        return convertByteArrayToRational(name, bytes, 0, byteOrder);
    }

    protected final RationalNumber convertByteArrayToRational(String name,
            byte bytes[], int start, int byteOrder)
    {
        int numerator = convertByteArrayToInt(name, bytes, start + 0, 4,
                byteOrder);
        int divisor = convertByteArrayToInt(name, bytes, start + 4, 4,
                byteOrder);

        return new RationalNumber(numerator, divisor);
    }

    protected final int convertByteArrayToInt(String name, byte bytes[],
            int byteOrder)
    {
        return convertByteArrayToInt(name, bytes, 0, 4, byteOrder);
    }

    protected final int convertByteArrayToInt(String name, byte bytes[],
            int start, int length, int byteOrder)
    {
        byte byte0 = bytes[start + 0];
        byte byte1 = bytes[start + 1];
        byte byte2 = bytes[start + 2];
        byte byte3 = 0;
        if (length == 4)
            byte3 = bytes[start + 3];

        // return convert4BytesToInt(name, byte0, byte1, byte2, byte3,
        // byteOrder);

        int result;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            result = ((0xff & byte0) << 24) + ((0xff & byte1) << 16)
                    + ((0xff & byte2) << 8) + ((0xff & byte3) << 0);
        // result = (( byte0) << 24) + ((byte1) << 16)
        // + (( byte2) << 8) + (( byte3) << 0);
        else
            // intel, little endian
            result = ((0xff & byte3) << 24) + ((0xff & byte2) << 16)
                    + ((0xff & byte1) << 8) + ((0xff & byte0) << 0);
        // result = (( byte3) << 24) + (( byte2) << 16)
        // + (( byte1) << 8) + (( byte0) << 0);

        if (debug)
            debugNumber(name, result, 4);

        return result;
    }

    protected final int[] convertByteArrayToIntArray(String name, byte bytes[],
            int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 4;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        int result[] = new int[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToInt(name, bytes, start + i * 4, 4,
                    byteOrder);
        }

        return result;
    }

    protected final int convertByteArrayToShort(String name, byte bytes[],
            int byteOrder)
    {
        return convertByteArrayToShort(name, 0, bytes, byteOrder);
    }

    protected final int convertByteArrayToShort(String name, int start,
            byte bytes[], int byteOrder)
    {
        byte byte0 = bytes[start + 0];
        byte byte1 = bytes[start + 1];

        // return convert2BytesToShort(name, byte0, byte1, byteOrder);

        int result;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            result = ((0xff & byte0) << 8) + ((0xff & byte1) << 0);
        else
            // intel, little endian
            result = ((0xff & byte1) << 8) + ((0xff & byte0) << 0);

        if (debug)
            debugNumber(name, result, 2);

        return result;
    }

    protected final int[] convertByteArrayToShortArray(String name,
            byte bytes[], int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 2;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        int result[] = new int[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToShort(name, start + i * 2, bytes,
                    byteOrder);

            // byte byte0 = bytes[start + i * 2];
            // byte byte1 = bytes[start + i * 2 + 1];
            // result[i] = convertBytesToShort(name, byte0, byte1, byteOrder);
        }

        return result;
    }

    public final byte[] readByteArray(String name, int length, String exception)
            throws IOException
    {
        byte result[] = new byte[length];

        int read = 0;
        while (read < length)
        {
            int count = is.read(result, read, length - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        if (debug)
        {
            for (int i = 0; ((i < length) && (i < 150)); i++)
            {
                debugNumber(name + " (" + i + ")", 0xff & result[i]);
            }
        }
        return result;
    }

    protected final void debugByteArray(String name, byte bytes[])
    {
        System.out.println(name + ": " + bytes.length);

        for (int i = 0; ((i < bytes.length) && (i < 50)); i++)
        {
            debugNumber(name + " (" + i + ")", bytes[i]);
        }
    }

    protected final void debugNumberArray(String name, int numbers[], int length)
    {
        System.out.println(name + ": " + numbers.length);

        for (int i = 0; ((i < numbers.length) && (i < 50)); i++)
        {
            debugNumber(name + " (" + i + ")", numbers[i], length);
        }
    }

    public final byte[] readBytearray(String name, byte bytes[], int start,
            int count)
    {
        if (bytes.length < (start + count))
            return null;

        byte result[] = new byte[count];
        System.arraycopy(bytes, start, result, 0, count);

        if (debug)
            debugByteArray(name, result);

        return result;
    }

    public final byte[] readByteArray(int length, String error)
            throws ImageReadException, IOException
    {
        boolean verbose = false;
        boolean strict = true;
        return readByteArray(length, error, verbose, strict);
    }

    public final byte[] readByteArray(int length, String error,
            boolean verbose, boolean strict) throws ImageReadException,
            IOException
    {
        byte bytes[] = new byte[length];
        int total = 0;
        int read;
        while ((read = read(bytes, total, length - total)) > 0)
            total += read;
        if (total < length)
        {
            if (strict)
                throw new ImageReadException(error);
            else if(verbose)
                System.out.println(error);
            return null;
        }
        return bytes;
    }

    protected final byte[] getBytearrayTail(String name, byte bytes[], int count)
    {
        return readBytearray(name, bytes, count, bytes.length - count);
    }

    protected final byte[] getBytearrayHead(String name, byte bytes[], int count)
    {
        return readBytearray(name, bytes, 0, bytes.length - count);
    }

    public final boolean compareByteArrays(byte a[], int aStart, byte b[],
            int bStart, int length)
    {
        if (a.length < (aStart + length))
            return false;
        if (b.length < (bStart + length))
            return false;

        for (int i = 0; i < length; i++)
        {
            if (a[aStart + i] != b[bStart + i])
            {
                debugNumber("a[" + (aStart + i) + "]", a[aStart + i]);
                debugNumber("b[" + (bStart + i) + "]", b[bStart + i]);

                return false;
            }
        }

        return true;
    }

    protected final int read4Bytes(String name, String exception, int byteOrder)
            throws IOException
    {
        int size = 4;
        byte bytes[] = new byte[size];

        int read = 0;
        while (read < size)
        {
            int count = is.read(bytes, read, size - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return convertByteArrayToInt(name, bytes, byteOrder);
    }

    protected final int read3Bytes(String name, String exception, int byteOrder)
            throws IOException
    {
        int size = 3;
        byte bytes[] = new byte[size];

        int read = 0;
        while (read < size)
        {
            int count = is.read(bytes, read, size - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return convertByteArrayToInt(name, bytes, 0, 3, byteOrder);

    }

    protected final int read2Bytes(String name, String exception, int byteOrder)
            throws IOException
    {
        int size = 2;
        byte bytes[] = new byte[size];

        int read = 0;
        while (read < size)
        {
            int count = is.read(bytes, read, size - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return convertByteArrayToShort(name, bytes, byteOrder);
    }

    public final int read1ByteInteger(String exception)
            throws ImageReadException, IOException
    {
        int byte0 = is.read();
        if (byte0 < 0)
            throw new ImageReadException(exception);

        return 0xff & byte0;
    }

    public final int read2ByteInteger(String exception)
            throws ImageReadException, IOException
    {
        int byte0 = is.read();
        int byte1 = is.read();
        if (byte0 < 0 || byte1 < 0)
            throw new ImageReadException(exception);

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            return ((0xff & byte0) << 8) + ((0xff & byte1) << 0);
        else
            // intel, little endian
            return ((0xff & byte1) << 8) + ((0xff & byte0) << 0);
    }

    public final int read4ByteInteger(String exception)
            throws ImageReadException, IOException
    {
        int byte0 = is.read();
        int byte1 = is.read();
        int byte2 = is.read();
        int byte3 = is.read();
        if (byte0 < 0 || byte1 < 0 || byte2 < 0 || byte3 < 0)
            throw new ImageReadException(exception);

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            return ((0xff & byte0) << 24) + ((0xff & byte1) << 16)
                    + ((0xff & byte2) << 8) + ((0xff & byte3) << 0);
        else
            // intel, little endian
            return ((0xff & byte3) << 24) + ((0xff & byte2) << 16)
                    + ((0xff & byte1) << 8) + ((0xff & byte0) << 0);
    }

    protected final void printCharQuad(String msg, int i)
    {
        System.out.println(msg + ": '" + (char) (0xff & (i >> 24))
                + (char) (0xff & (i >> 16)) + (char) (0xff & (i >> 8))
                + (char) (0xff & (i >> 0)) + "'");

    }

    protected final void printByteBits(String msg, byte i)
    {
        System.out.println(msg + ": '" + Integer.toBinaryString(0xff & i));
    }

    protected final static int charsToQuad(char c1, char c2, char c3, char c4)
    {
        return (((0xff & c1) << 24) | ((0xff & c2) << 16) | ((0xff & c3) << 8) | ((0xff & c4) << 0));
    }

    public final int findNull(byte src[])
    {
        return findNull(src, 0);
    }

    public final int findNull(byte src[], int start)
    {
        for (int i = start; i < src.length; i++)
        {
            if (src[i] == 0)
                return i;

        }
        return -1;
    }

    protected final byte[] getRAFBytes(RandomAccessFile raf, long pos,
            int length, String exception) throws IOException
    {
        byte result[] = new byte[length];

        if (debug)
        {
            System.out.println("getRAFBytes pos" + ": " + pos);
            System.out.println("getRAFBytes length" + ": " + length);
        }

        raf.seek(pos);

        int read = 0;
        while (read < length)
        {
            int count = raf.read(result, read, length - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return result;

    }

    protected void skipBytes(int length) throws IOException
    {
        skipBytes(length, "Couldn't skip bytes");
    }

}