package org.redalert1741.robotBase.config;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Config 
{
	private static Map<String, Double> doubleSettings;
	private static Map<String, Boolean> booleanSettings;
	private static Map<String, String> stringSettings;
	private static List<Configurable> configurables; 

	public static void dumpConfig()
	{
		System.out.println("DUMP");
		for(Map.Entry<String, Double> e : doubleSettings.entrySet())
		{
			System.out.println(e.getKey() + ": " + e.getValue());
		}
		System.out.println("END DUMP");
	}
	
	public static boolean loadFromFile(String filename)
	{
		return parse(filename);
	}

	public static double getSetting(String name, double reasonable_default)
	{
		double retval = reasonable_default;
		name = name.toLowerCase();
		
		if (doubleSettings.containsKey(name)) 
		{
			retval = doubleSettings.get(name);
		}

		return retval;
	}
	
	public static boolean getSetting(String name, boolean r_default)
	{
		boolean retval = r_default;
		name = name.toLowerCase();
		
		if (booleanSettings.containsKey(name)) 
		{
			retval = booleanSettings.get(name);
		}

		return retval;
	}
	
	public static String getSetting(String name, String r_default)
	{
		String retval = r_default;
		name = name.toLowerCase();
		
		if (stringSettings.containsKey(name)) 
		{
			retval = stringSettings.get(name);
		}

		return retval;
	}

	public static void setSetting(String name, double value)
	{
		name = name.toLowerCase();
		doubleSettings.put(name, value);
	}

	static boolean parse(String filename)
	{
		doubleSettings = new HashMap<String,Double>();
		booleanSettings = new HashMap<>();
		stringSettings = new HashMap<>();
		Scanner infile;
		try
		{
			infile = new Scanner(new File(filename));
		}
		catch (FileNotFoundException e)
		{
			System.out.println("Couldn't find config file \"" + filename + "\"");
			return false;
		} 
		
		/*
		 * Match exactly 0 '#'
		 * Match as many alphanumeric characters + '_'
		 * Optional ' ' around an '='
		 * Match a number, with an optional '.' and more numbers
		 */
		Pattern doublepattern = Pattern.compile("^(#{0})[\\w\\d_]+\\s*?=\\s*?-?(\\d+)?(\\.\\d+)?$");
		Pattern booleanpattern = Pattern.compile("^#{0}([\\w\\d_]+)\\s*?= ?([Tt]rue|[Ff]alse)$");
		Pattern stringpattern = Pattern.compile("^#{0}([\\w\\d_]+)\\s*?=\\s*?\"([^\"]*)\"$");
		Matcher t;
		while(infile.hasNextLine())
		{
			String in = infile.nextLine();
			if(doublepattern.matcher(in).matches())
			{
				String[] key = in.split(" ?=");
				Double value = Double.parseDouble(key[1]);
				doubleSettings.put(key[0].toLowerCase(), value);
				System.out.println(key[0] + ": " + value);
			}
			else if((t = booleanpattern.matcher(in)).matches())
			{
				String[] key = in.split(" ?=");
				Boolean value = Boolean.parseBoolean(key[1]);
				booleanSettings.put(key[0].toLowerCase(), value);
				System.out.println(key[0] + ": " + value);
			}
			else if((t = stringpattern.matcher(in)).matches())
			{
				String[] key = in.split(" ?=");
				//stringpattern.matcher(in);
				String value = t.group(2);
				stringSettings.put(key[0].toLowerCase(), value);
				System.out.println(key[0] + ": " + value);
			}
			else if(!in.startsWith("#") && !in.isEmpty())
			{
				System.out.println("Could not parse line \"" + in + "\"");
			}
		}
		infile.close();
		return true;
	}
	
	public static void addConfigurable(Configurable c)
	{
		if(configurables == null) { configurables = new ArrayList<>(); }
		configurables.add(c);
	}
	
	public static void reloadConfig()
	{
		for(Configurable c : configurables)
		{
			c.reloadConfig();
		}
	}

}

@@ -2305,14 +2305,13 @@
 e(%22%5E
-(
 #%7B0%7D
-)
+(
 %5B%5C%5Cw
@@ -2316,16 +2316,17 @@
 %5Cw%5C%5Cd_%5D+
+)
 %5C%5Cs*?=%5C%5C
@@ -2332,18 +2332,18 @@
 %5Cs*?
+(
 -?
-(
 %5C%5Cd
-+)?(
+*(?:
 %5C%5C.%5C
@@ -2347,16 +2347,17 @@
 %5C.%5C%5Cd+)?
+)
 $%22);%0A%09%09P
@@ -2620,16 +2620,21 @@
 ;%0A%09%09%09if(
+(t = 
 doublepa
@@ -2650,16 +2650,17 @@
 cher(in)
+)
 .matches
@@ -2678,39 +2678,32 @@
 %09%09String
-%5B%5D
  key = 
-in.split(%22 ?=%22
+t.group(1
 );%0A%09%09%09%09D
@@ -2735,22 +2735,26 @@
 eDouble(
-key%5B1%5D
+t.group(2)
 );%0A%09%09%09%09d
@@ -2766,35 +2766,32 @@
 Settings.put(key
-%5B0%5D
 .toLowerCase(), 
@@ -2816,35 +2816,32 @@
 .out.println(key
-%5B0%5D
  + %22: %22 + value)
@@ -2917,39 +2917,32 @@
 %09%09String
-%5B%5D
  key = 
-in.split(%22 ?=%22
+t.group(1
 );%0A%09%09%09%09B
@@ -2981,14 +2981,18 @@
 ean(
-key%5B1%5D
+t.group(2)
 );%0A%09
@@ -3009,35 +3009,32 @@
 Settings.put(key
-%5B0%5D
 .toLowerCase(), 
@@ -3059,35 +3059,32 @@
 .out.println(key
-%5B0%5D
  + %22: %22 + value)
@@ -3163,64 +3163,24 @@
 ring
-%5B%5D
  key = 
-in.split(%22 ?=%22);%0A%09%09%09%09//stringpattern.matcher(in
+t.group(1
 );%0A%09
@@ -3235,19 +3235,16 @@
 .put(key
-%5B0%5D
 .toLower
@@ -3289,11 +3289,8 @@
 (key
-%5B0%5D
  + %22

Use regex groups