]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/config/Configuration.java
af4e09cf5583bd6aa750b71d7c8c339f6dc8922c
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / config / Configuration.java
1 package com.irtimaled.bbor.client.config;
2
3 import com.google.common.io.Files;
4
5 import java.io.*;
6 import java.nio.charset.StandardCharsets;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 class Configuration {
12     private static final String FALLBACK_CATEGORY = "features";
13     private final File file;
14
15     Configuration(File file) {
16         this.file = file;
17     }
18
19     void save() {
20         try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
21             writer.write("# Configuration file\n");
22             for (String category : settingsGroup.keySet()) {
23                 writer.write("\n");
24                 writer.write(String.format("%s {\n", category));
25                 Map<String, Setting<?>> settings = settingsGroup.get(category);
26                 boolean first = true;
27                 for (String settingName : settings.keySet()) {
28                     if (!first)
29                         writer.write("\n");
30                     first = false;
31                     Setting setting = settings.get(settingName);
32                     writer.write(String.format("    # %s\n", setting.comment));
33                     writer.write(String.format("    %s:%s=%s\n", setting.getType(), settingName, setting.get()));
34                 }
35                 writer.write("}\n");
36             }
37         } catch (IOException ignored) {
38         }
39     }
40
41     private final Map<String, Map<String, Setting<?>>> settingsGroup = new HashMap<>();
42
43     void load() {
44         try {
45             List<String> lines = Files.readLines(file, StandardCharsets.UTF_8);
46             String category = null;
47             String lastCommentLine = null;
48             for (String line : lines) {
49                 String trimmedLine = line.trim();
50                 if (trimmedLine.isEmpty()) {
51                     continue;
52                 }
53                 if (trimmedLine.startsWith("#")) {
54                     lastCommentLine = trimmedLine.substring(1).trim();
55                     continue;
56                 }
57                 if (trimmedLine.equals("}")) {
58                     category = null;
59                     continue;
60                 }
61                 if (category == null && trimmedLine.endsWith("{")) {
62                     category = trimmedLine.substring(0, trimmedLine.length() - 1).trim();
63                     settingsGroup.put(category, new HashMap<>());
64                     continue;
65                 }
66                 if (category != null) {
67                     String[] items = trimmedLine.split("[:=]");
68                     char type = items[0].charAt(0);
69                     String name = items[1];
70                     String stringValue = items[2];
71                     Setting setting = getTypedSetting(type, stringValue);
72                     setting.comment = lastCommentLine;
73                     settingsGroup.get(category).put(name, setting);
74                 }
75             }
76         } catch (IOException ignored) {
77         }
78     }
79
80     private Setting<?> getTypedSetting(char type, String value) {
81         switch (type) {
82             case 'I':
83                 return new Setting<>(type, Integer.parseInt(value));
84             case 'B':
85                 return new Setting<>(type, value.equals("1") || value.toLowerCase().equals("true"));
86             case 'H':
87                 return new Setting<>(type, HexColor.from(value));
88         }
89         return new Setting<>(type, value);
90     }
91
92     <T> Setting<T> get(String category, String settingName, T defaultValue) {
93         char type = getType(defaultValue);
94         if (!settingsGroup.containsKey(category)) {
95             settingsGroup.put(category, new HashMap<>());
96         }
97         Map<String, Setting<?>> settings = settingsGroup.get(category);
98         Setting<?> setting = settings.get(settingName);
99         if (setting == null && !category.equals(FALLBACK_CATEGORY))
100             setting = getFallbackSetting(settingName, settings);
101         if (setting != null && setting.getType() != type) {
102             setting = null;
103         }
104         if (setting == null) {
105             settings.put(settingName, setting = new Setting<>(type, defaultValue));
106         }
107         return (Setting<T>) setting;
108     }
109
110     private Setting<?> getFallbackSetting(String settingName, Map<String, Setting<?>> settings) {
111         Map<String, Setting<?>> fallbackSettings = settingsGroup.get(FALLBACK_CATEGORY);
112         if (fallbackSettings == null) return null;
113
114         Setting<?> setting = fallbackSettings.get(settingName);
115         if (setting != null) {
116             fallbackSettings.remove(settingName);
117             settings.put(settingName, setting);
118         }
119         return setting;
120     }
121
122     private <T> char getType(T defaultValue) {
123         String[] typeNames = defaultValue.getClass().getName().split("[.]");
124         return typeNames[typeNames.length - 1].charAt(0);
125     }
126
127     void put(Setting<?> setting) {
128         String category = setting.category;
129         if (!settingsGroup.containsKey(category)) {
130             settingsGroup.put(category, new HashMap<>());
131         }
132         Map<String, Setting<?>> settings = settingsGroup.get(category);
133         settings.put(setting.name, setting);
134     }
135 }