//package Adaptivealgorithm;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;


public class LlamaAdaptive extends Algorithm {

	LinkedList <PDF> probabilitydist = new LinkedList();

	double meanintertime = 0;
	double variance = 0;

	PDF distribution = new PDF();
	public rechargeinfo runalgorithm(List presentinfo,boolean charging) throws IOException {
		rechargeinfo temp = new rechargeinfo();

		temp.dotask = false;
		temp.timeinterval = PropertyFileValues.defaulttime;


		if(charging)
		{
			FileWriter fw = new FileWriter(new File(PropertyFileValues.destination_dir+"/"+"Logger_"+String.valueOf(presentinfo.get(0)).substring(0,10)),true);
			fw.write("\nNetwork Application");
			fw.write("\nPresent Battery at time "+String.valueOf(presentinfo.get(0))+ " is "+
					String.valueOf(presentinfo.get(2)));

			fw.write("\nDoing Task and changing network download to 1");

			fw.close();
			temp.brightnesslevel= 1;
			temp.dotask = true;
			return temp;
		}

		// construct the histogram of recharges
		LinkedList <Bar> distribution = findhistogram(PropertyFileValues.archivefile
				, (new Integer(String.valueOf(presentinfo.get(2)))).intValue()
				, (new Long(String.valueOf(presentinfo.get(1))).longValue()));


		double meanintertimehrs = meanintertime/3600.0;
		double probability = 1.0 - PropertyFileValues.probassurance;
		double cdf = 0;
		double recharge = 0;


		// make cdf of the distribution
		LinkedList <Bar> cumulative = new LinkedList();
		double prob = 0;
		for(int i=0;i<distribution.size();i++)
		{
			Bar val = distribution.get(i);
			prob += val.val;
			Bar valnew = new Bar(val.bin,prob);
			cumulative.add(valnew);
		}

		for(int i=0;i<cumulative.size()-1;i++)
		{
			Bar firstprob = cumulative.get(i);
			Bar secondprob = cumulative.get(i+1);
			System.out.println("*** "+firstprob.val+" "+secondprob.val);
			if(probability >= firstprob.val && probability <= secondprob.val)
			{
				recharge = firstprob.bin;
				break;
			}
			else if(probability >= firstprob.val)
			{
				recharge = firstprob.bin;
			}

		}

		System.out.println(" "+recharge+" "+variance);
		//recharge = Math.min(recharge, variance);

		// amt of energy left
		double amtenergy = (recharge/100.0)*(new Double(String.valueOf(presentinfo.get(3))).doubleValue());

		System.out.println("Amount of Energy "+amtenergy+" "+recharge+" "+meanintertime/3600);
		double wattpower = (amtenergy)/(meanintertime/3600);

		System.out.println("In MAH "+wattpower);


		FileReader fr = new FileReader(new File(PropertyFileValues.appenergyinfo));
		BufferedReader fread = new BufferedReader(fr);

		String line = fread.readLine();

		double lastdouble = 0;
		boolean found = false;
		while(line != null)
		{
			StringTokenizer tok = new StringTokenizer(line);
			double level = new Double(tok.nextToken()).doubleValue();
			double energy = new Double(tok.nextToken()).doubleValue();
			if(energy >= wattpower)
			{
				break;
			}
			lastdouble = level;
			line = fread.readLine();
		}

		fread.close();

		System.out.println("LASTDOUBLE "+lastdouble+" "+wattpower);
		if(lastdouble == 0)
		{
			temp.dotask = true;
			temp.brightnesslevel = 0.25;
			temp.timeinterval = PropertyFileValues.defaulttime;
		}
		else
		{
			temp.dotask = true;
			temp.timeinterval = PropertyFileValues.defaulttime;
			temp.brightnesslevel = lastdouble;
		}

		// log information

		FileWriter fw = new FileWriter(new File(PropertyFileValues.destination_dir+"/"+"Logger_"+String.valueOf(presentinfo.get(0)).substring(0,10)),true);
		fw.write("\nPresent Battery at time "+String.valueOf(presentinfo.get(0))+ " is "+
				String.valueOf(presentinfo.get(2)));
		for(int i=0;i<distribution.size();i++)
		{
			Bar temp1 = distribution.get(i);
			fw.write("\n "+temp1.bin+" "+temp1.val);
		}
		if(temp.dotask)
			fw.write("\nDoing Task and changing network download to "+temp.brightnesslevel);
		else
			fw.write("\nNot doing task");	

		fw.write("\nMean inter recharge time "+meanintertime);
		fw.write("\nEnergy left at recharge "+amtenergy);

		fw.close();
		return temp;
	}

	private LinkedList<Bar> findhistogram(String filename,int percentage, long presenttime) throws IOException
	{
		System.out.println(""+filename);
		File dir1 = new File(PropertyFileValues.logfiles);
		String[] log_list = dir1.list();
		File directory = new File(filename);
		String[] file_list = directory.list();

		LinkedList <Long> time = new LinkedList();
		Histogram hist = new Histogram(0.0,100.0,20);

		for(int i=0;i<file_list.length;i++)
		{
			String datafile = filename + "/"+ file_list[i];
			FileReader f = new FileReader(new File(datafile));
			BufferedReader fr = new BufferedReader(f);
			int lastonac = 1;
			int onac;
			int charge = 0;
			long sectime=0;
			String line = fr.readLine();

			while(line != null)
			{
				StringTokenizer str = new StringTokenizer(line);
				Integer val;

				if(line.contains("2007") || line.contains("2006") && str.countTokens() == 6)
				{
					line = fr.readLine();
					sectime = new Long(line).longValue();
				}

				if(line.contains("battery"))
				{
					str.nextToken();
					val = new Integer(str.nextToken()).intValue();
					if(val <= 100)
					{
						charge = val.intValue();
						time.add(sectime);
					}
				}

				if(line.contains("onAC"))
				{
					str.nextToken();
					val = new Integer(str.nextToken());
					onac = val.intValue();
					if(onac == 1 && lastonac == 0)
					{
						//System.out.println("Charge "+charge);
						hist.addelement((double)charge);
					}
					lastonac=onac;
				}
				line = fr.readLine();
			}
		}

		for(int i=0;i<log_list.length;i++)
		{
			String datafile = PropertyFileValues.logfiles + "/"+ log_list[i];
			FileReader f = new FileReader(new File(datafile));
			BufferedReader fr = new BufferedReader(f);
			int lastonac = 1;
			int onac;
			int charge = 0;
			long sectime=0;
			String line = fr.readLine();

			while(line != null)
			{
				StringTokenizer str = new StringTokenizer(line);
				Integer val;

				if(line.contains("2007") || line.contains("2006") && str.countTokens() == 6)
				{
					line = fr.readLine();
					sectime = new Long(line).longValue();
				}

				if(line.contains("battery"))
				{
					str.nextToken();
					val = new Integer(str.nextToken()).intValue();
					if(val <= 100)
					{
						charge = val.intValue();
						time.add(sectime);
					}
				}

				if(line.contains("onAC"))
				{
					str.nextToken();
					val = new Integer(str.nextToken());
					onac = val.intValue();
					if(onac == 1 && lastonac == 0)
					{
						System.out.println("Charge "+charge);
						hist.addelement((double)charge);
					}
					lastonac=onac;
				}
				line = fr.readLine();
			}
			
		}
		
		System.out.println("Percentage of battery now :  "+percentage);
		LinkedList <Bar> distribution = new LinkedList();
		distribution = hist.distributionlessthanapoint(percentage);


		double mean = 0;
		for(int i=0;i<distribution.size();i++)
		{
			Bar temp = distribution.get(i);
			mean += temp.bin*temp.val;
		}
 
		variance = 0;
		System.out.println(" "+mean);
		for(int i=0;i<distribution.size();i++)
		{
			Bar temp = distribution.get(i);
			System.out.println("00  "+temp.bin+" "+mean +" "+temp.val);
			variance += (temp.bin - mean)*(temp.bin - mean)*temp.val;
		}

		System.out.println("Variance "+variance);
		variance = Math.sqrt(variance);

		for(int i=0; i<time.size() - 1;i++)
		{
			double difference = (double)(time.get(i+1).longValue() - time.get(i).longValue());

			if(difference > 0)
			{
				difference /= 1000.0;
				meanintertime += difference;
			}
		}

		meanintertime /= time.size();
		
		double lastrechargetime = time.get(time.size() - 1)/1000;
		
		double difference = (double)presenttime/1000.0 - lastrechargetime;
		
		System.out.println("difference "+difference+" "+meanintertime);
		
		
		
		return distribution;

	}

}
