/*
 *    GeoTools - OpenSource mapping toolkit
 *    http://geotools.org
 *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
 *    (C) 2003, Institut de Recherche pour le Développement
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.coverage.grid;

// J2SE dependencies
import java.awt.geom.AffineTransform;

// JUnit dependencies
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

// OpenGIS dependencies
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.geometry.Envelope;

// Geotools dependencies
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.operation.matrix.MatrixFactory;


/**
 * Test the {@link GridGeometry} implementation.
 *
 * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/test/java/org/geotools/coverage/grid/GridGeometryTest.java $
 * @version $Id: GridGeometryTest.java 25050 2007-04-06 00:41:49Z jgarnett $
 * @author Martin Desruisseaux
 */
public class GridGeometryTest extends TestCase {
    /**
     * Run the suite from the command line.
     */
    public static void main(final String[] args) {
        junit.textui.TestRunner.run(suite());
    }

    /**
     * Returns the test suite.
     */
    public static Test suite() {
        return new TestSuite(GridGeometryTest.class);
    }
    
    /**
     * Constructs a test case with the given name.
     */
    public GridGeometryTest(final String name) {
        super(name);
    }

    /**
     * Tests the construction with an identity transform.
     */
    public void testIdentity() throws FactoryException {
        final MathTransformFactory factory = ReferencingFactoryFinder.getMathTransformFactory(null);
        final int[] lower = new int[] {0,     0, 2};
        final int[] upper = new int[] {100, 200, 4};
        final MathTransform identity = factory.createAffineTransform(MatrixFactory.create(4));
        GridGeometry2D gg;
        try {
            gg = new GridGeometry2D(new GeneralGridRange(lower,upper), identity, null);
            fail();
        } catch (IllegalArgumentException e) {
            // This is the expected dimension.
        }
        upper[2] = 3;
        gg = new GridGeometry2D(new GeneralGridRange(lower,upper), identity, null);
        assertTrue(identity.isIdentity());
        assertTrue(gg.getGridToCoordinateSystem().isIdentity());
        assertTrue(gg.getGridToCRS2D().isIdentity());
        assertEquals(3, gg.getGridToCoordinateSystem().getSourceDimensions());
        assertEquals(2, gg.getGridToCRS2D().getSourceDimensions());
        assertTrue(gg.getGridToCRS2D() instanceof AffineTransform);
    }

    /**
     * Tests the construction from an envelope.
     */
    public void testEnvelope() {
        final int[]    lower   = new int[]    {   0,   0,  4};
        final int[]    upper   = new int[]    {  90,  45,  5};
        final double[] minimum = new double[] {-180, -90,  9};
        final double[] maximum = new double[] {+180, +90, 10};
        final GridGeometry2D gg;
        gg = new GridGeometry2D(new GeneralGridRange(lower,upper),
                                new GeneralEnvelope(minimum, maximum), null, false);
        final AffineTransform tr = (AffineTransform) gg.getGridToCRS2D();
        assertEquals(AffineTransform.TYPE_UNIFORM_SCALE |
                     AffineTransform.TYPE_TRANSLATION, tr.getType());

        assertEquals(4, tr.getScaleX(), 0);
        assertEquals(4, tr.getScaleY(), 0);
        assertEquals(-178, tr.getTranslateX(), 0);
        assertEquals( -88, tr.getTranslateY(), 0);
    }
}
