/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.spatial.jgeometry;

import java.util.ArrayList;
import java.util.List;

import oracle.spatial.geometry.JGeometry;
import org.eclipse.persistence.testing.models.spatial.jgeometry.SimpleSpatial;
import org.eclipse.persistence.testing.models.spatial.jgeometry.wrapped.WrappedSpatial;

/**
 * SQL samples from C:\oracle\db\10.2\md\demo\examples\eginsert.sql
 * Note: Table re-named from TEST81 to SIMPLE_SPATIAL
 */
public class SampleGeometries {
    private int srid = 0;

    public SampleGeometries() {
    }

    public SampleGeometries(int srid) {
        this.srid = srid;
    }

    public int getSRID() {
        return this.srid;
    }

    /**
     * @return population objects for database initialization
     */
    public List<SimpleSpatial> simplePopulation() throws Exception {
        List<SimpleSpatial> population = new ArrayList<SimpleSpatial>();

        population.add(new SimpleSpatial(1000, pointCluster1()));
        population.add(new SimpleSpatial(1001, pointCluster2()));
        population.add(new SimpleSpatial(1002, simplyPolygon()));
        population.add(new SimpleSpatial(1003, polygonOfCircularArcs()));
        population.add(new SimpleSpatial(1004, circle()));
        population.add(new SimpleSpatial(1005, rectangle()));
        population.add(new SimpleSpatial(1006, compoundLineAndRectangle()));
        population.add(new SimpleSpatial(1007,
                                         compoundPolygonWithRectangularHole()));
        population.add(new SimpleSpatial(1008, geometry1008()));
        population.add(new SimpleSpatial(1009, geometryWithNulls()));
        population.add(new SimpleSpatial(1010, null));
        population.add(new SimpleSpatial(1011, polygon1011()));
        population.add(new SimpleSpatial(1012, polygon1012()));
        population.add(new SimpleSpatial(1013, point()));

        return population;
    }

    public List<WrappedSpatial> wrappedPopulation() throws Exception {
        List<WrappedSpatial> population = new ArrayList<WrappedSpatial>();

        population.add(new WrappedSpatial(1000, 1, pointCluster1()));
        population.add(new WrappedSpatial(1001, 2, pointCluster2()));
        population.add(new WrappedSpatial(1002, 3, simplyPolygon()));
        population.add(new WrappedSpatial(1003, 4, polygonOfCircularArcs()));
        population.add(new WrappedSpatial(1004, 5, circle()));
        population.add(new WrappedSpatial(1005, 6, rectangle()));
        population.add(new WrappedSpatial(1006, 7,
                                          compoundLineAndRectangle()));
        population.add(new WrappedSpatial(1007, 8,
                                          compoundPolygonWithRectangularHole()));
        population.add(new WrappedSpatial(1008, 9, geometry1008()));
        population.add(new WrappedSpatial(1009, 10, geometryWithNulls()));
        population.add(new WrappedSpatial(1010, 11, null));
        population.add(new WrappedSpatial(1011, 12, polygon1011()));
        population.add(new WrappedSpatial(1012, 13, polygon1012()));
        population.add(new WrappedSpatial(1013, 14, point()));

        return population;
    }

    /**
     * mdsys.sdo_geometry(5,
     *                   NULL, null,
     *                   mdsys.sdo_elem_info_array(1,1,3),
     *                   mdsys.sdo_ordinate_array(1.1, 1.1, 2.2, 2.2, 3.3, 4.4)));
     */
    public JGeometry pointCluster1() {
        Object[] points =
            new Object[] { new double[] { 1.1, 1.1 }, new double[] { 2.2,
                                                                     2.2 },
                           new double[] { 3.3, 4.4 } };
        return JGeometry.createMultiPoint(points, 2, getSRID());
    }

    public JGeometry pointCluster2() {

        Object[] points =
            new Object[] { new double[] { 5, 6 }, new double[] { 7, 8 } };
        return JGeometry.createMultiPoint(points, 2, getSRID());
    }

    /**
     * mdsys.sdo_geometry(3,
     *            NULL, null,
     *            mdsys.sdo_elem_info_array(1,3,1),
     *            mdsys.sdo_ordinate_array(1, 1, 2, 2, 3, 3, 3, 1, 1, 1))
     */
    public JGeometry simplyPolygon() {
        double[] points = new double[] { 1, 1, 2, 2, 3, 3, 3, 1, 1, 1 };
        return JGeometry.createLinearPolygon(points, 2, getSRID());
    }

    /**
     * A polygon made up of circular arcs. Each triple of vertices make up an
     * arc and the end-point of arc1 is the first point of arc2
     * i.e. arc1= {(0,1), (1,0), (0,-1)} and arc2 = {(0,-1), (-1,0), (0,1)}
     *
     * mdsys.sdo_geometry(3,
     * NULL, null,
     * mdsys.sdo_elem_info_array(1,3,2),
     * mdsys.sdo_ordinate_array(0, 1, 1, 0, 0, -1, -1, 0, 0, 1)));
     */
    public JGeometry polygonOfCircularArcs() throws Exception {
        return new JGeometry(JGeometry.GTYPE_POLYGON, getSRID(),
                             new int[] { 1, 3, 2 },
                             new double[] { 0, 1, 1, 0, 0, -1, -1, 0, 0, 1 });
    }

    /**
     * A circle. (1,0), (0,1), (0,-1) are three points on the circumference
     *
     * mdsys.sdo_geometry(3,
     * NULL, null,
     * mdsys.sdo_elem_info_array(1,3,4),
     * mdsys.sdo_ordinate_array(1, 0, 0, 1, 0, -1))
     */
    public JGeometry circle() throws Exception {
        return JGeometry.createCircle(1, 0, 0, 1, 0, -1, getSRID());
    }

    /**
     * A rectangle. (10,10) is the lower left corner and (20,20) the upper-right
     *
     * mdsys.sdo_geometry(3,
     * NULL, null,
     * mdsys.sdo_elem_info_array(1,3,3),
     * mdsys.sdo_ordinate_array(10, 10, 20, 20))
     */
    public JGeometry rectangle() throws Exception {
        return JGeometry.createLinearPolygon(new double[] { 10, 10, 10, 20, 20,
                                                            20, 20, 10, 10,
                                                            10 }, 2,
                                             getSRID());
    }

    /**
     * A geometry collection consisting of one compound line and one rectangle
     *
     * mdsys.sdo_geometry(4,
     * NULL, null,
     * mdsys.sdo_elem_info_array(1,4,2, 1,2,1, 7,2,2, 17,3,3),
     * mdsys.sdo_ordinate_array(50,50,
     * 50,30,
     * 10,30,
     * 10,50,
     * 20,60,
     * 30,50,
     * 40,60,
     * 50,50,
     * 25,35,
     * 35,40))
     */
    public JGeometry compoundLineAndRectangle() throws Exception {
        return new JGeometry(JGeometry.GTYPE_COLLECTION, getSRID(),
                             new int[] { 1, 4, 2, 1, 2, 1, 7, 2, 2, 17, 3, 3 },
                             new double[] { 50, 50, 50, 30, 10, 30, 10, 50, 20,
                                            60, 30, 50, 40, 60, 50, 50, 25, 35,
                                            35, 40 });
    }

    /**
     * A compound polygon with a rectangular hole
     *
     * mdsys.sdo_geometry(3,
     * NULL, null,
     * mdsys.sdo_elem_info_array(1,5,2, 1,2,1, 7,2,2, 17,3,3),
     * mdsys.sdo_ordinate_array(50,50,
     * 50,30,
     * 10,30,
     * 10,50,
     * 20,60,
     * 30,50,
     * 40,60,
     * 50,50,
     * 25,35,
     * 35,40))
     */
    public JGeometry compoundPolygonWithRectangularHole() throws Exception {
        return new JGeometry(JGeometry.GTYPE_POLYGON, getSRID(),
                             new int[] { 1, 5, 2, 1, 2, 1, 7, 2, 2, 17, 3, 3 },
                             new double[] { 50, 50, 50, 30, 10, 30, 10, 50, 20,
                                            60, 30, 50, 40, 60, 50, 50, 25, 35,
                                            35, 40 });
    }

    /**
     * ??
     *
     * mdsys.sdo_geometry(3,
     * NULL, null,
     * mdsys.sdo_elem_info_array(1,3,1, 11,3,3),
     * mdsys.sdo_ordinate_array(50,50,
     * 50,30,
     * 10,30,
     * 10,50,
     * 50,50,
     * 25,35,
     * 35,40))
     */
    public JGeometry geometry1008() throws Exception {
        return new JGeometry(JGeometry.GTYPE_POLYGON, getSRID(),
                             new int[] { 1, 3, 1, 11, 3, 3 },
                             new double[] { 50, 50, 50, 30, 10, 30, 10, 50, 50,
                                            50, 25, 35, 35, 40 });
    }

    /**
     * This geometry will be ignored by the index creation routines
     *
     * mdsys.sdo_geometry(0, NULL, null, NULL, NULL)
     *
     * NOTE: JGeometries created this way are returned as NULL. Writing into the
     * database this way will leave a non-null instance in the cache until it
     * is refreshed or leaves the cache.
     */
    public JGeometry geometryWithNulls() throws Exception {
        return new JGeometry(0, getSRID(), null, null);
    }

    /**
     * ??
     *
     * mdsys.sdo_geometry(3,  null,
     * mdsys.sdo_point_type (12.5, 13.6, 14.7),
     * mdsys.sdo_elem_info_array(1,3,1, 11,3,3),
     * mdsys.sdo_ordinate_array(50,50,
     * 50,30,
     * 10,30,
     * 10,50,
     * 50,50,
     * 25,35,
     * 35,40))
     */
    public JGeometry polygon1011() throws Exception {
        return new JGeometry(JGeometry.GTYPE_POLYGON, getSRID(), 12.5, 13.6,
                             14.7, new int[] { 1, 3, 1, 11, 3, 3 },
                             new double[] { 50, 50, 50, 30, 10, 30, 10, 50, 50,
                                            50, 25, 35, 35, 40 });
    }

    /**
     * ??
     *
     * mdsys.sdo_geometry(3,  null,
     * mdsys.sdo_point_type (12.5, 13.6, NULL),
     * mdsys.sdo_elem_info_array(1,3,1, 11,3,3),
     * mdsys.sdo_ordinate_array(50,50,
     * 50,30,
     * 10,30,
     * 10,50,
     * 50,50,
     * 25,35,
     * 35,40))
     */
    public JGeometry polygon1012() throws Exception {
        return new JGeometry(JGeometry.GTYPE_POLYGON, getSRID(), 12.5, 13.6,
                             0.0, new int[] { 1, 3, 1, 11, 3, 3 },
                             new double[] { 50, 50, 50, 30, 10, 30, 10, 50, 50,
                                            50, 25, 35, 35, 40 });
    }

    /**
     * Just a point geometry. This method can used to save storage if all
     * geometries in a table are Points
     *
     * mdsys.sdo_geometry(1,  null,
     * mdsys.sdo_point_type (12.5, 13.6, NULL),
     * NULL, NULL)
     */
    public JGeometry point() throws Exception {
        return JGeometry.createPoint(new double[] { 12.5, 13.6 }, 2,
                                     getSRID());
    }
}

