package GUIs;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

import Common.NoAlgorithm;
import Cooperative.*;

/**
 * Author: Max Buegler - max@sarstech.com
 * Date: Oct 14, 2009
 * Time: 10:35:57 PM
 */
public class CooperativeGUI  extends JFrame {
    private JTextField pl;
    private JTextField[] values;
    private CoopAlgorithm algorithm;
    private JTextField algo;
    private JButton startbutton;
    private JPanel algoPanel;
    private JPanel valuePanel;
    private JComboBox algolist;

    public CooperativeGUI(boolean pack){
        super("WEGA GUI");
        //super.setSize(700,300);
        super.setLayout(new BorderLayout());
        JPanel topPanel=new JPanel();
        JLabel p1=new JLabel("Number of players:");
        pl=new JTextField("3",2);

        startbutton=new JButton("Start");
        startbutton.addActionListener(new StartListener(this));
        topPanel.add(p1);
        topPanel.add(pl);
        topPanel.add(startbutton);
        pl.addActionListener(new valuesListener());
        pl.addKeyListener(new valuesListener());
        super.add(topPanel,BorderLayout.NORTH);
        JPanel mainPanel=new JPanel();
        mainPanel.setLayout(new BorderLayout());
        valuePanel=new JPanel();
        valuePanel.setBorder(BorderFactory.createCompoundBorder(
                        BorderFactory.createTitledBorder("Coalition values"),
                        BorderFactory.createEmptyBorder(5,5,5,5)));

        mainPanel.add(valuePanel,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[]{
                    "Shapley value"});
            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);
        if (pack){
            setUpValuePanel();
            super.setVisible(true);
        }

    }
    public CooperativeGUI(ArrayList<Coalition> coalitions, int p){
        this(false);
        pl.setText(p+"");
        setUpValuePanel();
        for (int x=0;x<coalitions.size();x++)values[x].setText(coalitions.get(x).getValue()+"");
        super.setVisible(true);        
    }
    class AlgoListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            if (((String)algolist.getSelectedItem()).compareTo("Shapley value")==0)
                algorithm=new ShapleyValue();
            algo.setText(algorithm.getDescriptor());
            algoPanel.updateUI();
        }
    }

    class StartListener implements ActionListener {
        private JFrame frame;

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

        public void actionPerformed(ActionEvent e) {
            Main.CON.setText("");
            if (startbutton.getText().compareTo("Stop")==0){
                algorithm.stop();
                return;
            }

            int p=0;
            try{
                p=Integer.parseInt(pl.getText());
            }
            catch(Exception ex){
                JOptionPane.showMessageDialog(frame,"Please enter integer value for number of players");
                return;
            }
            ArrayList<Coalition> bco=getCoaltions(p);
            final ArrayList<Coalition> co=new ArrayList<Coalition>();
            double m=0;

            for (int x=0;x<values.length;x++){
                try{
                    co.add(new Coalition(bco.get(x).getPlayers(),Double.parseDouble(values[x].getText())));
                }
                catch(Exception ex){
                    JOptionPane.showMessageDialog(frame,"Please enter real value into cell "+x);
                    return;
                }
            }

            Main.CONFRAME.setVisible(true);
            startbutton.setText("Stop");
            final double mn=m;
            final int pc=p;
            new Thread(){
                public void run(){
                    algorithm.run(pc,co, 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 valuesListener implements ActionListener, KeyListener {
        public void actionPerformed(ActionEvent e) {
            setUpValuePanel();
            repaint();
        }

        public void keyTyped(KeyEvent e) {

        }

        public void keyPressed(KeyEvent e) {

        }

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

    class focusListener implements FocusListener{
        private int x;

        focusListener(int x) {
            this.x = x;
        }

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

        public void focusLost(FocusEvent e) {
            //To change body of implemented methods use File | Settings | File Templates.
        }
    }

    private ArrayList<Coalition> getCoaltions(int p){
        ArrayList<Coalition> c=new ArrayList<Coalition>();
        for (int x=0;x<p;x++){
            getCoaltions(p,x+1,0,c,new int[x+1]);
        }
        return c;
    }
    private void getCoaltions(int p,int m, int n,ArrayList<Coalition> c, int[] cc){
        if (m==n)c.add(new Coalition(cc.clone(),0));
        else{
            int s=0;
            if (n>0)s=cc[n-1]+1;
            for (int x=s;x<p;x++){
                cc[n]=x;
                getCoaltions(p,m,n+1,c,cc);
            }
        }
    }



    public void setUpValuePanel(){
        try{
            int p=Integer.parseInt(pl.getText());
            valuePanel.removeAll();
            ArrayList<Coalition> c=getCoaltions(p);
            values=new JTextField[c.size()];
            if (c.size()<=20)valuePanel.setLayout(new GridLayout(1,c.size()));
            else if (c.size()<=40)valuePanel.setLayout(new GridLayout(2,(int)Math.ceil(c.size()/2.0)));
            else if (c.size()<=60)valuePanel.setLayout(new GridLayout(3,(int)Math.ceil(c.size()/3.0)));
            else if (c.size()<=100)valuePanel.setLayout(new GridLayout(4,(int)Math.ceil(c.size()/4.0)));
            else valuePanel.setLayout(new GridLayout(8,(int)Math.ceil(c.size()/8.0)));
            for (int x=0;x<c.size();x++){
                    JPanel pt=new JPanel();
                    pt.setBorder(BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder(""),
                                BorderFactory.createEmptyBorder(2,2,2,2)));
                    pt.setLayout(new GridLayout(2,1));
                    values[x]=new JTextField("0",5);
                    values[x].addFocusListener(new focusListener(x));
                    String t=(c.get(x).getPlayers()[0]+1)+"";
                    for (int y=1;y<c.get(x).getPlayers().length;y++)t+=", "+(c.get(x).getPlayers()[y]+1);
                    JTextArea l=new JTextArea();
                    l.setEditable(false);
                    l.setCursor(null);
                    l.setOpaque(false);
                    l.setFocusable(false);
                    l.setLineWrap(true);
                    l.setText(t);
                    pt.add(l);
                    pt.add(values[x]);
                    valuePanel.add(pt);
            }
            valuePanel.updateUI();
            pack();
        }catch(Exception e){}

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

