import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.border.*;

/** separated from old GUI class
 * can now be used separately e.g. by GameTreeDisplay
 */
@SuppressWarnings("serial")
public class GUIPanel extends JPanel implements MouseListener {

    private Map<Coordinate,JLabel> pos2label = new LinkedHashMap<Coordinate,JLabel>();
    private Map<JPanel,Coordinate> panel2pos = new LinkedHashMap<JPanel,Coordinate>();
    private Game game;

    public GUIPanel(Game game) {
        this.game = game;
        int xSize = this.game.getHorizontalSize();
        int ySize = this.game.getVerticalSize();
        this.setLayout(new GridLayout(xSize,ySize));
        for (int y = 0; y < ySize; y++) {
            for (int x = 0; x < xSize; x++) {
                JLabel label = new JLabel(this.game.getContent(new Coordinate(x,y)), JLabel.CENTER);
                label.setFont(new Font("Arial Bold", Font.BOLD, 42));
                JPanel panel = new JPanel(new BorderLayout());
                panel.add(label, BorderLayout.CENTER);
                panel.setBorder(new LineBorder(Color.BLACK));
                panel.setBackground(Color.WHITE);
                this.add(panel);
                Coordinate pos = new Coordinate(x,y);
                this.pos2label.put(pos, label);
                this.panel2pos.put(panel, pos);
            }
        }
    }

    // helper
    private Coordinate getPosition(Component panel) {
        return this.panel2pos.get(panel);
    }

    // update all positions
    private void updateLabels() {
        for (Map.Entry<Coordinate,JLabel> entry : this.pos2label.entrySet()) {
            entry.getValue().setText(this.game.getContent(entry.getKey()));
        }
    }
    
    // add all mouse listeners
    public void addMouseListeners() {
        for (JPanel panel : this.panel2pos.keySet()) {
            panel.addMouseListener(this);
        }
    }

    @Override
    public void mouseClicked(MouseEvent event) {
        Coordinate pos = getPosition(event.getComponent());
        if (this.game.isFree(pos)) {
            this.game.addMove(pos);
            this.updateLabels();
            this.game.checkResult();
        }
    }

    @Override
    public void mouseEntered(MouseEvent event) {
        Component panel = event.getComponent();
        if (this.game.isFree(getPosition(panel))) {
            panel.setBackground(Color.CYAN);
        }
    }

    @Override
    public void mouseExited(MouseEvent event) {
        event.getComponent().setBackground(Color.WHITE);
    }

    @Override
    public void mousePressed(MouseEvent event) {
        Component panel = event.getComponent();
        if (this.game.isFree(getPosition(panel))) {
            panel.setBackground(Color.BLUE);
        } else {
            panel.setBackground(Color.RED);
        }
    }

    @Override
    public void mouseReleased(MouseEvent event) {
        event.getComponent().setBackground(Color.WHITE);
    }

}
