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

import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Spliterator;
import java.util.function.Supplier;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.hwmf.draw.HwmfGraphicsState;
import org.apache.poi.hwmf.record.HwmfHeader;
import org.apache.poi.hwmf.record.HwmfPlaceableHeader;
import org.apache.poi.hwmf.record.HwmfRecord;
import org.apache.poi.hwmf.record.HwmfRecordType;
import org.apache.poi.hwmf.record.HwmfWindowing.WmfSetWindowExt;
import org.apache.poi.hwmf.record.HwmfWindowing.WmfSetWindowOrg;
import org.apache.poi.util.Dimension2DDouble;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.RecordFormatException;
import org.apache.poi.util.Units;

public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
    /** Max. record length - processing longer records will throw an exception */
    public static final int MAX_RECORD_LENGTH = 50_000_000;

    private static final Logger LOG = LogManager.getLogger(HwmfPicture.class);

    final List<HwmfRecord> records = new ArrayList<>();
    final HwmfPlaceableHeader placeableHeader;
    final HwmfHeader header;
    /** The default charset */
    private Charset defaultCharset = LocaleUtil.CHARSET_1252;

    public HwmfPicture(InputStream inputStream) throws IOException {

        try (LittleEndianInputStream leis = new LittleEndianInputStream(inputStream)) {
            placeableHeader = HwmfPlaceableHeader.readHeader(leis);
            header = new HwmfHeader(leis);

            for (;;) {
                long recordSize;
                int recordFunction;
                try {
                    // recordSize in DWORDs
                    long recordSizeLong = leis.readUInt()*2;
                    if (recordSizeLong > Integer.MAX_VALUE) {
                        throw new RecordFormatException("record size can't be > "+Integer.MAX_VALUE);
                    } else if (recordSizeLong < 0L) {
                        throw new RecordFormatException("record size can't be < 0");
                    }
                    recordSize = (int)recordSizeLong;
                    recordFunction = leis.readShort();
                } catch (Exception e) {
                    LOG.atError().log("unexpected eof - wmf file was truncated");
                    break;
                }
                // 4 bytes (recordSize) + 2 bytes (recordFunction)
                int consumedSize = 6;
                HwmfRecordType wrt = HwmfRecordType.getById(recordFunction);
                if (wrt == null) {
                    throw new IOException("unexpected record type: "+recordFunction);
                }
                if (wrt == HwmfRecordType.eof) {
                    break;
                }
                if (wrt.constructor == null) {
                    throw new IOException("unsupported record type: "+recordFunction);
                }

                final HwmfRecord wr = wrt.constructor.get();
                records.add(wr);

                consumedSize += wr.init(leis, recordSize, recordFunction);
                int remainingSize = (int)(recordSize - consumedSize);
                if (remainingSize < 0) {
                    throw new RecordFormatException("read too many bytes. record size: "+recordSize + "; comsumed size: "+consumedSize);
                } else if(remainingSize > 0) {
                    long skipped = IOUtils.skipFully(leis, remainingSize);
                    if (skipped != (long)remainingSize) {
                        throw new RecordFormatException("Tried to skip "+remainingSize + " but skipped: "+skipped);
                    }
                }

                if (wr instanceof HwmfCharsetAware) {
                    ((HwmfCharsetAware)wr).setCharsetProvider(this::getDefaultCharset);
                }
            }
        }
    }

    public List<HwmfRecord> getRecords() {
        return Collections.unmodifiableList(records);
    }

    public void draw(Graphics2D ctx) {
        Dimension2D dim = getSize();
        int width = Units.pointsToPixel(dim.getWidth());
        // keep aspect ratio for height
        int height = Units.pointsToPixel(dim.getHeight());
        Rectangle2D bounds = new Rectangle2D.Double(0,0,width,height);
        draw(ctx, bounds);
    }

    public void draw(Graphics2D ctx, Rectangle2D graphicsBounds) {
        HwmfGraphicsState state = new HwmfGraphicsState();
        state.backup(ctx);
        try {
            Rectangle2D wmfBounds = getBounds();
            Rectangle2D innerBounds = getInnnerBounds();
            if (innerBounds == null) {
                innerBounds = wmfBounds;
            }

            // scale output bounds to image bounds
            ctx.translate(graphicsBounds.getCenterX(), graphicsBounds.getCenterY());
            ctx.scale(graphicsBounds.getWidth()/innerBounds.getWidth(), graphicsBounds.getHeight()/innerBounds.getHeight());
            ctx.translate(-innerBounds.getCenterX(), -innerBounds.getCenterY());


            HwmfGraphics g = new HwmfGraphics(ctx, innerBounds);
            HwmfDrawProperties prop = g.getProperties();
            prop.setViewportOrg(innerBounds.getX(), innerBounds.getY());
            prop.setViewportExt(innerBounds.getWidth(), innerBounds.getHeight());

            int idx = 0;
            for (HwmfRecord r : records) {
                prop = g.getProperties();
                Shape propClip = prop.getClip();
                Shape ctxClip = ctx.getClip();
                if (!Objects.equals(propClip, ctxClip)) {
                    int a = 5;
                }
                r.draw(g);
                idx++;
            }
        } finally {
            state.restore(ctx);
        }
    }

    /**
     * Returns the bounding box in device-independent units. Usually this is taken from the placeable header.
     *
     * @return the bounding box
     *
     * @throws RuntimeException if neither WmfSetWindowOrg/Ext nor the placeableHeader are set
     */
    public Rectangle2D getBounds() {
        if (placeableHeader != null) {
            return placeableHeader.getBounds();
        }
        Rectangle2D inner = getInnnerBounds();
        if (inner != null) {
            return inner;
        }
        throw new RuntimeException("invalid wmf file - window records are incomplete.");
    }

    /**
     * Returns the bounding box in device-independent units taken from the WmfSetWindowOrg/Ext records
     *
     * @return the bounding box or null, if the WmfSetWindowOrg/Ext records aren't set
     */
    public Rectangle2D getInnnerBounds() {
        WmfSetWindowOrg wOrg = null;
        WmfSetWindowExt wExt = null;
        for (HwmfRecord r : getRecords()) {
            if (r instanceof WmfSetWindowOrg) {
                wOrg = (WmfSetWindowOrg)r;
            } else if (r instanceof WmfSetWindowExt) {
                wExt = (WmfSetWindowExt)r;
            }
            if (wOrg != null && wExt != null) {
                return new Rectangle2D.Double(wOrg.getX(), wOrg.getY(), wExt.getSize().getWidth(), wExt.getSize().getHeight());
            }
        }
        return null;
    }


    public HwmfPlaceableHeader getPlaceableHeader() {
        return placeableHeader;
    }

    public HwmfHeader getHeader() {
        return header;
    }

    /**
     * Return the image bound in points
     *
     * @return the image bound in points
     */
    public Rectangle2D getBoundsInPoints() {
        double inch = (placeableHeader == null) ? 1440 : placeableHeader.getUnitsPerInch();
        Rectangle2D bounds = getBounds();

        //coefficient to translate from WMF dpi to 72dpi
        double coeff = Units.POINT_DPI/inch;
        return AffineTransform.getScaleInstance(coeff, coeff).createTransformedShape(bounds).getBounds2D();
    }


    /**
     * Return the image size in points
     *
     * @return the image size in points
     */
    public Dimension2D getSize() {
        Rectangle2D bounds = getBoundsInPoints();
        return new Dimension2DDouble(bounds.getWidth(), bounds.getHeight());
    }

    public Iterable<HwmfEmbedded> getEmbeddings() {
        return () -> new HwmfEmbeddedIterator(HwmfPicture.this);
    }

    @Override
    public Iterator<HwmfRecord> iterator() {
        return getRecords().iterator();
    }

    @Override
    public Spliterator<HwmfRecord> spliterator() {
        return getRecords().spliterator();
    }

    @Override
    public Map<String, Supplier<?>> getGenericProperties() {
        return null;
    }

    @Override
    public List<? extends GenericRecord> getGenericChildren() {
        return getRecords();
    }

    public void setDefaultCharset(Charset defaultCharset) {
        this.defaultCharset = defaultCharset;
    }

    public Charset getDefaultCharset() {
        return defaultCharset;
    }
}
