import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;

public class SpaceInvadersController implements ActionListener, KeyListener {
    private final SpaceInvadersModel model;
    private final SpaceInvadersView view;

    public SpaceInvadersController(SpaceInvadersModel model, SpaceInvadersView view) {
        this.model = model;
        this.view = view;

        Timer timer = new Timer(1000 / 60, this);
        timer.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        model.update();
        view.repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_LEFT) {
            model.setMovingLeft(true);
        } else if (keyCode == KeyEvent.VK_RIGHT) {
            model.setMovingRight(true);
        } else if (keyCode == KeyEvent.VK_SPACE) {
            model.startShooting();

            try {
                playSound();
            } catch (IOException | UnsupportedAudioFileException | LineUnavailableException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            model.setMovingLeft(false);
        }
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            model.setMovingRight(false);
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            model.stopShooting();
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // not used
    }

    private void playSound() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
        File soundFile = new File("resources/laser.wav");
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        Clip clip = AudioSystem.getClip();
        clip.open(audioInputStream);
        clip.start();

        FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        volume.setValue(-20.0f);
    }
}
