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

import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.HexDump;

/**
 * Escher array properties are the most wierd construction ever invented
 * with all sorts of special cases.  I'm hopeful I've got them all.
 *
 * @author Glen Stampoultzis (glens at superlinksoftware.com)
 */
public class EscherArrayProperty
        extends EscherComplexProperty
{
	/**
	 * The size of the header that goes at the
	 *  start of the array, before the data
	 */
    private static final int FIXED_SIZE = 3 * 2;
    /**
     * Normally, the size recorded in the simple data (for the complex
     *  data) includes the size of the header.
     * There are a few cases when it doesn't though...
     */
    private boolean sizeIncludesHeaderSize = true;

    /**
     * When reading a property from data stream remeber if the complex part is empty and set this flag.
     */
    private boolean emptyComplexPart = false;

    public EscherArrayProperty( short id, byte[] complexData )
    {
        super( id, checkComplexData(complexData) );
        emptyComplexPart = complexData.length == 0;
    }

    public EscherArrayProperty( short propertyNumber, boolean isBlipId, byte[] complexData )
    {
        super( propertyNumber, isBlipId, checkComplexData(complexData) );
    }

    private static byte[] checkComplexData( byte[] complexData )
    {
        if (complexData == null || complexData.length == 0)
            complexData = new byte[6];

        return complexData;
    }

    public int getNumberOfElementsInArray()
    {
        return LittleEndian.getUShort( complexData, 0 );
    }

    public void setNumberOfElementsInArray( int numberOfElements )
    {
        int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
        if ( expectedArraySize != complexData.length )
        {
            byte[] newArray = new byte[expectedArraySize];
            System.arraycopy( complexData, 0, newArray, 0, complexData.length );
            complexData = newArray;
        }
        LittleEndian.putShort( complexData, 0, (short) numberOfElements );
    }

    public int getNumberOfElementsInMemory()
    {
        return LittleEndian.getUShort( complexData, 2 );
    }

    public void setNumberOfElementsInMemory( int numberOfElements )
    {
        int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
        if ( expectedArraySize != complexData.length )
        {
            byte[] newArray = new byte[expectedArraySize];
            System.arraycopy( complexData, 0, newArray, 0, expectedArraySize );
            complexData = newArray;
        }
        LittleEndian.putShort( complexData, 2, (short) numberOfElements );
    }

    public short getSizeOfElements()
    {
        return LittleEndian.getShort( complexData, 4 );
    }

    public void setSizeOfElements( int sizeOfElements )
    {
        LittleEndian.putShort( complexData, 4, (short) sizeOfElements );

        int expectedArraySize = getNumberOfElementsInArray() * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
        if ( expectedArraySize != complexData.length )
        {
            // Keep just the first 6 bytes.  The rest is no good to us anyway.
            byte[] newArray = new byte[expectedArraySize];
            System.arraycopy( complexData, 0, newArray, 0, 6 );
            complexData = newArray;
        }
    }

    public byte[] getElement( int index )
    {
        int actualSize = getActualSizeOfElements(getSizeOfElements());
        byte[] result = new byte[actualSize];
        System.arraycopy(complexData, FIXED_SIZE + index * actualSize, result, 0, result.length );
        return result;
    }

    public void setElement( int index, byte[] element )
    {
        int actualSize = getActualSizeOfElements(getSizeOfElements());
        System.arraycopy( element, 0, complexData, FIXED_SIZE + index * actualSize, actualSize);
    }

    public String toString()
    {
        String nl = System.getProperty("line.separator");

        StringBuffer results = new StringBuffer();
        results.append("    {EscherArrayProperty:" + nl);
        results.append("     Num Elements: " + getNumberOfElementsInArray() + nl);
        results.append("     Num Elements In Memory: " + getNumberOfElementsInMemory() + nl);
        results.append("     Size of elements: " + getSizeOfElements() + nl);
        for (int i = 0; i < getNumberOfElementsInArray(); i++)
        {
            results.append("     Element " + i + ": " + HexDump.toHex(getElement(i)) + nl);
        }
        results.append("}" + nl);

        return "propNum: " + getPropertyNumber()
                + ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() )
                + ", complex: " + isComplex()
                + ", blipId: " + isBlipId()
                + ", data: " + nl + results.toString();
    }

    /**
     * We have this method because the way in which arrays in escher works
     * is screwed for seemly arbitary reasons.  While most properties are
     * fairly consistent and have a predictable array size, escher arrays
     * have special cases.
     *
     * @param data      The data array containing the escher array information
     * @param offset    The offset into the array to start reading from.
     * @return  the number of bytes used by this complex property.
     */
    public int setArrayData( byte[] data, int offset )
    {
        if (emptyComplexPart){
            complexData = new byte[0];
        } else {
            short numElements = LittleEndian.getShort(data, offset);
            short numReserved = LittleEndian.getShort(data, offset + 2);
            short sizeOfElements = LittleEndian.getShort(data, offset + 4);

            int arraySize = getActualSizeOfElements(sizeOfElements) * numElements;
            if (arraySize == complexData.length) {
                // The stored data size in the simple block excludes the header size
                complexData = new byte[arraySize + 6];
                sizeIncludesHeaderSize = false;
            }
            System.arraycopy(data, offset, complexData, 0, complexData.length );
        }
        return complexData.length;
    }

    /**
     * Serializes the simple part of this property.  ie the first 6 bytes.
     * 
     * Needs special code to handle the case when the size doesn't 
     *  include the size of the header block
     */
    public int serializeSimplePart( byte[] data, int pos )
    {
        LittleEndian.putShort(data, pos, getId());
        int recordSize = complexData.length;
        if(!sizeIncludesHeaderSize) {
        	recordSize -= 6;
        }
        LittleEndian.putInt(data, pos + 2, recordSize);
        return 6;
    }

    /**
     * Sometimes the element size is stored as a negative number.  We
     * negate it and shift it to get the real value.
     */
    public static int getActualSizeOfElements(short sizeOfElements)
    {
        if (sizeOfElements < 0)
            return (short) ( ( -sizeOfElements ) >> 2 );
        else
            return sizeOfElements;
    }

}
