package GUIs;

import Common.*;
import Matrix3P.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

/**
 * Author: Max Buegler - max@sarstech.com
 * Date: Oct 6, 2009
 * Time: 11:18:07 AM
 */
public class WegaGUI3P extends JFrame{
    private JTextField p1a,p2a,p3a;
    private JTextField[][][] matrix;
    private JPanel matrixPanel;
    private GameAlgorithm3P algorithm;
    private JTextField algo;
    private JButton startbutton;
    private JPanel algoPanel;
    private JComboBox algolist;

    public WegaGUI3P(){
        super("WEGA GUI");
        //super.setSize(700,300);
        super.setLayout(new BorderLayout());
        JPanel topPanel=new JPanel();
        JLabel p1=new JLabel("P1 Actions:");
        p1a=new JTextField("2",2);
        JLabel p2=new JLabel("P2 Actions:");
        p2a=new JTextField("2",2);
        JLabel p3=new JLabel("P3 Actions:");
        p3a=new JTextField("2",2);

        startbutton=new JButton("Start");
        startbutton.addActionListener(new StartListener(this));
        topPanel.add(p1);
        topPanel.add(p1a);
        topPanel.add(p2);
        topPanel.add(p2a);
        topPanel.add(p3);
        topPanel.add(p3a);
        //topPanel.add(games);
        topPanel.add(startbutton);
        p1a.addActionListener(new matrixListener());
        p2a.addActionListener(new matrixListener());
        p3a.addActionListener(new matrixListener());
        p1a.addKeyListener(new matrixListener());
        p2a.addKeyListener(new matrixListener());
        p3a.addKeyListener(new matrixListener());

        super.add(topPanel,BorderLayout.NORTH);
        JPanel mainPanel=new JPanel();
        mainPanel.setLayout(new BorderLayout());
        matrixPanel=new JPanel();
        matrixPanel.setBorder(BorderFactory.createCompoundBorder(
                        BorderFactory.createTitledBorder("Game matrix"),
                        BorderFactory.createEmptyBorder(5,5,5,5)));

        mainPanel.add(matrixPanel,BorderLayout.CENTER);
        algoPanel=new JPanel();
            algoPanel.setBorder(BorderFactory.createCompoundBorder(
                            BorderFactory.createTitledBorder("Algorithm"),
                            BorderFactory.createEmptyBorder(5,5,5,5)));
            algoPanel.setLayout(new GridBagLayout());
            GridBagConstraints cons=new GridBagConstraints();
            cons.gridx=0;
            cons.gridy=0;
            cons.weightx=0.2;
            cons.weighty=0.5;
            cons.gridheight=1;
            cons.gridwidth=1;
            algolist=new JComboBox(new String[]{
                    "Fictitious Play",
                    "Regret Matching"});
            algolist.addActionListener(new AlgoListener());
            algoPanel.add(algolist,cons);
            cons=new GridBagConstraints();
            cons.gridx=1;
            cons.gridy=0;
            cons.weightx=0.5;
            cons.weighty=0.5;
            cons.gridheight=1;
            cons.gridwidth=3;
            cons.fill=GridBagConstraints.HORIZONTAL;
            algo=new JTextField("(None)",40);
            algo.setEditable(false);
            algoPanel.add(algo,cons);
            cons=new GridBagConstraints();
            cons.gridx=4;
            cons.gridy=0;
            cons.weightx=0.2;
            cons.weighty=0.5;
            cons.gridheight=1;
            cons.gridwidth=1;
            JButton settings=new JButton("Settings...");
            settings.addActionListener(new SettingsListener());
            algo.addMouseListener(new SettingsListener());
            algoPanel.add(settings,cons);


        mainPanel.add(algoPanel,BorderLayout.SOUTH);
        super.add(mainPanel,BorderLayout.CENTER);

        algorithm=new NoAlgorithm();
        new AlgoListener().actionPerformed(null);
        setUpMatrixPanel();
        super.setVisible(true);
        
    }
    class StartListener implements ActionListener {
        private JFrame frame;

        StartListener(JFrame frame) {
            this.frame = frame;
        }

        public void actionPerformed(ActionEvent e) {
            if (startbutton.getText().compareTo("Stop")==0){
                algorithm.stop();
                return;
            }
            int a1=Integer.parseInt(p1a.getText());
            int a2=Integer.parseInt(p2a.getText());
            int a3=Integer.parseInt(p3a.getText());
            double[][][] p1=new double[a1][a2][a3];
            double[][][] p2=new double[a1][a2][a3];
            double[][][] p3=new double[a1][a2][a3];
            for (int z=0;z<a3;z++){
                for (int x=0;x<a1;x++){
                    for (int y=0;y<a2;y++){
                        try{
                            p1[x][y][z]=Double.parseDouble(matrix[3*x][y][z].getText());
                            p2[x][y][z]=Double.parseDouble(matrix[3*x+1][y][z].getText());
                            p3[x][y][z]=Double.parseDouble(matrix[3*x+2][y][z].getText());
                        }
                        catch(Exception ex){
                            JOptionPane.showMessageDialog(frame,"Please enter numeric value into matrix cell "+x+","+y+","+z);
                        }
                    }
                }
            }
            GameMatrix3P m=null;
            Main.CON.setText("");
            Main.CONFRAME.setVisible(true);
            m=new GameMatrix3P(p1,p2,p3);
            final GameMatrix3P m2=m;
            startbutton.setText("Stop");
            new Thread(){
                public void run(){
                    algorithm.run(m2, new ActionListener(){
                        public void actionPerformed(ActionEvent e) {
                            startbutton.setText("Start");
                        }
                    });
                }
            }.start();
        }
    }
    public void finishAlgo(){

    }
    class UpdateDescriptorListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            algo.setText(algorithm.getDescriptor());
            algoPanel.updateUI();
        }
    }
    class SettingsListener implements ActionListener,MouseListener{
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}

        public void mouseClicked(MouseEvent e) {
            actionPerformed(null);
        }

        public void actionPerformed(ActionEvent e) {
            algorithm.settings(new UpdateDescriptorListener());
            algoPanel.updateUI();
        }
    }
    class AlgoListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            if (((String)algolist.getSelectedItem()).compareTo("Fictitious Play")==0)
                algorithm=new FictitiousPlay3P();
            else if (((String)algolist.getSelectedItem()).compareTo("Regret Matching")==0)
                algorithm=new RegretMatching3P();
            algo.setText(algorithm.getDescriptor());
            algoPanel.updateUI();
        }
    }

    /*class SelectListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            final JFrame listFrame=new JFrame("Select Algorithm");
            listFrame.setLayout(new BorderLayout());
            listFrame.add(new JLabel("Please select an algorithm"),BorderLayout.NORTH);
            DefaultListModel lm=new DefaultListModel();
            final JList list=new JList(lm);
            //lm.addElement("Dominated Actions");
            lm.addElement("Fictitious Play");
            //lm.addElement("Mixed Action Play");
            lm.addElement("Regret Matching");
            //lm.addElement("Saddle Points");
            JScrollPane pane=new JScrollPane(list,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            listFrame.add(pane,BorderLayout.CENTER);
            list.addMouseListener(new MouseListener(){
                public void mouseClicked(MouseEvent e) {
                    //if (((String)list.getSelectedValue()).compareTo("Dominated Actions")==0)
                        //algorithm=new DominatedActions();
                    if (((String)list.getSelectedValue()).compareTo("Fictitious Play")==0)
                        algorithm=new FictitiousPlay3P();
                    else if (((String)list.getSelectedValue()).compareTo("Regret Matching")==0)
                        algorithm=new RegretMatching3P();
                    /*else if (((String)list.getSelectedValue()).compareTo("Saddle Points")==0)
                        algorithm=new SaddlePoints();
                    else if (((String)list.getSelectedValue()).compareTo("Mixed Action Play")==0)
                        algorithm=new MixedActionPlay();*/

                   /* algo.setText(algorithm.getDescriptor());
                    algoPanel.updateUI();
                    listFrame.setVisible(false);
                }
                public void mousePressed(MouseEvent e){}
                public void mouseReleased(MouseEvent e){}
                public void mouseEntered(MouseEvent e){}
                public void mouseExited(MouseEvent e) {}});
            listFrame.setSize(200,300);
            listFrame.setVisible(true);
        }
    } */

    class matrixListener implements ActionListener, KeyListener {
        public void actionPerformed(ActionEvent e) {
            setUpMatrixPanel();
            repaint();
        }

        public void keyTyped(KeyEvent e) {

        }

        public void keyPressed(KeyEvent e) {

        }

        public void keyReleased(KeyEvent e) {
            setUpMatrixPanel();
        }
    }

    class focusListener implements FocusListener{
        private int x,y,z;

        focusListener(int x, int y,int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public void focusGained(FocusEvent e) {
            matrix[x][y][z].setSelectionStart(0);
            matrix[x][y][z].setSelectionEnd(matrix[x][y][z].getText().length());
        }

        public void focusLost(FocusEvent e) {
            //To change body of implemented methods use File | Settings | File Templates.
        }
    }
    public void setUpMatrixPanel(){
        Random rnd=new Random();
        try{
            int a1=Integer.parseInt(p1a.getText());
            int a2=Integer.parseInt(p2a.getText());
            int a3=Integer.parseInt(p3a.getText());
            matrixPanel.removeAll();
            matrixPanel.setLayout(new GridLayout(1,a3));
            matrix=new JTextField[3*a1][a2][a3];
            for (int z=0;z<a3;z++){
                JPanel subPanel=new JPanel();
                subPanel.setBorder(BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder("Pl 3 action "+z),
                                BorderFactory.createEmptyBorder(5,5,5,5)));
                subPanel.setLayout(new GridLayout(a1,a2));
                for (int x=0;x<a1;x++){
                    for (int y=0;y<a2;y++){
                        JPanel pt=new JPanel();
                        pt.setBorder(BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder(""),
                                BorderFactory.createEmptyBorder(1,1,1,1)));
                        String v=rnd.nextInt(10)+"";//="0";
                        matrix[3*x][y][z]=new JTextField(v,2);
                        v=rnd.nextInt(10)+"";//="0";
                        matrix[3*x+1][y][z]=new JTextField(v,2);
                        v=rnd.nextInt(10)+"";//="0";
                        matrix[3*x+2][y][z]=new JTextField(v,2);

                        matrix[3*x][y][z].addFocusListener(new focusListener(3*x,y,z));
                        matrix[3*x+1][y][z].addFocusListener(new focusListener(3*x+1,y,z));
                        matrix[3*x+2][y][z].addFocusListener(new focusListener(3*x+2,y,z));
                        pt.add(matrix[3*x][y][z]);
                        pt.add(new JLabel(","));
                        pt.add(matrix[3*x+1][y][z]);
                        pt.add(new JLabel(","));
                        pt.add(matrix[3*x+2][y][z]);

                        subPanel.add(pt);
                    }
                }
                matrixPanel.add(subPanel);
            }
            matrixPanel.updateUI();
            pack();
        }catch(Exception e){}

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

}
