/*
 * @(#) CData.java  1.10 10/09/02
 *
 * Copyright ***,  All Rights Reserved.
 * 
 * This software is the proprietary information of ********  
 * Use is subject to license terms.
 * 
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.io.*;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.lang.*;
import java.util.*;
import javax.swing.table.*;

/**
 * Class that handles node info dialog box actions
 * 
 */
public class UINodeInfo extends JDialog implements ActionListener {

    //-----------------------------------------------------------------
    //
    // static data members
    //
    //-----------------------------------------------------------------

    //-----------------------------------------------------------------
    //
    // instance data members
    //
    //-----------------------------------------------------------------

    // data in two lists, user can set it from outside of the class
    //
    public Vertex vertex_d = null;
    Vector<String> node_symbols_d = new Vector<String>();
    Vector<String> level_symbols_d = new Vector<String>();
    String node_name_d = new String();
    
    // symbols for the node
    //
    NodeSymbolModel symbols_in_node_d = new NodeSymbolModel();
    LevelSymbolModel symbols_in_level_d = new LevelSymbolModel();
    JTable jNodeSymbols = new JTable( symbols_in_node_d);
    JTable jLevelSymbols = new JTable( symbols_in_level_d);

    JPanel jP1 = new JPanel();
    JPanel jP2 = new JPanel();
    JPanel jP3 = new JPanel();

    JPanel jMainPane = new JPanel();
    JPanel jBottomPane = new JPanel();
    GridBagLayout gridBagLayout1 = new GridBagLayout();
    JPanel jTopPane = new JPanel();
    JLabel jNodeName = new JLabel();
    JLabel jSymbolNumbers = new JLabel();
    JTextField jTextFieldNodeName = new JTextField();
    JPanel jMiddlePanel = new JPanel();
    BorderLayout borderLayout1 = new BorderLayout();
    JPanel jPanel_11 = new JPanel();
    JScrollPane jScrollPane1 = new JScrollPane();
    JPanel jPanel_12 = new JPanel();
    JButton jButtonRemove = new JButton();
    BorderLayout borderLayout2 = new BorderLayout();
    JPanel jPanel_13 = new JPanel();
    JScrollPane jScrollPane2 = new JScrollPane();
    GridBagLayout gridBagLayout3 = new GridBagLayout();

    JTextField jTextFieldAddedSymbol = new JTextField();

    JButton jButtonInsert = new JButton();
    JButton jButtonLoad = new JButton();
    JButton jButtonAdd = new JButton();
    JButton jButtonOK = new JButton();
    JButton jButtonCancel = new JButton();

    // borders
    //
    Border border11;  
    Border border13;

    //-----------------------------------------------------------------
    //
    // function members
    //
    //-----------------------------------------------------------------

    /**
     * default class constructor
     *
     * @param frame the Frame from which the dialog is displayed
     * @param title the String to display in the dialog's title bar
     * @param modal true for a modal dialog, false for one that allows other
     *     windows to be active at the same time 
     */
    public UINodeInfo(Frame frame, String title, boolean modal) {
	super(frame, title, modal);
    }

    public UINodeInfo() {
	this(null, "", false);
    }

    /**
     * initializes everything for a dialog
     * 
     */
    public void initAll(){
	try  {
	    jbInit();
	    pack();
	}
	catch(Exception ex) {
	    ex.printStackTrace();
	}
    }

    void jbInit() throws Exception {
	
	// set the main pane
	//
	jMainPane.setLayout(gridBagLayout1);
	jMainPane.setPreferredSize(new Dimension(450, 300));
	getContentPane().add(jMainPane);

	// add three panes on the main pane
	//
	jMainPane.add(jTopPane, 
		      new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
					     GridBagConstraints.CENTER, 
					     GridBagConstraints.BOTH, 
					     new Insets(0, 0, 5, 0), 0, 0));

	jMainPane.add(jMiddlePanel, 
		      new GridBagConstraints(0, 1, 1, 1, 1.0, 0.65,
					     GridBagConstraints.CENTER, 
					     GridBagConstraints.BOTH, 
					     new Insets(0, 5, 0, 5), 0, 0));

	jMainPane.add(jBottomPane, 
		      new GridBagConstraints(0, 2, 1, 1, 1.0, 0,
					     GridBagConstraints.CENTER, 
					     GridBagConstraints.BOTH, 
					     new Insets(5, 0, 10, 0), 0, 0));

	// add components on the top pane
	//
	jTopPane.add(jNodeName);
	jTextFieldNodeName.setText(node_name_d);
	jTopPane.add(jTextFieldNodeName);
	jSymbolNumbers.setText("Number of Symbols on Node: " + node_symbols_d.size());
	jTopPane.add(jSymbolNumbers);
	jTopPane.setLayout(new FlowLayout(FlowLayout.LEFT));

	jTextFieldNodeName.setPreferredSize(new Dimension(80, 24));
	jNodeName.setText("Node Name");
	jNodeName.setBounds(new Rectangle(16, 9, 41, 17));

	// add componets on the middle pane
	//
	jMiddlePanel.setLayout(gridBagLayout3);
	jMiddlePanel.add(jPanel_11, 
			 new GridBagConstraints(0, 0, 1, 1, 0.4, 1.0,
						GridBagConstraints.CENTER, 
						GridBagConstraints.BOTH, 
						new Insets(0, 0, 0, 0), 0, 0));
	
	jMiddlePanel.add(jPanel_12, 
			 new GridBagConstraints(1, 0, 1, 1, 0.0, 1.0,
						GridBagConstraints.CENTER, 
						GridBagConstraints.BOTH, 
						new Insets(0, 0, 0, 0), 0, 0));

	jMiddlePanel.add(jPanel_13, 
			 new GridBagConstraints(2, 0, 1, 1, 0.4, 1.0,
						GridBagConstraints.CENTER, 
						GridBagConstraints.BOTH, 
						new Insets(0, 0, 0, 0), 0, 0));

	// add panel 11 on the middle pane
	//
	jPanel_11.setLayout(borderLayout1);
	jPanel_11.add(jScrollPane1, BorderLayout.CENTER);
	jScrollPane1.getViewport().add(jNodeSymbols, null);

	border11 = BorderFactory.createCompoundBorder(new TitledBorder(BorderFactory.createLineBorder(Color.black,1),"Symbols in the Node"),BorderFactory.createEmptyBorder(1,1,1,1));
	jPanel_11.setBorder(border11);

	// add pane 13 on the middle pane
	//
	jPanel_13.setLayout(borderLayout2);
	jPanel_13.add(jScrollPane2, BorderLayout.CENTER);
	jScrollPane2.getViewport().add(jLevelSymbols, null);

	border13 = BorderFactory.createCompoundBorder(new TitledBorder(BorderFactory.createLineBorder(Color.black,1),"Symbols in the level"),BorderFactory.createEmptyBorder(1,1,1,1));
	jPanel_13.setBorder(border13);

	jButtonInsert.setText("  <<   ");
	jButtonLoad.setText("Load...");
	//jButtonRemove.setText(">>");
	jButtonInsert.setPreferredSize(new Dimension(80, 24));
	jButtonLoad.setPreferredSize(new Dimension(80, 24));
	//jButtonRemove.setPreferredSize(new Dimension(56, 24));

	// add panel 12
	//
	jPanel_12.setLayout(new BorderLayout());

	Box b = Box.createVerticalBox();
	b.setAlignmentX((float)0.5);
	b.setAlignmentY((float)20);
	b.setPreferredSize(new Dimension(80, 100));
	jP3.add(b);
	
	//b.add(jButtonRemove);
	//b.add(Box.createVerticalGlue());
	b.add(jButtonInsert);
	b.add(jButtonLoad);
	
	jP1.setPreferredSize(new Dimension(80, 50));
	jP2.setPreferredSize(new Dimension(80, 50));
	jP3.setPreferredSize(new Dimension(80, 100));
	jP3.setMaximumSize(new Dimension(80, 100));

	jPanel_12.add(jP3, "Center");
	jPanel_12.add(jP1, "North");
	jPanel_12.add(jP2, "South");
	
	// add components for the bottom pane
	//
	jBottomPane.setLayout(new FlowLayout(FlowLayout.CENTER));

	jButtonAdd.setText("Add");
	jButtonOK.setText("OK");
	jButtonCancel.setText("Cancel");
	jButtonRemove.setText("Delete");
    	jTextFieldAddedSymbol.setPreferredSize(new Dimension(100, 24));
	jButtonAdd.setPreferredSize(new Dimension(80, 24));
	jButtonOK.setPreferredSize(new Dimension(80, 24));
	jButtonCancel.setPreferredSize(new Dimension(80, 24));
	jButtonRemove.setPreferredSize(new Dimension(80, 24));

	jButtonAdd.addActionListener(this);
	jButtonOK.addActionListener(this);
	jButtonCancel.addActionListener(this);
	jButtonInsert.addActionListener(this);
	jButtonLoad.addActionListener(this);
	jButtonRemove.addActionListener(this);

	jBottomPane.add(jTextFieldAddedSymbol);
	jBottomPane.add(jButtonAdd);
	jBottomPane.add(jButtonRemove);
	jBottomPane.add(jButtonOK);
	jBottomPane.add(jButtonCancel);

    }

    /**
     * set corresponding vertex for this dialog
     * 
     * @param vertex_a the node
     */
    public void setVertex(Vertex vertex_a) {
	vertex_d = vertex_a;
	node_name_d = new String(vertex_d.name_d);

	// node_symbols_d = (Vector)vertex_d.symbols_d.clone();
	//
	node_symbols_d = vertex_d.symbols_d;
    }

    /**
     * handle the event when a button is clicked
     * 
     * @param e the button event
     */
    public void actionPerformed(ActionEvent e) {
	
	// decide which button is clicked
	//
	if(e.getSource() == jButtonAdd) {
	    String added_text = jTextFieldAddedSymbol.getText();
	    if ( added_text.length() != 0){
		if ( node_symbols_d.indexOf(added_text) < 0){
		    node_symbols_d.add( added_text ); 
		    symbols_in_node_d.fireTableDataChanged();
		}
		if ( level_symbols_d.indexOf(added_text) < 0){
		    level_symbols_d.add( added_text ); 
		    symbols_in_level_d.fireTableDataChanged();
		}
	    }
	}
	if(e.getSource() == jButtonOK) {

	    node_name_d = jTextFieldNodeName.getText();
	    vertex_d.name_d = node_name_d;
	    vertex_d.symbols_d = node_symbols_d;
	    
	    SearchLevel curr_level = CData.getCurrLevel();
	    curr_level.symbols_d = level_symbols_d;

	    // set the global symbol table
	    //
	    if (CData.symbol_dlg_d != null){
		CData.event_handler_d.showSymbolsDlg();
	    }
	    dispose();
	}
	if(e.getSource() == jButtonCancel) {
	    dispose();
	}
	if(e.getSource() == jButtonInsert) {
	    int i = jLevelSymbols.getSelectedRow();
	    int j = jLevelSymbols.getSelectedColumn();
	    String selected_string = (String)jLevelSymbols.getValueAt(i , j);
	    if ( selected_string != null){
		if ( node_symbols_d.indexOf(selected_string) < 0 ){
		    node_symbols_d.add( selected_string ); 
		    symbols_in_node_d.fireTableDataChanged();
		}
	    }
	}
	if(e.getSource() == jButtonRemove) {
	    int i = jNodeSymbols.getSelectedRow();
	    int j = jNodeSymbols.getSelectedColumn();
	    String selected_string = (String)jNodeSymbols.getValueAt(i , j);
	    if ( selected_string != null){
		node_symbols_d.remove( selected_string ); 
		symbols_in_node_d.fireTableDataChanged();
	    }
	}
	if(e.getSource() == jButtonLoad) {
	
	    String file_name = CData.chooseAnyFile("OK");

	    // get the file name
	    //
	    if ( file_name == null){
		JOptionPane.showMessageDialog(this, "Invalid File Name");
		return ;
	    } 
	    
	    File file = new File(file_name);
	    
	    if ( ! file.exists() ){
		JOptionPane.showMessageDialog(this, "Invalid File Name");
		return ;
	    }

	    // read from the file
	    //
	    try {
		 BufferedReader reader = 
		 new BufferedReader(new 
		     InputStreamReader(new FileInputStream(file_name)));
		 String line;
		 while ( (line = reader.readLine()) != null ){
		     
		     // add the new line to the symbol list
		     //
		     if ( line.length() != 0){
			 //if ( !node_symbols_d.contains(line) ){
			     node_symbols_d.add( line ); 
			     //}
			     //if ( !level_symbols_d.contains(line)){
			     level_symbols_d.add( line ); 
			     //}
		     }
		 }
		 CData.sortSymbols(node_symbols_d);
		 CData.sortSymbols(level_symbols_d);
		 symbols_in_node_d.fireTableDataChanged();
		 symbols_in_level_d.fireTableDataChanged();

	    } catch ( IOException io ){
		JOptionPane.showMessageDialog(this, "Invalid File Name");
	    }
	}
	
	// change the number of symbols
	//
	jSymbolNumbers.setText("Number of Symbols on Node: " + node_symbols_d.size());
	jSymbolNumbers.repaint();
    }

    // define inner class NodeSymbolModel
    //
    class NodeSymbolModel extends AbstractTableModel {
        final String[] columnNames = {"Symbol Name"};

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
	    return node_symbols_d.size(); 
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
	    return node_symbols_d.get(row);
        }

        public void setValueAt(Object aValue, int row, int col) {
	    node_symbols_d.set(row, aValue.toString());
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
	    return false;
        }
    } // end of class NodeSymbolModel

    // define inner class NodeSymbolModel
    //
    class LevelSymbolModel extends AbstractTableModel {
        final String[] columnNames = {"Symbol Name"};

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
	    return level_symbols_d.size(); 
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
	    return level_symbols_d.get(row);
        }

        public void setValueAt(Object aValue, int row, int col) {
	    level_symbols_d.set(row, aValue.toString());
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
	    return false;
        }
    } // end of class LevelSymbolModel
}





