/*
 *  ====================================================================
 *    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.hwpf.model;

import java.io.IOException;
import java.util.Arrays;
import java.util.NoSuchElementException;

import org.apache.poi.hwpf.model.io.HWPFOutputStream;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

/**
 * The PlfLfo structure contains the list format override data for the document.
 * <p>
 * Documentation quoted from Page 424 of 621. [MS-DOC] -- v20110315 Word (.doc)
 * Binary File Format
 * 
 * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
 */
public class PlfLfo
{
    private static POILogger log = POILogFactory.getLogger( PlfLfo.class );

    /**
     * An unsigned integer that specifies the count of elements in both the
     * rgLfo and rgLfoData arrays.
     */
    private int _lfoMac;

    private LFO[] _rgLfo;

    private LFOData[] _rgLfoData;

    
    PlfLfo( byte[] tableStream, int fcPlfLfo, int lcbPlfLfo )
    {
        /*
         * The PlfLfo structure contains the list format override data for the
         * document. -- Page 424 of 621. [MS-DOC] -- v20110315 Word (.doc)
         * Binary File Format
         */
        int offset = fcPlfLfo;

        /*
         * lfoMac (4 bytes): An unsigned integer that specifies the count of
         * elements in both the rgLfo and rgLfoData arrays. -- Page 424 of 621.
         * [MS-DOC] -- v20110315 Word (.doc) Binary File Format
         */
        long lfoMacLong = LittleEndian.getUInt( tableStream, offset );
        offset += LittleEndian.INT_SIZE;

        if ( lfoMacLong > Integer.MAX_VALUE )
        {
            throw new UnsupportedOperationException(
                    "Apache POI doesn't support rgLfo/rgLfoData size large than "
                            + Integer.MAX_VALUE + " elements" );
        }

        this._lfoMac = (int) lfoMacLong;
        _rgLfo = new LFO[_lfoMac];
        _rgLfoData = new LFOData[_lfoMac];

        /*
         * An array of LFO structures. The number of elements in this array is
         * specified by lfoMac. -- Page 424 of 621. [MS-DOC] -- v20110315 Word
         * (.doc) Binary File Format
         */
        for ( int x = 0; x < _lfoMac; x++ )
        {
            LFO lfo = new LFO( tableStream, offset );
            offset += LFO.getSize();
            _rgLfo[x] = lfo;
        }

        /*
         * An array of LFOData that is parallel to rgLfo. The number of elements
         * that are contained in this array is specified by lfoMac. -- Page 424
         * of 621. [MS-DOC] -- v20110315 Word (.doc) Binary File Format
         */
        for ( int x = 0; x < _lfoMac; x++ )
        {
            LFOData lfoData = new LFOData( tableStream, offset,
                    _rgLfo[x].getClfolvl() );
            offset += lfoData.getSizeInBytes();
            _rgLfoData[x] = lfoData;
        }

        if ( ( offset - fcPlfLfo ) != lcbPlfLfo )
        {
            if (log.check(POILogger.WARN)) {
                log.log(POILogger.WARN, "Actual size of PlfLfo is "
                        + (offset - fcPlfLfo) + " bytes, but expected "
                        + lcbPlfLfo);
            }
        }
    }

    void add( LFO lfo, LFOData lfoData )
    {
        // _lfoMac is the size of the array
        _rgLfo = Arrays.copyOf(_rgLfo, _lfoMac + 1);
        _rgLfo[_lfoMac] = lfo;

        _rgLfoData = Arrays.copyOf(_rgLfoData, _lfoMac + 1);
        _rgLfoData[_lfoMac] = lfoData;

        _lfoMac = _lfoMac + 1;
    }

    @Override
    public boolean equals( Object obj ) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PlfLfo other = (PlfLfo) obj;
        return _lfoMac == other._lfoMac &&
                Arrays.equals(_rgLfo, other._rgLfo) &&
                Arrays.equals(_rgLfoData, other._rgLfoData);
    }

    /**
     * An unsigned integer that specifies the count of elements in both the
     * rgLfo and rgLfoData arrays.
     */
    public int getLfoMac()
    {
        return _lfoMac;
    }

    public int getIlfoByLsid( int lsid )
    {
        for ( int i = 0; i < _lfoMac; i++ )
        {
            if ( _rgLfo[i].getLsid() == lsid )
            {
                return i + 1;
            }
        }
        throw new NoSuchElementException( "LFO with lsid " + lsid
                + " not found" );
    }

    /**
     * @param ilfo 1-based index
     * @return The {@link LFO} stored at the given index
     * @throws NoSuchElementException
     */
    public LFO getLfo( int ilfo ) throws NoSuchElementException
    {
        if ( ilfo <= 0 || ilfo > _lfoMac )
        {
            throw new NoSuchElementException( "LFO with ilfo " + ilfo
                    + " not found. lfoMac is " + _lfoMac );
        }
        return _rgLfo[ilfo - 1];
    }

    /**
     * @param ilfo 1-based index
     * @return The {@link LFOData} stored at the given index
     * @throws NoSuchElementException
     */
    public LFOData getLfoData( int ilfo ) throws NoSuchElementException
    {
        if ( ilfo <= 0 || ilfo > _lfoMac )
        {
            throw new NoSuchElementException( "LFOData with ilfo " + ilfo
                    + " not found. lfoMac is " + _lfoMac );
        }
        return _rgLfoData[ilfo - 1];
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + _lfoMac;
        result = prime * result + Arrays.hashCode( _rgLfo );
        result = prime * result + Arrays.hashCode( _rgLfoData );
        return result;
    }

    void writeTo( FileInformationBlock fib, HWPFOutputStream outputStream )
            throws IOException
    {
        final int offset = outputStream.getOffset();
        fib.setFcPlfLfo( offset );

        LittleEndian.putUInt( _lfoMac, outputStream );

        byte[] bs = new byte[LFO.getSize() * _lfoMac];
        for ( int i = 0; i < _lfoMac; i++ )
        {
            _rgLfo[i].serialize( bs, i * LFO.getSize() );
        }
        outputStream.write( bs, 0, LFO.getSize() * _lfoMac );

        for ( int i = 0; i < _lfoMac; i++ )
        {
            _rgLfoData[i].writeTo( outputStream );
        }
        fib.setLcbPlfLfo( outputStream.getOffset() - offset );
    }
}
