package homework4;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class OPAnalyze {

	public static final int minInterval = 8;
	
	private List incidents;
	private Map ucrMap;
	private Map freqMap;
	
	public static void main(String[] args) throws IOException {
		OPReader opr = new OPReader();
		opr.read();
		
		OPAnalyze opa = new OPAnalyze(opr);
		opa.problem1();
		opa.problem2();
	}
	
	public OPAnalyze(OPReader r) {
		incidents = r.getIncidents();
		ucrMap = r.getUcrMap();
		freqMap = r.getFreqMap();
	}

	public static int getInterval(OPIncident opi) {
		int result = (int) Math.ceil((opi.getHourOfDay()*60.0+opi.getMinutes())/minInterval);
		if (result == 0) {
			return 0;
		}
		return result-1;
	}
	
	public double getFreqMean(String ucr) {
		double sum = 0.0;
		
		Integer[] list = (Integer[]) freqMap.get(ucr);
		for (int i = 0; i < list.length; i++) {
			if (list[i] != null) {
				sum += list[i].intValue();
			}
		}
		
		return sum/list.length;
	}
	
	public double getFreqStndDev(String ucr) {
		double sum = 0.0;
		double mean = getFreqMean(ucr);
		
		Integer[] list = (Integer[]) freqMap.get(ucr);
		for (int i = 0; i < list.length; i++) {
			if (list[i] != null) {
				sum += (list[i].intValue()-mean)*(list[i].intValue()-mean);
			}
		}
		
		return Math.sqrt(sum/(list.length-1));
	}
	
	public double getTimeMean(String ucr) {
		double sum = 0.0;
		
		List list = (List) ucrMap.get(ucr);
		for (int i = 0; i < list.size(); i++) {
			OPIncident opi = (OPIncident) list.get(i);
			sum += getInterval(opi);
		}
		
		return sum/list.size();
	}
	
	public double getTimeStndDev(String ucr) {
		double sum = 0.0;
		double mean = getTimeMean(ucr);
		
		List list = (List) ucrMap.get(ucr);
		for (int i = 0; i < list.size(); i++) {
			OPIncident opi = (OPIncident) list.get(i);
			int interval = getInterval(opi);
			sum += (interval - mean)*(interval-mean);
		}
		
		return Math.sqrt(sum/(list.size()-1));
	}
	
	public double getCorrelation(String ucr) {
		double result = 0.0;
		double timeMean = getTimeMean(ucr);
		double freqMean = getFreqMean(ucr);
		
		List timeList = (List) ucrMap.get(ucr);
		Integer[] freqList = (Integer[]) freqMap.get(ucr);
		
		// calculate covariance
		for (int i = 0; i < timeList.size(); i++) {
			OPIncident opi = (OPIncident) timeList.get(i);
			int interval = getInterval(opi);
			result += (interval-timeMean)*(freqList[interval].intValue()-freqMean);
		}
		
		result = result/(timeList.size()-1);
		
		// calculate Pearson's Correlation
		double sisj = (getTimeStndDev(ucr)*getFreqStndDev(ucr));
		result = result/sisj;
		
		return result;
	}
	
	public void problem1() throws IOException {
		int[] sums = new int[24];
		
		for (int i = 0; i < incidents.size(); i++) {
			OPIncident op = (OPIncident) incidents.get(i);
			int hour = op.getHourOfDay();
			sums[hour]++;
		}
		
		int maxHour = 0;
		int count = 0;
		for (int i = 0; i < sums.length; i++) {
			if (sums[i] > count) {
				maxHour = i;
				count = sums[i];
			}
		}
		
		System.out.println("Highest Volume Time of Day (hour): " + maxHour);
	
		int[][] sums2 = new int[7][24];
		for (int i = 0; i < incidents.size(); i++) {
			OPIncident op = (OPIncident) incidents.get(i);
			int hour = op.getHourOfDay();
			int day = op.getDayOfWeek();
			sums2[day-1][hour]++;
		}
		
		// For incidents per hour/day of week graph
		/*for (int i = 0; i < 24; i++) {
			for (int j = 0; j < 7; j++) {
				System.out.println(j + "\t" + i + "\t" + sums2[j][i]);
			}
		}*/
		
		for (int i = 0; i < 7; i++) {
			maxHour = 0;
			count = 0;
			for (int j = 0; j < 24; j++) {
				if (sums2[i][j] > count) {
					count = sums2[i][j];
					maxHour = j;
				}
			}
			System.out.println("Day " + i + " Max Hour: " + maxHour + " Count: " + count);
		}
		
		BufferedWriter bw = new BufferedWriter(new FileWriter("hw4.dat"));
		Iterator it = ucrMap.keySet().iterator();
		while (it.hasNext()) {
			String ucr = (String) it.next();
			Integer[] freqs = (Integer[]) freqMap.get(ucr);
			for (int i = 0; i < Math.ceil(1440.0/OPAnalyze.minInterval); i++) {
				if (freqs[i] != null) {
					bw.write(ucr+ "\t" + i + "\t" + freqs[i].intValue()+ "\r\n");
				}
			}
		}
		bw.flush();
	}
	
	public void problem2() throws IOException {
		Set ucrs = new TreeSet();
		
		// Top 3 Incidents from HW #3
		ucrs.add("0911");
		ucrs.add("6589");
		ucrs.add("9103");
		
		BufferedWriter bw = new BufferedWriter(new FileWriter("top3.dat"));
		Iterator it = ucrs.iterator();
		while (it.hasNext()) {
			String ucr = (String) it.next();
			Integer[] freqs = (Integer[]) freqMap.get(ucr);
			for (int i = 0; i < Math.ceil(1440.0/OPAnalyze.minInterval); i++) {
				if (freqs[i] != null) {
					bw.write(ucr+ "\t" + i + "\t" + freqs[i].intValue()+ "\r\n");
				}
			}
		}
		bw.flush();
		
		it = ucrs.iterator();
		while (it.hasNext()) {
			String ucr = (String) it.next();
			System.out.println("UCR: " + ucr + " Correlation: " + getCorrelation(ucr));
		}
	}
}

