/*
 * [BreedA.java]
 *
 * Summary: Enum demonstrating use of an alias value.
 *
 * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2009-01-01 initial version
 */
package com.mindprod.example;

import static java.lang.System.*;

/**
 * Enum demonstrating use of an alias value.
 * <p/>
 * See a more sophisticated approach in the Rodents class, that allows
 * multiple aliases and uses a fast HashMap lookup.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2009-01-01 initial version
 * @since 2009-01-01
 */
@SuppressWarnings( { "UnusedDeclaration", "WeakerAccess" } )
public enum BreedA
    {
        /**
         * Dachshund smooth or curly.
         */
        DACHSHUND( "wiener dog" ),
        /**
         * Dalmatian, allow spelling error.
         *
         * @noinspection WeakerAccess
         */
        DALMATIAN( "dalmation"/* do not correct spelling! */ ),
        /**
         * Labrador retrievers, allow short name.
         */
        LABRADOR( "lab" );

    /**
     * alternate external name for this enum constant, we allow just one. It would be easy to extend this to
     * an array of aliases using String... on the constructor.
     */
    private final String alias;

    /**
     * constructor.
     *
     * @param alias, an alternate name for this breed.
     */
    BreedA( String alias )
        {
        this.alias = alias;
        }

    /**
     * Test harness.
     *
     * @param args not used.
     */
    @SuppressWarnings( { "UnusedParameters" } )
    public static void main( String[] args )
        {
        // prints DALMATIAN DALMATIAN DALMATIAN DACHSHUND
        BreedA myDog = BreedA.DALMATIAN;
        out.println( myDog );
        myDog = BreedA.valueOf( "DALMATIAN" );
        out.println( myDog );
        myDog = BreedA.valueOfAlias( "dalmation" ); // do not correct spelling.
        out.println( myDog );
        myDog = BreedA.valueOfAlias( "Wiener Dog" );
        out.println( myDog );
        // comparing enums
        BreedA yourDog = BreedA.LABRADOR;
        if ( myDog == yourDog )
            {
            out.println( "our dogs are the same breed" );
            }
        // You can't compare enums directly with >
        // However, enums implement Comparable
        if ( yourDog.compareTo( myDog ) > 0 )
            {
            out.println( "your dog has a higher ordinal" );
            }
        if ( yourDog.ordinal() > myDog.ordinal() )
            {
            out.println( "your dog has a higher ordinal" );
            }
        }

    /**
     * convert alias string to equivalent canonical enum constant, like valueOf but accepts aliases matching the
     * alias name too, and does not care about case.
     *
     * @param s alias as string.
     *
     * @return equivalent BreedA enum constant.
     * @noinspection WeakerAccess
     */
    public static BreedA valueOfAlias( String s )
        {
        try
            {
            return valueOf( s.toUpperCase() );
            }
        catch ( IllegalArgumentException e )
            {
            // usual method failed, try looking up alias
            // This seems long winded, why no HashSet?
            // Because Java won't let me access a static common
            // lookup in the enum constructors. There are problems with initialisation
            // enum constants at static init time.
            // See notes at http://mindprod.com/jgloss/enum.html on Piotr Kobza's
            // kludge to get one.
            for ( BreedA candidateEnum : BreedA.values() )
                {
                if ( candidateEnum.alias.equalsIgnoreCase( s ) )
                    {
                    return candidateEnum;
                    }
                }
            // fell out the bottom of search over all enums and aliases
            // give up.
            throw new IllegalArgumentException( "unknown Breed: " + s );
            }
        }

    /**
     * get alternative name for this breed.
     *
     * @return alias name for this breed.
     * @noinspection WeakerAccess
     */
    public String getAlias()
        {
        return alias;
        }
    }