/*
* Tyr is an AI for StarCraft: Broodwar, 
* 
* Please visit https://github.com/SimonPrins/Tyr for further information.
* 
* Copyright 2015 Simon Prins
*
* This file is part of Tyr.
* Tyr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* Tyr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Tyr.  If not, see http://www.gnu.org/licenses/.
*/

package com.tyr;

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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import bwapi.Unit;


/**
 * This class helps writing messages to the screen for debug purposes.
 * Also allows you to store information about the current opponent for future games.
 * @author Simon
 *
 */
public class DebugMessages
{
	/**
	 * List of messages that will be written to the screen at the end of the frame.
	 * After the messages have been displayed the list is cleared for next frame.
	 */
	private static ArrayList<String> messages = new ArrayList<String>();
	
	/**
	 * The messages that are added to the screen permanently.
	 */
	private static ArrayList<String> permanentMessages = new ArrayList<String>();
	
	/**
	 * The file in which we will store information about the opponent.
	 */
	private static File file;
	
	/**
	 * Maps a debug text to a unit.
	 */
	public static HashMap<Unit, String> unitInfo = new HashMap<Unit, String>();
	
	/**
	 * Writes a message to the screen this frame.
	 * @param message The message to write to the screen.
	 */
	public static void addMessage(String message)
	{
		messages.add(message);
	}

	/**
	 * Adds a message to the screen permanently.
	 * @param message The message to add to the screen.
	 */
	public static void addMessagePermanent(String message) 
	{
		permanentMessages.add(message);
	}
	
	/**
	 * Writes all stored messages to the screen.
	 */
	public static void toScreen()
	{
		for(int i=0; i<permanentMessages.size(); i++)
		{
			Tyr.game.setTextSize(bwapi.Text.Size.Enum.Small);
			Tyr.game.drawTextScreen(10, 25 + i*15, permanentMessages.get(i));
		}
		
		for(int i=0; i<messages.size(); i++)
		{
			Tyr.game.setTextSize(bwapi.Text.Size.Enum.Small);
			Tyr.game.drawTextScreen(10, 25 + (i + permanentMessages.size())*15, messages.get(i));
		}
		
		for (Map.Entry<Unit, String> entry : unitInfo.entrySet())
		{
			Tyr.game.drawTextMap(entry.getKey().getX(), entry.getKey().getY(), entry.getValue());
		}
		
		messages = new ArrayList<String>();
	}
	
	/**
	 * Creates a file to store information about the current enemy.
	 * If it already exists, no new file is created.
	 */
	private static void createFile()
	{
		file = createFile(Tyr.game.enemy().getRace() + " - " + getEnemyName() + ".txt");
	}
	
	/**
	 * Creates a file to store information about the current enemy.
	 * If it already exists, no new file is created.
	 * @param filename Name of the file you want to create.
	 */
	private static File createFile(String filename)
	{
		File result = null;
		try
		{
			result = new File("bwapi-data\\write\\" + filename);
			try 
			{
				if (!result.exists())
				{
					new File("bwapi-data\\write\\").mkdirs();
					result.createNewFile();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (Exception e) {}
		return result;
	}
	
	/**
	 * Get the name of the opponent.
	 * @return Get the name of the opponent.
	 */
	public static String getEnemyName()
	{
		List<String> namefile = DebugMessages.readFile("opponent.txt"); 
		if (namefile.size() == 0 || !Settings.getDebug())
			return Tyr.game.enemy().getName();
		else return namefile.get(0);
	}
	
	/**
	 * Reads information about the current opponent stored in the file.
	 * @return A list of all lines of text contained in the file.
	 */
	public static ArrayList<String> readFile()
	{
		return readFile(Tyr.game.enemy().getRace() + " - " + getEnemyName() + ".txt");
	}
	
	/**
	 * Reads the contents of a file.
	 * @param filename Name of the file to read.
	 * @return A list of all lines of text contained in the file.
	 */
	public static ArrayList<String> readFile(String filename)
	{
		try
		{
			File file = new File("bwapi-data\\read\\" + filename);
			
			if (!file.exists())
				return new ArrayList<String>();
			
			try 
			{
				FileReader reader = new FileReader(file);
				BufferedReader br = new BufferedReader(reader);
				ArrayList<String> result = new ArrayList<String>();
				
				for (String nextLine = br.readLine(); nextLine != null; nextLine = br.readLine())
					result.add(nextLine);
				br.close();
				return result;
				
			} catch (FileNotFoundException e)
			{
				return new ArrayList<String>();
			} catch (IOException e) {
				return new ArrayList<String>();
			}
		}
		catch(Exception e){return new ArrayList<String>();}
	}
	
	/**
	 * Saves the string to the file containing information about the current opponent.
	 * @param message
	 */
	public static void saveMessage(String message)
	{
		try
		{
			if (file == null)
				createFile();
			
			try
			{
				FileWriter writer = new FileWriter(file, true);
				writer.append(message + "\r\n");
				writer.close();
			} catch (IOException e) 
			{
				e.printStackTrace();
			}
		} catch(Exception e){}
	}
	
	public static void log(String message)
	{
		try
		{
			File log = createFile("log.txt");
			
			try
			{
				FileWriter writer = new FileWriter(log, true);
				writer.append(message + "\r\n");
				writer.close();
			} catch (IOException e) 
			{
				e.printStackTrace();
			}
		} catch(Exception e){}
	}
	
	public static void testGameEnd(boolean win)
	{
		try
		{
			File gameEnd = createFile("gameEnd.txt");

			try
			{
				FileWriter writer = new FileWriter(gameEnd, true);
				writer.append((win?"win":"loss") + "\r\n");
				writer.close();
			} catch (IOException e) 
			{
				e.printStackTrace();
			}
		} catch(Exception e){}
	}

	public static void testGameStart()
	{
		try
		{
			createFile("gameStart.txt");
		} catch(Exception e){}
	}
}
