package player.gamer.statemachine.sadna;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Utils {

	private static final String ALL_SEPERATOR = "#";
	private static final String WEIGHT_SEPERATOR = ":"; 
	
	/**
	 * Map between attribute index in the attributes vector and attribute name
	 */
	public static Map<Integer, String> attrs = new HashMap<Integer, String>();
	
	static {
		int counter = 0;
		
		attrs.put(counter++, "Player Won");
		attrs.put(counter++, "Opponent Won");
		
		attrs.put(counter++, "3 In a Row Even Threat (Player)");
		attrs.put(counter++, "3 In a Row Even Threat (Opponent)");
		
		attrs.put(counter++, "3 In a Diagonal Even Threat (Player)");
		attrs.put(counter++, "3 In a Diagonal Even Threat (Opponent)");
		
		attrs.put(counter++, "3 In a Row Odd Threat (Player)");
		attrs.put(counter++, "3 In a Row Odd Threat (Opponent)");
		
		attrs.put(counter++, "3 In a Diagonal Odd Threat (Player)");
		attrs.put(counter++, "3 In a Diagonal Odd Threat (Opponent)");
		
		attrs.put(counter++, "3 In a Column (Player)");
		attrs.put(counter++, "3 In a Column (Opponent)");

		attrs.put(counter++, "2 In a Row (Player)");
		attrs.put(counter++, "2 In a Row (Opponent)");
		
		attrs.put(counter++, "2 In a Diagonal (Player)");
		attrs.put(counter++, "2 In a Diagonal (Opponent)");

		attrs.put(counter++, "2 In a Column (Player)");
		attrs.put(counter++, "2 In a Column (Opponent)");

		attrs.put(counter++, "1 In a Row (Player)");
		attrs.put(counter++, "1 In a Row (Opponent)");
		
		attrs.put(counter++, "1 In a Column (Player)");
		attrs.put(counter++, "1 In a Column (Opponent)");
		
		attrs.put(counter++, "Distance From Center");
		
		attrs.put(counter++, "2 Immediate (Player)");
		attrs.put(counter++, "2 Immediate (Opponent)");
		
		attrs.put(counter++, "Double Threat (Player)");
		attrs.put(counter++, "Double Threat (Opponent)");
	}
	
	/**
	 * @param fileName The weights vector file name
	 * @return weights vector
	 */
	public static double[] readWeights(String fileName) throws IOException {
		double[] weightsVec = new double[Board.ATTR_VEC_SIZE];
		String weightsStr = Utils.readFile(fileName);
		String[] weights = weightsStr.split(ALL_SEPERATOR);
		for (int i = 0; i < weightsVec.length; i++) {
			String attrWeight = weights[i].substring(weights[i].indexOf(WEIGHT_SEPERATOR)+1);
			double wegiht = Double.valueOf(attrWeight);
			weightsVec[i] = wegiht; 
		}
		
		return weightsVec;
	}
	
	/**
	 * @param weights Weights vector
	 * @param fileName File name to write the vector to
	 */
	public static void writeWeights(double[] weights, String fileName) throws IOException {
		StringBuffer weightsStr = new StringBuffer();
		for (int i = 0; i < weights.length; i++) {
			weightsStr.append(attrs.get(i));
			weightsStr.append(WEIGHT_SEPERATOR);
			weightsStr.append(weights[i]);
			weightsStr.append("\r\n");
		}
		Utils.writeFile(fileName, weightsStr.toString());
	}

	public static String readFile(String fileName) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(fileName));
	    try {
	        StringBuilder sb = new StringBuilder();
	        String line = br.readLine();

	        while (line != null) {
	            sb.append(line);
	            sb.append(ALL_SEPERATOR);
	            line = br.readLine();
	        }
	        return sb.toString();
	    } finally {
	        br.close();
	    }
	}

	public static void writeFile(String fileName, String content) throws IOException {
		BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
		try {
			bw.write(content);
		} finally {
			bw.close();
		}		
	}
}
