/* Copyright (C) 2000, 2001  Free Software Foundation

   This file is part of libjava.

This software is copyrighted work licensed under the terms of the
Libjava License.  Please consult the file "LIBJAVA_LICENSE" for
details.  */

package java.awt.geom;
import java.awt.*;
import java.io.Serializable;

/**
 * @author Tom Tromey <tromey@cygnus.com>
 * @date April 16, 2000
 */

/* Status: mostly complete.  Search for fixme to see problems.
   Also, TYPE_ returns are not handled correctly.  */

public class AffineTransform implements Cloneable, Serializable
{
  public static final int TYPE_IDENTITY = 0;
  public static final int TYPE_FLIP = 64;
  public static final int TYPE_GENERAL_ROTATION = 16;
  public static final int TYPE_GENERAL_SCALE = 4;
  public static final int TYPE_GENERAL_TRANSFORM = 32;
  public static final int TYPE_MASK_ROTATION = 24;
  public static final int TYPE_MASK_SCALE = 6;
  public static final int TYPE_QUADRANT_ROTATION = 8;
  public static final int TYPE_TRANSLATION = 1;
  public static final int TYPE_UNIFORM_SCALE = 2;

  public AffineTransform ()
  {
    setToIdentity ();
  }

  public AffineTransform (AffineTransform tx)
  {
    setTransform (tx);
  }

  public AffineTransform (float m00, float m10,
			  float m01, float m11,
			  float m02, float m12)
  {
    this.m00 = m00;
    this.m10 = m10;
    this.m01 = m01;
    this.m11 = m11;
    this.m02 = m02;
    this.m12 = m12;
    this.type = TYPE_GENERAL_TRANSFORM;
  }

  public AffineTransform (float[] flatmatrix)
  {
    m00 = flatmatrix[0];
    m10 = flatmatrix[1];
    m01 = flatmatrix[2];
    m11 = flatmatrix[3];
    if (flatmatrix.length >= 6)
      {
	m02 = flatmatrix[4];
	m12 = flatmatrix[5];
      }
  }

  public AffineTransform (double m00, double m10, double m01,
			  double m11, double m02, double m12)
  {
    this.m00 = m00;
    this.m10 = m10;
    this.m01 = m01;
    this.m11 = m11;
    this.m02 = m02;
    this.m12 = m12;
    this.type = TYPE_GENERAL_TRANSFORM;
  }

  public AffineTransform (double[] flatmatrix)
  {
    m00 = flatmatrix[0];
    m10 = flatmatrix[1];
    m01 = flatmatrix[2];
    m11 = flatmatrix[3];
    if (flatmatrix.length >= 6)
      {
	m02 = flatmatrix[4];
	m12 = flatmatrix[5];
      }
  }

  public static AffineTransform getTranslateInstance (double tx, double ty)
  {
    AffineTransform t = new AffineTransform ();
    t.setToTranslation (tx, ty);
    return t;
  }

  public static AffineTransform getRotateInstance (double theta)
  {
    AffineTransform t = new AffineTransform ();
    t.setToRotation (theta);
    return t;
  }

  public static AffineTransform getRotateInstance (double theta,
						   double x, double y)
  {
    AffineTransform t = new AffineTransform ();
    t.rotate (theta, x, y);
    return t;
  }

  public static AffineTransform getScaleInstance (double sx, double sy)
  {
    AffineTransform t = new AffineTransform ();
    t.setToScale (sx, sy);
    return t;
  }

  public static AffineTransform getShearInstance (double shx, double shy)
  {
    AffineTransform t = new AffineTransform ();
    t.setToShear (shx, shy);
    return t;
  }

  public int getType ()
  {
    return type;
  }

  public double getDeterminant ()
  {
    return m00 * m11 - m01 * m10;
  }

  public void getMatrix (double[] flatmatrix)
  {
    flatmatrix[0] = m00;
    flatmatrix[1] = m10;
    flatmatrix[2] = m01;
    flatmatrix[3] = m11;
    if (flatmatrix.length >= 6)
      {
	flatmatrix[4] = m02;
	flatmatrix[5] = m12;
      }
  }

  public double getScaleX ()
  {
    return m00;
  }

  public double getScaleY ()
  {
    return m11;
  }

  public double getShearX ()
  {
    return m01;
  }

  public double getShearY ()
  {
    return m10;
  }

  public double getTranslateX ()
  {
    return m02;
  }

  public double getTranslateY ()
  {
    return m12;
  }

  public void translate (double tx, double ty)
  {
    m02 += tx * m00 + ty * m01;
    m12 += tx * m10 + ty * m11;
  }

  public void rotate (double theta)
  {
    double c = Math.cos (theta);
    double s = Math.sin (theta);
    double n00 = m00 *  c + m01 * s;
    double n01 = m00 * -s + m01 * c;
    double n10 = m10 *  c + m11 * s;
    double n11 = m10 * -s + m11 * c;

    m00 = n00;
    m01 = n01;
    m10 = n10;
    m11 = n11;
  }

  public void rotate (double theta, double x, double y)
  {
    translate (x, y);
    rotate (theta);
    translate (-x, -y);
  }

  public void scale (double sx, double sy)
  {
    m00 *= sx;
    m01 *= sy;
    m10 *= sx;
    m11 *= sy;
  }

  public void shear (double shx, double shy)
  {
    double n00 = m00 + shx * m01;
    double n01 = shx * m00 + m01;
    double n10 = m10 * shy + m11;
    double n11 = shx * m10 + m11;

    m00 = n00;
    m01 = n01;
    m10 = n10;
    m11 = n11;
  }

  public void setToIdentity ()
  {
    m00 = m11 = 1;
    m01 = m02 = m10 = m12 = 0;
    type = TYPE_IDENTITY;
  }

  public void setToTranslation (double tx, double ty)
  {
    m00 = m11 = 1;
    m01 = m10 = 0;
    m02 = tx;
    m12 = ty;
    type = TYPE_TRANSLATION;
  }

  public void setToRotation (double theta)
  {
    double c = Math.cos (theta);
    double s = Math.sin (theta);

    m00 = c;
    m01 = -s;
    m02 = 0;
    m10 = s;
    m11 = c;
    m12 = 0;
    type = TYPE_GENERAL_ROTATION;
  }

  public void setToRotation (double theta, double x, double y)
  {
    double c = Math.cos (theta);
    double s = Math.sin (theta);

    m00 = c;
    m01 = -s;
    m02 = x - x * c + y * s;
    m10 = s;
    m11 = c;
    m12 = y - x * s - y * c;
    type = TYPE_GENERAL_TRANSFORM;
  }

  public void setToScale (double sx, double sy)
  {
    m00 = sx;
    m01 = m02 = m10 = m12 = 0;
    m11 = sy;
    type = (sx == sy) ? TYPE_UNIFORM_SCALE : TYPE_GENERAL_SCALE;
  }

  public void setToShear (double shx, double shy)
  {
    m00 = m11 = 1;
    m01 = shx;
    m10 = shy;
    m02 = m12 = 0;
    type = TYPE_GENERAL_TRANSFORM;
  }

  public void setTransform (AffineTransform tx)
  {
    m00 = tx.m00;
    m01 = tx.m01;
    m02 = tx.m02;
    m10 = tx.m10;
    m11 = tx.m11;
    m12 = tx.m12;
    type = tx.type;
  }

  public void setTransform (double m00, double m10, double m01,
			    double m11, double m02, double m12)
  {
    this.m00 = m00;
    this.m10 = m10;
    this.m01 = m01;
    this.m11 = m11;
    this.m02 = m02;
    this.m12 = m12;
    this.type = 0;		// FIXME
  }

  public void concatenate (AffineTransform tx)
  {
    double n00 = m00 * tx.m00 + m01 * tx.m10;
    double n01 = m00 * tx.m01 + m01 * tx.m11;
    double n02 = m00 * tx.m02 + m01 * tx.m12 + m02;
    double n10 = m10 * tx.m00 + m11 * tx.m10;
    double n11 = m10 * tx.m01 + m11 * tx.m11;
    double n12 = m10 * tx.m02 + m11 * tx.m12 + m12;

    m00 = n00;
    m01 = n01;
    m02 = n02;
    m10 = n10;
    m11 = n11;
    m12 = n12;
  }

  public void preConcatenate (AffineTransform tx)
  {
    double n00 = tx.m00 * m00 + tx.m01 * m10;
    double n01 = tx.m00 * m01 + tx.m01 * m11;
    double n02 = tx.m00 * m02 + tx.m01 * m12 + tx.m02;
    double n10 = tx.m10 * m00 + tx.m11 * m10;
    double n11 = tx.m10 * m01 + tx.m11 * m11;
    double n12 = tx.m10 * m02 + tx.m11 * m12 + tx.m12;

    m00 = n00;
    m01 = n01;
    m02 = n02;
    m10 = n10;
    m11 = n11;
    m12 = n12;
  }

  public AffineTransform createInverse ()
    throws NoninvertibleTransformException
  {
    double det = getDeterminant ();
    if (det == 0)
      throw new NoninvertibleTransformException ("can't invert transform");

    double i00 = m11 / det;
    double i01 = -m10 / det;
    double i02 = 0;
    double i10 = m01 / det;
    double i11 = -m00 / det;
    double i12 = 0;

    return new AffineTransform (i00, i01, i02,
				i10, i11, i12);
  }

  public Point2D transform (Point2D src, Point2D dst)
  {
    if (dst == null)
      dst = new Point2D.Double ();

    // We compute and set separately to correctly overwrite if
    // src==dst.
    double x = src.getX ();
    double y = src.getY ();
    double nx = m00 * x + m01 * y + m02;
    double ny = m10 * x + m11 * y + m12;

    dst.setLocation (nx, ny);

    return dst;
  }

  public void transform (Point2D[] src, int srcOff,
			 Point2D[] dst, int dstOff,
			 int num)
  {
    while (num-- > 0)
      {
	dst[dstOff] = transform (src[srcOff], dst[dstOff]);
	++srcOff;
	++dstOff;
      }
  }

  public void transform (float[] srcPts, int srcOff,
			 float[] dstPts, int dstOff,
			 int num)
  {
    while (num-- > 0)
      {
	float x = srcPts[srcOff];
	float y = srcPts[srcOff + 1];
	srcOff += 2;
	float nx = (float) (m00 * x + m01 * y + m02);
	float ny = (float) (m10 * x + m10 * y + m12);
	dstPts[dstOff] = nx;
	dstPts[dstOff + 1] = ny;
	dstOff += 2;
      }
  }

  public void transform (double[] srcPts, int srcOff,
			 double[] dstPts, int dstOff,
			 int num)
  {
    while (num-- > 0)
      {
	double x = srcPts[srcOff];
	double y = srcPts[srcOff + 1];
	srcOff += 2;
	double nx = m00 * x + m01 * y + m02;
	double ny = m10 * x + m10 * y + m12;
	dstPts[dstOff] = nx;
	dstPts[dstOff + 1] = ny;
	dstOff += 2;
      }
  }

  public void transform (float[] srcPts, int srcOff,
			 double[] dstPts, int dstOff,
			 int num)
  {
    while (num-- > 0)
      {
	float x = srcPts[srcOff];
	float y = srcPts[srcOff + 1];
	srcOff += 2;
	double nx = m00 * x + m01 * y + m02;
	double ny = m10 * x + m10 * y + m12;
	dstPts[dstOff] = nx;
	dstPts[dstOff + 1] = ny;
	dstOff += 2;
      }
  }

  public void transform (double[] srcPts, int srcOff,
			 float[] dstPts, int dstOff,
			 int num)
  {
    while (num-- > 0)
      {
	double x = srcPts[srcOff];
	double y = srcPts[srcOff + 1];
	srcOff += 2;
	float nx = (float) (m00 * x + m01 * y + m02);
	float ny = (float) (m10 * x + m10 * y + m12);
	dstPts[dstOff] = nx;
	dstPts[dstOff + 1] = ny;
	dstOff += 2;
      }
  }

  public Point2D inverseTransform (Point2D src, Point2D dst)
    throws NoninvertibleTransformException
  {
    double det = getDeterminant ();
    if (det == 0)
      throw new NoninvertibleTransformException ("couldn't invert transform");

    if (dst == null)
      dst = new Point2D.Double ();
    double x = src.getX ();
    double y = src.getY ();
    double nx = (m11 * x + - m10 * y) / det;
    double ny = (m01 * x + - m00 * y) / det;
    dst.setLocation (nx, ny);
    return dst;
  }

  public void inverseTransform (double[] srcPts, int srcOff,
				double[] dstPts, int dstOff,
				int num)
    throws NoninvertibleTransformException
  {
    double det = getDeterminant ();
    if (det == 0)
      throw new NoninvertibleTransformException ("couldn't invert transform");

    while (num-- > 0)
      {
	double x = srcPts[srcOff];
	double y = srcPts[srcOff + 1];
	double nx = (m11 * x + - m10 * y) / det;
	double ny = (m01 * x + - m00 * y) / det;
	dstPts[dstOff] = nx;
	dstPts[dstOff + 1] = ny;
	dstOff += 2;
	srcOff += 2;
      }
  }

  public Point2D deltaTransform (Point2D src, Point2D dst)
  {
    if (dst == null)
      dst = new Point2D.Double ();
    double x = src.getX ();
    double y = src.getY ();
    double nx = m00 * x + m01 * y;
    double ny = m10 * x + m11 * y;
    dst.setLocation (nx, ny);
    return dst;
  }

  public void deltaTransform (double[] srcPts, int srcOff,
			      double[] dstPts, int dstOff,
			      int num)
  {
    while (num-- > 0)
      {
	double x = srcPts[srcOff];
	double y = srcPts[srcOff + 1];
	double nx = m00 * x + m01 * y;
	double ny = m10 * x + m11 * y;
	dstPts[dstOff] = nx;
	dstPts[dstOff + 1] = ny;
	dstOff += 2;
	srcOff += 2;
      }
  }

  public Shape createTransformedShape (Shape pSrc)
  {
    // FIXME
    return null;
  }

  public String toString ()
  {
    // FIXME
    return null;
  }

  public boolean isIdentity ()
  {
    return (m00 == 1 && m01 == 0 && m02 == 0
	    && m10 == 0 && m11 == 1 && m12 == 0);
  }

  public Object clone ()
  {
    return new AffineTransform (this);
  }

  public int hashCode ()
  {
    // FIXME
    return 23;
  }

  public boolean equals (Object obj)
  {
    if (! (obj instanceof AffineTransform))
      return false;
    AffineTransform t = (AffineTransform) obj;
    return (m00 == t.m00 && m01 == t.m01 && m02 == t.m02
	    && m10 == t.m10 && m11 == t.m11 && m12 == t.m12);
  }

  // This iterator is used to apply an AffineTransform to some other
  // iterator.  It is not private because we want to be able to access
  // it from the rest of this package.
  class Iterator implements PathIterator
  {
    // The iterator we are applied to.
    private PathIterator subIterator;

    public Iterator (PathIterator subIterator)
    {
      this.subIterator = subIterator;
    }

    public int currentSegment (double[] coords)
    {
      int r = subIterator.currentSegment (coords);
      int count = 0;

      switch (r)
	{
	case SEG_CUBICTO:
	  count = 3;
	  break;

	case SEG_QUADTO:
	  count = 2;
	  break;

	case SEG_LINETO:
	case SEG_MOVETO:
	  count = 1;
	  break;

	default:
	  // Error.  But how to report?
	case SEG_CLOSE:
	  break;
	}

      transform (coords, 0, coords, 0, count);

      return r;
    }

    public int currentSegment (float[] coords)
    {
      int r = subIterator.currentSegment (coords);
      int count = 0;

      switch (r)
	{
	case SEG_CUBICTO:
	  count = 3;
	  break;

	case SEG_QUADTO:
	  count = 2;
	  break;

	case SEG_LINETO:
	case SEG_MOVETO:
	  count = 1;
	  break;

	default:
	  // Error.  But how to report?
	case SEG_CLOSE:
	  break;
	}

      transform (coords, 0, coords, 0, count);

      return r;
    }

    public int getWindingRule ()
    {
      return subIterator.getWindingRule ();
    }

    public boolean isDone ()
    {
      return subIterator.isDone ();
    }

    public void next ()
    {
      subIterator.next ();
    }
  }

  private double m00, m01, m02;
  private double m10, m11, m12;
  private int type;
}
