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

import java.awt.Dimension;
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.ddf.EscherRecordTypes;
import org.apache.poi.hslf.blip.DIB;
import org.apache.poi.hslf.blip.EMF;
import org.apache.poi.hslf.blip.JPEG;
import org.apache.poi.hslf.blip.PICT;
import org.apache.poi.hslf.blip.PNG;
import org.apache.poi.hslf.blip.WMF;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.Units;

/**
 * A class that represents image data contained in a slide show.
 */
public abstract class HSLFPictureData implements PictureData, GenericRecord {

    /**
     * Size of the image checksum calculated using MD5 algorithm.
     */
    protected static final int CHECKSUM_SIZE = 16;

    /**
    * Binary data of the picture
    */
    private byte[] rawdata;
    /**
     * The offset to the picture in the stream
     */
    private int offset;

    /**
     * The instance type/signatures defines if one or two UID instances will be included
     */
    private int uidInstanceCount = 1;

    /**
     * The 1-based index within the pictures stream
     */
    private int index = -1;

    /**
     * Blip signature.
     */
    protected abstract int getSignature();

    public abstract void setSignature(int signature);

    /**
     * The instance type/signatures defines if one or two UID instances will be included
     */
    protected int getUIDInstanceCount() {
        return uidInstanceCount;
    }

    /**
     * The instance type/signatures defines if one or two UID instances will be included
     *
     * @param uidInstanceCount the number of uid sequences
     */
    protected void setUIDInstanceCount(int uidInstanceCount) {
        this.uidInstanceCount = uidInstanceCount;
    }

    /**
     * Returns the raw binary data of this Picture excluding the first 8 bytes
     * which hold image signature and size of the image data.
     *
     * @return picture data
     */
    public byte[] getRawData(){
        return rawdata;
    }

    public void setRawData(byte[] data){
        rawdata = (data == null) ? null : data.clone();
    }

    /**
     * File offset in the 'Pictures' stream
     *
     * @return offset in the 'Pictures' stream
     */
    public int getOffset(){
        return offset;
    }

    /**
     * Set offset of this picture in the 'Pictures' stream.
     * We need to set it when a new picture is created.
     *
     * @param offset in the 'Pictures' stream
     */
    public void setOffset(int offset){
        this.offset = offset;
    }

    /**
     * Returns 16-byte checksum of this picture
     */
    public byte[] getUID(){
        return Arrays.copyOf(rawdata, 16);
    }

    @Override
    public byte[] getChecksum() {
        return getChecksum(getData());
    }

    /**
     * Compute 16-byte checksum of this picture using MD5 algorithm.
     */
    public static byte[] getChecksum(byte[] data) {
        MessageDigest md5 = CryptoFunctions.getMessageDigest(HashAlgorithm.md5);
        md5.update(data);
        return md5.digest();
    }

    /**
     * Write this picture into <code>OutputStream</code>
     */
    public void write(OutputStream out) throws IOException {
        byte[] data;

        data = new byte[LittleEndianConsts.SHORT_SIZE];
        LittleEndian.putUShort(data, 0, getSignature());
        out.write(data);

        data = new byte[LittleEndianConsts.SHORT_SIZE];
        PictureType pt = getType();
        LittleEndian.putUShort(data, 0, pt.nativeId + EscherRecordTypes.BLIP_START.typeID);
        out.write(data);

        byte[] rd = getRawData();

        data = new byte[LittleEndianConsts.INT_SIZE];
        LittleEndian.putInt(data, 0, rd.length);
        out.write(data);

        out.write(rd);
    }

    /**
     * Create an instance of <code>PictureData</code> by type.
     *
     * @param type type of the picture data.
     * Must be one of the static constants defined in the <code>Picture<code> class.
     * @return concrete instance of <code>PictureData</code>
     */
     public static HSLFPictureData create(PictureType type){
        HSLFPictureData pict;
        switch (type){
            case EMF: pict = new EMF(); break;
            case WMF: pict = new WMF(); break;
            case PICT: pict = new PICT(); break;
            case JPEG: pict = new JPEG(); break;
            case PNG: pict = new PNG(); break;
            case DIB: pict = new DIB(); break;
            default:
                throw new IllegalArgumentException("Unsupported picture type: " + type);
        }
        return pict;
    }

    /**
     * Return 24 byte header which preceeds the actual picture data.
     * <p>
     * The header consists of 2-byte signature, 2-byte type,
     * 4-byte image size and 16-byte checksum of the image data.
     * </p>
     *
     * @return the 24 byte header which preceeds the actual picture data.
     */
    public byte[] getHeader() {
        byte[] header = new byte[16 + 8];
        LittleEndian.putInt(header, 0, getSignature());
        LittleEndian.putInt(header, 4, getRawData().length);
        System.arraycopy(rawdata, 0, header, 8, 16);
        return header;
    }

    /**
     * @return the 1-based index of this pictures within the pictures stream
     */
    public int getIndex() {
        return index;
    }

    /**
     * @param index sets the 1-based index of this pictures within the pictures stream
     */
    public void setIndex(int index) {
        this.index = index;
    }

    @Override
    public final String getContentType() {
        return getType().contentType;
    }

    @Override
    public Dimension getImageDimensionInPixels() {
        Dimension dim = getImageDimension();
        return new Dimension(
            Units.pointsToPixel(dim.getWidth()),
            Units.pointsToPixel(dim.getHeight())
        );
    }

    @Override
    public Map<String, Supplier<?>> getGenericProperties() {
        final Map<String,Supplier<?>> m = new LinkedHashMap<>();
        m.put("type", this::getType);
        m.put("imageDimension", this::getImageDimension);
        m.put("signature", this::getSignature);
        m.put("uidInstanceCount", this::getUIDInstanceCount);
        m.put("offset", this::getOffset);
        m.put("uid", this::getUID);
        m.put("checksum", this::getChecksum);
        m.put("index", this::getIndex);
        m.put("rawData", this::getRawData);
        return Collections.unmodifiableMap(m);
    }
}
