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

import java.awt.Rectangle;
import java.io.IOException;

import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianInputStream;

/**
 * Extracts the full header from EMF files.
 * @see org.apache.poi.sl.image.ImageHeaderEMF
 */
@Internal
public class HemfHeader implements HemfRecord {

    private Rectangle boundsRectangle;
    private Rectangle frameRectangle;
    private long bytes;
    private long records;
    private int handles;
    private long nDescription;
    private long offDescription;
    private long nPalEntries;
    private boolean hasExtension1;
    private long cbPixelFormat;
    private long offPixelFormat;
    private long bOpenGL;
    private boolean hasExtension2;
    private long micrometersX;
    private long micrometersY;

    public Rectangle getBoundsRectangle() {
        return boundsRectangle;
    }

    public Rectangle getFrameRectangle() {
        return frameRectangle;
    }

    public long getBytes() {
        return bytes;
    }

    public long getRecords() {
        return records;
    }

    public int getHandles() {
        return handles;
    }

    public long getnDescription() {
        return nDescription;
    }

    public long getOffDescription() {
        return offDescription;
    }

    public long getnPalEntries() {
        return nPalEntries;
    }

    public boolean isHasExtension1() {
        return hasExtension1;
    }

    public long getCbPixelFormat() {
        return cbPixelFormat;
    }

    public long getOffPixelFormat() {
        return offPixelFormat;
    }

    public long getbOpenGL() {
        return bOpenGL;
    }

    public boolean isHasExtension2() {
        return hasExtension2;
    }

    public long getMicrometersX() {
        return micrometersX;
    }

    public long getMicrometersY() {
        return micrometersY;
    }

    @Override
    public String toString() {
        return "HemfHeader{" +
                "boundsRectangle=" + boundsRectangle +
                ", frameRectangle=" + frameRectangle +
                ", bytes=" + bytes +
                ", records=" + records +
                ", handles=" + handles +
                ", nDescription=" + nDescription +
                ", offDescription=" + offDescription +
                ", nPalEntries=" + nPalEntries +
                ", hasExtension1=" + hasExtension1 +
                ", cbPixelFormat=" + cbPixelFormat +
                ", offPixelFormat=" + offPixelFormat +
                ", bOpenGL=" + bOpenGL +
                ", hasExtension2=" + hasExtension2 +
                ", micrometersX=" + micrometersX +
                ", micrometersY=" + micrometersY +
                '}';
    }

    @Override
    public HemfRecordType getRecordType() {
        return HemfRecordType.header;
    }

    @Override
    public long init(LittleEndianInputStream leis, long recordId, long recordSize) throws IOException {
        if (recordId != 1L) {
            throw new IOException("Not a valid EMF header. Record type:"+recordId);
        }
        //read the record--id and size (2 bytes) have already been read
        byte[] data = new byte[(int)recordSize];
        IOUtils.readFully(leis, data);

        int offset = 0;

        //bounds
        int boundsLeft = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        int boundsTop = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        int boundsRight = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        int boundsBottom = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        boundsRectangle = new Rectangle(boundsLeft, boundsTop,
                boundsRight - boundsLeft, boundsBottom - boundsTop);

        int frameLeft = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        int frameTop = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        int frameRight = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        int frameBottom = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        frameRectangle = new Rectangle(frameLeft, frameTop,
                frameRight - frameLeft, frameBottom - frameTop);

        long recordSignature = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        if (recordSignature != 0x464D4520) {
            throw new IOException("bad record signature: " + recordSignature);
        }

        long version = LittleEndian.getInt(data, offset); offset += LittleEndian.INT_SIZE;
        //According to the spec, MSOffice doesn't pay attention to this value.
        //It _should_ be 0x00010000
        bytes = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
        records = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
        handles = LittleEndian.getUShort(data, offset);offset += LittleEndian.SHORT_SIZE;
        offset += LittleEndian.SHORT_SIZE;//reserved
        nDescription = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
        offDescription = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
        nPalEntries = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;

        //should be skips
        offset += 8;//device
        offset += 8;//millimeters


        if (recordSize+8 >= 100) {
            hasExtension1 = true;
            cbPixelFormat = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
            offPixelFormat = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
            bOpenGL= LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
        }

        if (recordSize+8 >= 108) {
            hasExtension2 = true;
            micrometersX = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
            micrometersY = LittleEndian.getUInt(data, offset); offset += LittleEndian.INT_SIZE;
        }
        return recordSize;
    }
}
