/* ====================================================================
   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 java.util.Iterator;
import java.util.NoSuchElementException;

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

/**
 * Escher array properties are the most weird construction ever invented
 * with all sorts of special cases.  I'm hopeful I've got them all.
 */
public final class EscherArrayProperty extends EscherComplexProperty implements Iterable<byte[]> {
    /**
     * 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 remember if the complex part is empty and set this flag.
     */
    private boolean emptyComplexPart;

    public EscherArrayProperty(short id, byte[] complexData) {
        super(id, checkComplexData(complexData));
        emptyComplexPart = (complexData == null || 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) {
            return new byte[6];
        }

        return complexData;
    }

    public int getNumberOfElementsInArray() {
        return (emptyComplexPart) ? 0 : LittleEndian.getUShort(getComplexData(), 0);
    }

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

    public int getNumberOfElementsInMemory() {
        return (emptyComplexPart) ? 0 : LittleEndian.getUShort(getComplexData(), 2);
    }

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

    public short getSizeOfElements() {
        return (emptyComplexPart) ? 0 : LittleEndian.getShort( getComplexData(), 4 );
    }

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

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

    public byte[] getElement(int index) {
        int actualSize = getActualSizeOfElements(getSizeOfElements());
        byte[] result = new byte[actualSize];
        System.arraycopy(getComplexData(), 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, getComplexData(), FIXED_SIZE + index * actualSize, actualSize);
    }

    @Override
    public String toString() {
        StringBuilder results = new StringBuilder();
        results.append("propNum: ").append(getPropertyNumber());
        results.append(", propName: ").append(EscherProperties.getPropertyName( getPropertyNumber() ));
        results.append(", complex: ").append(isComplex());
        results.append(", blipId: ").append(isBlipId());
        results.append(", data: \n");
        results.append("    {EscherArrayProperty:" + '\n');
        results.append("     Num Elements: ").append(getNumberOfElementsInArray()).append('\n');
        results.append("     Num Elements In Memory: ").append(getNumberOfElementsInMemory()).append('\n');
        results.append("     Size of elements: ").append(getSizeOfElements()).append('\n');
        for (int i = 0; i < getNumberOfElementsInArray(); i++) {
            results.append("     Element ").append(i).append(": ").append(HexDump.toHex(getElement(i))).append('\n');
        }
        results.append("}" + '\n');

        return results.toString();
    }

    @Override
    public String toXml(String tab){
        StringBuilder builder = new StringBuilder();
        builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId()))
                .append("\" name=\"").append(getName()).append("\" blipId=\"")
                .append(isBlipId()).append("\">\n");
        for (int i = 0; i < getNumberOfElementsInArray(); i++) {
            builder.append("\t").append(tab).append("<Element>").append(HexDump.toHex(getElement(i))).append("</Element>\n");
        }
        builder.append(tab).append("</").append(getClass().getSimpleName()).append(">");
        return builder.toString();
    }

    /**
     * We have this method because the way in which arrays in escher works
     * is screwed for seemly arbitrary 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){
            setComplexData(new byte[0]);
        } else {
            short numElements = LittleEndian.getShort(data, offset);
            // LittleEndian.getShort(data, offset + 2); // numReserved
            short sizeOfElements = LittleEndian.getShort(data, offset + 4);

            // the code here seems to depend on complexData already being
            // sized correctly via the constructor
            int arraySize = getActualSizeOfElements(sizeOfElements) * numElements;
            if (arraySize == getComplexData().length) {
                // The stored data size in the simple block excludes the header size
                setComplexData(new byte[arraySize + 6]);
                sizeIncludesHeaderSize = false;
            }
            System.arraycopy(data, offset, getComplexData(), 0, getComplexData().length );
        }
        return getComplexData().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
     */
    @Override
    public int serializeSimplePart(byte[] data, int pos) {
        LittleEndian.putShort(data, pos, getId());
        int recordSize = getComplexData().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.
     */
    private static int getActualSizeOfElements(short sizeOfElements) {
        if (sizeOfElements < 0) {
            return (short) ( ( -sizeOfElements ) >> 2 );
        }
        return sizeOfElements;
    }

    @Override
    public Iterator<byte[]> iterator() {
        return new Iterator<byte[]>(){
            int idx;
            @Override
            public boolean hasNext() {
                return (idx < getNumberOfElementsInArray());
            }
            
            @Override
            public byte[] next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                return getElement(idx++);
            }
            
            @Override
            public void remove() {
                throw new UnsupportedOperationException("not yet implemented");
            }
        };
    }
    
    
}
