import acm.program.*;
import acm.util.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/* This program allows the user to type a color name and have that become the
 * background color of the window. It uses a large data file of color names.
 */
public class ColoredWindow extends GraphicsProgram {
    /* Private constants */
    private static final int TEXT_FIELD_WIDTH = 16;
    private static final String COLORS_FILE = "res/colors.txt";

    /* Private fields */
    private JTextField colorNameEntry;       // text field used for data entry
    private HashMap<String, Color> colors;   // color data from file

    public void init() {
          readColors();
        addInteractors();
    }

    /* Adds the interactors and event listeners to the window. */
    private void addInteractors() {
        add(new JLabel("Enter color: "), SOUTH);
        colorNameEntry = new JTextField(TEXT_FIELD_WIDTH);
        colorNameEntry.setActionCommand("Show");
        add(colorNameEntry, SOUTH);
        
        add(new JButton("Show"), SOUTH);
        add(new JButton("Random"), SOUTH);
        addActionListeners();

        colorNameEntry.addActionListener(this); // listen for ENTER pressed
    }

    /* Triggered when the user enters a color or clicks "Random". */
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Random")) {
            // Pick a random color name - first convert all keys to an ArrayList
            ArrayList<String> colorNames = new ArrayList<String>(colors.keySet());
            int randomIndex = RandomGenerator.getInstance().nextInt(0, 
                colorNames.size());
            String colorName = colorNames.get(randomIndex);
            colorNameEntry.setText(colorName);
            setBackground(colors.get(colorName));
        } else {
            // Get the (case-insensitive) color entered and display it, if valid
            String colorName = colorNameEntry.getText().toLowerCase();
            Color chosenColor = colors.get(colorName);
            if (chosenColor != null) {
                setBackground(chosenColor);
            }
        }
    }

    /* Read the color data from the file into a map of (name -> Color) */
    private void readColors() {
        colors = new HashMap<String, Color>();
        try {
            Scanner sc = new Scanner(new File(COLORS_FILE));
            while (sc.hasNext()) {
                String colorName = sc.nextLine().toLowerCase(); // normalize case
                String rgbValues = sc.nextLine();
                Scanner tokens = new Scanner(rgbValues);
                int r = tokens.nextInt();
                int g = tokens.nextInt();
                int b = tokens.nextInt();
                Color c = new Color(r, g, b);
                colors.put(colorName, c);
            }
        } catch (FileNotFoundException e) {
            println("Couldn't load color file");
        }
    }
}
