import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.media.AudioClip;
import javafx.stage.Stage;

/**
 * Displays a picture of a bird selected by the user and plays an audio clip of the bird's
 * song.
 *
 * @author Drue Coles
 */
public class BirdSong extends Application {

    private final String[] birds = {
            "American_Goldfinch", "American_Robin", "Baltimore_Oriole",
            "Black-Capped_Chickadee", "Carolina_Wren", "Eastern_Bluebird",
            "Field_Sparrow", "White-Breasted_Nuthatch"
    };

    private final Image[] images = new Image[birds.length];
    private final AudioClip[] clips = new AudioClip[birds.length];

    /**
     * Loads images and audio clips. These resources are stored in a project-level folder
     * named birds, which was marked as Resources Root in the IntelliJ IDE.
     */
    public BirdSong() {
        for (int i = 0; i < birds.length; i++) {
            String imageFile = birds[i] + ".jpg";
            final int width = 400;

            // The fourth argument indicates that the aspect ratio of the image is to be
            // preserved, so we only need to specify the width (height = 0 has no effect).
            images[i] = new Image(imageFile, width, 0, true, true);
            
            String audioFile =  "file:birds/" + birds[i] + ".mp3";
            //clips[i] = new AudioClip(audioFile);
        }
    }

    @Override
    public void start(Stage primaryStage) {
        BorderPane root = new BorderPane();
        root.setPadding(new Insets(10));
        Scene scene = new Scene(root);

        // used for text on button and radio buttons
        String style = "-fx-font-size: 18; -fx-font-weight: BOLD";

        // control nodes
        ImageView currentImage = new ImageView(images[0]);
        RadioButton[] radioButtons = new RadioButton[birds.length];
        ToggleGroup toggleGroup = new ToggleGroup();
        Button playButton = new Button("Play song");
        playButton.setStyle(style);

        // two children of the root node
        FlowPane playButtonFlowPane = new FlowPane();
        HBox hBox = new HBox(10);

        // Initialize flow pane containing the play button.
        playButtonFlowPane.getChildren().add(playButton);
        playButtonFlowPane.setAlignment(Pos.CENTER);
        playButtonFlowPane.setPadding(new Insets(10, 0, 0, 10));
        root.setBottom(playButtonFlowPane);

        // Initialize VBox to hold image and a VBox containing the radio buttons.
        VBox radioButtonVBox = new VBox(8);
        hBox.getChildren().addAll(currentImage, radioButtonVBox);
        root.setCenter(hBox);

        class RadioButtonHandler implements EventHandler<ActionEvent> {
            private int indexOfBird;

            private RadioButtonHandler(int indexOfBird) {
                this.indexOfBird = indexOfBird;
            }

            // Set image of selected bird and turn off all audio clips.
            @Override
            public void handle(ActionEvent event) {
                currentImage.setImage(images[indexOfBird]);
                for (AudioClip clip : clips) {
                    clip.stop();
                }
            }
        }

        // Create radio buttons and register event handlers.
        for (int i = 0; i < birds.length; i++) {
            radioButtons[i] = new RadioButton(birds[i].replace("_", " "));
            radioButtons[i].setStyle(style);
            radioButtons[i].setPadding(new Insets(8, 0, 8, 3));
            radioButtonVBox.getChildren().add(radioButtons[i]);
            radioButtons[i].setOnAction(new RadioButtonHandler(i));
            toggleGroup.getToggles().add(radioButtons[i]);
        }
        radioButtons[0].setSelected(true);

        class ButtonHandler implements EventHandler<ActionEvent> {
            // Find index of selected radio button and play corresponding audio clip.
            @Override
            public void handle(ActionEvent event) {
                for (int i = 0; i < birds.length; i++) {
                    if (radioButtons[i].isSelected()) {
                        clips[i].play();
                    }
                }
            }
        }
        playButton.setOnAction(new ButtonHandler());

        primaryStage.setTitle("Bird Song");
        primaryStage.setScene(scene);
        primaryStage.setAlwaysOnTop(true);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}