code: /*******************************************************************************
   * Copyright (c) 2015 MITRE
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Apache License, Version 2.0 which
   * accompanies this distribution and is available at
   *    http://www.apache.org/licenses/LICENSE-2.0.txt
   ******************************************************************************/
  
  package org.locationtech.spatial4j.shape.impl;
  
  import org.locationtech.spatial4j.context.SpatialContext;
  import org.locationtech.spatial4j.shape.Rectangle;
  
  /**
   * INTERNAL: A numeric range between a pair of numbers.
   * Perhaps this class could become 1st class citizen extending Shape but not now.
   * Only public so is accessible from tests in another package.
   */
  @Deprecated // See BBoxCalculator
  public class Range {
    protected final double min, max;
  
    public static Range xRange(Rectangle rect, SpatialContext ctx) {
      if (ctx.isGeo())
        return new LongitudeRange(rect.getMinX(), rect.getMaxX());
      else
        return new Range(rect.getMinX(), rect.getMaxX());
    }
  
    public static Range yRange(Rectangle rect, SpatialContext ctx) {
      return new Range(rect.getMinY(), rect.getMaxY());
    }
  
    public Range(double min, double max) {
      this.min = min;
      this.max = max;
    }
  
    public double getMin() {
      return min;
    }
  
    public double getMax() {
      return max;
    }
  
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
  
      Range range = (Range) o;
  
      if (Double.compare(range.max, max) != 0) return false;
      if (Double.compare(range.min, min) != 0) return false;
  
      return true;
    }
  
    @Override
    public int hashCode() {
      int result;
      long temp;
      temp = min != +0.0d ? Double.doubleToLongBits(min) : 0L;
      result = (int) (temp ^ (temp >>> 32));
      temp = max != +0.0d ? Double.doubleToLongBits(max) : 0L;
      result = 31 * result + (int) (temp ^ (temp >>> 32));
      return result;
    }
  
    @Override
    public String toString() {
      return "Range{" + min + " TO " + max + '}';
    }
  
    public double getWidth() {
      return max - min;
    }
  
    public boolean contains(double v) {
      return v >= min && v <= max;
    }
  
    public double getCenter() {
      return min + getWidth()/2;
    }
  
    public Range expandTo(Range other) {
      assert this.getClass() == other.getClass();
      return new Range(Math.min(min, other.min), Math.max(max, other.max));
    }
  
    public double deltaLen(Range other) {
      double min3 = Math.max(min, other.min);
      double max3 = Math.min(max, other.max);
      return max3 - min3;
    }
  
    @Deprecated // See BBoxCalculator
    public static class LongitudeRange extends Range {
  
      public static final LongitudeRange WORLD_180E180W = new LongitudeRange(-180, 180);
  
      public LongitudeRange(double min, double max) {
        super(min, max);
      }
  
      public LongitudeRange(Rectangle r) {
        super(r.getMinX(), r.getMaxX());
      }
  
      @Override
      public double getWidth() {
        double w = super.getWidth();
        if (w < 0)
          w += 360;
        return w;
      }
  
      @Override
      public boolean contains(double v) {
        if (!crossesDateline())
          return super.contains(v);
        return v >= min || v <= max;// the OR is the distinction from non-dateline cross
      }
  
      public boolean crossesDateline() {
        return min > max;
      }
  
      @Override
      public double getCenter() {
        double ctr = super.getCenter();
        if (ctr > 180)
          ctr -= 360;
        return ctr;
      }
  
      public double compareTo(LongitudeRange b) {
        return diff(getCenter(), b.getCenter());
      }
  
      /** a - b (compareTo order).  < 0 if a < b */
      private static double diff(double a, double b) {
        double diff = a - b;
        if (diff <= 180) {
          if (diff >= -180)
            return diff;
          return diff + 360;
        } else {
          return diff - 360;
        }
      }
  
      @Override
      public Range expandTo(Range other) {
        return expandTo((LongitudeRange) other);
      }
  
      public LongitudeRange expandTo(LongitudeRange other) {
        LongitudeRange a, b;// a.ctr <= b.ctr
        if (this.compareTo(other) <= 0) {
          a = this;
          b = other;
        } else {
          a = other;
          b = this;
        }
        LongitudeRange newMin = b.contains(a.min) ? b : a;//usually 'a'
        LongitudeRange newMax = a.contains(b.max) ? a : b;//usually 'b'
        if (newMin == newMax)
          return newMin;
        if (newMin == b && newMax == a)
          return WORLD_180E180W;
        return new LongitudeRange(newMin.min, newMax.max);
      }
    }
  }
  
  