/*
 * [TestRandomEnum.java]
 *
 * Summary: Demonstrate use of general purpose enum code. In particular select a random value of an arbitrary enum.
 *
 * 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-03-24 initial version
 */
package com.mindprod.example;

import java.lang.annotation.ElementType;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import static java.lang.System.*;

/**
 * Demonstrate use of general purpose enum code. In particular select a random value of an arbitrary enum.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2009-08-25 initial version
 * @since 2009-08-25
 */
public class TestRandomEnum
    {
    /**
     * wheel to generate random integers.
     */
    private static final Random wheel = new Random();

    /**
     * get a randomly selected member of the enum. Works an any enum type.
     *
     * @param e a sample enum constant of the enum class.
     *
     * @return an randomly selected enum constant of the enum
     */
    private static Enum<?> randomEnum( Enum<?> e )
        {
        // The enum constant in an inner class of the enclosing class for the enum as a whole.
        // Get the class for the enum as a whole.
        return randomEnum( e.getDeclaringClass() );
        }

    /**
     * Get a randomly selected member of the enum, given the class of the enum as a whole.
     *
     * @param clazz class of the enum as a whole.
     *
     * @return a randomly selected enum constant of the enum.
     */
    private static <E extends Enum<E>> E randomEnum( Class<E> clazz )
        {
        // We have to misspell this as clazz because class is a reserved keyword.
        // We can't use values() since we don't have a reference to the enum class to access the static method.
        E[] values = clazz.getEnumConstants();
        return values[ wheel.nextInt( values.length ) ];
        }

    /**
     * Test driver to exercise the methods in the class.
     *
     * @param args not used
     */
    public static void main( String[] args )
        {
        // Instead of creating our own enum for the test, we borrow the TimeUnit enum from the Java class library.
        out.println( "Possible TimeUnits: " );
        for ( TimeUnit e : TimeUnit.values() )
            {
            out.println( " " + e );
            }
        // Use  the variant that takes the a sample enum constant.
        out.println( "Random TimeUnit: " + randomEnum( TimeUnit.SECONDS ) );
        // Instead of creating our own enum for the test, we borrow the ElementType enum from the Java class library.
        out.println( "Possible ElementTypes: " );
        for ( ElementType e : ElementType.values() )
            {
            out.println( " " + e );
            }
        // Use  the variant that takes the class of the entire enum.
        out.println( "Random ElementType: " + randomEnum( ElementType.class ) );
        }
    }