/* ====================================================================
   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.record;

import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.io.IOException;

import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;

public class HwmfWindowing {

    /**
     * The META_SETVIEWPORTORG record defines the viewport origin in the playback device context.
     */
    public static class WmfSetViewportOrg implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the vertical offset, in device units.
         */
        private int y;

        /**
         * A 16-bit signed integer that defines the horizontal offset, in device units.
         */
        private int x;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.setViewportOrg;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            y = leis.readShort();
            x = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.getProperties().setViewportOrg(x, y);
        }
    }

    /**
     * The META_SETVIEWPORTEXT record sets the horizontal and vertical extents
     * of the viewport in the playback device context.
     */
    public static class WmfSetViewportExt implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the vertical extent
         * of the viewport in device units.
         */
        private int height;

        /**
         * A 16-bit signed integer that defines the horizontal extent
         * of the viewport in device units.
         */
        private int width;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.setViewportExt;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            height = leis.readShort();
            width = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.getProperties().setViewportExt(width, height);
        }
    }

    /**
     * The META_OFFSETVIEWPORTORG record moves the viewport origin in the playback device context
     * by specified horizontal and vertical offsets.
     */
    public static class WmfOffsetViewportOrg implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the vertical offset, in device units.
         */
        private int yOffset;

        /**
         * A 16-bit signed integer that defines the horizontal offset, in device units.
         */
        private int xOffset;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.offsetViewportOrg;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            yOffset = leis.readShort();
            xOffset = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            Rectangle2D viewport = ctx.getProperties().getViewport();
            double x = (viewport == null) ? 0 : viewport.getX();
            double y = (viewport == null) ? 0 : viewport.getY();
            ctx.getProperties().setViewportOrg(x+xOffset, y+yOffset);
        }
    }

    /**
     * The META_SETWINDOWORG record defines the output window origin in the playback device context.
     */
    public static class WmfSetWindowOrg implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units.
         */
        private int y;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units.
         */
        private int x;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.setWindowOrg;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            y = leis.readShort();
            x = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.getProperties().setWindowOrg(x, y);
            ctx.updateWindowMapMode();
        }

        public int getY() {
            return y;
        }

        public int getX() {
            return x;
        }
    }

    /**
     * The META_SETWINDOWEXT record defines the horizontal and vertical extents
     * of the output window in the playback device context.
     */
    public static class WmfSetWindowExt implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the vertical extent of
         * the window in logical units.
         */
        private int height;

        /**
         * A 16-bit signed integer that defines the horizontal extent of
         * the window in logical units.
         */
        private int width;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.setWindowExt;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            height = leis.readShort();
            width = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.getProperties().setWindowExt(width, height);
            ctx.updateWindowMapMode();
        }

        public int getHeight() {
            return height;
        }

        public int getWidth() {
            return width;
        }
    }

    /**
     * The META_OFFSETWINDOWORG record moves the output window origin in the
     * playback device context by specified horizontal and vertical offsets.
     */
    public static class WmfOffsetWindowOrg implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the vertical offset, in device units.
         */
        private int yOffset;

        /**
         * A 16-bit signed integer that defines the horizontal offset, in device units.
         */
        private int xOffset;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.offsetWindowOrg;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            yOffset = leis.readShort();
            xOffset = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            Rectangle2D window = ctx.getProperties().getWindow();
            ctx.getProperties().setWindowOrg(window.getX()+xOffset, window.getY()+yOffset);
            ctx.updateWindowMapMode();
        }
    }

    /**
     * The META_OFFSETWINDOWORG record moves the output window origin in the
     * playback device context by specified horizontal and vertical offsets.
     */
    public static class WmfScaleWindowExt implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the amount by which to divide the
         * result of multiplying the current y-extent by the value of the yNum member.
         */
        private int yDenom;

        /**
         * A 16-bit signed integer that defines the amount by which to multiply the
         * current y-extent.
         */
        private int yNum;

        /**
         * A 16-bit signed integer that defines the amount by which to divide the
         * result of multiplying the current x-extent by the value of the xNum member.
         */
        private int xDenom;

        /**
         * A 16-bit signed integer that defines the amount by which to multiply the
         * current x-extent.
         */
        private int xNum;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.scaleWindowExt;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            yDenom = leis.readShort();
            yNum = leis.readShort();
            xDenom = leis.readShort();
            xNum = leis.readShort();
            return 4*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            Rectangle2D window = ctx.getProperties().getWindow();
            double width = window.getWidth() * xNum / xDenom;
            double height = window.getHeight() * yNum / yDenom;
            ctx.getProperties().setWindowExt(width, height);
            ctx.updateWindowMapMode();
        }
    }


    /**
     * The META_SCALEVIEWPORTEXT record scales the horizontal and vertical extents of the viewport
     * that is defined in the playback device context by using the ratios formed by the specified
     * multiplicands and divisors.
     */
    public static class WmfScaleViewportExt implements HwmfRecord {

        /**
         * A 16-bit signed integer that defines the amount by which to divide the
         * result of multiplying the current y-extent by the value of the yNum member.
         */
        private int yDenom;

        /**
         * A 16-bit signed integer that defines the amount by which to multiply the
         * current y-extent.
         */
        private int yNum;

        /**
         * A 16-bit signed integer that defines the amount by which to divide the
         * result of multiplying the current x-extent by the value of the xNum member.
         */
        private int xDenom;

        /**
         * A 16-bit signed integer that defines the amount by which to multiply the
         * current x-extent.
         */
        private int xNum;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.scaleViewportExt;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            yDenom = leis.readShort();
            yNum = leis.readShort();
            xDenom = leis.readShort();
            xNum = leis.readShort();
            return 4*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            Rectangle2D viewport = ctx.getProperties().getViewport();
            if (viewport == null) {
                viewport = ctx.getProperties().getWindow();
            }
            double width = viewport.getWidth() * xNum / xDenom;
            double height = viewport.getHeight() * yNum / yDenom;
            ctx.getProperties().setViewportExt(width, height);
        }
    }

    /**
     * The META_OFFSETCLIPRGN record moves the clipping region in the playback device context by the
     * specified offsets.
     */
    public static class WmfOffsetClipRgn implements HwmfRecord, HwmfObjectTableEntry {

        /**
         * A 16-bit signed integer that defines the number of logical units to move up or down.
         */
        private int yOffset;

        /**
         * A 16-bit signed integer that defines the number of logical units to move left or right.
         */
        private int xOffset;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.offsetClipRgn;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            yOffset = leis.readShort();
            xOffset = leis.readShort();
            return 2*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.addObjectTableEntry(this);
        }
        
        @Override
        public void applyObject(HwmfGraphics ctx) {
        }
    }

    /**
     * The META_EXCLUDECLIPRECT record sets the clipping region in the playback device context to the
     * existing clipping region minus the specified rectangle.
     */
    public static class WmfExcludeClipRect implements HwmfRecord, HwmfObjectTableEntry {

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
         * lower-right corner of the rectangle.
         */
        private int bottom;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
         * lower-right corner of the rectangle.
         */
        private int right;

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
         * upper-left corner of the rectangle.
         */
        private int top;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
         * upper-left corner of the rectangle.
         */
        private int left;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.excludeClipRect;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            bottom = leis.readShort();
            right = leis.readShort();
            top = leis.readShort();
            left = leis.readShort();
            return 4*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.addObjectTableEntry(this);
        }
        
        @Override
        public void applyObject(HwmfGraphics ctx) {
        }
    }


    /**
     * The META_INTERSECTCLIPRECT record sets the clipping region in the playback device context to the
     * intersection of the existing clipping region and the specified rectangle.
     */
    public static class WmfIntersectClipRect implements HwmfRecord, HwmfObjectTableEntry {

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
         * lower-right corner of the rectangle.
         */
        private int bottom;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
         * lower-right corner of the rectangle.
         */
        private int right;

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
         * upper-left corner of the rectangle.
         */
        private int top;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
         * upper-left corner of the rectangle.
         */
        private int left;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.intersectClipRect;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            bottom = leis.readShort();
            right = leis.readShort();
            top = leis.readShort();
            left = leis.readShort();
            return 4*LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.addObjectTableEntry(this);
        }
        
        @Override
        public void applyObject(HwmfGraphics ctx) {
        }
    }

    /**
     * The META_SELECTCLIPREGION record specifies a Region Object to be the current clipping region.
     */
    public static class WmfSelectClipRegion implements HwmfRecord {

        /**
         * A 16-bit unsigned integer used to index into the WMF Object Table to get
         * the region to be clipped.
         */
        private int region;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.selectClipRegion;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            region = leis.readShort();
            return LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {

        }
    }

    public static class WmfScanObject {
        /**
         * A 16-bit unsigned integer that specifies the number of horizontal (x-axis)
         * coordinates in the ScanLines array. This value MUST be a multiple of 2, since left and right
         * endpoints are required to specify each scanline.
         */
        private int count;
        /**
         * A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the top scanline.
         */
        private int top;
        /**
         * A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the bottom scanline.
         */
        private int bottom;
        /**
         * A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
         * in logical units, of the left endpoint of the scanline.
         */
        private int left_scanline[];
        /**
         * A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
         * in logical units, of the right endpoint of the scanline.
         */
        private int right_scanline[];
        /**
         * A 16-bit unsigned integer that MUST be the same as the value of the Count
         * field; it is present to allow upward travel in the structure.
         */
        private int count2;

        public int init(LittleEndianInputStream leis) {
            count = leis.readUShort();
            top = leis.readUShort();
            bottom = leis.readUShort();
            int size = 3*LittleEndianConsts.SHORT_SIZE;
            left_scanline = new int[count/2];
            right_scanline = new int[count/2];
            for (int i=0; i<count/2; i++) {
                left_scanline[i] = leis.readUShort();
                right_scanline[i] = leis.readUShort();
                size += 2*LittleEndianConsts.SHORT_SIZE;
            }
            count2 = leis.readUShort();
            size += LittleEndianConsts.SHORT_SIZE;
            return size;
        }
    }

    public static class WmfCreateRegion implements HwmfRecord, HwmfObjectTableEntry {
        /**
         * A 16-bit signed integer. A value that MUST be ignored.
         */
        private int nextInChain;
        /**
         * A 16-bit signed integer that specifies the region identifier. It MUST be 0x0006.
         */
        private int objectType;
        /**
         * A 32-bit unsigned integer. A value that MUST be ignored.
         */
        private int objectCount;
        /**
         * A 16-bit signed integer that defines the size of the region in bytes plus the size of aScans in bytes.
         */
        private int regionSize;
        /**
         * A 16-bit signed integer that defines the number of scanlines composing the region.
         */
        private int scanCount;

        /**
         * A 16-bit signed integer that defines the maximum number of points in any one scan in this region.
         */
        private int maxScan;

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
         * lower-right corner of the rectangle.
         */
        private int bottom;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
         * lower-right corner of the rectangle.
         */
        private int right;

        /**
         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
         * upper-left corner of the rectangle.
         */
        private int top;

        /**
         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
         * upper-left corner of the rectangle.
         */
        private int left;

        /**
         * An array of Scan objects that define the scanlines in the region.
         */
        private WmfScanObject scanObjects[];

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.createRegion;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            nextInChain = leis.readShort();
            objectType = leis.readShort();
            objectCount = leis.readInt();
            regionSize = leis.readShort();
            scanCount = leis.readShort();
            maxScan = leis.readShort();
            left = leis.readShort();
            top = leis.readShort();
            right = leis.readShort();
            bottom = leis.readShort();
            
            int size = 9*LittleEndianConsts.SHORT_SIZE+LittleEndianConsts.INT_SIZE;

            scanObjects = new WmfScanObject[scanCount];
            for (int i=0; i<scanCount; i++) {
                size += (scanObjects[i] = new WmfScanObject()).init(leis);
            }

            return size;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.addObjectTableEntry(this);
        }
        
        @Override
        public void applyObject(HwmfGraphics ctx) {
            Rectangle2D lastRect = null;
            Area scanLines = new Area();
            int count = 0;
            for (WmfScanObject so : scanObjects) {
                int y = Math.min(so.top, so.bottom);
                int h = Math.abs(so.top - so.bottom - 1);
                for (int i=0; i<so.count/2; i++) {
                    int x = Math.min(so.left_scanline[i], so.right_scanline[i]);
                    int w = Math.abs(so.right_scanline[i] - so.left_scanline[i] - 1);
                    lastRect = new Rectangle2D.Double(x,y,w,h);
                    scanLines.add(new Area(lastRect));
                    count++;
                }
            }
            
            Shape region = null;
            if (count > 0) {
                region = (count == 1) ? lastRect : scanLines;
            }

            ctx.getProperties().setRegion(region);
        }
    }
}
