//***********************************************************
//*
//* File:           TournamentPanel.java
//* Author:         Abhinav Kamra
//* Contact:        kamra-at-cs.columbia.edu
//* Update:         9.13.2002
//*
//* Description:    Visual Tournament setup and analysis 
//*                 class.
//*
//***********************************************************

package ui;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.TableModel;
import java.text.NumberFormat;

public final class TournamentPanel extends JPanel {

    JTabbedPane         _tabs;
    ConfigurationPanel  _configure;
    AnalysisPanel       _analysis;
    IFCTournament       _tournament;
    IFCModel            _model;
    IFCModel            _sourcemodel;
    IFCUI               _ui;
    Random              _random;
    static final int    _CWIDTH = 400;
    static final int    _CHEIGHT = 100;
    static final int    _CMIN_GAMES = 1;
    static final int    _CMAX_GAMES = 10000;
    static final int    _CMAX_SAMPLES = 250;
    static final int    _COPY_VALUES = 11;

    static final int[] cookieCopyArray = { 1, 2, 3, 4, 5, 6, 7, 12, 13, 20, 53 };


    public TournamentPanel() throws Exception {
        super();
        setLayout(new BorderLayout());
        setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(),
                                                     BorderFactory.createLoweredBevelBorder()));
        setPreferredSize(new Dimension(_CWIDTH, _CHEIGHT));
        setMinimumSize(new Dimension(_CWIDTH, _CHEIGHT));

        _configure = new ConfigurationPanel();
        _tabs = new JTabbedPane();
        _tabs.addTab("Configure", _configure);
        _tabs.addTab("Analysis", new JPanel());
        add(_tabs);
        _random = new Random();
    }

    public JButton[] exportTools() {
        return _configure.exportTools();
    }

    public JMenu exportMenu() {
        return null;
    }

    public void register(IFCUI __ui, IFCModel __model) throws Exception {
        _ui = __ui;
        _model = (IFCModel) __model.getClass().newInstance();
        _sourcemodel = __model;
        _configure.register(_model.exportConfiguration());;
        repaint();
    }

    public JPanel exportViewPanel() throws Exception {
        return this;
    }
    
    private final class ConfigurationPanel extends JPanel implements ActionListener, ListSelectionListener, ItemListener {

        JScrollPane      _scrplayers;
        JScrollPane      _scrclasses;
        JList            _players;
        JList            _classes;
//        JTextField       _numplayers;
//        JTextField       _numrounds;
//        JTextField       _numgames;
	JComboBox	 _gamefilesbox;
        JButton          _run;
        IFCConfiguration _config;
//        JRadioButton     _roundrobin;
//        JRadioButton     _multisample;
//        JRadioButton     _multiplayer;
        final ImageIcon  _CRUN_ICON          = new ImageIcon("Images/alum_run.gif");
        final int        _CSLOT_WIDTH        = _CWIDTH;
        final int        _CSLOT_HEIGHT       = 100;
        final int        _CTEXT_WIDTH        = _CWIDTH;
        final int        _CTEXT_HEIGHT       = 40;
        final int        _CCOMBO_HEIGHT       = 20;
        final int        _CRADIO_HEIGHT      = 20;
        final int        _CDEFAULT_NUM_GAMES = 10;
        final Font       _CCONFIG_FONT       = new Font("Courier", Font.BOLD, 16);
        final Font       _CLIST_FONT         = new Font("Courier", Font.BOLD, 10);
        final Font       _CCOMBO_FONT         = new Font("Courier", Font.BOLD, 10);
        final String     _CSPACER            = "  ";

	String[]	_gamefilelist;
	String		_gamefile;
        
        public ConfigurationPanel() throws Exception {
            super();
            setLayout(new GridLayout(2, 2));
            setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(),
                                                     BorderFactory.createLoweredBevelBorder()));
            setPreferredSize(new Dimension(_CWIDTH, _CHEIGHT));
            setMinimumSize(new Dimension(_CWIDTH, _CHEIGHT));

            _run = new JButton(_CRUN_ICON);
            _run.addActionListener(this);
        }

        public void register(IFCConfiguration __config) throws Exception {
            SlotPanel slot;
            JPanel box;
            JLabel label;
            ButtonGroup bg;

            removeAll();
            _config = __config;
            slot = new SlotPanel(_CSLOT_WIDTH, _CSLOT_HEIGHT);
            slot.setVertical();
            _classes = new JList(_config.classList());
            _classes.setFont(_CLIST_FONT);
            _classes.addListSelectionListener(this);
            _scrclasses = new JScrollPane(_classes);
            label = new JLabel("Available Players");
            label.setFont(_CCONFIG_FONT);
            slot.add(label, _scrclasses);
            add(slot);

            slot = new SlotPanel(_CSLOT_WIDTH, _CSLOT_HEIGHT);
            slot.setVertical();
            _players = new JList(_config.playerList());
            _players.setFont(_CLIST_FONT);
            _players.addListSelectionListener(this);
            _scrplayers = new JScrollPane(_players);
            label = new JLabel("Contestants");
            label.setFont(_CCONFIG_FONT);
            slot.add(label, _scrplayers);
            add(slot);;

            box = new JPanel();
            box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
            slot = new SlotPanel(_CTEXT_WIDTH, _CTEXT_HEIGHT);
            box.add(slot);

/*           slot = new SlotPanel(_CTEXT_WIDTH, _CTEXT_HEIGHT);
            _numplayers = new JTextField(Integer.toString(_config.numPlayers()));
            _numplayers.setFont(_CCONFIG_FONT);
            label = new JLabel("NumPlayers:  ");
            label.setFont(_CCONFIG_FONT);
            slot.add(label, _numplayers);
            box.add(slot);

            slot = new SlotPanel(_CTEXT_WIDTH, _CTEXT_HEIGHT);
            _numrounds = new JTextField(Integer.toString(_config.numRounds()));
            _numrounds.setFont(_CCONFIG_FONT);
            label = new JLabel("NumRounds:   ");
            label.setFont(_CCONFIG_FONT);
            slot.add(label, _numrounds);
            box.add(slot);
*/
/*            slot = new SlotPanel(_CTEXT_WIDTH, _CTEXT_HEIGHT);
            _numgames = new JTextField(Integer.toString(_CDEFAULT_NUM_GAMES));
            _numgames.setFont(_CCONFIG_FONT);
            label = new JLabel("NumGames:    ");
            label.setFont(_CCONFIG_FONT);
            slot.add(label, _numgames);
            box.add(slot);
*/            

	_gamefilelist = _config.gameFileList();
	_gamefile = _gamefilelist[0];
            slot = new SlotPanel(_CWIDTH, _CCOMBO_HEIGHT);
            _gamefilesbox = new JComboBox(_gamefilelist);
            _gamefilesbox.setFont(_CCOMBO_FONT);
            _gamefilesbox.setSelectedItem(_gamefile);
            _gamefilesbox.addItemListener(this);
            label = new JLabel("Files: ");
            label.setFont(_CCONFIG_FONT);
            slot.add(label, _gamefilesbox);
            box.add(slot);

            add(box);
/*            box = new JPanel();
            box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
            slot = new SlotPanel(_CTEXT_WIDTH, _CTEXT_HEIGHT);
            box.add(slot);
            slot = new SlotPanel(_CTEXT_WIDTH, _CTEXT_HEIGHT);
            label = new JLabel("Tournament Type");
            label.setFont(_CCONFIG_FONT);
            slot.add(new JLabel(_CSPACER), label);
            box.add(slot);
            slot = new SlotPanel(_CTEXT_WIDTH, _CRADIO_HEIGHT);
            _roundrobin = new JRadioButton("Round Robin");
            _roundrobin.setFont(_CLIST_FONT);
            _roundrobin.addActionListener(this);
            _roundrobin.setSelected(true);
            slot.add(new JLabel(_CSPACER), _roundrobin);
            box.add(slot);
            slot = new SlotPanel(_CTEXT_WIDTH, _CRADIO_HEIGHT);
            _multiplayer = new JRadioButton("Multiplayer");
            _multiplayer.setFont(_CLIST_FONT);
            _multiplayer.addActionListener(this);
            slot.add(new JLabel(_CSPACER), _multiplayer);
            box.add(slot);
            slot = new SlotPanel(_CTEXT_WIDTH, _CRADIO_HEIGHT);
            _multisample = new JRadioButton("Multisample");
            _multisample.setFont(_CLIST_FONT);
            _multisample.addActionListener(this);
            slot.add(new JLabel(_CSPACER), _multisample);
            box.add(slot);
            bg = new ButtonGroup();
            bg.add(_roundrobin);
            bg.add(_multiplayer);
            bg.add(_multisample);
            add(box);
*/        }


        //********************************************
        //*
        //* ItemListener Interface
        //*
        //********************************************            
        public void itemStateChanged(ItemEvent __event) {
            Object source = __event.getSource();                        
            
            try {
                if (source == _gamefilesbox) {
                    _config.setGameFile((String) _gamefilesbox.getSelectedItem());
                    _ui.configure(_config);
                    return;
                }
            } catch (Exception EXC) {
                System.out.println(EXC.getMessage());
                EXC.printStackTrace();
            }
        }

        public void valueChanged(ListSelectionEvent __event) {
            try {
                Object source = __event.getSource();
                ListModel listmodel;
                Vector contents;
                Class selection;
                int val;
                int _MAX;
                
                if (source == _classes) {
                    listmodel = _classes.getModel();
                    selection = (Class) listmodel.getElementAt(_classes.getSelectedIndex());

                    contents = new Vector();
                    listmodel = _players.getModel();
                    _MAX = listmodel.getSize();
                    for (int i=0; i < _MAX; i++) {
                        contents.add(listmodel.getElementAt(i));
                    }
                    if (!contents.contains(selection)) {
                        contents.add(selection);
                        _players.setListData(contents);
                        repaint();
                    }
                }
                
                if (source == _players) {
                    val = _players.getSelectedIndex();
                    contents = new Vector();
                    listmodel = _players.getModel();
                    _MAX = listmodel.getSize();
                    for (int i=0; i < _MAX; i++) {
                        if (i != val) {
                            contents.add(listmodel.getElementAt(i));
                        }
                    }
                    _players.setListData(contents);
                    repaint();
                }

            } catch (Exception EXC) {
                System.out.println(EXC.getMessage());
                EXC.printStackTrace();
            }
        }

        public void actionPerformed(ActionEvent __event) {
            try {
                Object source = __event.getSource();
                IFCGameRecord[] games=null;
                IFCTournamentResults[] results;
                IFCTournament tournament=null;
                ListModel listmodel;
                Class[] clist;
                Class[] plist;
                int _MAXI;
                
/*
                if (source == _run) {
                    _sourcemodel.run(tournament);
                    repaint();
                    _ui.refresh();
                    return;
                }
*/

                if (source == _run) {
                        listmodel = _players.getModel();
                        _MAXI = listmodel.getSize();
                        if (_MAXI < 2) {
                            throw new Exception("Error:  Invalid Number of Players Specified");
                        }
                        clist = new Class[_MAXI];
                        for (int i=0; i < _MAXI; i++) {
                            clist[i] = (Class) listmodel.getElementAt(i);
                        }

                        games = new GameRecord[_COPY_VALUES];
                        for (int j=0; j < _COPY_VALUES; j++) {
                            plist = new Class[_MAXI];
                            System.arraycopy(clist, 0, plist, 0, _MAXI);
                            games[j] = new GameRecord();
                            games[j].setPlayers(plist);
                            games[j].setCookieCopies(cookieCopyArray[j]);
                            games[j].setGameFile(_config.gameFile());
                        }
System.out.println("File is " + _config.gameFile());
                    tournament = new Tournament();
                    tournament.setGames(games);
                    _model.run(tournament);
                    results = new IFCTournamentResults[1];
                    results[0] = new TournamentResults(games);
System.out.println("File printed");
/*
                    _tabs.remove(1);
                    results = new IFCTournamentResults[2];
                    results[0] = new TournamentResults(games);
                    results[1] = new PlayerSpecificResults(games);
                    _analysis = new AnalysisPanel(results);
                    _tabs.addTab("Analysis", _analysis);
                    _tabs.setSelectedComponent(_analysis);
*/                    _ui.maximizeViewSize();
                    repaint();
                }
            } catch (Exception EXC) {
                System.out.println(EXC.getMessage());
                EXC.printStackTrace();
            }
        }

        public JButton[] exportTools() {
            JButton[] RET = new JButton[1];
            RET[0] = _run;
            return RET;
        }
        
        double choose(int __c, int __n) {
            return  (factorial(__c) / (factorial(__n) * factorial(__c - __n)));
        }
        
        double factorial(int __n) {
            double RET=1;

            for (int i=2; i <= __n; i++) {
                RET *= i;
            }
            return RET;
        }
    }

    private final class AnalysisPanel extends JPanel {

        JTabbedPane             _tabs;
        IFCTournamentResults[]  _results;
        final Font              _CHEADER_FONT = new Font("Courier", Font.BOLD, 14);
        final Font              _CCELL_FONT = new Font("Courier", Font.BOLD, 12);

        public AnalysisPanel(IFCTournamentResults[] __results) throws Exception {
            super();
            
            JTable table;
            JScrollPane scr;
            int _MAX;

            setLayout(new BorderLayout());
            setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(),
                                                     BorderFactory.createLoweredBevelBorder()));
            setPreferredSize(new Dimension(_CWIDTH, _CHEIGHT));
            setMinimumSize(new Dimension(_CWIDTH, _CHEIGHT));

            _tabs = new JTabbedPane();
            _results = __results;
            _MAX = _results.length;
            for (int i=0; i < _MAX; i++) {
                table = new JTable();
                table.setFont(_CCELL_FONT);
                table.getTableHeader().setFont(_CHEADER_FONT);
                table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
                table.setModel(_results[i]);
                table.getColumnModel().addColumnModelListener(_results[i]);
                scr = new JScrollPane(table);
                _tabs.add(_results[i].name(), scr);
            }
            add(_tabs);
        }
    }
}



