package de.dhbwstuttgart.typeinference.unify.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public abstract class OrderingExtend<T> extends com.google.common.collect.Ordering<T> {

	public List<T> maxElements(Iterable<T> iterable) {
		ArrayList<T> ret = new ArrayList<>();
		while (iterable.iterator().hasNext()) {
			Set<T> believe = new HashSet<>(); 
		
			T max = max(iterable);
			ret.add(max);
		
			Iterator<T> it = iterable.iterator();
			while (it.hasNext()) {
				T elem = it.next();
				if (!(compare(max, elem) == 1) && !max.equals(elem)) {
					believe.add(elem);
				}
			}
			iterable = believe;
		}
		return ret;
	}
	
	public List<T> minElements(Iterable<T> iterable) {
		ArrayList<T> ret = new ArrayList<>();
		while (iterable.iterator().hasNext()) {
			Set<T> believe = new HashSet<>(); 
		
			T min = min(iterable);
			ret.add(min);
		
			Iterator<T> it = iterable.iterator();
			while (it.hasNext()) {
				T elem = it.next();
				if (!(compare(min, elem) == -1) && !min.equals(elem)) {
					believe.add(elem);
				}
			}
			iterable = believe;
		}
		return ret;
	}
	
	
	public List<T> smallerEqThan(T elem, Iterable<T> iterable) {
		List<T> ret = smallerThan(elem, iterable);
		ret.add(elem);
		return ret;
		
	}
	
	public List<T> smallerThan(T elem, Iterable<T> iterable) {
		ArrayList<T> ret = new ArrayList<>();
		Iterator<T> it = iterable.iterator();
		while (it.hasNext()) {
			T itElem = it.next();
				if (!itElem.equals(elem) && compare(elem, itElem) == 1) {
					ret.add(itElem);
				}
			}
		return ret;
	}
	
	public List<T> greaterEqThan(T elem, Iterable<T> iterable) {
		List<T> ret = greaterThan(elem, iterable);
		ret.add(elem);
		return ret;
		
	}
	
	public List<T> greaterThan(T elem, Iterable<T> iterable) {
		ArrayList<T> ret = new ArrayList<>();
		Iterator<T> it = iterable.iterator();
		while (it.hasNext()) {
			T itElem = it.next();
				if (!itElem.equals(elem) && (compare(elem, itElem) == -1)) {
					ret.add(itElem);
				}
			}
		return ret;
	}
}
