/* ====================================================================
   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.HexDump;
import org.apache.poi.util.LittleEndian;

public class EscherBitmapBlip extends EscherBlipRecord {
    public static final short RECORD_ID_JPEG = (short) 0xF018 + 5;
    public static final short RECORD_ID_PNG = (short) 0xF018 + 6;
    public static final short RECORD_ID_DIB = (short) 0xF018 + 7;

    private static final int HEADER_SIZE = 8;

    private final byte[] field_1_UID = new byte[16];
    private byte field_2_marker = (byte) 0xFF;

    @Override
    public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
        int bytesAfterHeader = readHeader( data, offset );
        int pos = offset + HEADER_SIZE;

        System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16;
        field_2_marker = data[pos]; pos++;

        setPictureData(data, pos, bytesAfterHeader - 17);

        return bytesAfterHeader + HEADER_SIZE;
    }

    @Override
    public int serialize( int offset, byte[] data, EscherSerializationListener listener ) {
        listener.beforeRecordSerialize(offset, getRecordId(), this);

        LittleEndian.putShort( data, offset, getOptions() );
        LittleEndian.putShort( data, offset + 2, getRecordId() );
        LittleEndian.putInt( data, offset + 4, getRecordSize() - HEADER_SIZE );
        int pos = offset + HEADER_SIZE;

        System.arraycopy( field_1_UID, 0, data, pos, 16 );
        data[pos + 16] = field_2_marker;
        byte pd[] = getPicturedata();
        System.arraycopy( pd, 0, data, pos + 17, pd.length );

        listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this);
        return HEADER_SIZE + 16 + 1 + pd.length;
    }

    @Override
    public int getRecordSize() {
        return 8 + 16 + 1 + getPicturedata().length;
    }

    /**
     * Gets the first MD4, that specifies the unique identifier of the
     * uncompressed blip data
     *
     * @return the first MD4
     */
    public byte[] getUID() {
        return field_1_UID;
    }

    /**
     * Sets the first MD4, that specifies the unique identifier of the
     * uncompressed blip data
     *
     * @param field_1_UID the first MD4
     */
    public void setUID( byte[] field_1_UID ) {
        if (field_1_UID == null || field_1_UID.length != 16) {
            throw new IllegalArgumentException("field_1_UID must be byte[16]");
        }
        System.arraycopy(field_1_UID, 0, this.field_1_UID , 0, 16);
    }

    /**
     * Gets an unsigned integer that specifies an application-defined internal
     * resource tag. This value MUST be 0xFF for external files.
     *
     * @return the marker
     */
    public byte getMarker() {
        return field_2_marker;
    }

    /**
     * Sets an unsigned integer that specifies an application-defined internal
     * resource tag. This value MUST be 0xFF for external files.
     *
     * @param field_2_marker the marker
     */
    public void setMarker( byte field_2_marker ) {
        this.field_2_marker = field_2_marker;
    }

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

        String extraData = HexDump.dump(getPicturedata(), 0, 0);

        return getClass().getName() + ":" + nl +
            "  RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
            "  Version: 0x" + HexDump.toHex( getVersion() ) + nl +
            "  Instance: 0x" + HexDump.toHex( getInstance() ) + nl +
            "  UID: 0x" + HexDump.toHex( field_1_UID ) + nl +
            "  Marker: 0x" + HexDump.toHex( field_2_marker ) + nl +
            "  Extra Data:" + nl + extraData;
    }

    @Override
    public String toXml(String tab) {
        String extraData = HexDump.dump(getPicturedata(), 0, 0);
        StringBuilder builder = new StringBuilder();
        builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance())))
            .append(tab).append("\t").append("<UID>0x").append(HexDump.toHex(field_1_UID)).append("</UID>\n")
            .append(tab).append("\t").append("<Marker>0x").append(HexDump.toHex(field_2_marker)).append("</Marker>\n")
            .append(tab).append("\t").append("<ExtraData>").append(extraData).append("</ExtraData>\n");
        builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
        return builder.toString();
    }
}
