/*
 * 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.
 */

/* $Id$ */

package org.apache.fop.area;

import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;

import org.apache.fop.datatypes.FODimension;
import org.apache.fop.traits.WritingMode;

import static org.apache.fop.fo.Constants.EN_LR_TB;
import static org.apache.fop.fo.Constants.EN_RL_TB;
import static org.apache.fop.fo.Constants.EN_TB_LR;
import static org.apache.fop.fo.Constants.EN_TB_RL;

/**
 * Describe a PDF or PostScript style coordinate transformation matrix (CTM).
 * The matrix encodes translations, scaling and rotations of the coordinate
 * system used to render pages.
 */
public class CTM implements Serializable {

    private static final long serialVersionUID = -8743287485623778341L;

    private double a;
    private double b;
    private double c;
    private double d;
    private double e;
    private double f;

    private static final CTM CTM_LRTB = new CTM(1, 0, 0, 1, 0, 0);
    private static final CTM CTM_RLTB = new CTM(1, 0, 0, 1, 0, 0);
    private static final CTM CTM_TBRL = new CTM(0, 1, -1, 0, 0, 0);

    /**
     * Create the identity matrix
     */
    public CTM() {
        a = 1;
        b = 0;
        c = 0;
        d = 1;
        e = 0;
        f = 0;
    }

    /**
     * Initialize a CTM from the passed arguments.
     *
     * @param a the x scale
     * @param b the x shear
     * @param c the y shear
     * @param d the y scale
     * @param e the x shift
     * @param f the y shift
     */
    public CTM(double a, double b, double c, double d, double e, double f) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.e = e;
        this.f = f;
    }

    /**
     * Initialize a CTM to the identity matrix with a translation
     * specified by x and y
     *
     * @param x the x shift
     * @param y the y shift.
     */
    public CTM(double x, double y) {
        this.a = 1;
        this.b = 0;
        this.c = 0;
        this.d = 1;
        this.e = x;
        this.f = y;
    }

    /**
     * Initialize a CTM with the values of another CTM.
     *
     * @param ctm another CTM
     */
    protected CTM(CTM ctm) {
        this.a = ctm.a;
        this.b = ctm.b;
        this.c = ctm.c;
        this.d = ctm.d;
        this.e = ctm.e;
        this.f = ctm.f;
    }

    /**
     * Initialize a CTM with the values of an AffineTransform.
     *
     * @param at the transformation matrix
     */
    public CTM(AffineTransform at) {
        double[] matrix = new double[6];
        at.getMatrix(matrix);
        this.a = matrix[0];
        this.b = matrix[1];
        this.c = matrix[2];
        this.d = matrix[3];
        this.e = matrix[4];
        this.f = matrix[5];
    }

    /**
     * Return a CTM which will transform coordinates for a particular writing-mode
     * into normalized first quandrant coordinates.
     * @param wm A writing mode constant from fo.properties.WritingMode, ie.
     * one of LR_TB, RL_TB, TB_RL, TB_LR.
     * @param ipd The inline-progression dimension of the reference area whose
     * CTM is being set..
     * @param bpd The block-progression dimension of the reference area whose
     * CTM is being set.
     * @return a new CTM with the required transform
     */
    public static CTM getWMctm(WritingMode wm, int ipd, int bpd) {
        CTM wmctm;
        switch (wm.getEnumValue()) {
            case EN_LR_TB:
                return new CTM(CTM_LRTB);
            case EN_RL_TB:
                return new CTM(CTM_RLTB);
            case EN_TB_RL:  // CJK
            case EN_TB_LR:  // CJK
                wmctm = new CTM(CTM_TBRL);
                wmctm.e = bpd;
                return wmctm;
            default:
                return null;
        }
    }

    /**
     * Multiply new passed CTM with this one and generate a new result CTM.
     * @param premult The CTM to multiply with this one. The new one will be
     * the first multiplicand.
     * @return CTM The result of multiplying premult * this.
     */
    public CTM multiply(CTM premult) {
        return new CTM((premult.a * a) + (premult.b * c),
                              (premult.a * b) + (premult.b * d),
                              (premult.c * a) + (premult.d * c),
                              (premult.c * b) + (premult.d * d),
                              (premult.e * a) + (premult.f * c) + e,
                              (premult.e * b) + (premult.f * d) + f);
    }

    /**
     * Rotate this CTM by "angle" radians and return a new result CTM.
     * This is used to account for reference-orientation.
     * @param angle The angle in radians. Positive angles are measured counter-
     * clockwise.
     * @return CTM The result of rotating this CTM.
     */
    public CTM rotate(double angle) {
        double cos;
        double sin;
        if (angle == 90.0 || angle == -270.0) {
            cos = 0.0;
            sin = 1.0;
        } else if (angle == 270.0 || angle == -90.0) {
            cos = 0.0;
            sin = -1.0;
        } else if (angle == 180.0 || angle == -180.0) {
            cos = -1.0;
            sin = 0.0;
        } else {
            double rad = Math.toRadians(angle);
            cos = Math.cos(rad);
            sin = Math.sin(rad);
        }
        CTM rotate = new CTM(cos, -sin, sin, cos, 0, 0);
        return multiply(rotate);
    }

    /**
     * Translate this CTM by the passed x and y values and return a new result CTM.
     * @param x The amount to translate along the x axis.
     * @param y The amount to translate along the y axis.
     * @return CTM The result of translating this CTM.
     */
    public CTM translate(double x, double y) {
        CTM translate = new CTM(1, 0, 0, 1, x, y);
        return multiply(translate);
    }

    /**
     * Scale this CTM by the passed x and y values and return a new result CTM.
     * @param x The amount to scale along the x axis.
     * @param y The amount to scale along the y axis.
     * @return CTM The result of scaling this CTM.
     */
    public CTM scale(double x, double y) {
        CTM scale = new CTM(x, 0, 0, y, 0, 0);
        return multiply(scale);
    }

    /**
     * Transform a rectangle by the CTM to produce a rectangle in the transformed
     * coordinate system.
     * @param inRect The rectangle in the original coordinate system
     * @return Rectangle2D The rectangle in the transformed coordinate system.
     */
    public Rectangle2D transform(Rectangle2D inRect) {
        // Store as 2 sets of 2 points and transform those, then
        // recalculate the width and height
        int x1t = (int)(inRect.getX() * a + inRect.getY() * c + e);
        int y1t = (int)(inRect.getX() * b + inRect.getY() * d + f);
        int x2t = (int)((inRect.getX() + inRect.getWidth()) * a
                        + (inRect.getY() + inRect.getHeight()) * c + e);
        int y2t = (int)((inRect.getX() + inRect.getWidth()) * b
                        + (inRect.getY() + inRect.getHeight()) * d + f);
        // Normalize with x1 < x2
        if (x1t > x2t) {
            int tmp = x2t;
            x2t = x1t;
            x1t = tmp;
        }
        if (y1t > y2t) {
            int tmp = y2t;
            y2t = y1t;
            y1t = tmp;
        }
        return new Rectangle(x1t, y1t, x2t - x1t, y2t - y1t);
    }

    /**
     * Get string for this transform.
     *
     * @return a string with the transform values
     */
    @Override
    public String toString() {
        return "[" + a + " " + b + " " + c + " " + d + " " + e + " "
               + f + "]";
    }

    /**
     * Get an array containing the values of this transform.
     * This creates and returns a new transform with the values in it.
     *
     * @return an array containing the transform values
     */
    public double[] toArray() {
        return new double[]{a, b, c, d, e, f};
    }

    /**
     * Returns this CTM as an AffineTransform object.
     * @return the AffineTransform representation
     */
    public AffineTransform toAffineTransform() {
        return new AffineTransform(toArray());
    }

    /**
     * Construct a coordinate transformation matrix (CTM).
     * @param absRefOrient absolute reference orientation
     * @param writingMode the writing mode
     * @param absVPrect absolute viewpoint rectangle
     * @param reldims relative dimensions
     * @return CTM the coordinate transformation matrix (CTM)
     */
    public static CTM getCTMandRelDims(int absRefOrient,
                                       WritingMode writingMode,
                                       Rectangle2D absVPrect,
                                       FODimension reldims) {
        int width;
        int height;
        // We will use the absolute reference-orientation to set up the CTM.
        // The value here is relative to its ancestor reference area.
        if (absRefOrient % 180 == 0) {
            width = (int) absVPrect.getWidth();
            height = (int) absVPrect.getHeight();
        } else {
            // invert width and height since top left are rotated by 90 (cl or ccl)
            height = (int) absVPrect.getWidth();
            width = (int) absVPrect.getHeight();
        }
        /* Set up the CTM for the content of this reference area.
         * This will transform region content coordinates in
         * writing-mode relative into absolute page-relative
         * which will then be translated based on the position of
         * the region viewport.
         * (Note: scrolling between region vp and ref area when
         * doing online content!)
         */
        CTM ctm = new CTM(absVPrect.getX(), absVPrect.getY());

        // First transform for rotation
        if (absRefOrient != 0) {
            // Rotation implies translation to keep the drawing area in the
            // first quadrant. Note: rotation is counter-clockwise
            switch (absRefOrient) {
                case 90:
                case -270:
                    ctm = ctm.translate(0, width); // width = absVPrect.height
                    break;
                case 180:
                case -180:
                    ctm = ctm.translate(width, height);
                    break;
                case 270:
                case -90:
                    ctm = ctm.translate(height, 0); // height = absVPrect.width
                    break;
                default:
                    throw new RuntimeException();
            }
            ctm = ctm.rotate(absRefOrient);
        }
        /* Since we've already put adjusted width and height values for the
         * top and left positions implied by the reference-orientation, we
         * can set ipd and bpd appropriately based on the writing mode.
         */

        switch (writingMode.getEnumValue()) {
        case EN_TB_LR:
        case EN_TB_RL:
            reldims.ipd = height;
            reldims.bpd = width;
            break;
        case EN_LR_TB:
        case EN_RL_TB:
        default:
            reldims.ipd = width;
            reldims.bpd = height;
            break;
        }
        // Set a rectangle to be the writing-mode relative version???
        // Now transform for writing mode
        return ctm.multiply(CTM.getWMctm(writingMode, reldims.ipd, reldims.bpd));
    }

}
