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

import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.DeflaterOutputStream;

import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.hslf.usermodel.HSLFPictureData;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.LittleEndianOutputStream;
import org.apache.poi.util.Removal;
import org.apache.poi.util.Units;

/**
 * Represents a metafile picture which can be one of the following types: EMF, WMF, or PICT.
 * A metafile is stored compressed using the ZIP deflate/inflate algorithm.
 */
public abstract class Metafile extends HSLFPictureData {

    /**
     * @deprecated Use {@link HSLFSlideShow#addPicture(byte[], PictureType)} or one of it's overloads to create new
     *             {@link Metafile}. This API led to detached {@link Metafile} instances (See Bugzilla
     *             46122) and prevented adding additional functionality.
     */
    @Deprecated
    @Removal(version = "5.3")
    public Metafile() {
        this(new EscherContainerRecord(), new EscherBSERecord());
    }

    /**
     * Creates a new instance.
     *
     * @param recordContainer Record tracking all pictures. Should be attached to the slideshow that this picture is
     *                        linked to.
     * @param bse Record referencing this picture. Should be attached to the slideshow that this picture is linked to.
     */
    @Internal
    protected Metafile(EscherContainerRecord recordContainer, EscherBSERecord bse) {
        super(recordContainer, bse);
    }

    /**
     *  A structure which represents a 34-byte header preceding the compressed metafile data
     */
    public static class Header{
        private static final int RECORD_LENGTH = 34;
        
        /**
         * size of the original file
         */
        private int wmfsize;

        /**
         * Boundary of the metafile drawing commands
         */
        private final Rectangle bounds = new Rectangle();

        /**
         *  Size of the metafile in EMUs
         */
        private final Dimension size = new Dimension();

        /**
         * size of the compressed metafile data
         */
        private int zipsize;

        /**
         * Reserved. Always 0.
         */
        private int compression;

        /**
         * Reserved. Always 254.
         */
        private int filter = 254;

        public void read(byte[] data, int offset){
            @SuppressWarnings("resource")
            LittleEndianInputStream leis = new LittleEndianInputStream(
                new ByteArrayInputStream(data, offset, RECORD_LENGTH));
            
            wmfsize = leis.readInt();

            int left = leis.readInt();
            int top = leis.readInt();
            int right = leis.readInt();
            int bottom = leis.readInt();
            bounds.setBounds(left, top, right-left, bottom-top);

            int width = leis.readInt();
            int height = leis.readInt();
            size.setSize(width, height);

            zipsize = leis.readInt();
            compression = leis.readUByte();
            filter = leis.readUByte();
        }

        public void write(OutputStream out) throws IOException {
            @SuppressWarnings("resource")
            LittleEndianOutputStream leos = new LittleEndianOutputStream(out);
            
            //hmf
            leos.writeInt(wmfsize);
            //left
            leos.writeInt(bounds.x);
            //top
            leos.writeInt(bounds.y);
            //right
            leos.writeInt(bounds.x + bounds.width);
            //bottom
            leos.writeInt(bounds.y + bounds.height);
            //inch
            leos.writeInt(size.width);
            //inch
            leos.writeInt(size.height); 
            leos.writeInt(zipsize); 
            leos.writeByte(compression);
            leos.writeByte(filter);
        }

        void write(byte[] destination, int offset) {
            //hmf
            LittleEndian.putInt(destination, offset, wmfsize);
            offset += 4;

            //left
            LittleEndian.putInt(destination, offset, bounds.x);
            offset += 4;

            //top
            LittleEndian.putInt(destination, offset, bounds.y);
            offset += 4;

            //right
            LittleEndian.putInt(destination, offset, bounds.x + bounds.width);
            offset += 4;

            //bottom
            LittleEndian.putInt(destination, offset, bounds.y + bounds.height);
            offset += 4;

            //inch
            LittleEndian.putInt(destination, offset, size.width);
            offset += 4;

            //inch
            LittleEndian.putInt(destination, offset, size.height);
            offset += 4;

            LittleEndian.putInt(destination, offset, zipsize);
            offset += 4;

            destination[offset] = (byte) compression;
            offset++;

            destination[offset] = (byte) filter;
        }

        public int getSize(){
            return 34;
        }
        
        public int getWmfSize() {
            return wmfsize;
        }
        
        protected void setWmfSize(int wmfSize) {
            this.wmfsize = wmfSize;
        }
        
        protected void setZipSize(int zipSize) {
            this.zipsize = zipSize;
        }

        public Rectangle getBounds() {
            return (Rectangle)bounds.clone();
        }
        
        protected void setBounds(Rectangle bounds) {
            this.bounds.setBounds(bounds);
        }
        
        protected void setDimension(Dimension size) {
            this.size.setSize(size);
        }
    }

    protected static byte[] compress(byte[] bytes, int offset, int length) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (DeflaterOutputStream deflater = new DeflaterOutputStream(out)) {
            deflater.write(bytes, offset, length);
        } catch (IOException e) {
            // IOException won't get thrown by the DeflaterOutputStream in this configuration because:
            //  1. ByteArrayOutputStream doesn't throw an IOException during writes.
            //  2. The DeflaterOutputStream is not finished until we're done writing.
            throw new AssertionError("Won't happen", e);
        }
        return out.toByteArray();
    }

    @Override
    public Dimension getImageDimension() {
        int prefixLen = 16*getUIDInstanceCount();
        Header header = new Header();
        header.read(getRawData(), prefixLen);
        return new Dimension(
            (int)Math.round(Units.toPoints((long)header.size.getWidth())),
            (int)Math.round(Units.toPoints((long)header.size.getHeight()))
        );
    }
}
