/* ====================================================================
   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.poi.poifs.storage;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;

import org.apache.poi.poifs.common.POIFSBigBlockSize;
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.filesystem.BATManaged;
import org.apache.poi.util.IntList;

/**
 * This class manages and creates the Block Allocation Table, which is
 * basically a set of linked lists of block indices.
 * <P>
 * Each block of the filesystem has an index. The first block, the
 * header, is skipped; the first block after the header is index 0,
 * the next is index 1, and so on.
 * <P>
 * A block's index is also its index into the Block Allocation
 * Table. The entry that it finds in the Block Allocation Table is the
 * index of the next block in the linked list of blocks making up a
 * file, or it is set to -2: end of list.
 *
 * @author Marc Johnson (mjohnson at apache dot org)
 */
public final class BlockAllocationTableWriter implements BlockWritable, BATManaged {
    private IntList    _entries;
    private BATBlock[] _blocks;
    private int        _start_block;
    private POIFSBigBlockSize _bigBlockSize;

    /**
     * create a BlockAllocationTableWriter
     */
    public BlockAllocationTableWriter(POIFSBigBlockSize bigBlockSize)
    {
       _bigBlockSize = bigBlockSize; 
        _start_block  = POIFSConstants.END_OF_CHAIN;
        _entries      = new IntList();
        _blocks       = new BATBlock[ 0 ];
    }

    /**
     * Create the BATBlocks we need
     *
     * @return start block index of BAT blocks
     */
    public int createBlocks()
    {
        int xbat_blocks = 0;
        int bat_blocks  = 0;

        while (true)
        {
            int calculated_bat_blocks  =
                BATBlock.calculateStorageRequirements(_bigBlockSize,
                                                      bat_blocks
                                                      + xbat_blocks
                                                      + _entries.size());
            int calculated_xbat_blocks =
                HeaderBlockWriter.calculateXBATStorageRequirements(
                      _bigBlockSize, calculated_bat_blocks);

            if ((bat_blocks == calculated_bat_blocks)
                    && (xbat_blocks == calculated_xbat_blocks))
            {

                // stable ... we're OK
                break;
            }
            bat_blocks  = calculated_bat_blocks;
            xbat_blocks = calculated_xbat_blocks;
        }
        int startBlock = allocateSpace(bat_blocks);

        allocateSpace(xbat_blocks);
        simpleCreateBlocks();
        return startBlock;
    }

    /**
     * Allocate space for a block of indices
     *
     * @param blockCount the number of blocks to allocate space for
     *
     * @return the starting index of the blocks
     */
    public int allocateSpace(final int blockCount)
    {
        int startBlock = _entries.size();

        if (blockCount > 0)
        {
            int limit = blockCount - 1;
            int index = startBlock + 1;

            for (int k = 0; k < limit; k++)
            {
                _entries.add(index++);
            }
            _entries.add(POIFSConstants.END_OF_CHAIN);
        }
        return startBlock;
    }

    /**
     * get the starting block
     *
     * @return the starting block index
     */
    public int getStartBlock()
    {
        return _start_block;
    }

    /**
     * create the BATBlocks
     */
    void simpleCreateBlocks()
    {
        _blocks = BATBlock.createBATBlocks(_bigBlockSize, _entries.toArray());
    }

    /**
     * Write the storage to an OutputStream
     *
     * @param stream the OutputStream to which the stored data should
     *               be written
     *
     * @exception IOException on problems writing to the specified
     *            stream
     */
    public void writeBlocks(final OutputStream stream)
        throws IOException
    {
        for (int j = 0; j < _blocks.length; j++)
        {
            _blocks[ j ].writeBlocks(stream);
        }
    }
    
    /**
     * Write the BAT into its associated block
     */
    public static void writeBlock(final BATBlock bat, final ByteBuffer block) 
        throws IOException
    {
        bat.writeData(block);
    }

    /**
     * Return the number of BigBlock's this instance uses
     *
     * @return count of BigBlock instances
     */
    public int countBlocks()
    {
        return _blocks.length;
    }

    /**
     * Set the start block for this instance
     */
    public void setStartBlock(int start_block)
    {
        _start_block = start_block;
    }
}
