/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.uima.fit.util;

import org.apache.uima.cas.text.AnnotationFS;

/**
 * This class is back-ported for testing only from UIMAv3. It is used to check that the behavior
 * of uimaFIT v2 and uimaFITv2 with respect to the select utilities is aligned.
 */
final class AnnotationPredicates {
  public static boolean coveredBy(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aYBegin <= aXBegin && aXEnd <= aYEnd;
  }

  public static boolean coveredBy(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aYBegin <= aX.getBegin() && aX.getEnd() <= aYEnd;
  }

  /**
   * Y is starting before or at the same position as A and ends after or at the
   * same position as X.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X is covered by Y.
   */
  public static boolean coveredBy(AnnotationFS aX, AnnotationFS aY) {
    return aY.getBegin() <= aX.getBegin() && aX.getEnd() <= aY.getEnd();
  }

  public static boolean covering(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aXBegin <= aYBegin && aYEnd <= aXEnd;
  }

  public static boolean covering(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aX.getBegin() <= aYBegin && aYEnd <= aX.getEnd();
  }

  /**
   * X is starting before or at the same position as Y and ends after or at the
   * same position as Y.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X is covering Y.
   */
  public static boolean covering(AnnotationFS aX, AnnotationFS aY) {
    return aX.getBegin() <= aY.getBegin() && aY.getEnd() <= aX.getEnd();
  }

  public static boolean colocated(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aXBegin == aYBegin && aXEnd == aYEnd;
  }

  public static boolean colocated(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aX.getBegin() == aYBegin && aX.getEnd() == aYEnd;
  }

  /**
   * X starts and ends at the same position as Y.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X is at the same location as Y.
   */
  public static boolean colocated(AnnotationFS aX, AnnotationFS aY) {
    return aX.getBegin() == aY.getBegin() && aX.getEnd() == aY.getEnd();
  }

  public static boolean overlapping(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aYBegin == aXBegin || aYEnd == aXEnd || (aXBegin < aYEnd && aYBegin < aXEnd);
  }

  public static boolean overlapping(AnnotationFS aX, int aYBegin, int aYEnd) {
    int xBegin = aX.getBegin();
    int xEnd = aX.getEnd();
    return aYBegin == xBegin || aYEnd == xEnd || (xBegin < aYEnd && aYBegin < xEnd);
  }

  /**
   * The intersection of the spans X and Y is non-empty. If either X or Y have a
   * zero-width, then the intersection is considered to be non-empty if the begin
   * of X is either within Y or the same as the begin of Y - and vice versa.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X overlaps with Y in any way.
   */
  public static boolean overlapping(AnnotationFS aX, AnnotationFS aY) {
    int xBegin = aX.getBegin();
    int xEnd = aX.getEnd();
    int yBegin = aY.getBegin();
    int yEnd = aY.getEnd();
    return yBegin == xBegin || yEnd == xEnd || (xBegin < yEnd && yBegin < xEnd);
  }

  public static boolean overlappingAtBegin(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aXBegin < aYBegin && aYBegin < aXEnd && aXEnd <= aYEnd;
  }

  public static boolean overlappingAtBegin(AnnotationFS aX, int aYBegin, int aYEnd) {
    int xEnd = aX.getEnd();
    return aYBegin < xEnd && xEnd <= aYEnd && aX.getBegin() < aYBegin;
  }

  /**
   * X is starting before or at the same position as Y and ends before Y ends.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X overlaps Y on the left.
   */
  public static boolean overlappingAtBegin(AnnotationFS aX, AnnotationFS aY) {
    int xEnd = aX.getEnd();
    int yBegin = aY.getBegin();
    return yBegin < xEnd && xEnd <= aY.getEnd() && aX.getBegin() < yBegin;
  }

  public static boolean overlappingAtEnd(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aYBegin <= aXBegin && aXBegin < aYEnd && aYEnd < aXEnd;
  }

  public static boolean overlappingAtEnd(AnnotationFS aX, int aYBegin, int aYEnd) {
    int xBegin = aX.getBegin();
    return aYBegin <= xBegin && xBegin < aYEnd && aYEnd < aX.getEnd();
  }

  /**
   * X is starting after Y starts and ends after or at the same position as Y.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X overlaps Y on the right.
   */
  public static boolean overlappingAtEnd(AnnotationFS aX, AnnotationFS aY) {
    int xBegin = aX.getBegin();
    int yEnd = aY.getEnd();
    return xBegin < yEnd && aY.getBegin() <= xBegin && yEnd < aX.getEnd();
  }

  public static boolean following(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aXBegin >= aYEnd;
  }

  public static boolean following(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aX.getBegin() >= aYEnd;
  }

  /**
   * X starts at or after the position that Y ends.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X is right of Y.
   */
  public static boolean following(AnnotationFS aX, AnnotationFS aY) {
    return aX.getBegin() >= aY.getEnd();
  }

  public static boolean preceding(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aYBegin >= aXEnd;
  }

  public static boolean preceding(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aYBegin >= aX.getEnd();
  }

  /**
   * X ends before or at the position that Y starts.
   * 
   * @param aX
   *          X
   * @param aY
   *          Y
   * @return whether X left of Y.
   */
  public static boolean preceding(AnnotationFS aX, AnnotationFS aY) {
    return aY.getBegin() >= aX.getEnd();
  }
  
  public static boolean beginningWith(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aXBegin == aYBegin;
  }

  public static boolean beginningWith(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aX.getBegin() == aYBegin;
  }

  public static boolean beginningWith(AnnotationFS aX, AnnotationFS aY) {
    return aX.getBegin() == aY.getBegin();
  }

  public static boolean endingWith(int aXBegin, int aXEnd, int aYBegin, int aYEnd) {
    return aXEnd == aYEnd;
  }
  public static boolean endingWith(AnnotationFS aX, int aYBegin, int aYEnd) {
    return aX.getEnd() == aYEnd;
  }

  public static boolean endingWith(AnnotationFS aX, AnnotationFS aY) {
    return aX.getEnd() == aY.getEnd();
  }
}
