import java.awt.Color;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


/*******************************************************************************
 *  Třída Barva definuje skupinu základních barev pro použití
 *  při kreslení tvarů před zavedením balíčků.
 *  Její metody jsou podmnožinou metod stejnojmenné třídy
 *  definované v balíčku rup.společné.
 *
 * @author     Rudolf Pecinovský
 * @version    2.01, duben 2004
 */
public class Barva
{
    /** Počet pojmenovaných barev se při konstrukci následujících instancí 
     *  načítá, a proto musí být deklarován před nimi. */
    private static int pojmenovaných = 0;
    
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    private static final Map<String,Barva> NÁZVY = 
                                            new LinkedHashMap<String,Barva>();
    private static final List<Barva> BARVY = new ArrayList<Barva>( 32 );

    public static final Barva ČERNÁ   = new Barva( 0x00, 0x00, 0x00, "černá",    "cerna"   );
    public static final Barva MODRÁ   = new Barva( 0x00, 0x00, 0xFF, "modrá",    "modra"   );
    public static final Barva ČERVENÁ = new Barva( 0xFF, 0x00, 0x00, "červena",  "cervena" );
    public static final Barva FIALOVÁ = new Barva( 0xFF, 0x00, 0xFF, "fialová",  "fialova" );
    public static final Barva ZELENÁ  = new Barva( 0x00, 0xFF, 0x00, "zelená",   "zelena"  );
    public static final Barva AZUROVÁ = new Barva( 0x00, 0xFF, 0xFF, "azurová",  "azurova" );
    public static final Barva ŽLUTÁ   = new Barva( 0xFF, 0xFF, 0x00, "žlutá",    "zluta"   );
    public static final Barva BÍLÁ    = new Barva( 0xFF, 0xFF, 0xFF, "bílá",     "bila"    );
    public static final Barva KRÉMOVÁ = new Barva( 0xFF, 0xFF, 0xCC, "krémová",  "kremova" );
    public static final Barva ŠEDÁ    = new Barva( 0x99, 0x99, 0x99, "šedá",     "seda"    );
    public static final Barva OCELOVÁ = new Barva( 0x00, 0x99, 0xCC, "ocelová",  "ocelova" );
    public static final Barva RŮŽOVÁ  = new Barva( 0xFF, 0x99, 0x99, "růžová",   "ruzova"  );
    public static final Barva HNĚDÁ   = new Barva( 0x99, 0x33, 0x00, "hnědá",    "hneda"   );
    public static final Barva KHAKI   = new Barva( 0x99, 0x99, 0x00, "vojenská", "vojenska");
    public static final Barva CIHLOVÁ = new Barva( 0xFF, 0x66, 0x33, "cihlová",  "cihlova" );
    public static final Barva ZLATÁ   = new Barva( 0xFF, 0x99, 0x00, "zlatá",    "zlata"   );
    public static final Barva STŘÍBRNÁ= new Barva( 0xCC, 0xCC, 0xCC, "stříbrná", "stribrna");


//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
    
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    private final String název;     //Název barvy zadávaný konstruktoru
    private final Color  color;     //Barva ze standardní knihovny
    private final int    index = pojmenovaných++;


//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ METODY TŘÍDY ======================================================

    /***************************************************************************
     * Vrátí vektor řetězců s názvy definovaných barev.
     *
     * @return  Vektror řetězců s názvy znamých barev
     */
    public static String[] getZnáméNázvy()
    {
        String[] s = new String[ pojmenovaných ];
        for( int i=-1;   ++i < pojmenovaných;   s[i] = BARVY.get(i).název );
        return s;
    }


    /***************************************************************************
     * Vrátí vektor definovaných barev.
     *
     * @return  Vektror řetězců s názvy znamých barev
     */
    public static Barva[] getZnáméBarvy()
    {
        //return (Barva[])BARVY.toArray( new Barva[0] );
        return BARVY.toArray( new Barva[0] );
    }



//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vytvoří instanci nerůhledné pojmenované barvy 
     * se zadanou velikostí barevných složek.
     *
     * @param red       Velikost červené složky
     * @param green     Velikost zelené složky
     * @param blue      Velikost modré složky
     * @param název     Název vytvořené barvy
     * @param názevBHC  Název bez háčků a čárek
     */
    public Barva( int red, int green, int blue, 
                   String název, String názevBHC )
    {
        this( red, green, blue, 0xFF, název, názevBHC );
    }
    

    /***************************************************************************
     * Vytvoří instanci pojmenované barvy se zadanou velikostí barevných složek
     * a hladinou průhlednosti nastavovanou v kanále alfa.
     *
     * @param red       Velikost červené složky
     * @param green     Velikost zelené složky
     * @param blue      Velikost modré složky
     * @param alfa      Hladina průhlednosti: 0=průhledná, 255=neprůhledná
     * @param název     Název vytvořené barvy
     * @param názevBHC  Název bez háčků a čárek
     */
    public Barva( int red, int green, int blue, int alfa, 
                   String název, String názevBHC )
    {
        color = new Color( red, green, blue, alfa );
        this.název = název;
        String nhc  = název.toLowerCase();
        String nbhc = názevBHC.toLowerCase();
        if( NÁZVY.containsKey( nhc )  ||  NÁZVY.containsKey( nbhc ) )
            throw new IllegalArgumentException(
                "\nBarva se zadaným názvem " + nhc + " či " + nbhc +
                " již existuje" );
        NÁZVY.put( nhc,  this );
        NÁZVY.put( nbhc, this );
        BARVY.add( index, this );
    }
    

    /***************************************************************************
     * Vytvoří instanci nepojmenované barvy se zadanou velikostí barevných 
     * složeka hladinou průhlednosti nastavovanou v kanále alfa.
     *
     * @param red   Velikost červené složky
     * @param green Velikost zelené složky
     * @param blue  Velikost modré složky
     * @param alfa  Hladina průhlednosti: 0=průhledná, 255=neprůhledná
     */
    public Barva( int red, int green, int blue, int alfa )
    {
        color = new Color( red, green, blue, alfa );
        this.název = "Barva(r=" + red + ",g=" + green +
                     ",b=" + blue + ",a=" + alfa + ")" ;
    }
    

    /***************************************************************************
     * Převede název barvy na příslušný objekt typu Barva.
     *
     * @param  nazevBarvy  Název požadované barvy - lze si vybrat z hodnot:
     *                    "černá",  "modrá",   "červena", "fialová",
     *                    "zelená", "azurová", "žlutá",   "bílá". "krémová"
     *
     * @return Instance třídy Barva reprezentující zadanou barvu
     *
     * @throws IllegalArgumentException není-li barva (název) mezi známými
     */
    public static Barva getBarva( String názevBarvy )
    {
        Barva barva = NÁZVY.get( názevBarvy.toLowerCase() );
        if( barva != null )
            return barva;
        else
            throw new IllegalArgumentException(
                "Takto pojmenovanou barvu neznám." );
    }



//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================

    /***************************************************************************
     * Vrátí název barvy.
     *
     * @return Řetězec definující zadanou barvu.
     */
    public String getNázev()
    {
        return název;
    }


    /***************************************************************************
     * Převede námi používanou barvu na typ používaný kreslítkem.
     * Metoda je používaná ve třídě AktivníPlátno.
     *
     * @return Instance třídy Color reprezentující zadanou barvu
     */
    public Color getColor()
    {
        return color;
    }



//== PŘEKRYTÉ METODY IMPLEMENTOVANÝCH ROZHRANÍ =================================
//== PŘEKRYTÉ ABSTRAKTNÍ METODY RODIČOVSKÉ TŘÍDY ===============================
//== PŘEKRYTÉ KONKRÉTNÍ METODY RODIČOVSKÉ TŘÍDY ================================

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



//== NOVĚ ZAVEDENÉ METODY INSTANCÍ =============================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTY A METODA MAIN =======================================================
}

