/*
 * @(#) EventHandler.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 package
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.io.*;
import java.lang.*;
import java.util.*;

/**
 * This class is designed to handle all events
 * 
 */
public class EventHandler implements ActionListener, 
				     MouseListener,
				     MouseMotionListener{

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

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

    /**
     * data member about current status
     */
    protected String curr_am_string_d = CData.AM_NONE;
    public Vertex curr_vertex_focus_d = null;
    public Vertex curr_vertex_copy_d = null;
    public GraphArc curr_arc_focus_d = null;

    public DiGraph curr_graph_copy_d = null;

    /**
     * mouse positions
     */
    protected int mouse_x_d = 0;
    protected int mouse_y_d = 0;

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

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

    /**
     * resets the focus to 0 value
     * 
     */
    public void resetFocus() {

	curr_am_string_d = CData.AM_NONE;
	curr_vertex_focus_d = null;
	curr_arc_focus_d = null;
    }

    /**
     * handle the event when a command is issued
     * 
     * @param e the event
     */
    public void actionPerformed(ActionEvent e) {
	
	// check the menu first
	//
	CData.main_frame_d.checkMenu();

	//System.out.println(e.getSource().getClass().getName());

	// branches on the action command
	//
	/*
	if (e.getSource().getClass().getName().equals("JFileChooser")) {
	    System.out.println("file chooser");
	}
	*/

	CData.io_d.clear();

	// file menu
	//
	if ( e.getActionCommand().equals(CData.AM_FILE_EXIT) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    fileExit_actionPerformed(e);
	}
	if ( e.getActionCommand().equals(CData.AM_FILE_SAVE) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    CData.store2(false, false);
	}
	if ( e.getActionCommand().equals(CData.AM_FILE_SAVE_AS) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    CData.store2(true, false);
	}
	if ( e.getActionCommand().equals(CData.AM_FILE_SAVE_ALL) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    showSaveAllDlg();
	}
	if ( e.getActionCommand().equals(CData.AM_FILE_OPEN) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    CData.load(false);
	}
	if ( e.getActionCommand().equals(CData.AM_FILE_NEW) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    CData.newModel(true);
	}
	if ( e.getActionCommand().equals(CData.AM_FILE_CLOSE) ){
	    curr_am_string_d = CData.AM_FILE_EXIT;
	    CData.newModel(false);
	}
	if ( e.getActionCommand().equals(CData.AM_HELP_ABOUT) ){
	    curr_am_string_d = CData.AM_HELP_ABOUT;
	    helpAbout_actionPerformed(e);
	}

	// grammar menu
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_INSERT_START) ){
	    if ( CData.curr_graph_d == null )
		return;
	    curr_am_string_d = CData.AM_GRAMMAR_INSERT_START;
	    grammarInsertStart_actionPerformed(e);
	}

	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_INSERT_STOP) ){
	    if ( CData.curr_graph_d == null )
		return;
	    curr_am_string_d = CData.AM_GRAMMAR_INSERT_STOP;
	    grammarInsertStart_actionPerformed(e);
	}

	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_INSERT_NODE) ){
	    if ( CData.curr_graph_d == null )
		return;
	    curr_am_string_d = CData.AM_GRAMMAR_INSERT_NODE;
	    grammarInsertStart_actionPerformed(e);
	}
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_INSERT_ARC) ){
	    curr_am_string_d = CData.AM_GRAMMAR_INSERT_ARC;
	    grammarInsertStart_actionPerformed(e);
	}
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_INSERT_SELF_ARC) ){
	    curr_am_string_d = CData.AM_GRAMMAR_INSERT_SELF_ARC;
	    grammarInsertStart_actionPerformed(e);
	}
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_CUT) ){
	    curr_am_string_d = CData.AM_GRAMMAR_CUT;
	    curr_vertex_copy_d = new Vertex(curr_vertex_focus_d);
	    CData.curr_graph_d.removeVertex(curr_vertex_focus_d);
	    curr_vertex_focus_d = null;
	    curr_am_string_d = CData.AM_NONE;
	}
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_COPY) ){
	    
	    if ( curr_vertex_focus_d == null ){
		return;
	    }
	    curr_am_string_d = CData.AM_GRAMMAR_COPY;
	    curr_vertex_copy_d = new Vertex(curr_vertex_focus_d);
	    curr_am_string_d = CData.AM_NONE;
	}
	// paste a node
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_PASTE) ){
	    if ( curr_vertex_copy_d == null ){
		return;
	    }
	    curr_am_string_d = CData.AM_GRAMMAR_PASTE;
	    //Point location = curr_vertex_copy_d.getVertexLocation();
	    Point location = curr_vertex_copy_d.getLocation();
	    location.x += 15;
	    location.y += 15;
	    Vertex paste_vertex = new Vertex(curr_vertex_copy_d);
	    CData.work_area_d.insertVertexAt( paste_vertex, 
					   location);
	    CData.curr_graph_d.insertVertex(paste_vertex);
	    //curr_vertex_focus_d = null;
	    curr_am_string_d = CData.AM_NONE;
	}
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_DELETE) ){
	    if ( curr_vertex_focus_d != null ){
		CData.curr_graph_d.removeVertex(curr_vertex_focus_d);
	    }
	    if ( curr_arc_focus_d != null ){
		CData.curr_graph_d.removeArc(curr_arc_focus_d);
	    }
	    curr_vertex_focus_d = null;
	    curr_arc_focus_d = null;
	    curr_am_string_d = CData.AM_NONE;
	}
	
	// add a graph
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_ADD_GRAPH) ){
	    
	    SearchLevel curr_level = 	    
		(SearchLevel)CData.getCurrLevel();
	    String new_name = curr_level.createGraphName();
            
	    CData.curr_graph_index_d = 0;
	    curr_level.graph_names_d.insertElementAt(new_name, 0);
	    curr_am_string_d = CData.AM_NONE;
 	    CData.main_frame_d.updateAll();
	     
}

	// delete a graph
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_DELETE_GRAPH) ){
	    
	    SearchLevel curr_level = 	    
		(SearchLevel)CData.getCurrLevel();
	    //System.out.println(curr_level);
	    String curr_name = 
		(String)curr_level.graph_names_d.get(CData.curr_graph_index_d);
	    //System.out.println(curr_name);
	    curr_level.graphs_d.remove(curr_name);
	    curr_level.graph_names_d.remove(curr_name);
	    CData.curr_graph_index_d --;

	    if ( CData.curr_graph_index_d < 0 ){
		CData.curr_graph_index_d = 0;
	    }

	    curr_am_string_d = CData.AM_NONE;
	    CData.main_frame_d.updateAll();
	}

	// copy a graph
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_COPY_GRAPH) ){
	    
	    if ( CData.curr_graph_d == null ){
		return;
	    }
	    //System.out.println("copy a graph");
	    curr_graph_copy_d = new DiGraph(CData.curr_graph_d);
	    curr_am_string_d = CData.AM_NONE;
	}

	// paste a graph
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_PASTE_GRAPH) ){
	    if ( curr_graph_copy_d == null ){
		return;
	    }
	    String graph_name = (String) 
		CData.getCurrLevel().graph_names_d.
		get(CData.curr_graph_index_d);

	    //System.out.println("paste a graph");
	    // set current graph
	    //
	    CData.curr_graph_d = new DiGraph(curr_graph_copy_d);
	    CData.getCurrLevel().graphs_d.put(graph_name, CData.curr_graph_d);
	    //curr_vertex_focus_d = null;
	    curr_am_string_d = CData.AM_NONE;
	    CData.main_frame_d.updateAll();
	}

	// weight a graph
	//
	if ( e.getActionCommand().equals(CData.AM_GRAMMAR_WEIGHT_GRAPH) ){
	    if ( CData.curr_graph_d == null ){
		return;
	    }
	    CData.curr_graph_d.resetGraphArcWeight((float)1.0);
	}

	// hiearchy menu
	//
	if ( e.getActionCommand().equals(CData.AM_H_ADD_LEVEL) ){
	    curr_am_string_d = CData.AM_H_ADD_LEVEL;
	    CData.addLevel(CData.curr_level_index_d + 1);
	    curr_am_string_d = CData.AM_NONE;
	    CData.main_frame_d.updateAll();
	}
	if ( e.getActionCommand().equals(CData.AM_H_DELETE_LEVEL) ){
	    CData.search_levels_d.remove(CData.getCurrLevel());
	    CData.main_frame_d.jTabbedPaneLeft.
		removeTabAt(CData.curr_level_index_d);
	    curr_am_string_d = CData.AM_NONE;
	    CData.main_frame_d.updateAll();
	}
	if ( e.getActionCommand().equals(CData.AM_H_CHECK_LEVEL) ){
	    if (CData.check()){
		CData.showMessageDlg("Check", "Checking passed !");
	    }
	}
	if ( e.getActionCommand().equals(CData.AM_H_SYMBOLS) ){
	    curr_am_string_d = CData.AM_H_SYMBOLS;
	    hSymbols_actionPerformed(e);
	}
	
	// repaint the work area
	//
	CData.work_area_d.insertAll();
	CData.work_area_d.repaint();
	
	CData.removeTempFile();
    }

    /**
     * exit the application
     * 
     * @param e any event
     */
    public void fileExit_actionPerformed(ActionEvent e) {
	System.exit(0);
    }

    /**
     * Help | About action performed
     * 
     * @param e any event
     */
    private void helpAbout_actionPerformed(ActionEvent e) {
	UIMainFrame_AboutBox dlg 
	    = new UIMainFrame_AboutBox( CData.main_frame_d);
	Dimension dlgSize = dlg.getPreferredSize();
	Dimension frmSize = CData.main_frame_d.getSize();
	Point loc = CData.main_frame_d.getLocation();
	dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, 
			(frmSize.height - dlgSize.height) / 2 + loc.y);
	dlg.setModal(true);
	dlg.setVisible(true);//.show();
    }

    /**
     * Hiearchy | Symbols action performed
     * 
     * @param e any event
     */
    private void hSymbols_actionPerformed(ActionEvent e) {

	showSymbolsDlg();
    }

    /**
     * Hiearchy | Symbols action performed
     * 
     */
    public void showSymbolsDlg() {

	UISymbolDialog dlg = null;
	if (CData.symbol_dlg_d == null ){
	    CData.symbol_dlg_d = 
		new UISymbolDialog( CData.main_frame_d, "symbols", false);
	    dlg = CData.symbol_dlg_d;
	    Dimension dlgSize = dlg.getPreferredSize();
	    Dimension frmSize = CData.main_frame_d.getSize();
	    Point loc = CData.main_frame_d.getLocation();
	    dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, 
			    (frmSize.height - dlgSize.height) / 2 + loc.y);
	    dlg.setModal(false);
	
	}

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

	// dlg.level_symbols_d = (Vector)curr_level.symbols_d.clone();
	//
	dlg.level_symbols_d = curr_level.symbols_d;

	dlg.level_name_d = new String (curr_level.level_name_d);
	dlg.initAll();
	dlg.setVisible(true);//.show();
    }

    /**
     * Hiearchy | Symbols action performed
     * 
     */
    public void showSaveAllDlg() {

	UISaveAllDialog dlg = 
	    new UISaveAllDialog( CData.main_frame_d, "SaveAlls", false);
	Dimension dlgSize = dlg.getPreferredSize();
	Dimension frmSize = CData.main_frame_d.getSize();
	Point loc = CData.main_frame_d.getLocation();
	dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, 
			(frmSize.height - dlgSize.height) / 2 + loc.y);
	dlg.setModal(true);
	dlg.initAll();
	dlg.setVisible(true);//.show();
    }

    /**
     * Grammar | Insert Start
     * 
     * @param e the action event
     */
    private void grammarInsertStart_actionPerformed(ActionEvent e) {
	
	// Create an instance of java.awt.Cursor
	//
	Cursor c = new Cursor ( Cursor.HAND_CURSOR );

	// Set cursor for the work area
	//
	CData.work_area_d.setCursor(c);

	// then waiting for the mouse left-click on the work area
    }

    /**
     * handle the event when mouse is clicked
     * 
     * @param e the mouse event
     */
    public void mousePressed(MouseEvent e) {

	// declare local variables
	//

	// restore the shape of the mouse
	//
	Cursor c = new Cursor ( Cursor.DEFAULT_CURSOR );
	CData.work_area_d.setCursor(c);
	//System.out.println("mouse clicked");

	// did the user click on the WorkArea with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("WorkArea")) {
	    //System.out.println("workarea clicked");
	    if (CData.work_area_d.digraph_d == CData.curr_graph_d) {
		if (SwingUtilities.isLeftMouseButton(e)) {
		    workAreaLMClicked(e);
		}
		if (SwingUtilities.isRightMouseButton(e)) {
		    //CData.printDebugMsg(new String(((WorkArea)e.getSource()).
		    //			digraph_d.vertices_d.size()));
		    workAreaRMClicked(e);
		}
	    }
	}

	// did the user click on a vertex with the right mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if(SwingUtilities.isRightMouseButton(e)) {
		//System.out.println("vertex rm clicked");
		vertexRMClicked(e);
	    }
	    if (SwingUtilities.isLeftMouseButton(e)) {	    
		//System.out.println("vertex lm clicked");
		vertexLMClicked(e);
	    }
	}
	
	// repaint the work area
	//
	CData.work_area_d.insertAll();
	CData.work_area_d.repaint();
    }

    /**
     * handle the event when left button of mouse is clicked
     * on the work area
     * @param e the mouse event
     */
    public void workAreaLMClicked(MouseEvent e) {
	
	// declare local variables
	//
	ImageIcon icon = null;
	int type = CData.NONE_VERTEX;
	String vertex_name;
	vertex_name = CData.START_VERTEX_NAME;

	Point location = e.getPoint();
	//DiGraph curr_graph = getCurrGraph();

	if ( CData.curr_graph_d == null ){
	    curr_am_string_d = CData.AM_NONE;
	    return;
	}

	
	// find the focus
	//
	curr_arc_focus_d = CData.curr_graph_d.findFocusGraphArc(location);
	curr_vertex_focus_d = null;
	
	if ( false ){
	    
	}
	else {
	    // insert a start node
	    //
	    if ( curr_am_string_d.equals(CData.AM_GRAMMAR_INSERT_START) ){
		icon  = new ImageIcon(CData.START_IMAGE);
		type = CData.START_VERTEX;
		vertex_name = CData.START_VERTEX_NAME;
		Vertex vertex = new Vertex(vertex_name, icon, type);
		CData.work_area_d.insertVertex(vertex, location);
		CData.curr_graph_d.insertVertex(vertex);
		curr_vertex_focus_d = vertex;
		curr_am_string_d = CData.AM_NONE;
	    }
	    // insert a stop node
	    //
	    if ( curr_am_string_d.equals(CData.AM_GRAMMAR_INSERT_STOP) ){
		icon  = new ImageIcon(CData.TERM_IMAGE);
		type = CData.TERM_VERTEX;
		vertex_name = CData.TERM_VERTEX_NAME;
		Vertex vertex = new Vertex(vertex_name, icon, type);
		CData.work_area_d.insertVertex(vertex, location);
		CData.curr_graph_d.insertVertex(vertex);
		curr_vertex_focus_d = vertex;
		curr_am_string_d = CData.AM_NONE;
	    }
	    // insert a normal node
	    //
	    if ( curr_am_string_d.equals(CData.AM_GRAMMAR_INSERT_NODE) ){
		icon  = new ImageIcon(CData.NODE_IMAGE);
		type = CData.NODE_VERTEX;
		vertex_name = CData.NODE_VERTEX_NAME;
		Vertex vertex = new Vertex(vertex_name, icon, type);
		CData.work_area_d.insertVertex(vertex, location);
		CData.curr_graph_d.insertVertex(vertex);
		curr_vertex_focus_d = vertex;
		curr_am_string_d = CData.AM_NONE;
	    }
	}

    }

    /**
     * handle the event when left button of mouse is clicked
     * on the work area
     *
     * @param e the mouse event
     */
    public void workAreaRMClicked(MouseEvent e) {
	
	// declare local variables
	//
	ImageIcon icon = null;
	int type = CData.NONE_VERTEX;
	String vertex_name;
	vertex_name = CData.START_VERTEX_NAME;

	Point location = e.getPoint();

	if ( CData.curr_graph_d == null ){
	    curr_am_string_d = CData.AM_NONE;
	    return;
	}

	// find the focus
	//
	curr_arc_focus_d = CData.curr_graph_d.findFocusGraphArc(location);

	if ( curr_arc_focus_d != null ){
	    
	    // repaint the work area
	    //
	    CData.work_area_d.repaint();
	    CData.printDebugMsg("arc selected");

	    UIArcInfo dlg 
		= new UIArcInfo( CData.main_frame_d, new String("Symbols"), 
				  true, curr_arc_focus_d);	

	    Dimension dlgSize = dlg.getPreferredSize();
	    Dimension frmSize = CData.main_frame_d.getSize();
	    Point loc = CData.main_frame_d.getLocation();
	    dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, 
			    (frmSize.height - dlgSize.height) / 2 + loc.y);
	    dlg.setVisible(true);//.show();	
	}
    }

    /**
     * handle the event when left button of mouse is clicked
     * on the vertex
     *
     * @param e the mouse event
     */
    public void vertexLMClicked(MouseEvent e) {
	
	Vertex selected_vertex = (Vertex)e.getSource();
	curr_arc_focus_d = null;

	// insert an self arc
	//
	if ( curr_am_string_d.equals(CData.AM_GRAMMAR_INSERT_SELF_ARC) ){
	    
	    curr_vertex_focus_d = selected_vertex;
	    GraphArc new_arc = new GraphArc();
	    new_arc.from_d = curr_vertex_focus_d;
	    new_arc.to_d = selected_vertex;
	    CData.curr_graph_d.insertArc(new_arc);
	    curr_am_string_d = CData.AM_NONE;
	    curr_vertex_focus_d = null;

	}
	else if (curr_am_string_d.equals(CData.AM_GRAMMAR_INSERT_ARC) &&
		 curr_vertex_focus_d != null) {

	    GraphArc new_arc = new GraphArc();
	    new_arc.from_d = curr_vertex_focus_d;
	    new_arc.to_d = selected_vertex;
	    CData.curr_graph_d.insertArc(new_arc);
	    curr_am_string_d = CData.AM_NONE;
	    curr_vertex_focus_d = null;
	}
	else if ( curr_vertex_focus_d == null ) {
	    curr_vertex_focus_d = selected_vertex;
	}
	else {
	    curr_vertex_focus_d = selected_vertex;
	}
    }

    /**
     * handle the event when right button of mouse is clicked
     * on the vertex
     *
     * @param e the mouse event
     */
    public void vertexRMClicked(MouseEvent e) {

	Vertex curr_vertex = (Vertex)e.getSource();
	if ( curr_vertex.isStart() || curr_vertex.isTerm() ){
	    return;
	} 

	UINodeInfo dlg 
	    = new UINodeInfo( CData.main_frame_d, new String("Symbols"), true);	
	dlg.setVertex(curr_vertex);

	//dlg.level_symbols_d = (Vector)CData.getCurrLevel().symbols_d.clone();
	//
	dlg.level_symbols_d = CData.getCurrLevel().symbols_d;

	Dimension dlgSize = dlg.getPreferredSize();
	Dimension frmSize = CData.main_frame_d.getSize();
	Point loc = CData.main_frame_d.getLocation();
	dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, 
			(frmSize.height - dlgSize.height) / 2 + loc.y);
	dlg.setModal(true);
	dlg.initAll();
	dlg.setVisible(true);//.show();	

	// set the vertex text
	//
	if (curr_vertex.name_d.length() > 5) {
	    curr_vertex.setText(curr_vertex.name_d.substring(0, 5));
	}
	else {
	    curr_vertex.setText(curr_vertex.name_d);
	}
    }

    /**
     * handle the event when mouse is clicked
     * 
     * @param e the mouse event
     */
    public void mouseMoved(MouseEvent e) {
	
	// update the location of the mouse coordinates
	//
	mouse_x_d = e.getX();
	mouse_y_d = e.getY();
    }

    /**
     * handle the event when mouse is clicked
     * 
     * @param e the mouse event
     */
    public void mouseClicked(MouseEvent e) {

	/*
	// did the user click on a vertex with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if (SwingUtilities.isLeftMouseButton(e)) {
		if (curr_vertex_focus_d != null) {
		    curr_vertex_focus_d.getModel().setSelected(false);
		}
		curr_vertex_focus_d = (Vertex)e.getSource();
		curr_vertex_focus_d.getModel().setSelected(true);
	    }

	}

	// repaint the work area
	//
	CData.work_area_d.repaint();
	*/
    }

    /**
     * handle the event when mouse is clicked
     * 
     * @param e the mouse event
     */
    public void mouseReleased(MouseEvent e) {
	
    }

    /**
     * handle the event when mouse is clicked
     * 
     * @param e the mouse event
     */
    public void mouseEntered(MouseEvent e) {
	
    }

    /**
     * handle the event when mouse is clicked
     * 
     * @param e the mouse event
     */
    public void mouseExited(MouseEvent e) {
	
    }

    /**
     * handle the event when mouse is dragged
     * 
     * @param e the mouse event
     */
    public void mouseDragged(MouseEvent e) {	

	// declare local variables
	//
	int xdelta = 0;
	int ydelta = 0;
	int newWidth = 0;
	int newHeight = 0;
	boolean forwardLink = false;
	boolean reverseLink = false;

	// did the user click on a vertex with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if (SwingUtilities.isLeftMouseButton(e)) {

		curr_vertex_focus_d = (Vertex)e.getSource();

		// determine the location and width of the vertex
		//
		Point loc = curr_vertex_focus_d.getLocation();
		    
		int vertexWidth = curr_vertex_focus_d.getVertexWidth();
		int vertexHeight = curr_vertex_focus_d.getVertexHeight();
		    
		int xloc = (loc.x + e.getX() - (vertexWidth / 2));
		int yloc = (loc.y + e.getY() - (vertexHeight / 2));
		    
		int xloc1 = loc.x + e.getX() + (vertexWidth / 2);
		int yloc1 = loc.y + e.getY() + (vertexHeight / 2);

		// make sure the user does not move the vertex out of
		// the work area
		//
		if ((xloc >= 0) && (yloc >= 0)) {
			
		    // determine the new width for the work area
		    //
		    if (xloc1 > CData.work_area_d.getWidth()) {
			
			xdelta = xloc1 - CData.work_area_d.getWidth();
			newWidth = CData.work_area_d.getWidth() + xdelta;
		    }
			
		    // determine the new height for the work area
		    //
		    if (yloc1 > CData.work_area_d.getHeight()) {
                            
			ydelta = yloc1 - CData.work_area_d.getHeight();
			newHeight = CData.work_area_d.getHeight() + ydelta;
		    }

		    // update the scroll bars of the work area
		    //
		    if ((xloc1 >= CData.work_area_d.getWidth()) || 
			(yloc1 >= CData.work_area_d.getHeight())) {

			// scroll the work area to the new region
			//
			Rectangle rect = new Rectangle(xloc, yloc, 
						       vertexWidth, 
						       vertexHeight);
			CData.work_area_d.scrollRectToVisible(rect);
			    
			// make sure that the width and does not
			// decrease, i.e., it does not scroll back
			//
			if (newWidth <= CData.WORKAREA_WIDTH) {
			    newWidth = CData.WORKAREA_WIDTH;
			} else {
			    CData.WORKAREA_WIDTH = newWidth;
			}
			    
			// make sure that the height and does not
			// decrease, i.e., it does not scroll back
			//
			if (newHeight <= CData.WORKAREA_HEIGHT) {
			    newHeight = CData.WORKAREA_HEIGHT;
			} else {
			    CData.WORKAREA_HEIGHT = newHeight;
			}
			    
			// update client's preferred size because the area 
			// taken up by the work area has gotten larger
			//
			CData.work_area_d.
			    setPreferredSize(new Dimension(newWidth, 
							   newHeight));
			    
			// let the scroll pane know to update itself
			// and its corresponding scroll bars
			//
			CData.work_area_d.revalidate();
		    }
			
		    // drag the vertex to the location the user specifies
		    //
			curr_vertex_focus_d.setLocation(xloc, yloc);
		}
		
		// repaint the work area
		//
		CData.work_area_d.insertAll();
		CData.work_area_d.repaint();
	    }
        }
    }
        
}// end of the class



