package shapes77.util;
/* Saved in UTF-8 codepage: Příliš žluťoučký kůň úpěl ďábelské ódy. ÷ × ¤ */

import java.awt.Color;

import java.text.Collator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;



/*******************************************************************************
 * Třída {@code NamedColor} definuje skupinu základních barev
 * pro použití při kreslení tvarů.
 * Není definována jako výčtový typ,
 * aby uživatel mohl libovolně přidávat vlastní barvy.
 *
 * @author  Rudolf PECINOVSKÝ
 * @version 2020-Winter
 */
public class NamedColor
{
//\CC== CLASS CONSTANTS (CONSTANT CLASS/STATIC ATTRIBUTES/FIELDS) ==============

    /** Počet pojmenovaných barev se při konstrukci následujících instancí
     *  načítá, a proto musí být počítající atribut deklarován před nimi. */
    private static int count = 0;

    /** Atribut průhlednosti pro průsvitné barvy. */
    private static final int TRANSLUCENCE = 128;

    /** Minimální velikost složky při změnách světlosti a průhlednosti. */
    private static final int MINC = 32;

    /** Maximální velikost složky při změnách světlosti a průhlednosti. */
    private static final int MAXC = 255;

    /** Koeficient změny velikost složky při změnách světlosti a průhlednosti.*/
    private static final double CHANGE_KOEF = 0.7;

    /** Mapa všech doposud vytvořených barev klíčovaná jejich názvy. */
    private static final Map<String,NamedColor> name2namedColor =
                                                new LinkedHashMap<>();

    /** Mapa všech doposud vytvořených barev klíčovaná jejich názvy
     *  s odstraněnou diakritikou. */
    private static final Map<String,NamedColor> nameRA2namedColor =
                                                new LinkedHashMap<>();

    /** Mapa všech doposud vytvořených barev klíčovaná jejich "FX-barvou". */
    private static final Map<Color,NamedColor>  color2namedColor =
                                                new LinkedHashMap<>();

    /** Seznam všech dosud vytvořených barev. */
    private static final List<NamedColor> namedColorList = new ArrayList<>(32);



    //########## COLORS ########################################################

    //########## Colors with equivalent constant in javafx.scene.paint.Color

    /** Black = RGBA(0, 0, 0, 255); */         public static final NamedColor
    BLACK      = new NamedColor(Color.BLACK,        "black"     );

    /** Blue = RGBA(0, 0, 255, 255); */        public static final NamedColor
    BLUE       = new NamedColor(Color.BLUE,         "blue"      );

    /** Red = RGBA(255, 0, 0, 255); */         public static final NamedColor
    RED        = new NamedColor(Color.RED,          "red"       );

    /** Magenta = RGBA(255, 0, 255, 255); */   public static final NamedColor
    MAGENTA    = new NamedColor(Color.MAGENTA,      "magenta"   );

    /** Green = RGBA(0, 255, 0, 255); */       public static final NamedColor
    GREEN      = new NamedColor(Color.GREEN,        "green"     );

    /** Cyan = RGBA(0, 255, 255, 255); */      public static final NamedColor
    CYAN       = new NamedColor(Color.CYAN,         "cyan"      );

    /** Yellow = RGBA(255, 255, 0, 255); */    public static final NamedColor
    YELLOW     = new NamedColor(Color.YELLOW,       "yellow"    );

    /** White = RGBA(255, 255, 255, 255); */   public static final NamedColor
    WHITE      = new NamedColor(Color.WHITE,        "white"     );

    /** Light gray = RGBA(192,192,192,255); */ public static final NamedColor
    LIGHT_GRAY = new NamedColor(Color.LIGHT_GRAY,   "lightgray" );//192 = 0xC0

    /** Gray = RGBA(128, 128, 128, 255); */    public static final NamedColor
    GRAY       = new NamedColor(Color.GRAY,         "gray"      );//128 = 0x80

    /** Dark gray = RGBA(64, 64, 64, 255); */  public static final NamedColor
    DARK_GRAY  = new NamedColor(Color.DARK_GRAY,    "darkgray"  );//64 = 0x40

    /** Pink = RGBA(255, 175, 175, 255); */    public static final NamedColor
    PINK       = new NamedColor(Color.PINK,         "pink"      );//175 = 0xAF

    /** Orange = RGBA(255, 200, 0, 255); */    public static final NamedColor
    ORANGE     = new NamedColor(Color.ORANGE,       "orange"    );


    //########## Colors without equivalent constant in javafx.scene.paint.Color

    /** Amber = RGBA(255, 204, 000, 255);*/ public static final NamedColor
    AMBER  = new NamedColor(new Color(0xFF, 0xCC, 0x00, 255), "amber");

    /** Brick = RGBA(255, 102, 0, 255); */     public static final NamedColor
    BRICK  = new NamedColor(new Color(0xFF, 0x66, 0x00, 255), "brick"     );

    /** Brown = RGBA(153, 51, 0, 255); */      public static final NamedColor
    BROWN  = new NamedColor(new Color(0x99, 0x33, 0x00, 255),  "brown"    );

    /** Creamy = RGBA(255, 255, 204, 255); */  public static final NamedColor
    CREAMY = new NamedColor(new Color(0xFF, 0xFF, 0xCC, 255),  "creamy"   );

    /** Gold = RGBA(255, 224,  0, 255); */     public static final NamedColor
    GOLD   = new NamedColor(new Color(0xFF, 0xE0, 0x00, 255), "gold"      );

    /** Khaki = RGBA(153, 153, 0, 255); */     public static final NamedColor
    KHAKI  = new NamedColor(new Color(0x99, 0x99, 0x00, 255), "khaki"    );

    /** Ochre  = RGBA(255, 153, 000, 255); */  public static final NamedColor
    OCHRE  = new NamedColor(new Color(0xFF, 0x99, 0x00, 255), "ochre" );

    /** Silver = RGBA(216, 216, 216, 255); */  public static final NamedColor
    SILVER = new NamedColor(new Color(0xD8, 0xD8, 0xD8, 255), "silver"    );

    /** Steely = RGBA(0, 153, 204, 255); */    public static final NamedColor
    STEELY = new NamedColor(new Color(0x00, 0x99, 0xCC, 255),  "steely"   );


    //########## Translucent colors

    /** Milky = RGBA(255, 255, 255, 128) - half translucent white! */
    public static final NamedColor
    MILKY  = new NamedColor(new Color(0xFF, 0xFF, 0xFF, 128),  "milky"    );

    /** Smoky = RGBA(128, 128, 128, 128) - half translucent gray! */
    public static final NamedColor
    SMOKY  = new NamedColor(new Color(0x80, 0x80, 0x80, 128),  "smoky"    );

    /** NO = RGBA(0, 0, 0, 0) - transparent invisible color */
    public static final NamedColor
    NO     = new NamedColor(new Color(0x00, 0x00, 0x00, 000),  "no"       );



//\CV== CLASS VARIABLES (VARIABLE CLASS/STATIC ATTRIBUTES/FIELDS) ==============

    /** Příznak indikující, zda mají být názvy barev uváděny velkými písmeny. */
    private static boolean inUpperCase = false;



//##############################################################################
//\CI== CLASS (STATIC) INITIALIZER (CLASS CONSTRUCTOR) =========================
//\CF== CLASS (STATIC) FACTORY METHODS =========================================
//
//    /***************************************************************************
//     * Vrátí barvu se zadaným indexem (pořadím vzniku).
//     *
//     * @param index Index požadované barvy
//     * @return      Barva se zadaným indexem
//     */
//    public static NamedColor getNamedColor(int index)
//    {
//        return namedColorList.get(index);
//    }
//

    /***************************************************************************
     * Převede název barvy na příslušný objekt typu NamedColor.
     *
     * @param colorName  Název požadované barvy - pole, resp seznam názvů
     *                   existujících barev je možno získat zavoláním metody
     *                   {@link #getArrayOfNames()}, resp.
     *                   {@link #getListOfNames()}
     * @return Instance třídy {@code NamedColor} reprezentující zadanou barvu
     * @throws IllegalArgumentException
     *         Není-li barva zadaného názvu mezi existujícími barvami
     */
    public static NamedColor getNamedColor(String colorName)
    {
        NamedColor namedColor = name2namedColor.get(colorName.toLowerCase());
        if (namedColor != null) {
            return namedColor;
        }
        else {
            throw new IllegalArgumentException(
                      "\nNeznám barvu nazvanou: " + colorName);
        }
    }


    /***************************************************************************
     * Vrátí neprůhlednou instanci barvy se zadanými velikostmi složek.
     * Není-li barva ještě definována, vytvoří ji
     * a přiřadí jí název odvozený z velikostí jejích barevných složek.
     *
     * @param red     Velikost červené složky
     * @param green   Velikost zelené složky
     * @param blue    Velikost modré složky
     * @return NamedColor se zadanými velikostmi jednotlivých složek
     */
    public
    static NamedColor getNamedColor(int red, int green, int blue)
    {
        return getNamedColor(red, green, blue, 1);
    }


    /***************************************************************************
     * Vrátí instanci barvy se zadanými velikostmi složek a průhledností.
     * Není-li barva ještě definována, vytvoří ji
     * a přiřadí jí název odvozený z velikostí jejích složek.
     *
     * @param red     Velikost červené složky
     * @param green   Velikost zelené složky
     * @param blue    Velikost modré složky
     * @param opacity Hladina opacity (neprůhlednosti):
     *                0=průhledná, 1=neprůhledná
     * @return Barva se zadanými velikostmi jednotlivých složek
     */
    public
    static NamedColor getNamedColor(int red, int green, int blue,
                                    int opacity)
    {
        Color color = new Color(red, green, blue, opacity);
        NamedColor namedColor = color2namedColor.get(color);
        if (namedColor != null) {
            return namedColor;
        }
        String colorName = "Color(r=" + red + ",g=" + green +
                       ",b=" + blue + ",o=" + opacity + ")" ;
        return getNamedColor(red, green, blue, opacity, colorName);
    }


    /***************************************************************************
     * Vrátí instanci neprůhledné barvy se zadanými barevnými složkami
     * a zadaným názvem. Pokud takováto barva neexistuje, vytvoří ji.
     * Existuje-li barva se zadaným názvem ale jinými složkami, anebo
     * existuje-li barva se zadanými složkami, ale jiným názvem,
     * vyhodí výjimku {@link IllegalArgumentException}.
     *
     * @param red     Velikost červené složky
     * @param green   Velikost zelené složky
     * @param blue    Velikost modré složky
     * @param name    Název vytvořené barvy
     *
     * @return Barva se zadaným názvem a velikostmi jednotlivých složek
     * @throws IllegalArgumentException má-li některé ze známých barev některý
     *         ze zadaných názvů a přitom má jiné nastavení barevných složek
     *         nebo má jiný druhý název.
     */
    public
    static NamedColor getNamedColor(int red, int green, int blue,
                                    String name)
    {
        return getNamedColor(red, green, blue, 255, name);
    }


    /***************************************************************************
     * Vrátí instanci barvy se zadanými barevnými složkami, průhledností
     * a názvem. Pokud takováto barva neexistuje, vytvoří ji.
     * Existuje-li barva se zadaným názvem ale jinými složkami, anebo
     * existuje-li barva se zadanými složkami, ale jiným názvem,
     * vyhodí výjimku {@link IllegalArgumentException}.
     *
     * @param red       Velikost červené složky
     * @param green     Velikost zelené složky
     * @param blue      Velikost modré složky
     * @param opacity   Hladina opacity (neprůhlednosti):
     *                  0=průhledná, 1=neprůhledná
     * @param colorName Název vytvořené barvy
     * @return Instance třídy {@code NamedColor} reprezentující zadanou barvu.
     * @throws IllegalArgumentException Má-li některá ze definovaných barev
     *         zadaný název, a přitom má jiné nastavení barevných složek, anebo
     *         má shodnou velikost složek, ale jiný druhý název,
     *         anebo je jako název zadán prázdný řetězec.
     * @throws NullPointerException  Je-li {@code název} {@code null}.
     */
    public
    static NamedColor getNamedColor(int red,  int green, int blue,
                                    int opacity, String colorName)
    {
        colorName = colorName.trim().toLowerCase();
        if ((colorName == null)  ||  colorName.isEmpty())  {
            throw new IllegalArgumentException(
                "\nThe color must have nonempty name");
        }
        Color color = new Color(red, green, blue, opacity);
        NamedColor fromName = namedColor(colorName);
        NamedColor fromColor = color2namedColor.get(color);

        if ((fromName != null)  &&  (fromName == fromColor)) {
            //The requested color already exists
            return fromName;
        }
        if ((fromName == null)  &&  (fromColor == null)) {
            //The requested color doesn't exist yet
            return new NamedColor(red, green, blue, opacity, colorName);
        }
        //What color doesn't alow adding the requested one?
        NamedColor b = (fromColor != null)  ?  fromColor  :  fromName;
        Color      c = b.awtColor;
        throw new IllegalArgumentException(
            "\nThe given arguments collide with an existing color"+
            "[existing × given]:" +
            "\nName :        " + b.name()  + " × " + colorName +
            "\nRed:          " + c.getRed()   + " × " + red       +
            "\nGreen:        " + c.getGreen() + " × " + green     +
            "\nBlue:         " + c.getBlue()  + " × " + blue      +
            "\nTransparency: " + c.getAlpha() + " × " + opacity
           );
    }



//\CG== CLASS (STATIC) GETTERS AND SETTERS =====================================

    /***************************************************************************
     * Vrátí pole doposud definovaných barev.
     *
     * @return  Pole doposud definovaných barev
     */
    public static NamedColor[] getArrayOfNamedColors()
    {
        return namedColorList.toArray(new NamedColor[namedColorList.size()]);
    }


    /***************************************************************************
     * Vrátí pole řetězců s názvy doposud definovaných barev.
     *
     * @return  Vektor řetězců s dopsud definovanými názvy barev
     */
    public static String[] getArrayOfNames()
    {
        String[] names = name2namedColor.keySet()
                         .toArray(new String[name2namedColor.size()]);
        if (inUpperCase) {
            for (int i = 0;   i < names.length;   i++) {
                names[i] = names[i].toUpperCase();
            }
        }
        Arrays.sort(names, Collator.getInstance());
        return names;
    }


    /***************************************************************************
     * Vrátí seznam doposud definovaných barev.
     *
     * @return  Seznam doposud definovaných barev
     */
    public
    static List<NamedColor> getListOfNamedColors()
    {
        return Collections.unmodifiableList(namedColorList);
    }


    /***************************************************************************
     * Vrátí seznam názvů doposud definovaných barev.
     *
     * @return  Seznam názvů doposud definovaných barev
     */
    public
    static List<String> getListOfNames()
    {
        return Arrays.asList(getArrayOfNames());
    }


    /***************************************************************************
     * Nastaví, zda se budou názvy barev vypisovat velkými písmeny.
     *
     * @param inUpperCase {@code true} mají-li se názvy vypisovat velkými
     *                    písmeny, jinak {@code false}
     * @return Původní nastavení
     */
    public static boolean setInUppercase(boolean inUpperCase)
    {
        boolean originalSetting = NamedColor.inUpperCase;
        NamedColor.inUpperCase = inUpperCase;
        return originalSetting;
    }



//\CM== CLASS (STATIC) REMAINING NON-PRIVATE METHODS ===========================

    /***************************************************************************
     * Otevře dialogové okno, v němž vypíše všechny doposud definované
     * názvy barev. Jména jsou lexikograficky seřazena.
     */
    public static void showDefinedNames()
    {
        final int LINE_LENGTH = 64;
        String[] names = getArrayOfNames();
        StringBuilder sb = new StringBuilder();
        for (int i=0, inLine=0;   i < names.length;   i++) {
            String text = names[i];
            int textLength = text.length();
            if ((inLine + textLength)  >=  LINE_LENGTH) {
                sb.append('\n');
                inLine = 0;
            }
            sb.append(text);
            inLine += textLength + 2;
            if (i < names.length) {
                sb.append(", ");
            }
        }
        IO.inform(sb);
    }



//\CP== CLASS (STATIC) PRIVATE AND AUXILIARY METHODS ===========================

    /***************************************************************************
     * Převede zadané reálné číslo v rozsahu {@code [0; 1]}
     * na celé číslo v rozsahu {@code [0; 255]}
     *
     * @param d Převáděné číslo
     * @return Převedené číslo
     */
    private static int d2i(double d)
    {
        int i = (int)(d * 255);
        return i;
    }


    /***************************************************************************
     * Vrátí barvu se stejnými hodnotami komponent jako má parametr.
     * Není-li taková barva ještě definována, vytvoří jí
     * a pojmenuje ji s využitím hodnota jejích složek.
     *
     * @param c  Barva, která je instancí třídy {@link java.awt.Color}
     * @return Odpovídající barva třídy {@code Barva}
     */
    private static NamedColor getNamedColor(Color c)
    {
        NamedColor b = color2namedColor.get(c);
        if (b != null) {
            return b;
        }
        else {
            return getNamedColor(c.getRed(),  c.getGreen(),
                                 c.getBlue(), c.getAlpha());
        }
    }


    /***************************************************************************
     * Vrátí barvu s daným názvem přičem je schopen ignorovat diakritiku.
     *
     * @param name Název hledané barvy
     * @return Barva se zadaným názvem nebo {@code null}.
     */
    private static NamedColor namedColor(String name) {
        name = name.toLowerCase();
        NamedColor color = name2namedColor.get(name);
        if (color == null) {
            color = nameRA2namedColor.get(name);
        }
        return color;
    }



//##############################################################################
//\IC== INSTANCE CONSTANTS (CONSTANT INSTANCE ATTRIBUTES/FIELDS) ===============

    /** Název barvy zadávaný konstruktoru. */
    private final String name;

    /** Instance třídy {@link AWTColor} (potomka třídy {@link java.awt.Color})
     *  představující stejnou barvu. */
    private final Color awtColor;

    /** Index barvy v seznamu dosud vytvořených barev. */
    private final int index = count++;



//\IV== INSTANCE VARIABLES (VARIABLE INSTANCE ATTRIBUTES/FIELDS) ===============



//##############################################################################
//\II== INSTANCE INITIALIZERS (CONSTRUCTORS) ===================================

    /***************************************************************************
     * Vytvoří instanci barvy se zadanou velikostí barevných složek,
     * hladinou průhlednosti nastavovanou v kanále opacity
     * a se zadaným názvem.
     *
     * @param red     Velikost červené složky
     * @param green   Velikost zelené složky
     * @param blue    Velikost modré složky
     * @param opacity Hladina opacity (neprůhlednosti):
     *                0=průhledná, 1=neprůhledná
     * @param name    Název vytvořené barvy
     */
    private NamedColor(int red, int green, int blue, int opacity,
                       String name)
    {
        this(new Color(red, green, blue, opacity), name);
    }


    /***************************************************************************
     * Vytvoří barvu se zadaným názvem ekvivalentní zadané instanci třídy
     * {@link javafx.scene.paint.Color}.
     * Účelem tohoto konstruktoru je co nejjednodušší předání komponent barev,
     * které již mají definované ekvivalentní názvy
     * ve třídě {@link javafx.scene.paint.Color}.
     *
     * @param color     Instance třídy {@link java.awt.Color} požadované barvy
     * @param colorName Název vytvářené barvy; {@code null} označuje,
     *                  že se má pro barvu vytvořit generický název
     */
    private NamedColor(Color color, String colorName)
    {
        colorName     = colorName.toLowerCase();
        this.awtColor = color;
        this.name     = colorName;
        if (name2namedColor.containsKey(colorName)    ||
            color2namedColor.containsKey(color))
        {
            throw new IllegalArgumentException(
                "\nInternal error - the color " + getNamePrivate() +
                " and/or " + getCharacteristicsHexPrivate() +
                " already exists");
        }

        NamedColor me = this;
        name2namedColor .put(colorName, me);
        color2namedColor.put(awtColor, me);
        namedColorList  .add(me);

        addNameWithoutAccents();
    }



//\IA== INSTANCE ABSTRACT METHODS ==============================================
//\IG== INSTANCE GETTERS AND SETTERS ===========================================

    /***************************************************************************
     * Vrátí instanci třídy {@link java.awt.Color}
     * reprezentující barvu ekvivalentní zadané barvě.
     *
     * @return Instance třídy {@link java.awt.Color}
     *         reprezentující barvu ekvivalentní zadané barvě
     */
    public Color getAWTColor()
    {
        return awtColor;
    }


    /***************************************************************************
     * Vrátí řetězec s charakteristikou dané barvy obsahující
     * název a hodnoty barevných složek uvedené v desítkové soustavě
     *
     * @return Řetězec s dekadickou charakteristikou barvy
     */
    public String getCharacteristicsDec()
    {
        return String.format("%s(Dec:R=%d,G=%d,B=%d,A=%d)", name,
                             awtColor.getRed(),  awtColor.getGreen(),
                             awtColor.getBlue(), awtColor.getAlpha()
                            );
    }


    /***************************************************************************
     * Vrátí řetězec s charakteritikou dané barvy obsahující název a
     * hodnoty barevných složek uvedené v šestnáctkové soustavě
     *
     * @return Řetězec s hexadecimální charakteristikou barvy
     */
    public String getCharacteristicsHex()
    {
        return getCharacteristicsHexPrivate();
    }


    /***************************************************************************
     * Vrátí index barvy v seznamu dosud vytvořených barev.
     *
     * @return Index dané barvy
     */
    public int index()
    {
        return index;
    }


    /***************************************************************************
     * Vrátí název barvy.
     *
     * @return Název barvy
     */
    public String name()
    {
        return getNamePrivate();
    }



//\IM== INSTANCE REMAINING NON-PRIVATE METHODS =================================

    /***************************************************************************
     * Vrátí světlejší verzi dané barvy. Pozor, vzhledem k zaokrouhlovacím
     * chybám nejsou operace světlejší a tmavší zcela reverzní.
     *
     * @return Světlejší verze barvy
     */
    public
    NamedColor brighter()
    {
        Color c = awtColor.brighter();
        if (c.equals(awtColor)) {
            c = new Color(Math.max(c.getRed(),   MINC),
                          Math.max(c.getGreen(), MINC),
                          Math.max(c.getBlue(),  MINC),  c.getAlpha());
        }
        return getNamedColor(c);
    }


    /***************************************************************************
     * Vrátí tmavší verzi dané barvy. Pozor, vzhledem k zaokrouhlovacím
     * chybám nejsou operace světlejší a tmavší zcela reverzní.
     *
     * @return Tmavší verze barvy
     */
    public
    NamedColor darker()
    {
        return getNamedColor(awtColor.darker());
    }


    /***************************************************************************
     * Vrátí barvu inverzní k zadané barvě, tj. barvu s inverzními
     * hodnotami jednotlivých barevných složek, ale se stejnou průhledností.
     *
     * @return Inverzní barva
     */
    public NamedColor inverse()
    {
        return getNamedColor(MAXC - awtColor.getRed(), MAXC - awtColor.getGreen(),
                             MAXC - awtColor.getBlue(), awtColor.getAlpha());
    }


    /***************************************************************************
     * Vrátí méně průhlednou verzi dané barvy.
     * Pozor, vzhledem k zaokrouhlovacím chybám není oparace plně reverzibilní.
     *
     * @return Méně průhledná verze barvy
     */
    public
    NamedColor lessTransparent()
    {
        int op = (int)(awtColor.getAlpha() * CHANGE_KOEF);
        return getNamedColor(new Color(awtColor.getRed(),  awtColor.getGreen(),
                                       awtColor.getBlue(), op));
    }


    /***************************************************************************
     * Vrátí průhlednější verzi dané barvy.
     * Pozor, vzhledem k zaokrouhlovacím chybám není operace plně reverzibilní.
     *
     * @return Průhlednější verze barvy
     */
    public
    NamedColor moreTransparent()
    {
        int op = (int)(awtColor.getAlpha() / CHANGE_KOEF);
        return getNamedColor(new Color(awtColor.getRed(), awtColor.getGreen(),
                                       awtColor.getBlue(), op));
    }


    /***************************************************************************
     * Vrátí název dané barvy.
     *
     * @return  Název dané barvy
     */
    @Override
    public String toString()
    {
        return name();
    }


    /***************************************************************************
     * Vrátí průsvitnou verzi dané barvy,
     * tj. barvu se stejnými barvenými složkami a průsvitností 0,5.
     *
     * @return Průsvitná verze dané barvy
     */
    public NamedColor translucent()
    {
        Color newColor = new Color(awtColor.getRed(),  awtColor.getGreen(),
                                   awtColor.getBlue(), TRANSLUCENCE);
        NamedColor namedColor = color2namedColor.get(newColor);
        if (namedColor == null) {
            String name2 = "translucent_" + this.name;
            namedColor = name2namedColor.get(name2);
            if (namedColor == null) {
                namedColor = getNamedColor(
                    awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue(),
                    TRANSLUCENCE, name2);
            }
        }
        return namedColor;
    }



//\IP== INSTANCE PRIVATE AND AUXILIARY METHODS =================================

    /***************************************************************************
     * Obsahuje-li název diakritiku,
     * uloží do příslušné mapy jeho verzi bez diakritiky.
     */
    private void addNameWithoutAccents() {
        String bhc = IO.toASCII (name);
        if (! name.equals(bhc)) {
            nameRA2namedColor.put(bhc, this);
        }
    }


    /***************************************************************************
     * Vrátí řetězec s charakteristikou dané barvy obsahující název a
     * hodnoty barevných složek uvedené v šestnáctkové soustavě
     *
     * @return Řetězec s hexadecimální charakteristikou barvy
     */
    private String getCharacteristicsHexPrivate()
    {
        return String.format("%s(Hex:R=%02X,G=%02X,B=%02X,A=%02X)", name,
                             d2i(awtColor.getRed()),  d2i(awtColor.getGreen()),
                             d2i(awtColor.getBlue()), d2i(awtColor.getAlpha())
                            );
    }


    /***************************************************************************
     * Vrátí název barvy.
     *
     * @return Název barvy
     */
    private String getNamePrivate()
    {
        return (inUpperCase  ?  name.toUpperCase()  :  name);
    }



//##############################################################################
//\NT== NESTED DATA TYPES ======================================================
}
