import java.util.*;
/**
 * A class that implements the java.util.Comparator interface to compare two items regarding their overlapping.
 * You can set two parameters representing the minimal pourcentages of overlapping of respectively the
 * the submitted system item and the reference item. Default overlapping values are 1/3 for system items and
 * 2/3 for reference items.
 *
 * @author NIST-ITL-IAD-Retrieval Group
 * This software was produced by NIST, an agency of the
 * U.S. government, and by statute is not subject to copyright in the
 * United States. Recipients of this software assume all
 * responsibilities associated with its operation, modification and
 * maintenance.
 *
 */
public class OverlapComparator implements Comparator{

    /**
     * The unique instance of this class.
     *
     * @see #getInstance()
     */
    private static OverlapComparator myInstance = null;
	/**
     * The required overlapping pourcentage of the sytem item to consider two transitions as equal.
     *
     * @see #setRMin()
     */
	private static double staticpSys = 0.333333;
	/**
     * The required overlapping pourcentage of the reference item to consider two transitions as equal.
     *
     * @see #setRMin()
     */
	private static double staticpRef = 0.666666;
	/**
     * Private constructor.
     *
     */
	private OverlapComparator(){}
    /**
     * Private constructor with two required parameters.
     *
     */
    private OverlapComparator(double pSys, double pRef){ 
    	staticpSys = pSys;
    	staticpRef = pRef;
    }
    /**
     * Sets the reference item overlapping parameter.
     *
     */
	public static void setPRef(double pRef){ 
		staticpRef = pRef;
	}
	/**
     * Sets the system item overlapping parameter.
     *
     */
	public static void setPSys(double pSys){ 
		staticpSys = pSys;
	}
	/**
     * Gets the reference item overlapping parameter.
     *
     */
	public static double getPRef(){ return staticpRef; }
	/**
     * Sets the system item overlapping parameter.
     *
     */
	public static double getPSys(){ return staticpSys; }
	/**
     * Returns the unique instance of this class and set the parameters.
     *
     */
    public static OverlapComparator getInstance(double pSys, double pRef){
		if(myInstance == null)
	    	myInstance = new OverlapComparator(pSys, pRef);
		return myInstance;
    }
    /**
     * Returns the unique instance of this class.
     *
     */
    public static OverlapComparator getInstance(){
		if(myInstance == null)
	    	myInstance = new OverlapComparator();
		return myInstance;
    }
    /**
     * Compares its two arguments for ordering them. Uses the overlapping parameter to check the equality.
     *
     * @return    a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
     * @exception ClassCastException Thrown if one of the arguments is not a item instance.
     */
	public int compare(Object o1, Object o2) throws ClassCastException{

		if((o1 instanceof KnownItem || o1 instanceof SystemItem) && 
		   (o2 instanceof KnownItem || o2 instanceof SystemItem)){

			KnownItem oRef = null;
			SystemItem oSys = null;
			Item intersection = null;
			if(o1 instanceof KnownItem){
				oRef = (KnownItem)o1;
				oSys = (SystemItem)o2;				
			}
			else{
				oRef = (KnownItem)o2;
				oSys = (SystemItem)o1;
			}
			intersection = oRef.intersection(oSys);
			//Equality test according to this comparator
			if((intersection.length() >= (staticpRef*oRef.length())) &&
			   (intersection.length() >= (staticpSys*oSys.length())))
				return 0;
			else{
				if(((Item)o1).getMilliStart()  <= ((Item)o2).getMilliStart()) return -1;
				else return 1;
			}
		}
		else throw new ClassCastException("Instance Problem for OverlapComparator");
	}

}