/* ====================================================================
   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.util.Arrays;

import org.apache.logging.log4j.LogManager;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.StringUtil;

/**
 * The STTB is a string table that is made up of a header that is followed by an
 * array of elements. The cData value specifies the number of elements that are
 * contained in the array.
 * <p>
 * Class and fields descriptions are quoted from [MS-DOC] -- v20121003 Word
 * (.doc) Binary File Format; Copyright (c) 2012 Microsoft Corporation; Release:
 * October 8, 2012
 * <p>
 * This class is internal. It content or properties may change without notice
 * due to changes in our knowledge of internal Microsoft Word binary structures.
 *
 * @author Sergey Vladimirov; according to [MS-DOC] -- v20121003 Word (.doc)
 *         Binary File Format; Copyright (c) 2012 Microsoft Corporation;
 *         Release: October 8, 2012
 */
public class Sttb
{

    private int _cbExtra;

    private final int _cDataLength;

    private String[] _data;

    private byte[][] _extraData;

    private final boolean _fExtend = true;

    public Sttb( byte[] buffer, int startOffset )
    {
        this( 2, buffer, startOffset );
    }

    public Sttb( int cDataLength, byte[] buffer, int startOffset )
    {
        this._cDataLength = cDataLength;
        fillFields( buffer, startOffset );
    }

    public Sttb( int cDataLength, String[] data )
    {
        this._cDataLength = cDataLength;

        this._data = Arrays.copyOf(data, data.length);

        this._cbExtra = 0;
        this._extraData = null;
    }

    public void fillFields( byte[] buffer, int startOffset )
    {
        short ffff = LittleEndian.getShort( buffer, startOffset );
        int offset = startOffset + LittleEndianConsts.SHORT_SIZE;

        if ( ffff != (short) 0xffff )
        {
            LogManager.getLogger(Sttb.class).atWarn().log(
                    "Non-extended character Pascal strings are not supported right now. " +
                            "Creating empty values in the RevisionMarkAuthorTable for now.  " +
                            "Please, contact POI developers for update."
            );
            //set data and extraData to empty values to avoid
            //downstream NPE in case someone calls getEntries on RevisionMarkAuthorTable
            _data = new String[0];
            _extraData = new byte[0][];

            return;
        }
        // strings are extended character strings

        int cData = _cDataLength == 2 ? LittleEndian.getUShort( buffer, offset )
                : LittleEndian.getInt( buffer, offset );
        offset += _cDataLength;

        this._cbExtra = LittleEndian.getUShort( buffer, offset );
        offset += 2;

        _data = new String[cData];
        _extraData = new byte[cData][];

        for ( int i = 0; i < cData; i++ )
        {
            int cchData = LittleEndian.getShort( buffer, offset );
            offset += 2;

            if ( cchData < 0 )
                continue;

            _data[i] = StringUtil.getFromUnicodeLE( buffer, offset, cchData );
            offset += cchData * 2;

            _extraData[i] = Arrays.copyOfRange( buffer, offset, offset+_cbExtra );
            offset += _cbExtra;
        }
    }

    /**
     * The definition of each STTB specifies the meaning of this field. If this
     * STTB uses extended characters, the size of this field is 2*cchData bytes
     * and it is a Unicode string unless otherwise specified by the STTB
     * definition. If this STTB does not use extended characters, then the size
     * of this field is cchData bytes and it is an ANSI string, unless otherwise
     * specified by the STTB definition.
     */
    public String[] getData()
    {
        return _data;
    }

    public int getSize()
    {
        // ffff
        int size = LittleEndianConsts.SHORT_SIZE;

        // cData
        size += _cDataLength;

        // cbExtra
        size += LittleEndianConsts.SHORT_SIZE;

        if ( this._fExtend )
        {
            for ( String data : _data )
            {
                // cchData
                size += LittleEndianConsts.SHORT_SIZE;
                // data
                size += 2 * data.length();
            }
        }
        else
        {
            for ( String data : _data )
            {
                // cchData
                size += LittleEndianConsts.BYTE_SIZE;
                // data
                size += data.length();
            }
        }

        // extraData
        if ( _extraData != null )
        {
            size += _cbExtra * _data.length;
        }

        return size;
    }

    public byte[] serialize()
    {
        final byte[] buffer = new byte[getSize()];

        LittleEndian.putShort( buffer, 0, (short) 0xffff );

        if ( _data == null || _data.length == 0 )
        {
            if ( _cDataLength == 4 )
            {
                LittleEndian.putInt( buffer, 2, 0 );
                LittleEndian.putUShort( buffer, 6, _cbExtra );
                return buffer;
            }

            LittleEndian.putUShort( buffer, 2, 0 );
            LittleEndian.putUShort( buffer, 4, _cbExtra );
            return buffer;
        }

        int offset;
        if ( _cDataLength == 4 )
        {
            LittleEndian.putInt( buffer, 2, _data.length );
            LittleEndian.putUShort( buffer, 6, _cbExtra );
            offset = 2 + LittleEndianConsts.INT_SIZE + LittleEndianConsts.SHORT_SIZE;
        }
        else
        {
            LittleEndian.putUShort( buffer, 2, _data.length );
            LittleEndian.putUShort( buffer, 4, _cbExtra );
            offset = 2 + LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.SHORT_SIZE;
        }

        for ( int i = 0; i < _data.length; i++ )
        {
            String entry = _data[i];
            if ( entry == null )
            {
                // is it correct?
                buffer[offset] = -1;
                buffer[offset + 1] = 0;
                offset += 2;
                continue;
            }

            if ( _fExtend )
            {
                LittleEndian.putUShort( buffer, offset, entry.length() );
                offset += LittleEndianConsts.SHORT_SIZE;

                StringUtil.putUnicodeLE( entry, buffer, offset );
                offset += 2 * entry.length();
            }
            else
            {
                throw new UnsupportedOperationException(
                        "ANSI STTB is not supported yet" );
            }

            if ( _cbExtra != 0 )
            {
                if ( _extraData[i] != null && _extraData[i].length != 0 )
                {
                    System.arraycopy( _extraData[i], 0, buffer, offset,
                            Math.min( _extraData[i].length, _cbExtra ) );
                }
                offset += _cbExtra;
            }
        }

        return buffer;
    }

    public int serialize( byte[] buffer, int offset )
    {
        byte[] bs = serialize();
        System.arraycopy( bs, 0, buffer, offset, bs.length );
        return bs.length;
    }
}
