/*
 * 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.expressions.spatial;

import java.io.StringWriter;

/**
 * PUBLIC:
 * A utility class used to set parameters on spatial operators within TopLink's
 * expression framework. This class allows the aptial operator parameters to be
 * passed in directly as a string or to be programatically configured using the
 * attributes defined and the enum types. Each spatial operator offers different
 * parameter arguments and values. This class does not enforce these rules but
 * instead leaves it to the caller to decide what values they want included.
 * <p>
 * When providing the parameter string through setParams or the constructor none
 * of the other values will be used. Instead the string as provided will be used.
 * <p>
 * Creating an instance of SpatialParameters without configuring it and passing
 * it into the SpatialExpressionFactory call is equivalent to passing in null.
 * The resulting SQL will have NULL writen out for the parameters argument to the
 * spatial operator.
 *
 * @since Oracle TopLink 11.1.1.0.0
 */
public class SpatialParameters {
    private String params = null;
    private Number minResolution = null;
    private Number maxResolution = null;
    private Units units = null;
    private Number distance = null;
    private QueryType queryType = null;
    private Mask[] masks = null;

    private static String UNIT_PARAM = "UNIT=";
    private static String MAX_RES_PARAM = "MAX_RESOLUTION=";
    private static String MIN_RES_PARAM = "MIN_RESOLUTION=";
    private static String DISTANCE_PARAM = "DISTANCE=";
    private static String QUERYTYPE_PARAM = "QUERYTYPE=";
    private static String MASK_PARAM = "MASK=";

    public SpatialParameters() {
    }

    public SpatialParameters(String params) {
        setParams(params);
    }

    /**
     * PUBLIC:
     * Set the PARAMS (String) value. If this value is set then no other param
     * values will be used.
     * @param params
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setParams(String params) {
        this.params = params;
        return this;
    }

    public String getParams() {
        return params;
    }

    /**
     * PUBLIC:
     * Set the MIN_RESOLUTION parameter
     * @param minResolution
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setMinResolution(Number minResolution) {
        this.minResolution = minResolution;
        return this;
    }

    public Number getMinResolution() {
        return minResolution;
    }

    /**
     * PUBLIC:
     * Set the MAX_RESOLUTION parameter
     * @param maxResolution
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setMaxResolution(Number maxResolution) {
        this.maxResolution = maxResolution;
        return this;
    }

    public Number getMaxResolution() {
        return maxResolution;
    }

    /**
     * PUBLIC:
     * Set the UNIT parameter
     * @param units a value from the SpatialParameters.Units enum
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setUnits(SpatialParameters.Units units) {
        this.units = units;
        return this;
    }

    public SpatialParameters.Units getUnits() {
        return units;
    }

    /**
     * PUBLIC:
     * Set the DISTANCE parameter
     * @param distance
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setDistance(Number distance) {
        this.distance = distance;
        return this;
    }

    public Number getDistance() {
        return distance;
    }

    /**
     * PUBLIC:
     * Set the QUERY_TYPE parameter
     * @param queryType a value from the SpatialParameters.QueryType enum
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setQueryType(QueryType queryType) {
        this.queryType = queryType;
        return this;
    }

    public SpatialParameters.QueryType getQueryType() {
        return queryType;
    }

    /**
     * PUBLIC:
     * Set the MASK parameter
     * @param masks an array of values from the SpatialParmeters.Mask enum
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setMasks(Mask[] masks) {
        this.masks = masks;
        return this;
    }

    /**
     * PUBLIC:
     * Set the MASK parameter
     * @param mask a value from the SpatialParmeters.Mask enum
     * @return this instance of SpatialParameters
     */
    public SpatialParameters setMask(Mask mask) {
        this.masks = new Mask[] { mask };
        return this;
    }

    public Mask[] getMasks() {
        return masks;
    }

    /**
     * PUBLIC:
     * build a String describing this set of parameters that can be used in conjunction with an Oracle Spatial function
     * @return
     */
    public String getParameterString() {
        if (getParams() != null) {
            return getParams();
        }

        StringWriter writer = new StringWriter();
        boolean hasParams = false;

        hasParams = writeParam(writer, DISTANCE_PARAM, getDistance(), hasParams);
        hasParams = writeParam(writer, MAX_RES_PARAM, getMaxResolution(), hasParams);
        hasParams = writeParam(writer, MIN_RES_PARAM, getMinResolution(), hasParams);
        hasParams = writeParam(writer, UNIT_PARAM, getUnits(), hasParams);
        hasParams = writeParam(writer, MASK_PARAM, getMasks(), hasParams);
        hasParams = writeParam(writer, QUERYTYPE_PARAM, getQueryType(), hasParams);

        return hasParams ? writer.toString() : null;
    }


    /**
     * INTERNAL:
     * Write the parameter onto the StringWriter being used to construct the
     * params string. Only write something if there is a value and return
     * true indicating if a parameter is written.
     */
    private boolean writeParam(StringWriter writer, String paramName, Object paramValue, boolean hasParams) {
        if (paramValue != null) {
            if (hasParams) {
                writer.write(" ");
            }
            if (paramValue.getClass().isArray()) {
                Object[] values = (Object[])paramValue;

                if (values.length == 0) {
                    return false;
                }
                writer.write(paramName);
                writer.write(values[0].toString());
                for (int index = 1; index < values.length; index++) {
                    writer.write("+");
                    writer.write(values[index].toString());
                }

            } else {
                writer.write(paramName);
                writer.write(paramValue.toString());
            }
            return true;
        }
        return hasParams;
    }


    public enum Units {
        M, // Meter
        KM, // Kilometer
        CM, //Centimeter
        MM, // Millimeter
        MILE, // Mile
        NAUT_MILE, // Nautical Mile
        FOOT, // Foot
        INCH,
        ; // Inch
    }

    public enum QueryType {
        WINDOW,
        JOIN,
        FILTER,
        ;
    }

    public enum Mask {
        TOUCH,
        OVERLAPBDYDISJOINT,
        OVERLAPBDYINTERSECT,
        EQUAL,
        INSIDE,
        COVEREDBY,
        CONTAINS,
        COVERS,
        ANYINTERACT,
        ON,
        ;
    }
}
