import java.awt.Color;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;

/**
 * Trida Barva slouzi k ... sem napiste popis teto tridy.
 *
 * @author     jmeno autora
 * @version    cislo verze, datum
 */
public class Barva extends Color
{
//== VEREJNE KONSTANTY =========================================================
    
//== SOUKROME KONSTANTY ========================================================

    private static final Barva CERNA   = new Barva( 0x00, 0x00, 0x00 );
    private static final Barva MODRA   = new Barva( 0x00, 0x00, 0xFF );
    private static final Barva CERVENA = new Barva( 0xFF, 0x00, 0x00 );
    private static final Barva FIALOVA = new Barva( 0xFF, 0x00, 0xFF );
    private static final Barva ZELENA  = new Barva( 0x00, 0xFF, 0x00 );
    private static final Barva AZUROVA = new Barva( 0x00, 0xFF, 0xFF );
    private static final Barva ZLUTA   = new Barva( 0xFF, 0xFF, 0x00 );
    private static final Barva BILA    = new Barva( 0xFF, 0xFF, 0xFF );
    
    
    
//== ATRIBUTY TRIDY ============================================================

    private static final Map barvy = new HashMap();
    static {
        barvy.put( "cerna",     CERNA   );
        barvy.put( "modra",     MODRA   );
        barvy.put( "cervena",   CERVENA );
        barvy.put( "fialova",   FIALOVA );
        barvy.put( "zelena",    ZELENA  );
        barvy.put( "azurova",   AZUROVA );
        barvy.put( "blankytna", AZUROVA );
        barvy.put( "zluta",     ZLUTA   );
        barvy.put( "bila",      BILA    );
    }
    
    private static final Map nazvy = new HashMap();
    static {
        nazvy.put(  new Integer( 0xFF000000 ),  "cerna"   );
        nazvy.put(  new Integer( 0xFF0000FF ),  "modra"   );
        nazvy.put(  new Integer( 0xFFFF0000 ),  "cervena" );
        nazvy.put(  new Integer( 0xFFFF00FF ),  "fialova" );
        nazvy.put(  new Integer( 0xFF00FF00 ),  "zelena"  );
        nazvy.put(  new Integer( 0xFF00FFFF ),  "azurova" );
        nazvy.put(  new Integer( 0xFFFFFF00 ),  "zluta"   );
        nazvy.put(  new Integer( 0xFFFFFFFF ),  "bila"    );
    }    



//== ATRIBUTY INSTANCI =========================================================
//== PRISTUPOVE METODY ATRIBUTU TRIDY ==========================================
//== OSTATNI METODY TRIDY ======================================================

    /**
     * Prevede nazev barvy na prislusny objekt typu Barva.
     *
     * @param  nazevBarvy  nova barva popredi - lze si vybrat z hodnot:
     *                    "cerna",  "modra",     "cervena", "fialova",
     *                    "zelena", "blankytna", "zluta",   "bila".
     *         Pripadne z dalsich hodnot pridanych do seznamu v programu.
     *         
     *         <p>Dalsi moznosti je zadat barvu primo prostrednictvim
     *         hexadecimalni hodnoty jednotlivych slozek - napr.:
     *         cerna = "RGB:000000", cervena = "RGB:FF0000",
     *         zelena= "RGB:00FF00", modra   = "RGB:0000FF",
     *         bila  = "RGB:FFFFFF", zluta   = "RGB:FFFF00".
     *         Krome barev je mozne zadat i pruhlednost - ta se zadava
     *         retezcem "ARGB:AArrggbb", kde AA je hexadecimalni
     *         hodnota pruhlednosti (FF=pruhledny, 00=nepruhledny).
     *
     * @return instance tridy Barva reprezentujici zadanou barvu
     * 
     * @throws IllegalArgumentException neni-li barva (nazev) mezi znamymi
     *         a neni-li ji mozno dekodovat
     */
    public static Barva getBarva(String nazevBarvy)
    {
        Barva barva = (Barva)barvy.get( nazevBarvy );
        if( barva != null )  
            return barva;
        else
            throw new IllegalArgumentException(
                "Takto pojemnovanou barvu neznam." );
    }//public static Barva getBarva(String nazevBarvy)
    

    /**
     * Prevede objekt typu Color na prislusny nazev barvy.
     *
     * @param  barva prevadena barva
     *
     * @return retezec definujici zadanou barvu.
     *                 Neni-li pro tuto barvu k dipozici znamy retezec,
     *                 vrati retezec "ARGB:AARRGGBB", kde
     *                 AA je hexadecimalni hodnota pruhlednosti (00=napruhledna),
     *                 RR je hexadecimalni hodnota cervene,
     *                 GG je hexadecimalni hodnota zelene a
     *                 BB je hexadecimalni hodnota modre.
     */
    public static String getNazev(Color barva)
    {
        String nazev = (String)nazvy.get( barva );
        if( nazev != null )
            return nazev;
        else
            return barva.toString();
    }//public static String getNazev(Color barva)
    
    
    /**
     * Zaradi novy nazev barvy mezi registrovane nazvy barev.
     * Zadany nazev ani barva nesmeji byt doposud zaregistrovany.
     *
     * @param  nazev    pridavany nazev barvy
     * @param  cervena  velikost cervene barevn?lozky (0-255, 0x00-0xFF)
     * @param  zelena   velikost zelene barevn?lozky (0-255, 0x00-0xFF)
     * @param  modra    velikost modre barevn?lozky (0-255, 0x00-0xFF)
     * @param  alfa     mira opaknosti: 0=pruhledny, 255,0xFF=nepruhledny,opakni
     * 
     * @throws IllegalArgumentException je-li jiz v seznamu dana barva 
     *         nebo jina barva se stejnym nazvem
     */
    public static void pridej( String nazev, 
                               int cervena, int zelena, int modra, int alfa )
    {
        pridej( nazev, (alfa<<24) | (cervena<<16) | (zelena<<8) | modra ); 
    }//public void pridej(String nazev, Color barva)
    
    
    /**
     * Zaradi novy nazev barvy mezi registrovane nazvy barev.
     * Zadany nazev ani barva nesmeji byt doposud zaregistrovany.
     *
     * @param  nazev    pridavany nazev barvy
     * @param  cervena  velikost cervene barevn?lozky (0-255, 0x00-0xFF)
     * @param  zelena   velikost zelene barevn?lozky (0-255, 0x00-0xFF)
     * @param  modra    velikost modre barevn?lozky (0-255, 0x00-0xFF)
     * 
     * @throws IllegalArgumentException je-li jiz v seznamu dana barva 
     *         nebo jina barva se stejnym nazvem
     */
    public static void pridej( String nazev, 
                               int cervena, int zelena, int modra )
    {
        pridej( nazev, 0xFF000000 | (cervena<<16) | (zelena<<8) | modra ); 
    }//public void pridej(String nazev, Color barva)
    
    
    /**
     * Zaradi novy nazev barvy mezi registrovane nazvy barev.
     * Zadany nazev ani barva nesmeji byt doposud zaregistrovany.
     *
     * @param  nazev  pridavany nazev barvy
     * @param  argb   velikosti slozek alfa-blue-green-red
     * 
     * @throws IllegalArgumentException je-li jiz v seznamu dana barva 
     *         nebo jina barva se stejnym nazvem
     */
    public static void pridej( String nazev, int argb )
    {
        if( barvy.containsKey( nazev ) )
        {
            throw new IllegalArgumentException(
                "Zadany nazev je jiz prirazen barve " + nazev );
                //barvy.toString() );
        }
        Integer _argb = new Integer( argb );
        if( nazvy.containsKey( _argb ) )
        {
            throw new IllegalArgumentException(
                "Zadane barve ARGB:" + Integer.toHexString(argb) +
                " je jiz prirazen nazev \"" + nazev + '\"' );
        }
        barvy.put( nazev,  new Barva(argb) );
        nazvy.put( _argb,  nazev );
    }//public static void pridej( String nazev, Color barva )
    
   
    /**
     * Prazdna metoda - tento komentar nahradte vlastnim
     *
     * @return  vrati retezec se seznamem znamch barev
     */
    public static String getZnameNazvy() 
    {
        Set sada = barvy.keySet();
        Iterator it = sada.iterator();
        StringBuffer sb = new StringBuffer( 128 );
        boolean first = true;
        while( it.hasNext() )
        {
            if( first )
                first = false;
            else
                sb.append(", ");
            sb.append( it.next().toString() );
        }
        return sb.toString();
    }//public static String getZnameNazvy()


    
//== KONSTRUKTORY ==============================================================
    
    /**
     * Vytvori instanci zadanou velikosti barevnych slozek.
     */
    public Barva( int red, int green, int blue )
    {
        super( red, green, blue );
    }//public Barva( int red, int green, int blue )
    
      
    /**
     * Vytvori instanci zadanou velikosti barevnych slozek.
     */
    public Barva( int red, int green, int blue, int alpha )
    {
        super( red, green, blue, alpha );
    }//public Barva( int red, int green, int blue, int alpha )
    
      
    /**
     * Vytvori instanci zadanou velikosti barevnych slozek.
     */
    public Barva( int argb )
    {
        super( argb, true );
    }//public Barva( int argb )
    

  
//== PRISTUPOVE METODY ATRIBUTU INSTANCI =======================================
//== OSTATNI METODY INSTANCI ===================================================

    /**
     * Metoda prevadi instanci na retezec - 
     * pouziva se vetsinou pro ucely ladeni. 
     * Mela by ji definovat kazda trida a uvest v ni 
     * vsechny potrebne informace o vnitrnim stavu instance.
     *
     * @return     retezec informujici o vnitrnim stavu instance
     */
    public String toString() 
    {
        String nazev = nazvy.containsKey(this) ? 
                          (String)nazvy.get(this) : null;
        return "ARGB:" + Integer.toHexString(getRGB()) +
               ((nazev == null) ? "" : " (" + nazev + ")");
    }//public String toString()



//== SOUKROME A POMOCNE METODY =================================================

    /**
     * Prazdna metoda - tento komentar nahradte vlastnim
     *
     * @param  x   parametr 
     * @return     vraci-li neco jineho nez void
     */
    private static int slozky( String nazev ) 
    {
        //nazev = nazev.trim();
        Object b = barvy.get( nazev );
        if( b != null )
            return ((Color)b).getRGB();
        if( nazev.startsWith("RGB:") )
            return (int)( 0xFF000000L |
                Long.parseLong( nazev.substring(4), 16 ) );
        if( nazev.startsWith("ARGB:") )
            return (int)Long.parseLong( nazev.substring( 5 ), 16 );
        throw new IllegalArgumentException(
                "Nepovolena barva: nazevBarvy=\"" + nazev + "\"" );
    }//private static int slozky( String nazev )
    


//== VNORENE A VNITRNI TRIDY ===================================================
        
}//public class Barva