/*
 * 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.imaging.common.mylzw;

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

import org.apache.commons.imaging.common.BinaryConstants;

public class MyBitOutputStream extends OutputStream implements BinaryConstants
{
    private final OutputStream os;
    private final int byteOrder;

    public MyBitOutputStream(OutputStream os, int byteOrder)
    {
        this.byteOrder = byteOrder;
        this.os = os;
    }

    @Override
    public void write(int value) throws IOException
    {
        writeBits(value, 8);
    }

    private int bitsInCache = 0;
    private int bitCache = 0;

    // TODO: in and out streams CANNOT accurately read/write 32bits at a time,
    // as int will overflow.  should have used a long
    public void writeBits(int value, int SampleBits) throws IOException
    {
        int sampleMask = (1 << SampleBits) - 1;
        value &= sampleMask;

        if (byteOrder == BYTE_ORDER_NETWORK) // MSB, so add to right
        {
            bitCache = (bitCache << SampleBits) | value;
        }
        else if (byteOrder == BYTE_ORDER_INTEL) // LSB, so add to left
        {
            bitCache = bitCache | (value << bitsInCache);
        }
        else
            throw new IOException("Unknown byte order: " + byteOrder);
        bitsInCache += SampleBits;

        while (bitsInCache >= 8)
        {
            if (byteOrder == BYTE_ORDER_NETWORK) // MSB, so write from left
            {
                int b = 0xff & (bitCache >> (bitsInCache - 8));
                actualWrite(b);

                bitsInCache -= 8;
            }
            else if (byteOrder == BYTE_ORDER_INTEL) // LSB, so write from right
            {
                int b = 0xff & bitCache;
                actualWrite(b);

                bitCache >>= 8;
                bitsInCache -= 8;
            }
            int remainderMask = (1 << bitsInCache) - 1; // unneccesary
            bitCache &= remainderMask; // unneccesary
        }

    }

    private int bytesWritten = 0;

    private void actualWrite(int value) throws IOException
    {
        os.write(value);
        bytesWritten++;
    }

    public void flushCache() throws IOException
    {
        if (bitsInCache > 0)
        {
            int bitMask = (1 << bitsInCache) - 1;
            int b = bitMask & bitCache;

            if (byteOrder == BYTE_ORDER_NETWORK) // MSB, so write from left
            {
                b <<= 8 - bitsInCache; // left align fragment.
                os.write(b);
            }
            else if (byteOrder == BYTE_ORDER_INTEL) // LSB, so write from right
            {
                os.write(b);
            }
        }

        bitsInCache = 0;
        bitCache = 0;
    }

    public int getBytesWritten()
    {
        return bytesWritten + ((bitsInCache > 0) ? 1 : 0);
    }

}