/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2005 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */
package org.freedesktop.cairo;

import org.gnu.glib.Struct;
import org.gnu.glib.Handle;

/**
 * TODO: error handling
 *
 * @deprecated This class is part of the java-gnome 2.x family of libraries,
 *             which, due to their inefficiency and complexity, are no longer
 *             being maintained and have been abandoned by the java-gnome
 *             project. This class may exist in java-gnome 4.0; look out for
 *             <code>org.freedesktop.cairo.Matrix</code>.
 *             As this package was never correctly implemented in java-gnome 2.x,
 *             any new code written will likely have a considerably different
 *             public API.
 */
public class Matrix extends CairoObject {

    Matrix(Handle hndl) {
        super(hndl);
    }

    /**
     * Creates a new matrix initialized with a noop transform.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
	public Matrix() {
		super(new_identity_matrix());
	}

    /**
     * Disposes all the native resources used by the matrix.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    protected void finalize() throws Throwable {
        free_matrix(getHandle());
        super.finalize();
    }

    /**
     * Sets the matrix to be the affine transformation given by xx, yx, xy, yy,
     * x0, y0. The transformation is given by: <code> 
     *  x_new = xx * x + xy * y + x0;
     *  y_new = yx * x + yy * y + y0;
     *  </code>
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void init(double xx, double yx, double xy, double yy, double x0,
            double y0) {
        cairo_matrix_init(getHandle(), xx, yx, xy, yy, x0, y0);
    }

    /**
     * Modifies the matrix to be an identity transformation.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void initIdentity() {
        cairo_matrix_init_identity(getHandle());
    }

    /**
     * Initializes the matrix to a transformation that translates by tx and ty
     * in the X and Y dimensions, respectively.
     * 
     * @param tx
     *            amount to translate in the X direction.
     * @param ty
     *            amount to translate in the Y direction.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void initTranslate(double tx, double ty) {
        cairo_matrix_init_translate(getHandle(), tx, ty);
    }

    /**
     * Initializes the matrix to a transformation that scales by sx and sy in
     * the X and Y dimensions, respectively.
     * 
     * @param sx
     *            scale factor in the X direction.
     * @param sy
     *            scale factor in the Y direction.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void initScale(double sx, double sy) {
        cairo_matrix_init_scale(getHandle(), sx, sy);
    }

    /**
     * Initialized the matrix to a transformation that rotates by
     * 
     * @radians.
     * 
     * @param radians
     *            angle of rotation, in radians. The direction of rotation is
     *            defined such that positive angles rotate in the direction from
     *            the positive X axis toward the positive Y axis. With the
     *            default axis orientation of cairo, positive angles rotate in a
     *            clockwise direction.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void initRotate(double radians) {
        cairo_matrix_init_rotate(getHandle(), radians);
    }

    /**
     * Appends a transaltion transformation to this matrix.
     * 
     * @param tx
     *            X axis translation
     * @param ty
     *            Y axis translation
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void translate(double tx, double ty) {
        cairo_matrix_translate(getHandle(), tx, ty);
    }

    /**
     * Appends non-uniform scaling to this matrix.
     * 
     * @param sx
     *            X axis scaling factor
     * @param sy
     *            Y axis scaling factor
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void scale(double sx, double sy) {
        cairo_matrix_scale(getHandle(), sx, sy);
    }

    /**
     * Appends rotation transformation to this matrix.
     * 
     * @param radians
     *            The rotation angle in radians.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void rotate(double radians) {
        cairo_matrix_rotate(getHandle(), radians);
    }

    /**
     * Inverts this matrix.
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void invert() {
        cairo_matrix_invert(getHandle());
    }

    /**
     * Multiplies 2 matrices and returns the result.
     * 
     * @param a
     *            first matrix
     * @param b
     *            second matrix
     * @return The product
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    static public Matrix multiply(Matrix a, Matrix b) {
        Handle hndl = cairo_matrix_multiply(a.getHandle(), b.getHandle());
        return new Matrix(hndl);
    }

    /**
     * Transforms the given distance and returns transformed co-ordinates
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Point transformDistance(Point distance) {
        double[] dx = new double[] { distance.getX() };
        double[] dy = new double[] { distance.getY() };
        cairo_matrix_transform_distance(getHandle(), dx, dy);
        return new Point(dx[0], dy[0]);
    }

    /**
     * Transforms the given point and returns transformed co-ordinates
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Point transformPoint(Point point) {
        double[] dx = new double[] { point.getX() };
        double[] dy = new double[] { point.getY() };
        cairo_matrix_transform_distance(getHandle(), dx, dy);
        return new Point(dx[0], dy[0]);
    }

    public double getXX() {
        return getXX(getHandle());
    }

    public void setXX(double xx) {
        setXX(getHandle(), xx);
    }

    public double getYX() {
        return getYX(getHandle());
    }

    public void setYX(double yx) {
        setYX(getHandle(), yx);
    }

    public double getXY() {
        return getXY(getHandle());
    }

    public void setXY(double xy) {
        setXY(getHandle(), xy);
    }

    public double getYY() {
        return getYY(getHandle());
    }

    public void setYY(double yy) {
        setYY(getHandle(), yy);
    }

    public double getX0() {
        return getX0(getHandle());
    }

    public void setX0(double x0) {
        setX0(getHandle(), x0);
    }

    public double getY0() {
        return getY0(getHandle());
    }

    public void setY0(double y0) {
        setY0(getHandle(), y0);
    }

    /*
     * Native calls
     * @deprecated Superceeded by java-gnome 4.0; this method or constant
     *             will no doubt exist conceptually, but it may have a different
     *             name or signature in order that the presented API is an
     *             algorithmic mapping of the underlying native libraries.
     */
    native static final private double getXX(Handle matrix);

    native static final private double getYX(Handle matrix);

    native static final private double getXY(Handle matrix);

    native static final private double getYY(Handle matrix);

    native static final private double getX0(Handle matrix);

    native static final private double getY0(Handle matrix);

    native static final private void setXX(Handle matrix, double xx);

    native static final private void setYX(Handle matrix, double yx);

    native static final private void setXY(Handle matrix, double xy);

    native static final private void setYY(Handle matrix, double yy);

    native static final private void setX0(Handle matrix, double x0);

    native static final private void setY0(Handle matrix, double y0);

    native static final private Handle new_identity_matrix();

    native static final private void free_matrix(Handle matrix);

    native static final private void cairo_matrix_init(Handle matrix,
            double xx, double yx, double xy, double yy, double x0, double y0);

    native static final private void cairo_matrix_init_identity(Handle matrix);

    native static final private void cairo_matrix_init_translate(Handle matrix,
            double tx, double ty);

    native static final private void cairo_matrix_init_scale(Handle matrix,
            double sx, double sy);

    native static final private void cairo_matrix_init_rotate(Handle matrix,
            double radians);

    native static final private void cairo_matrix_translate(Handle matrix,
            double tx, double ty);

    native static final private void cairo_matrix_scale(Handle matrix,
            double sx, double sy);

    native static final private void cairo_matrix_rotate(Handle matrix,
            double radians);

    native static final private void cairo_matrix_invert(Handle matrix);

    native static final private Handle cairo_matrix_multiply(Handle a,
            Handle b);

    native static final private void cairo_matrix_transform_distance(
            Handle handle, double[] dx, double[] dy);

    native static final private void cairo_matrix_transform_point(
            Handle handle, double[] x, double[] y);

}
