Resources system rewrite + new "--save-config DIR" option
[jvcard.git] / src / be / nikiroo / jvcard / tui / UiColors.java
index eadcd2985ca0546af2ab39126d4cb048ac5181ae..abac7d54b56146746a88b6ae83c2451ac9d11178 100644 (file)
@@ -2,6 +2,10 @@ package be.nikiroo.jvcard.tui;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.MissingResourceException;
+
+import be.nikiroo.jvcard.resources.bundles.ColorBundle;
+import be.nikiroo.jvcard.resources.enums.ColorOption;
 
 import com.googlecode.lanterna.TextColor;
 import com.googlecode.lanterna.gui2.Label;
@@ -12,84 +16,28 @@ import com.googlecode.lanterna.gui2.Label;
  * @author niki
  * 
  */
-public class UiColors {
+public class UiColors extends ColorBundle {
        static private Object lock = new Object();
        static private UiColors instance = null;
 
-       private Map<Element, TextColor> mapForegroundColor = null;
-       private Map<Element, TextColor> mapBackgroundColor = null;
-       private boolean utf = true;
+       private Map<String, TextColor> colorMap = null;
 
-       /**
-        * Get the (unique) instance of this class.
-        * 
-        * @return the (unique) instance
-        */
-       static public UiColors getInstance() {
-               synchronized (lock) {
-                       if (instance == null)
-                               instance = new UiColors();
-               }
-
-               return instance;
-       }
-
-       public enum Element {
-               DEFAULT, //
-               TITLE_MAIN, TITLE_VARIABLE, TITLE_COUNT, //
-               ACTION_KEY, ACTION_DESC, //
-               LINE_MESSAGE, LINE_MESSAGE_ERR, LINE_MESSAGE_QUESTION, LINE_MESSAGE_ANS, //
-               CONTACT_LINE, CONTACT_LINE_SEPARATOR, CONTACT_LINE_SELECTED, CONTACT_LINE_SEPARATOR_SELECTED, CONTACT_LINE_DIRTY, CONTACT_LINE_DIRTY_SELECTED, //
-               VIEW_CONTACT_NAME, VIEW_CONTACT_NORMAL, VIEW_CONTACT_NOTES_TITLE, //
-               ;
-
-               /**
-                * Get the foreground colour of this element.
-                * 
-                * @return the colour
-                */
-               public TextColor getForegroundColor() {
-                       return UiColors.getInstance().getForegroundColor(this);
-               }
-
-               /**
-                * Get the background colour of this element.
-                * 
-                * @return the colour
-                */
-               public TextColor getBackgroundColor() {
-                       return UiColors.getInstance().getBackgroundColor(this);
-               }
-
-               public Label createLabel(String text) {
-                       return UiColors.getInstance().createLabel(this, text);
-               }
-
-               public void themeLabel(Label lbl) {
-                       UiColors.getInstance().themeLabel(this, lbl);
-               }
+       private UiColors() {
+               super();
+               colorMap = new HashMap<String, TextColor>();
        }
 
        /**
-        * Check if unicode characters should be used.
+        * Create a new {@link Label} with the colours of the given {@link ColorOption}.
         * 
-        * @return TRUE to allow unicode
-        */
-       public boolean isUnicode() {
-               return utf;
-       }
-
-       /**
-        * Allow or disallow unicode characters in the program.
+        * @param el
+        *            the {@link ColorOption}
+        * @param text
+        *            the text of the {@link Label}
         * 
-        * @param utf
-        *            TRUE to allow unuciode, FALSE to only allow ASCII characters
+        * @return the new {@link Label}
         */
-       public void setUnicode(boolean utf) {
-               this.utf = utf;
-       }
-
-       private Label createLabel(Element el, String text) {
+       static public Label createLabel(ColorOption el, String text) {
                if (text == null)
                        text = "";
 
@@ -98,62 +46,112 @@ public class UiColors {
                return lbl;
        }
 
-       private void themeLabel(Element el, Label lbl) {
-               lbl.setForegroundColor(el.getForegroundColor());
-               lbl.setBackgroundColor(el.getBackgroundColor());
+       /**
+        * Theme a {@link Label} with the colours of the given {@link ColorOption}.
+        * 
+        * @param el
+        *            the {@link ColorOption}
+        * @param lbl
+        *            the {@link Label}
+        */
+       static public void themeLabel(ColorOption el, Label lbl) {
+               lbl.setForegroundColor(getForegroundColor(el));
+               lbl.setBackgroundColor(getBackgroundColor(el));
        }
 
-       private TextColor getForegroundColor(Element el) {
-               if (mapForegroundColor.containsKey(el)) {
-                       return mapForegroundColor.get(el);
+       /**
+        * Return the background colour of the given element.
+        * 
+        * @param el
+        *            the {@link ColorOption}
+        * 
+        * @return its background colour
+        */
+       static public TextColor getBackgroundColor(ColorOption el) {
+               if (!getInstance().colorMap.containsKey(el.name() + "_BG")) {
+                       String value = null;
+                       try {
+                               value = getInstance().map.getString(el.name() + "_BG");
+                       } catch (MissingResourceException mre) {
+                               value = null;
+                       }
+                       getInstance().colorMap.put(el.name() + "_BG",
+                                       convertToColor(value, TextColor.ANSI.BLACK));
                }
 
-               return TextColor.ANSI.BLACK;
+               return getInstance().colorMap.get(el.name() + "_BG");
        }
 
-       private TextColor getBackgroundColor(Element el) {
-               if (mapBackgroundColor.containsKey(el)) {
-                       return mapBackgroundColor.get(el);
+       /**
+        * Return the foreground colour of the given element.
+        * 
+        * @param el
+        *            the {@link ColorOption}
+        * 
+        * @return its foreground colour
+        */
+       static public TextColor getForegroundColor(ColorOption el) {
+               if (!getInstance().colorMap.containsKey(el.name() + "_FG")) {
+                       String value = null;
+                       try {
+                               value = getInstance().map.getString(el.name() + "_FG");
+                       } catch (MissingResourceException mre) {
+                               value = null;
+                       }
+                       getInstance().colorMap.put(el.name() + "_FG",
+                                       convertToColor(value, TextColor.ANSI.WHITE));
                }
 
-               return TextColor.ANSI.WHITE;
+               return getInstance().colorMap.get(el.name() + "_FG");
        }
 
-       private UiColors() {
-               mapForegroundColor = new HashMap<Element, TextColor>();
-               mapBackgroundColor = new HashMap<Element, TextColor>();
-
-               // TODO: get from a file instead?
-               // TODO: use a theme that doesn't give headaches...
-               addEl(Element.ACTION_KEY, TextColor.ANSI.WHITE, TextColor.ANSI.RED);
-               addEl(Element.ACTION_DESC, TextColor.ANSI.WHITE, TextColor.ANSI.BLUE);
-               addEl(Element.CONTACT_LINE, TextColor.ANSI.WHITE, TextColor.ANSI.BLACK);
-               addEl(Element.CONTACT_LINE_SELECTED, TextColor.ANSI.WHITE,
-                               TextColor.ANSI.BLUE);
-               addEl(Element.CONTACT_LINE_SEPARATOR, TextColor.ANSI.RED,
-                               TextColor.ANSI.BLACK);
-               addEl(Element.CONTACT_LINE_SEPARATOR_SELECTED, TextColor.ANSI.RED,
-                               TextColor.ANSI.BLUE);
-               addEl(Element.LINE_MESSAGE, TextColor.ANSI.BLUE, TextColor.ANSI.WHITE);
-               addEl(Element.LINE_MESSAGE_ERR, TextColor.ANSI.RED,
-                               TextColor.ANSI.WHITE);
-               addEl(Element.LINE_MESSAGE_QUESTION, TextColor.ANSI.BLUE,
-                               TextColor.ANSI.WHITE);
-               addEl(Element.LINE_MESSAGE_ANS, TextColor.ANSI.BLUE,
-                               TextColor.ANSI.BLACK);
-               addEl(Element.TITLE_MAIN, TextColor.ANSI.WHITE, TextColor.ANSI.BLUE);
-               addEl(Element.TITLE_VARIABLE, TextColor.ANSI.GREEN, TextColor.ANSI.BLUE);
-               addEl(Element.TITLE_COUNT, TextColor.ANSI.RED, TextColor.ANSI.BLUE);
-               addEl(Element.VIEW_CONTACT_NAME, TextColor.ANSI.BLACK,
-                               TextColor.ANSI.WHITE);
-               addEl(Element.VIEW_CONTACT_NORMAL, TextColor.ANSI.WHITE,
-                               TextColor.ANSI.BLACK);
-               addEl(Element.VIEW_CONTACT_NOTES_TITLE, TextColor.ANSI.BLACK,
-                               TextColor.ANSI.WHITE);
+       /**
+        * Get the (unique) instance of this class.
+        * 
+        * @return the (unique) instance
+        */
+       static private UiColors getInstance() {
+               synchronized (lock) {
+                       if (instance == null)
+                               instance = new UiColors();
+               }
+
+               return instance;
        }
 
-       private void addEl(Element el, TextColor fore, TextColor back) {
-               mapForegroundColor.put(el, fore);
-               mapBackgroundColor.put(el, back);
+       /**
+        * Convert the given {@link String} value to a {@link TextColor}.
+        * 
+        * @param value
+        *            the {@link String} to convert
+        * @param defaultColor
+        *            the default {@link TextColor} to return if the conversion
+        *            failed
+        * 
+        * @return the converted colour
+        */
+       static private TextColor convertToColor(String value, TextColor defaultColor) {
+               try {
+                       if (value.startsWith("@")) {
+                               int r = Integer.parseInt(value.substring(1, 3), 16);
+                               int g = Integer.parseInt(value.substring(3, 5), 16);
+                               int b = Integer.parseInt(value.substring(5, 7), 16);
+                               return TextColor.Indexed.fromRGB(r, g, b);
+                       } else if (value.startsWith("#")) {
+                               int r = Integer.parseInt(value.substring(1, 3), 16);
+                               int g = Integer.parseInt(value.substring(3, 5), 16);
+                               int b = Integer.parseInt(value.substring(5, 7), 16);
+                               return new TextColor.RGB(r, g, b);
+                       } else if (value.replaceAll("[0-9]*", "").length() == 0) {
+                               return new TextColor.Indexed(Integer.parseInt(value));
+                       } else {
+                               return TextColor.ANSI.valueOf(value);
+                       }
+               } catch (Exception e) {
+                       new Exception("Cannot convert value to colour: " + value, e)
+                                       .printStackTrace();
+               }
+
+               return defaultColor;
        }
 }