/*
 * @(#) UIMainFrame.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 packages
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;

/**
 * This class is construct the main frame of the network builder.
 * 
 */
public class UIMainFrame extends JFrame implements TreeSelectionListener,
						   ListSelectionListener,
						   CellEditorListener,
						   ChangeListener{

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

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

    // the graph name list indicate which graph is current graph
    //
    public Vector<String> level_graphs_d = new Vector<String>();
    public LevelGraphTableModel graphs_in_level_d 
	= new LevelGraphTableModel();

    // a list of graph names
    //
    JTable jGraphList = new JTable(graphs_in_level_d);

    // status flag
    //
    boolean updating_d = false;

    // menu options
    //
    JMenuBar jMenuBarMain = new JMenuBar();

    JMenu jMenuFile = new JMenu();
    JMenuItem jMenuFileNew = new JMenuItem();
    JMenuItem jMenuFileOpen = new JMenuItem();
    JMenuItem jMenuFileSave = new JMenuItem();
    JMenuItem jMenuFileSaveAs = new JMenuItem();
    JMenuItem jMenuFileSaveAll = new JMenuItem();
    JMenuItem jMenuFileClose = new JMenuItem();
    JMenuItem jMenuFileExit = new JMenuItem();

    JMenu jMenuHelp = new JMenu();
    JMenuItem jMenuHelpAbout = new JMenuItem();
    //JMenuItem jMenuHelpTest = new JMenuItem();

    JMenu jMenuGrammar = new JMenu();
    JMenuItem jMenuGrammarInsertStart = new JMenuItem();
    JMenuItem jMenuGrammarInsertStop = new JMenuItem();
    JMenuItem jMenuGrammarInsertNode = new JMenuItem();
    JMenuItem jMenuGrammarInsertArc = new JMenuItem();
    JMenuItem jMenuGrammarInsertSelfArc = new JMenuItem();

    JMenuItem jMenuGrammarCopyGraph = new JMenuItem();
    JMenuItem jMenuGrammarPasteGraph = new JMenuItem();
    JMenuItem jMenuGrammarAddGraph = new JMenuItem();
    JMenuItem jMenuGrammarDeleteGraph = new JMenuItem();
    JMenuItem jMenuGrammarWeightGraph = new JMenuItem();

    // menu for Edit
    //
    JMenu jMenuEdit = new JMenu();
    JMenuItem jMenuEditCopy = new JMenuItem();
    JMenuItem jMenuEditCut = new JMenuItem();
    JMenuItem jMenuEditPaste = new JMenuItem();
    JMenuItem jMenuEditDelete = new JMenuItem();

    // menu for hiearchy
    //
    JMenu jMenuH = new JMenu();
    JMenuItem jMenuHAddLevel = new JMenuItem();
    JMenuItem jMenuHDeleteLevel = new JMenuItem();
    JMenuItem jMenuHCheckLevel = new JMenuItem();
    JMenuItem jMenuHAddGraph = new JMenuItem();
    JMenuItem jMenuHDeleteGraph = new JMenuItem();
    JMenuItem jMenuHSymbols = new JMenuItem();

    // panels
    //
    public JTabbedPane jTabbedPaneLeft = new JTabbedPane();

    JLabel statusBar = new JLabel();
    BorderLayout borderLayout1 = new BorderLayout();
    JPanel jPanel1 = new JPanel();
    BorderLayout borderLayout2 = new BorderLayout();
    JSplitPane jSplitPane1 = new JSplitPane();
    JSplitPane jSplitPane2 = new JSplitPane();
    JPanel jGraphPane = new JPanel();
    JPanel jPanel3 = new JPanel();
    JPanel jListPanel = new JPanel();
    JTree jLevelTree = null;

    BorderLayout borderLayout3 = new BorderLayout();
    BorderLayout borderLayout4 = new BorderLayout();
    JLabel jLabel1 = new JLabel();
    JLabel jLabel2 = new JLabel();
    JPanel jPanel5 = new JPanel();
    JPanel jTreePanel = new JPanel();
    BorderLayout borderLayout5 = new BorderLayout();
    BorderLayout borderLayout6 = new BorderLayout();
    TitledBorder titledBorder1;
    TitledBorder titledBorder2;
    Border border1;
    Border border2;

    JPanel jPanel7 = new JPanel();
    BorderLayout borderLayout7 = new BorderLayout();
    JLabel jLabel3 = new JLabel();
    JScrollPane jWorkPane = null;
    JScrollPane jLevelTreePane = null;
    JScrollPane jGraphListPane = new JScrollPane();

    JComboBox jComboBox1 = new JComboBox();
    FlowLayout flowLayout1 = new FlowLayout();
    JComboBox jComboBox2 = new JComboBox();
    JLabel jLabel4 = new JLabel();
    JComboBox jComboBox3 = new JComboBox();
    JLabel jLabel5 = new JLabel();

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

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

    /**
     * the class constructor
     */
    public UIMainFrame() {
	enableEvents(AWTEvent.WINDOW_EVENT_MASK);
	try  {
	    jbInit();
	    checkMenu();
	    CData.loadOptions();
	}
	catch(Exception e) {
	    e.printStackTrace();
	}
    }

    /**
     * add a new level to the search levels 
     * 
     * @param new_level_a the new level to be added
     */
    public void addLevel(SearchLevel new_level_a) {
	
	// create an new tab page for this level
	//
	jTabbedPaneLeft.addTab(new_level_a.level_name_d, 
			       new_level_a.jGraphPane);
	
    }

    /**
     * inserts a new level to the search levels at index
     * 
     * @param new_level_a the new level to be added
     * @param index_a index for level to be inserted
     */
    public void insertLevel(SearchLevel new_level_a, int index_a) {
	
	// create an new tab page for this level
	//
	jTabbedPaneLeft.insertTab(new_level_a.level_name_d, 
			       null,
			       new_level_a.jGraphPane, 
			       new_level_a.level_name_d,
			       index_a);
	
    }

    /**
     * pre Component initialization
     * 
     */
    private void jbPreInit() throws Exception  {

	// init the level tree
	//
	DefaultMutableTreeNode root 
	    = new DefaultMutableTreeNode(CData.LEVEL_TREE_ROOT_NAME);

	jLevelTree = new JTree(root );
	jLevelTree.addTreeSelectionListener(this);

	// add the cell editor listener
	//
	jLevelTree.setCellEditor(new 
	    javax.swing.tree.
	    DefaultTreeCellEditor(jLevelTree, new DefaultTreeCellRenderer()));

	jLevelTree.getCellEditor().addCellEditorListener(this);

	// set the tree itself
	//
	jLevelTree.setEditable(true);
	jLevelTree.getSelectionModel().
	    setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
	jLevelTree.setShowsRootHandles(true);
	
	// set the panel for the tree of levels
	//
	jLevelTreePane 
	    = new JScrollPane(jLevelTree, 
			      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
			      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
	jLevelTreePane.setPreferredSize(new Dimension(400, 500));

	// set the table of list of graph names
	//
	jGraphListPane.getViewport().add(jGraphList);

	// init the scrollPane, the workarea is in this pane
	//
	jWorkPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				    JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
	jWorkPane.getViewport().add(CData.work_area_d);
	CData.work_area_d.revalidate();
	CData.work_area_d.setPreferredSize(new Dimension(CData.WORKAREA_WIDTH,
							 CData.WORKAREA_HEIGHT));	
	CData.work_area_d.addMouseListener(CData.event_handler_d);
	CData.work_area_d.addMouseMotionListener(CData.event_handler_d);

	// init data
	//
	CData.curr_graph_d = new DiGraph();
	CData.work_area_d.setDiGraph(CData.curr_graph_d);
    }

    /**
     * initialize the menus
     * 
     * @param none
     * @return void
     */
    private void initMenu() throws Exception  {

	// menu bar, top level
	//
	jMenuBarMain.add(jMenuFile);
	jMenuBarMain.add(jMenuEdit);
	jMenuBarMain.add(jMenuH);
	jMenuBarMain.add(jMenuGrammar);
	jMenuBarMain.add(Box.createHorizontalGlue());
	jMenuBarMain.add(jMenuHelp);
	this.setJMenuBar(jMenuBarMain);

	// menu File
	//
	jMenuFile.setText("File");

	jMenuFileNew.setText("New");
	jMenuFileOpen.setText("Open");
	jMenuFileSave.setText("Save");
	jMenuFileSaveAs.setText("Save As");
	jMenuFileSaveAll.setText("Save All");
	jMenuFileClose.setText("Close");
	jMenuFileExit.setText("Exit");

	jMenuFileNew.setActionCommand(CData.AM_FILE_NEW);
	jMenuFileOpen.setActionCommand(CData.AM_FILE_OPEN);
	jMenuFileSave.setActionCommand(CData.AM_FILE_SAVE);
	jMenuFileSaveAs.setActionCommand(CData.AM_FILE_SAVE_AS);
	jMenuFileSaveAll.setActionCommand(CData.AM_FILE_SAVE_ALL);
	jMenuFileClose.setActionCommand(CData.AM_FILE_CLOSE);
	jMenuFileExit.setActionCommand(CData.AM_FILE_EXIT);

	jMenuFile.add(jMenuFileNew);
	jMenuFile.add(jMenuFileOpen);
	jMenuFile.add(jMenuFileSave);
	jMenuFile.add(jMenuFileSaveAs);
	jMenuFile.add(jMenuFileSaveAll);

	jMenuFile.addSeparator();
	//jMenuFile.addSeparator();

	jMenuFile.add(jMenuFileClose);
	jMenuFile.add(jMenuFileExit);
	
	jMenuFileNew.addActionListener(CData.event_handler_d);
	jMenuFileOpen.addActionListener(CData.event_handler_d);
	jMenuFileSave.addActionListener(CData.event_handler_d);
	jMenuFileSaveAs.addActionListener(CData.event_handler_d);
	jMenuFileClose.addActionListener(CData.event_handler_d);
	jMenuFileSaveAll.addActionListener(CData.event_handler_d);
	jMenuFileExit.addActionListener(CData.event_handler_d);

	// menu edit
	//
	jMenuEdit.setText("Edit");
	
	jMenuEditCopy.setText("Copy");
	jMenuEditCut.setText("Cut");
	jMenuEditPaste.setText("Paste");
	jMenuEditDelete.setText("Delete");
	
	jMenuEditCopy.setActionCommand(CData.AM_GRAMMAR_COPY);
	jMenuEditCut.setActionCommand(CData.AM_GRAMMAR_CUT);
	jMenuEditPaste.setActionCommand(CData.AM_GRAMMAR_PASTE);
	jMenuEditDelete.setActionCommand(CData.AM_GRAMMAR_DELETE);
	
	jMenuEdit.add(jMenuEditCopy);
	jMenuEdit.add(jMenuEditCut);
	jMenuEdit.add(jMenuEditPaste);
	jMenuEdit.add(jMenuEditDelete);

	jMenuEditCopy.addActionListener(CData.event_handler_d);
	jMenuEditCut.addActionListener(CData.event_handler_d);
	jMenuEditPaste.addActionListener(CData.event_handler_d);
	jMenuEditDelete.addActionListener(CData.event_handler_d);

	// set the accelerator
	//
	jMenuEditDelete.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0));
	jMenuEditCopy.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
						  ActionEvent.CTRL_MASK));
	jMenuEditCut.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
						  ActionEvent.CTRL_MASK));
	jMenuEditPaste.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
						  ActionEvent.CTRL_MASK));

	// menu Grammar
	//
	jMenuGrammar.setText("Graph");

	jMenuGrammarInsertStart.setText("Insert Start");
	jMenuGrammarInsertStop.setText("Insert Stop");
	jMenuGrammarInsertNode.setText("Insert Node");
	jMenuGrammarInsertArc.setText("Insert Arc");
	jMenuGrammarInsertSelfArc.setText("Insert Self Arc");

	jMenuGrammarCopyGraph.setText("Copy Graph");
	jMenuGrammarPasteGraph.setText("Paste Graph");
	jMenuGrammarAddGraph.setText("Add Graph");
	jMenuGrammarDeleteGraph.setText("Delete Graph");
	jMenuGrammarWeightGraph.setText("Set Equal Weights");

	jMenuGrammarInsertStart.setActionCommand(CData.AM_GRAMMAR_INSERT_START);
	jMenuGrammarInsertStop.setActionCommand(CData.AM_GRAMMAR_INSERT_STOP);
	jMenuGrammarInsertNode.setActionCommand(CData.AM_GRAMMAR_INSERT_NODE);
	jMenuGrammarInsertArc.setActionCommand(CData.AM_GRAMMAR_INSERT_ARC);
	jMenuGrammarInsertSelfArc.setActionCommand(CData.AM_GRAMMAR_INSERT_SELF_ARC);

	jMenuGrammarCopyGraph.setActionCommand(CData.AM_GRAMMAR_COPY_GRAPH);
	jMenuGrammarPasteGraph.setActionCommand(CData.AM_GRAMMAR_PASTE_GRAPH);
	jMenuGrammarAddGraph.setActionCommand(CData.AM_GRAMMAR_ADD_GRAPH);
	jMenuGrammarDeleteGraph.setActionCommand(CData.AM_GRAMMAR_DELETE_GRAPH);
	jMenuGrammarWeightGraph.setActionCommand(CData.AM_GRAMMAR_WEIGHT_GRAPH);

	jMenuGrammar.add(jMenuGrammarInsertStart);
	jMenuGrammar.add(jMenuGrammarInsertStop);
	jMenuGrammar.add(jMenuGrammarInsertNode);

	jMenuGrammar.addSeparator();
	jMenuGrammar.add(jMenuGrammarInsertArc);
	jMenuGrammar.add(jMenuGrammarInsertSelfArc);


	jMenuGrammar.addSeparator();
	jMenuGrammar.add(jMenuGrammarAddGraph);
	jMenuGrammar.add(jMenuGrammarDeleteGraph);
	jMenuGrammar.add(jMenuGrammarCopyGraph);
	jMenuGrammar.add(jMenuGrammarPasteGraph);
	jMenuGrammar.add(jMenuGrammarWeightGraph);

	jMenuGrammarInsertStart.addActionListener(CData.event_handler_d);
	jMenuGrammarInsertStop.addActionListener(CData.event_handler_d);
	jMenuGrammarInsertNode.addActionListener(CData.event_handler_d);
	jMenuGrammarInsertArc.addActionListener(CData.event_handler_d);
	jMenuGrammarInsertSelfArc.addActionListener(CData.event_handler_d);

	jMenuGrammarCopyGraph.addActionListener(CData.event_handler_d);
	jMenuGrammarPasteGraph.addActionListener(CData.event_handler_d);
	jMenuGrammarAddGraph.addActionListener(CData.event_handler_d);
	jMenuGrammarDeleteGraph.addActionListener(CData.event_handler_d);
	jMenuGrammarWeightGraph.addActionListener(CData.event_handler_d);
	
	// set the accelerator
	//
	jMenuGrammarInsertArc.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I,
						  ActionEvent.ALT_MASK));
	jMenuGrammarInsertSelfArc.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
						  ActionEvent.ALT_MASK));
	jMenuGrammarCopyGraph.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
						  ActionEvent.ALT_MASK));
	jMenuGrammarPasteGraph.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
						  ActionEvent.ALT_MASK));
	jMenuGrammarAddGraph.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,
						  ActionEvent.ALT_MASK));
	jMenuGrammarDeleteGraph.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D,
						  ActionEvent.ALT_MASK));
	jMenuGrammarWeightGraph.
	    setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
						  ActionEvent.ALT_MASK));

	// menus for the Hiearchical Levels
	//
	jMenuH.setText("Hierarchy");

	jMenuHAddLevel.setText("Add Level");
	jMenuHDeleteLevel.setText("Delete Level");
	jMenuHCheckLevel.setText("Check Levels");
	jMenuHSymbols.setText("Symbols");


	jMenuHAddLevel.setActionCommand(CData.AM_H_ADD_LEVEL);
	jMenuHDeleteLevel.setActionCommand(CData.AM_H_DELETE_LEVEL);
	jMenuHCheckLevel.setActionCommand(CData.AM_H_CHECK_LEVEL);

	jMenuHAddGraph.setActionCommand(CData.AM_H_ADD_GRAPH);
	jMenuHDeleteGraph.setActionCommand(CData.AM_H_DELETE_GRAPH);

	jMenuHSymbols.setActionCommand(CData.AM_H_SYMBOLS);

	jMenuH.add(jMenuHAddLevel);
	jMenuH.add(jMenuHDeleteLevel);
	jMenuH.add(jMenuHCheckLevel);
	jMenuH.addSeparator();
	//jMenuH.add(jMenuHAddGraph);
	//jMenuH.add(jMenuHDeleteGraph);
	//jMenuH.addSeparator();
	jMenuH.add(jMenuHSymbols);

	jMenuHAddLevel.addActionListener(CData.event_handler_d);
	jMenuHDeleteLevel.addActionListener(CData.event_handler_d);
	jMenuHCheckLevel.addActionListener(CData.event_handler_d);

	jMenuHAddGraph.addActionListener(CData.event_handler_d);
	jMenuHDeleteGraph.addActionListener(CData.event_handler_d);

	jMenuHSymbols.addActionListener(CData.event_handler_d);
	
	// menu help
	//
	jMenuHelp.setText("Help");

	jMenuHelpAbout.setText("About");
	jMenuHelpAbout.setActionCommand(CData.AM_HELP_ABOUT);
	jMenuHelpAbout.addActionListener(CData.event_handler_d);
	jMenuHelp.add(jMenuHelpAbout);

    }

    /**
     * Component initialization
     * 
     * @return void
     */
    private void jbInit() throws Exception  {

	// special init forward
	//
	jbPreInit();
	CData.init();
      
	// init the menu
	//
	initMenu();

	titledBorder1 = new TitledBorder("");
	titledBorder2 = new TitledBorder("");
	border1 = BorderFactory.createEmptyBorder();
	border2 = BorderFactory.createEmptyBorder();
	this.getContentPane().setLayout(borderLayout1);
	this.setSize(new Dimension(800, 600));
	this.setTitle("Network Builder");
	statusBar.setText(" ");

	jPanel1.setLayout(borderLayout2);
	jSplitPane1.setLastDividerLocation(200);
	jSplitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT);
	jSplitPane2.setLeftComponent(null);
	jSplitPane2.setTopComponent(jPanel3);
	jPanel3.setLayout(borderLayout3);
	jListPanel.setLayout(borderLayout4);
	jLabel1.setBorder(BorderFactory.createEtchedBorder());
	jLabel1.setText("Hierarchy");
	jLabel2.setBorder(BorderFactory.createEtchedBorder());
	jLabel2.setText("Graph List");
	jPanel5.setLayout(borderLayout5);
	jTreePanel.setLayout(borderLayout6);

	jPanel3.setBorder(BorderFactory.createLineBorder(Color.black));
	jListPanel.setBorder(BorderFactory.createLineBorder(Color.black));

	jGraphPane.setLayout(borderLayout7);
	jLabel3.setPreferredSize(new Dimension(80, 24));
	jLabel3.setText("Model Name");
	jPanel7.setLayout(flowLayout1);
	jComboBox1.setMaximumSize(new Dimension(80, 24));
	jComboBox1.setMinimumSize(new Dimension(80, 24));
	jComboBox1.setPreferredSize(new Dimension(100, 24));
	jComboBox2.setPreferredSize(new Dimension(100, 24));
	jComboBox2.setMinimumSize(new Dimension(80, 24));
	jComboBox2.setMaximumSize(new Dimension(80, 24));
	jLabel4.setText("Level");
	jLabel4.setPreferredSize(new Dimension(60, 24));
	jComboBox3.setPreferredSize(new Dimension(100, 24));
	jComboBox3.setMinimumSize(new Dimension(80, 24));
	jComboBox3.setMaximumSize(new Dimension(80, 24));
	jLabel5.setText("Model Type");
	jLabel5.setPreferredSize(new Dimension(80, 24));
	jWorkPane.setBackground(Color.white);
	jWorkPane.setBorder(BorderFactory.createEtchedBorder());
	jPanel7.setBorder(BorderFactory.createEtchedBorder());

	this.getContentPane().add(statusBar, BorderLayout.EAST);
	this.getContentPane().add(jPanel1, BorderLayout.CENTER);

	jPanel1.add(jSplitPane1, BorderLayout.CENTER);
	jSplitPane1.add(jSplitPane2, JSplitPane.TOP);
	jSplitPane2.add(jPanel3, JSplitPane.TOP);
	jPanel3.add(jPanel5, BorderLayout.NORTH);
	jPanel5.add(jLabel1, BorderLayout.CENTER);
	jPanel3.add(jTreePanel, BorderLayout.CENTER);
	jTreePanel.add(jLevelTreePane, BorderLayout.CENTER);
	jSplitPane2.add(jListPanel, JSplitPane.BOTTOM);
	jListPanel.add(jGraphListPane, BorderLayout.CENTER);
	jListPanel.add(jLabel2, BorderLayout.NORTH);

	jSplitPane1.add(jTabbedPaneLeft, JSplitPane.BOTTOM);
	
	// create an empty graph
	//
	jTabbedPaneLeft.addChangeListener(this);
	//jTabbedPaneLeft.addTab("Graph", jGraphPane);

	//jTabbedPaneLeft.addTab("Symbol", jSymbolPane);

	jPanel7.add(jLabel4, null);
	jPanel7.add(jComboBox2, null);
	jPanel7.add(jLabel3, null);
	jPanel7.add(jComboBox1, null);
	jPanel7.add(jLabel5, null);
	jPanel7.add(jComboBox3, null);
	jGraphPane.add(jWorkPane, BorderLayout.CENTER);

	jSplitPane1.setDividerLocation(200);
	jSplitPane2.setDividerLocation(250);

	// set the action listener
	//
	ListSelectionModel model = jGraphList.getSelectionModel();
	model.addListSelectionListener(this);
	updateAll();
    }

    /**
     * this function update all interface when level/graph is changed
     * 
     * @param e a window event
      */
    protected void processWindowEvent(WindowEvent e) {
	super.processWindowEvent(e);
	if(e.getID() == WindowEvent.WINDOW_CLOSING) {
	    CData.event_handler_d.fileExit_actionPerformed(null);
	}
    }

    /**
     * this function update all interface when level/graph is changed
     * 
     */
    public void updateAll() {

	updating_d = true;

	SearchLevel curr_level = 	    
	    (SearchLevel)CData.getCurrLevel();

	if ( curr_level != null ){
	    curr_level.sortSymbols();
	}

	// set the tree for levels
	//
	DefaultTreeModel model = (DefaultTreeModel)jLevelTree.getModel();
	DefaultMutableTreeNode  root = 
	    (DefaultMutableTreeNode)jLevelTree.getModel().getRoot();

	// remove all children
	//
	root.removeAllChildren();

	for (int i = 0 ; i < CData.search_levels_d.size(); i++){
	    curr_level = (SearchLevel)CData.search_levels_d.get(i);
	    root.add(new DefaultMutableTreeNode(curr_level.level_name_d));

	}
	model.reload();

	// set the tree selection
	//
	if ( CData.curr_level_index_d >= 0 ){
	    // set the tree selection
	    //
	    TreePath curr_path = 
		new TreePath(((DefaultMutableTreeNode)
			      root.getChildAt(CData.curr_level_index_d)).getPath());
	    
	    jLevelTree.setSelectionPath(curr_path);

	}

	// set to current level
	//
	curr_level = (SearchLevel)CData.getCurrLevel();

	int level_index =  CData.curr_level_index_d;
	
	// set the symbol list ( graph name list )
	//
	if ( CData.curr_level_index_d > 0 &&
	     curr_level.graph_names_d.size() == 0 ){
	    if ( CData.getLevel(level_index - 1).contexts_d.size() > 0 ){
		curr_level.graph_names_d = 
		    CData.getLevel(level_index - 1).contexts_d;
	    }
	    else {
		curr_level.graph_names_d = 
		    CData.getLevel(level_index - 1).symbols_d;
	    }
	}
	
	// set graph names , these names will be displayed in
	// the graph list
	//
	if ( curr_level != null ){
	    level_graphs_d = curr_level.graph_names_d;
	}

	graphs_in_level_d.fireTableDataChanged();

	// clear all levels
	//
	//jTabbedPaneLeft.removeAll();

	// set the labels
	//
	for ( int i = 0 ; i < CData.search_levels_d.size(); i ++ ){
	    SearchLevel level = (SearchLevel)CData.search_levels_d.get(i);
	    //jTabbedPaneLeft.addTab(level.level_name_d, 
	    //		   level.jGraphPane);
	    jTabbedPaneLeft.setTitleAt(i, level.level_name_d);	    
	}
	
	// set the graph in the work area
	//
	if ( curr_level != null){

	    // find the panel first
	    //
	    int i = jTabbedPaneLeft.
		indexOfComponent(curr_level.jGraphPane);

	    // set current work pane
	    //
	    jTabbedPaneLeft.setSelectedIndex(i);
	    //jWorkPane = curr_level.jWorkPane;

	    // set the graph and workarea
	    //
	    if (curr_level.graph_names_d.size() > CData.curr_graph_index_d ){
		
		CData.printDebugMsg("current level index:" 
				   + CData.curr_level_index_d);
		CData.printDebugMsg("current graph index:" 
				   + CData.curr_graph_index_d);

		String graph_name = (String) 
		    curr_level.graph_names_d.get(CData.curr_graph_index_d);

		CData.printDebugMsg("curr graph name: " + graph_name);

		// set current graph
		//
		CData.curr_graph_d = 
		    (DiGraph)curr_level.graphs_d.get(graph_name);
		
		if ( CData.curr_graph_d == null ){
		    CData.printDebugMsg("create new graph for: " + graph_name);
		    CData.curr_graph_d = new DiGraph();
		    curr_level.graphs_d.put(graph_name, CData.curr_graph_d);
		}
		
		// set current work area
		//
		//jWorkPane.getViewport().removeAll();

		// set the graph, the work area
		//
		CData.work_area_d.setDiGraph(CData.curr_graph_d);
		//jWorkPane.getViewport().add(CData.work_area_d);

		// insert all vertices into the work area
		//
		CData.work_area_d.insertAll();
		//CData.work_area_d.repaint();
		CData.work_area_d.revalidate();

		// set the selection
		//
		jGraphList.changeSelection(CData.curr_graph_index_d, 0,
				       false,false);
		curr_level.setWorkArea(CData.work_area_d);
	    }
	}
	else {
	    CData.curr_graph_d = null;
	    CData.work_area_d.setDiGraph(null);
	}

	// set the global symbol table
	//
	if (CData.symbol_dlg_d != null){
	    CData.event_handler_d.showSymbolsDlg();
	}
	CData.event_handler_d.resetFocus();

	//jWorkPane.setPreferredSize(new Dimension(1, 1));	
	//jWorkPane.setViewportView(CData.work_area_d);
	//CData.work_area_d.setPreferredSize(new Dimension(6, 10));	
	//CData.work_area_d.revalidate();
	//jWorkPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
	//jWorkPane.revalidate();
	//jWorkPane.repaint();
	//CData.work_area_d.setPreferredSize(new Dimension(600, 1000));	
	//CData.work_area_d.revalidate();
	//CData.work_area_d.repaint();
	//jTabbedPaneLeft.repaint();

	updating_d = false;
    }
    
    /**
     * handle the event the tabbed pane changed
     * 
     * @param e the mouse event
     */
    public void editingStopped(ChangeEvent e) {

	CData.printDebugMsg("editingStopped");

	if ( updating_d ){
	    return;
	}
	
	// set the tree for levels
	//
	DefaultTreeModel model = (DefaultTreeModel)jLevelTree.getModel();
	DefaultMutableTreeNode  root = 
	    (DefaultMutableTreeNode)jLevelTree.getModel().getRoot();

	DefaultMutableTreeNode  selectedNode = 
	    (DefaultMutableTreeNode)jLevelTree.getLastSelectedPathComponent();
	if ( selectedNode == root || selectedNode == null ){
	    return;
	}

	// set previous value to search level
	//
	for ( int i = 0; i < root.getChildCount(); i++ ){
	    DefaultMutableTreeNode curr_node = 
		(DefaultMutableTreeNode)root.getChildAt(i);
	    String level_name = (String)curr_node.getUserObject();
	    CData.getLevel(i).level_name_d = level_name;
	}

	// update all
	//
	updateAll();
    }
    
    /**
     * empty implementation
     * 
     * @param e the change event
     */
    public void editingCanceled(ChangeEvent e) {
	
	return;
    }
    
    /**
     * updates data upon a state changed event
     * 
     * @param e the change event
     */
    public void stateChanged(ChangeEvent e) {
	
	if ( updating_d ){
	    return;
	}
	
	// set correct level and graph
	//
	CData.curr_graph_index_d = 0;
	//CData.curr_level_index_d = 0;
        CData.curr_level_index_d = jTabbedPaneLeft.getSelectedIndex();
	updateAll();
    }
    
    /**
     * updates data when a value is changed
     * 
     * @param e the list selection even
     */
    public void valueChanged(ListSelectionEvent e) {
	
	if ( updating_d ){
	    return;
	}
	
	// if  the user click on the symbol list
	//
	int i = jGraphList.getSelectedRow();
	int j = jGraphList.getSelectedColumn();
	
	if ( i >= 0 && j >= 0 ){
	    String selected_string = (String)jGraphList.getValueAt(i,j);
	    
	    CData.curr_graph_index_d = 
		CData.getCurrLevel().graph_names_d.indexOf(selected_string);
	    updateAll();
	}
    }
    
    /**
     * checks the menu 
     * 
     */
    public void checkMenu() {

	// check the menu options
	//
	jMenuGrammarInsertStart.setEnabled(true);		    
	jMenuGrammarInsertStop.setEnabled(true);		    
	jMenuHSymbols.setEnabled(true);
	jMenuGrammar.setEnabled(true);

	if ( CData.curr_graph_d == null ){
	    jMenuGrammar.setEnabled(false);
	}
	else {
	    if ( CData.curr_graph_d.hasStart() ){
		jMenuGrammarInsertStart.setEnabled(false);		    
	    }
	    if ( CData.curr_graph_d.hasTerm() ){
		jMenuGrammarInsertStop.setEnabled(false);		    
	    }
	}
	
	if ( CData.search_levels_d == null ){
	    jMenuHSymbols.setEnabled(false);
	}
	else if ( CData.search_levels_d.size() == 0 ){
	    jMenuHSymbols.setEnabled(false);
	}
    }

    /**
     * handle the tree selection event when a value is changed
     * 
     * @param e tree selection event
     */
    public void valueChanged(TreeSelectionEvent e) {
	
	if ( updating_d ){
	    return;
	}

	DefaultMutableTreeNode  root = 
	    (DefaultMutableTreeNode)jLevelTree.getModel().getRoot();
	DefaultMutableTreeNode  selectedNode = 
	    (DefaultMutableTreeNode)jLevelTree.getLastSelectedPathComponent();
	if ( selectedNode != root && selectedNode != null ){
	    CData.curr_level_index_d = 
		((DefaultMutableTreeNode)selectedNode.getParent()).
		getIndex(selectedNode);
	    CData.curr_graph_index_d = 0;
	    jGraphList.editingCanceled(new ChangeEvent(this));
	    updateAll();
	}
    }

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

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

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

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

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

        public void setValueAt(Object aValue, int row, int col) {
	    SearchLevel curr_level = 	    
		(SearchLevel)CData.getCurrLevel();
	    String curr_name = (String)level_graphs_d.get(row);
	    String new_name = aValue.toString();

	    if ( curr_level.graphs_d.containsKey(new_name) ){
		return;
	    }

	    CData.curr_graph_d = 
		(DiGraph)CData.getCurrLevel().graphs_d.get(curr_name);
		
	    if ( CData.curr_graph_d == null ){
		CData.curr_graph_d = new DiGraph();
	    }
	    curr_level.graphs_d.put(new_name, CData.curr_graph_d);
	    curr_level.graphs_d.remove(curr_name);
		
	    level_graphs_d.set(row, aValue.toString());
        }

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

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













