package Main;

import java.util.ArrayList;
import java.util.List;
/**
 * This class contains a number of useful public static method.
 * @author Hamoon
 *
 */
public class UtilityMethods {
	static String dir = "";
	static String ADDRESS_FOR_COMMAND_FILES = "Command Files/";
	static String ADDRESS_FOR_AUTOMATA_LIBRARY = "Automata Library/";
	static String ADDRESS_FOR_WORDS_LIBRARY = "Word Automata Library/";
	static String ADDRESS_FOR_RESULT = "Result/";
	static String ADDRESS_FOR_CUSTOM_BASES = "Custom Bases/";
	static String ADDRESS_FOR_TEST_LIBRARY = "Test Library/";
	public static void setPaths(){
		String path = System.getProperty("user.dir");
		if(path.substring(path.length()-3).equals("bin"))
			dir = "../";
	}
	public static String get_address_for_command_files(){return dir+ADDRESS_FOR_COMMAND_FILES;}
	public static String get_address_for_automata_library(){return dir+ADDRESS_FOR_AUTOMATA_LIBRARY;}
	public static String get_address_for_result(){return dir+ADDRESS_FOR_RESULT;}
	public static String get_address_for_custom_bases(){return dir+ADDRESS_FOR_CUSTOM_BASES;}
	public static String get_address_for_words_library(){return dir+ADDRESS_FOR_WORDS_LIBRARY;}
	public static String get_address_for_test_library(){return dir+ADDRESS_FOR_TEST_LIBRARY;}
	
	
	public static String newLineString =  System.lineSeparator();
	public static char min(char a,char b){
		if(a < b)return a;
		return b;
	}
	public static char max(char a,char b){
		if(a < b)return b;
		return a;
	}
	public static String newLine(){
		return newLineString;
	}
	/**
	 * checks if a string is \\d+
	 * @param s
	 * @return
	 */
	public static boolean isNumber(String s){
		return s.matches("^\\d+$");
	}
	
	/**
	 * permutes L with regard to permutation. For example if permutation = [1,2,0] then the return value is
	 * [L[1],L[2],L[0]]
	 * @param L
	 * @param permutation
	 * @return
	 */
	public static <T> List<T> permute(List<T> L,int[] permutation){
		List<T> R = new ArrayList<T>(L);
		for(int i = 0 ; i < L.size();i++)
			R.set(permutation[i],L.get(i));
		return R;
	}
	/**
	 * For example when L = [1,2,3] then the result is the string "(1,2,3)"
	 * @param l
	 * @return
	 */
	public static <T> String toTuple(List<T> l){
		String s = "(";
		for(int i = 0; i < l.size();i++){
			if(i == 0)s+=l.get(i);
			else s += ","+l.get(i);
		}
			
		return s + ")";
	}
	/**
	 * For example when L = [1,3,2,1,3] the result is [1,3,2]
	 * @param L
	 */
	public static <T> void removeDuplicates(List<T> L){
		if(L == null || L.size() <= 1) return;
		List<T> R = new ArrayList<T>();
		for(int i = 0 ; i < L.size();i++){
			boolean flag = true;
			for(int j = 0 ; j < i;j++){
				if(L.get(i).equals(L.get(j))){
					flag = false;
					break;
				}
			}
			if(flag)R.add(L.get(i));
		}
		L.clear();
		L.addAll(R);
	}
	/**
	 * Checks if the set of L and R are equal. L and R does not have duplicates.
	 * @param L
	 * @param R
	 * @return
	 */
	public static <T> boolean areEqual(List<T> L, List<T> R){
		if(L == null && R == null)return true;
		if(L == null || R == null)return false;
		if(L.size() != R.size())return false;
		for(T x:L)
			if(!R.contains(x))return false;
		return true;
	}
	/**
	 * add elements of R that does not exits in L to L.
	 * @param L
	 * @param R
	 */
	public static <T> void addAllWithoutRepetition(List<T> L, List<T> R){
		if(R == null || R.size() == 0)return;
		for(T x:R){
			boolean flag = true;
			for(T y:L){
				if(y.equals(x)){
					flag = false;
					break;
				}
			}
			if(flag)
				L.add(x);
		}
	}
	/**
	 * For example when indices = [1,3] and L = [X,Y,Z,W] then the result is [X,Z]
	 * @param L
	 * @param indices
	 */
	public static <T> void removeIndices(List<T> L, List<Integer> indices) {
		List<T> R = new ArrayList<T>();
		for(int i = 0 ; i < L.size();i++){
			if(indices.indexOf(i) == -1)
				R.add(L.get(i));
		}
		L.clear();
		L.addAll(R);
	}
	/**
	 * @param s
	 * @return
	 */
	public static int parseInt(String s){
		String[] part = s.split("\\s+");
		StringBuffer b = new StringBuffer();
		for(String x:part){
			b.append(x); 
		}
		return Integer.parseInt(b.toString());
	}
	
}
