/* ====================================================================
   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.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.poi.hwpf.model.types.BKFAbstractType;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

@Internal
public class BookmarksTables
{
    private static final POILogger LOG = POILogFactory.getLogger( BookmarksTables.class );

    private PlexOfCps descriptorsFirst = new PlexOfCps( 4 );

    private PlexOfCps descriptorsLim = new PlexOfCps( 0 );

    private List<String> names = new ArrayList<>(0);

    public BookmarksTables( byte[] tableStream, FileInformationBlock fib )
    {
        read( tableStream, fib );
    }

    public void afterDelete( int startCp, int length )
    {
        descriptorsFirst.adjust( startCp, -length );
        descriptorsLim.adjust( startCp, -length );
        for ( int i = 0; i < descriptorsFirst.length(); i++ )
        {
            GenericPropertyNode startNode = descriptorsFirst.getProperty( i );
            GenericPropertyNode endNode = descriptorsLim.getProperty( i );
            if ( startNode.getStart() == endNode.getStart() )
            {
                LOG.log( POILogger.DEBUG, "Removing bookmark #",
                        Integer.valueOf( i ), "..." );
                remove( i );
                i--;
                continue;
            }
        }
    }

    public void afterInsert( int startCp, int length )
    {
        descriptorsFirst.adjust( startCp, length );
        descriptorsLim.adjust( startCp - 1, length );
    }

    public int getBookmarksCount()
    {
        return descriptorsFirst.length();
    }

    public GenericPropertyNode getDescriptorFirst( int index )
            throws IndexOutOfBoundsException
    {
        return descriptorsFirst.getProperty( index );
    }

    public int getDescriptorFirstIndex( GenericPropertyNode descriptorFirst )
    {
        // TODO: very non-optimal
        return Arrays.asList( descriptorsFirst.toPropertiesArray() ).indexOf(
                descriptorFirst );
    }

    public GenericPropertyNode getDescriptorLim( int index )
            throws IndexOutOfBoundsException
    {
        return descriptorsLim.getProperty( index );
    }

    public int getDescriptorsFirstCount()
    {
        return descriptorsFirst.length();
    }

    public int getDescriptorsLimCount()
    {
        return descriptorsLim.length();
    }

    public String getName( int index )
    {
        return names.get( index );
    }

    public int getNamesCount()
    {
        return names.size();
    }

    private void read( byte[] tableStream, FileInformationBlock fib )
    {
        int namesStart = fib.getFcSttbfbkmk();
        int namesLength = fib.getLcbSttbfbkmk();

        if ( namesStart != 0 && namesLength != 0 )
            this.names = new ArrayList<>(Arrays.asList(SttbUtils
                    .readSttbfBkmk(tableStream, namesStart)));

        int firstDescriptorsStart = fib.getFcPlcfbkf();
        int firstDescriptorsLength = fib.getLcbPlcfbkf();
        if ( firstDescriptorsStart != 0 && firstDescriptorsLength != 0 )
            descriptorsFirst = new PlexOfCps(tableStream,
                 firstDescriptorsStart, firstDescriptorsLength,
                 BKFAbstractType.getSize() );

        int limDescriptorsStart = fib.getFcPlcfbkl();
        int limDescriptorsLength = fib.getLcbPlcfbkl();
        if ( limDescriptorsStart != 0 && limDescriptorsLength != 0 )
            descriptorsLim = new PlexOfCps( tableStream, limDescriptorsStart,
                    limDescriptorsLength, 0 );
    }

    public void remove( int index )
    {
        descriptorsFirst.remove( index );
        descriptorsLim.remove( index );
        names.remove( index );
    }

    public void setName( int index, String name )
    {
        names.set( index, name );
    }

    public void writePlcfBkmkf( FileInformationBlock fib,
            ByteArrayOutputStream tableStream ) throws IOException
    {
        if ( descriptorsFirst == null || descriptorsFirst.length() == 0 )
        {
            fib.setFcPlcfbkf( 0 );
            fib.setLcbPlcfbkf( 0 );
            return;
        }

        int start = tableStream.size();
        tableStream.write( descriptorsFirst.toByteArray() );
        int end = tableStream.size();

        fib.setFcPlcfbkf( start );
        fib.setLcbPlcfbkf( end - start );
    }

    public void writePlcfBkmkl( FileInformationBlock fib,
            ByteArrayOutputStream tableStream ) throws IOException
    {
        if ( descriptorsLim == null || descriptorsLim.length() == 0 )
        {
            fib.setFcPlcfbkl( 0 );
            fib.setLcbPlcfbkl( 0 );
            return;
        }

        int start = tableStream.size();
        tableStream.write( descriptorsLim.toByteArray() );
        int end = tableStream.size();

        fib.setFcPlcfbkl( start );
        fib.setLcbPlcfbkl( end - start );
    }

    public void writeSttbfBkmk( FileInformationBlock fib,
            ByteArrayOutputStream tableStream ) throws IOException
    {
        if ( names == null || names.isEmpty() )
        {
            fib.setFcSttbfbkmk( 0 );
            fib.setLcbSttbfbkmk( 0 );
            return;
        }

        int start = tableStream.size();
        SttbUtils.writeSttbfBkmk( names.toArray(new String[0]),
                tableStream );
        int end = tableStream.size();

        fib.setFcSttbfbkmk( start );
        fib.setLcbSttbfbkmk( end - start );
    }
}
