package com.contentful.java.cda;

/**
 * This enumeration will be used to formulate more complex search queries.
 *
 * @see FetchQuery<T>.#where(String, QueryOperation, T...)
 */
public class QueryOperation<T> {

  public static final QueryOperation<String> IsEqualTo = new QueryOperation<String>("");
  public static final QueryOperation<String> IsNotEqualTo = new QueryOperation<String>("[ne]");
  public static final QueryOperation<String> HasOneOf = new QueryOperation<String>("[in]");
  public static final QueryOperation<String> HasNoneOf = new QueryOperation<String>("[nin]");
  public static final QueryOperation<String> HasAllOf = new QueryOperation<String>("[all]");

  public static final QueryOperation<Integer> IsLessThan = new QueryOperation<Integer>("[lt]");
  public static final QueryOperation<Integer> IsLessThanOrEqualTo
      = new QueryOperation<Integer>("[lte]");
  public static final QueryOperation<Integer> IsGreaterThan = new QueryOperation<Integer>("[gt]");
  public static final QueryOperation<Integer> IsGreaterThanOrEqualTo
      = new QueryOperation<Integer>("[gte]");

  public static final QueryOperation<Boolean> Exists = new QueryOperation<Boolean>("[exists]"
      , true);

  public static final QueryOperation<String> IsEarlierThan = new QueryOperation<String>("[lt]");
  public static final QueryOperation<String> IsEarlierOrAt = new QueryOperation<String>("[lte]");
  public static final QueryOperation<String> IsLaterThan = new QueryOperation<String>("[gt]");
  public static final QueryOperation<String> IsLaterOrAt = new QueryOperation<String>("[gte]");

  public static final QueryOperation<String> Matches = new QueryOperation<String>("[match]");

  public static final QueryOperation<Location> IsCloseTo = new QueryOperation<Location>("[near]");
  public static final QueryOperation<BoundingBox> IsWithinBoundingBoxOf
      = new QueryOperation<BoundingBox>("[within]");
  public static final QueryOperation<BoundingCircle> IsWithinCircleOf
      = new QueryOperation<BoundingCircle>("[within]");

  final String operator;
  final T defaultValue;

  /**
   * Create an operation, using only an operator.
   * <p>
   * This means this operation needs to have a value to operate on.
   *
   * @param operator a string representing the url parameter operation (aka. [eq])
   */
  protected QueryOperation(String operator) {
    this(operator, null);
  }

  /**
   * Create an operation which does take its default value, if no value is given.
   *
   * @param operator     the operator to be used.
   * @param defaultValue the default value of the operation.
   */
  protected QueryOperation(String operator, T defaultValue) {
    this.operator = operator;
    this.defaultValue = defaultValue;
  }

  /**
   * Check presence of a default value
   *
   * @return true if this operation can be used without a parameter.
   */
  protected boolean hasDefaultValue() {
    return defaultValue != null;
  }

  /**
   * Model representing coordinates for query operations.
   */
  public static class Location {
    private final double latitude;
    private final double longitude;

    /**
     * Create a location based on its coodinates.
     *
     * @param latitude  of this location.
     * @param longitude of this location.
     */
    public Location(double latitude, double longitude) {
      this.latitude = latitude;
      this.longitude = longitude;
    }

    @Override
    public String toString() {
      return String.format("%f,%f", latitude, longitude);
    }
  }

  /**
   * Model representing a bounding box in geocoordinates.
   */
  public static class BoundingBox {
    private final Location bottomLeft;
    private final Location topRight;

    /**
     * Construct a bounding box with type save arguments.
     *
     * @param bottomLeft bottom left corner of bounding box.
     * @param topRight   top right corner of bounding box.
     */
    public BoundingBox(Location bottomLeft, Location topRight) {
      this.bottomLeft = bottomLeft;
      this.topRight = topRight;
    }

    /**
     * Simple constructor of bounding box taking double parameters instead of locations
     *
     * @param bottom bottom most location of the box.
     * @param left   left most location of the box.
     * @param top    top most location of the box.
     * @param right  right most location of the box.
     */
    public BoundingBox(double bottom, double left, double top, double right) {
      this.bottomLeft = new Location(bottom, left);
      this.topRight = new Location(top, right);
    }

    @Override public String toString() {
      return String.format("%s,%s", bottomLeft.toString(), topRight.toString());
    }
  }

  /**
   * Model representing a bounding circle in geocoordinates.
   */
  public static class BoundingCircle {
    private final Location center;
    private final double radius;

    /**
     * Type safe constructor of bounding circle.
     *
     * @param center position of circle on the globe in geo location.
     * @param radius the radius of the circle in kilometer.
     */
    public BoundingCircle(Location center, double radius) {
      this.center = center;
      this.radius = radius;
    }

    /**
     * Simple constructor of bounding circle.
     *
     * @param centerLatitude  center coordinate on latitude axis.
     * @param centerLongitude center coordinate of circle, on longitude axis.
     * @param radius          in km.
     */
    public BoundingCircle(double centerLatitude, double centerLongitude, double radius) {
      this.center = new Location(centerLatitude, centerLongitude);
      this.radius = radius;
    }

    @Override public String toString() {
      return String.format("%s,%f", center.toString(), radius);
    }
  }
}

@@ -3393,32 +3393,102 @@
 ngitude;%0A    %7D%0A%0A
+    /**%0A     * @return returns a url friendly representation.%0A     */%0A
     @Override%0A  
@@ -3485,16 +3485,16 @@
 verride%0A
-
     publ
@@ -4608,32 +4608,102 @@
  right);%0A    %7D%0A%0A
+    /**%0A     * @return returns a url friendly representation.%0A     */%0A
     @Override pu
@@ -5763,24 +5763,94 @@
 ius;%0A    %7D%0A%0A
+    /**%0A     * @return returns a url friendly representation.%0A     */%0A
     @Overrid

Add missing public annotations