package net.oni2.aeinstaller.backend.packages;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;

import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
import net.oni2.aeinstaller.backend.Paths;
import net.oni2.platformtools.applicationinvoker.EExeType;

/**
 * @author Christian Illy
 */
public class Mod_Info {
	private double aeVersion = 0;
	private String name = "";
	private String creator = "";
	private EBSLInstallType bslInstallType = EBSLInstallType.NORMAL;
	private String version = "";
	private String description = "";

	private HashSet<Integer> incompatibilities = new HashSet<Integer>();
	private HashSet<Integer> dependencies = new HashSet<Integer>();
	private HashSet<Integer> unlockLevel = new HashSet<Integer>();

	private File exeFile = null;
	private EExeType exeType = EExeType.OSBINARY;
	private File iconFile = null;
	private String workingDir = "Base";

	/**
	 * @param f
	 *            Mod_Info.cfg
	 * @param packageNumber
	 *            Package number this Mod_Info belongs to
	 */
	public Mod_Info(File f, int packageNumber) {
		InputStreamReader isr = null;
		try {
			FileInputStream fstream = new FileInputStream(f);
			isr = new InputStreamReader(fstream);
			BufferedReader br = new BufferedReader(isr);
			String strLine;
			while ((strLine = br.readLine()) != null) {
				if (strLine.indexOf("->") < 1)
					continue;
				int pos = strLine.indexOf("//");
				while (pos >= 0) {
					if ((pos < 6)
							|| !strLine.substring(pos - 5, pos).equals("http:")) {
						strLine = strLine.substring(0, pos);
						break;
					} else {
						pos = strLine.indexOf("//", pos + 1);
					}
				}
				String[] split = strLine.split("->", 2);
				String sName = split[0].trim();
				String sVal = split[1].trim();
				if (sName.equalsIgnoreCase("AEInstallVersion")) {
					aeVersion = Double.parseDouble(sVal);
				} else if (sName.equalsIgnoreCase("NameOfMod")) {
					name = sVal;
				} else if (sName.equalsIgnoreCase("Creator")) {
					creator = sVal;
				} else if (sName.equalsIgnoreCase("HasBsl")) {
					if (sVal.equalsIgnoreCase("addon"))
						bslInstallType = EBSLInstallType.ADDON;
				} else if (sName.equalsIgnoreCase("ModVersion")) {
					version = sVal;
				} else if (sName.equalsIgnoreCase("Readme")) {
					description = "<p>" + sVal.replaceAll("\\\\n", "<br>")
							+ "</p>";
				} else if (sName.equalsIgnoreCase("DependsOn")) {
					String[] depsS = sVal.split(",");
					for (String s : depsS) {
						try {
							int dep = Integer.parseInt(s);
							dependencies.add(dep);
						} catch (NumberFormatException e) {
							System.err
									.format("Mod_Info of %05d does contain a non-number dependency: '%s'\n",
											packageNumber, s);
						}
					}
				} else if (sName.equalsIgnoreCase("IncompatibleWith")) {
					String[] confS = sVal.split(",");
					for (String s : confS) {
						try {
							int conf = Integer.parseInt(s);
							incompatibilities.add(conf);
						} catch (NumberFormatException e) {
							System.err
									.format("Mod_Info of %05d does contain a non-number incompatibility: '%s'\n",
											packageNumber, s);
						}
					}
				} else if (sName.equalsIgnoreCase("UnlockLevel")) {
					String[] levelsS = sVal.split(",");
					for (String s : levelsS) {
						try {
							int level = Integer.parseInt(s);
							unlockLevel.add(level);
						} catch (NumberFormatException e) {
							System.err
									.format("Mod_Info of %05d does contain a non-number UnlockLevel value: '%s'\n",
											packageNumber, s);
						}
					}
				} else if (sName.equalsIgnoreCase("ExeName")) {
					exeFile = CaseInsensitiveFile.getCaseInsensitiveFile(
							Paths.getEditionBasePath(), sVal);
				} else if (sName.equalsIgnoreCase("ExeType")) {
					if (sVal.equalsIgnoreCase("OSBinary"))
						exeType = EExeType.OSBINARY;
					else if (sVal.equalsIgnoreCase("WinExe"))
						exeType = EExeType.WINEXE;
					else if (sVal.equalsIgnoreCase("DotNet"))
						exeType = EExeType.DOTNET;
					else if (sVal.equalsIgnoreCase("Jar"))
						exeType = EExeType.JAR;
				} else if (sName.equalsIgnoreCase("WorkingDir")) {
					workingDir = sVal;
				} else if (sName.equalsIgnoreCase("IconName")) {
					iconFile = CaseInsensitiveFile.getCaseInsensitiveFile(
							Paths.getEditionBasePath(), sVal);
				}
			}
			if (exeFile != null) {
				if (exeFile.getName().toLowerCase().endsWith(".jar"))
					exeType = EExeType.JAR;
				else if (exeType == EExeType.OSBINARY && exeFile.getName().toLowerCase().endsWith(".exe"))
					exeType = EExeType.WINEXE;
			}
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (isr != null) {
				try {
					isr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * @return the aeVersion
	 */
	public double getAeVersion() {
		return aeVersion;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @return the creator
	 */
	public String getCreator() {
		return creator;
	}

	/**
	 * @return the bslInstallType
	 */
	public EBSLInstallType getBslInstallType() {
		return bslInstallType;
	}

	/**
	 * @return the version
	 */
	public String getVersion() {
		return version;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @return the incompatibilities
	 */
	public HashSet<Integer> getIncompatibilities() {
		return incompatibilities;
	}

	/**
	 * @return the dependencies
	 */
	public HashSet<Integer> getDependencies() {
		return dependencies;
	}

	/**
	 * @return the unlockLevel
	 */
	public HashSet<Integer> getUnlockLevel() {
		return unlockLevel;
	}

	/**
	 * @return the exeFile
	 */
	public File getExeFile() {
		return exeFile;
	}

	/**
	 * @return the exeType
	 */
	public EExeType getExeType() {
		return exeType;
	}

	/**
	 * @return the iconFile
	 */
	public File getIconFile() {
		return iconFile;
	}

	/**
	 * @return the workingDir
	 */
	public String getWorkingDir() {
		return workingDir;
	}

}
