package graphbrowser;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.net.*;
import java.lang.Math;
import java.io.*;

import graph.*;

/* updated on Oct.1 by Qian Li to support Copy/Paste */

//import java.awt.datatransfer.*;



// *********************** GraphPanel ***********************

public class GraphPanel extends Panel implements Runnable, ActionListener, MouseListener, MouseMotionListener,KeyListener{ //, ClipboardOwner
  public boolean notfrommenu=true;

  GraphWindow graphWindow;
  GraphEngine graphEngine;
  Thread processGraph;
  public Graph graph;

  Node aNode;
  Link aLink;
  PopupMenu popmenu=new PopupMenu("Popup Menu");
  MenuItem plabel=new MenuItem("Node Label");
  MenuItem pnodedel=new MenuItem("Node Delete");
  MenuItem pnodeopen=new MenuItem("Node Open");

  MenuItem pcreategraph=new MenuItem("Create Graph Content");
  MenuItem pcreatehtml=new MenuItem("Create HTML Content");
  MenuItem pcreatetext=new MenuItem("Create TEXT Content");

  GraphPanel (GraphWindow w, Graph g, int x, int y) {

    graphWindow = w;
    graphEngine = graphWindow.graphEngine;
    if (graphEngine==null) System.out.println("Already null GraphEngine");
    graph = g;
    maxX = x;  // max size of virtual area for graph
    maxY = y;
    URL u = g.getUID();
    System.out.println("Graph UID = "+u);
    popmenu.add(plabel);
    popmenu.add(pnodedel);
    popmenu.add(pnodeopen);
    popmenu.add(pcreategraph);
    popmenu.add(pcreatehtml);
    popmenu.add(pcreatetext);

    this.add(popmenu);

    plabel.addActionListener(this);
    pnodedel.addActionListener(this);
    pnodeopen.addActionListener(this);
    pcreategraph.addActionListener(this);
    pcreatehtml.addActionListener(this);
    pcreatetext.addActionListener(this);


    createPopupMenu();

  }  // end GraphPanel constructor

  public void actionPerformed(ActionEvent e) {
    Object esource=e.getSource();
    boolean isWrite=graphWindow.isWrite();

    if (esource instanceof MenuItem) {
      switch(graphEngine.getWorkingMode()) {

      case GraphEngine.PASTEGRAPHMODE:
        if ( (esource == pasteGraphPopupReference) && isWrite){
            pasteNodeByReference(false);
        }
        else
        if ( (esource == pasteGraphPopup11LevelReference) && isWrite) {
            pasteNodeByValue(GraphEngine.CLONE_ONELAYER_REFERENCE, false);
        }
        else
        if ( (esource == pasteGraphPopup11LevelValue) && isWrite) {
            pasteNodeByValue(GraphEngine.CLONE_ONELAYER, false);
        }
        else
        if ( (esource == pasteGraphPopupNNLevelReference) && isWrite) {
            pasteNodeByValue(GraphEngine.CLONE_RECURSION_REFERENCE, false);
        }
        else
        if ( (esource == pasteGraphPopupNNLevelValue) && isWrite) {
            pasteNodeByValue(GraphEngine.CLONE_RECURSION, false);
        }
        else
        if (esource == pasteGraphPopupCancel) {
            showMessage("Cancel.");
        }
        graphEngine.setWorkingMode(GraphEngine.NORMALMODE);
        break;

      case GraphEngine.PASTECONTENTMODE:
        if ( (esource == pasteContentPopupReference)&& isWrite) {
            showMessage("pasteContentPopupReference");
            pasteNodeByReference(false);
        }
        else
        if ( (esource == pasteContentPopupValue) && isWrite) {
            pasteNodeByValue(GraphEngine.CLONE_ONELAYER, false);
        }
        else
        if (esource == pasteContentPopupCancel)  {
            showMessage("Cancel.");
        }
        graphEngine.setWorkingMode(GraphEngine.NORMALMODE);
        break;

      case GraphEngine.MOVEGRAPHMODE:
        System.out.println("!!! move graph node actionlistener");
        if ((esource == moveGraphPopupReference) && isWrite) {
            pasteNodeByReference(true);
        }
        /*   waiit for implementation
        else
        if (esource == moveGraphPopup11LevelReference) {
            pasteNodeByValue(CLONE_ONELAYER_REFERENCE, true);
        }
        else
        if (esource == moveGraphPopup11LevelValue) {
            pasteNodeByValue(CLONE_ONELAYER, true);
        }
        else
        if (esource == moveGraphPopupNNLevelReference) {
            pasteNodeByValue(CLONE_RECURSION_REFERENCE, true);
        }
        else
        if (esource == moveGraphPopupNNLevelValue) {
            pasteNodeByValue(CLONE_RECURSION, true);
        }
        */
        else if (esource == moveGraphPopupCancel) {
            showMessage("Cancel.");
        }
        graphEngine.setWorkingMode(GraphEngine.NORMALMODE);
        break;

      case GraphEngine.MOVECONTENTMODE:
        if ( (esource == moveContentPopupReference) && isWrite) {
            pasteNodeByReference(true);
        }
        /*
        else
        if (esource == moveContentPopupValue) {
            pasteNodeByValue(CLONE_ONELAYER, true);
        }
        */
        else
        if (esource == moveContentPopupCancel) {
            showMessage("Cancel.");
        }
        graphEngine.setWorkingMode(GraphEngine.NORMALMODE);
        break;

     }
    }
  }

  public void init ()  {
  }  // end init

  public void start ()  {
    addMouseListener(this);
    addMouseMotionListener(this);
    addKeyListener(this);
    processGraph = new Thread(this);  // a thread to paint the graph all the time!
    processGraph.start();
  }  // end start

  public void stop () {
    if (processGraph != null) {
      processGraph.stop();
      processGraph = null;
    }  // end if
  }  // end stop

  public void run ()  {
    while (true) {


      repaint();  // generates new display (update called)
      try {Thread.sleep(100);}
      catch (InterruptedException e) { System.out.println("Interrupted in GraphPanel thread");}
    }  // end while
  }  // end run

// ***************************** OffScreen Graphics

Image offScreen;
Dimension offScreensize;
Graphics offGraphics;
Font nodeFont = new Font ( "Helvetica", Font.BOLD, 14);
//int nodeMargin = No;
int maxX, maxY;

Color linkColor = Color.blue;
Color nodeColor =  new Color ( 206, 246, 216 );
Color labelColor = Color.black;
public static Color ContentedLabelColor = Color.blue;
public static Color ForwardedLabelColor = Color.pink;

Color selectColor = Color.pink;
Color linkSelectColor = Color.red;

  public void update ( Graphics g )  {

    Dimension d = this.size();
    FontMetrics nodeFm;

    if ( (offScreen == null) ||
         (d.width != offScreensize.width) ||
         (d.height != offScreensize.height) )
         {
            offScreen = createImage ( d.width, d.height );
            offScreensize = d;
            offGraphics = offScreen.getGraphics ();
         }
    offGraphics.setColor ( getBackground () );
    offGraphics.fillRect ( 0, 0, d.width, d.height );
    offGraphics.setFont ( nodeFont );

    synchronized (graph) {
    if ( aLinkMoveInProgress ||
         aLinkBeingAdded )
        paintLinkDrag ( offGraphics );

      paintLinks ( offGraphics );
      paintNodes ( offGraphics );
    }
    g.drawImage ( offScreen, 0, 0, null );
    //// System.out.println("draw graph for one time");

  }  // end update

  public void paintLinkDrag ( Graphics g )
    {
        Node n;
        Point pf, pt;
        if ( aLinkMoveInProgress ) {
            n = linkDragFromNode;
            if ( n != null)  {
                pf = subtractPoints(n.getCenter( ), offSet);
                pt = dragSSPoint;
                g.setColor ( linkSelectColor );
                g.drawLine ( pf.x, pf.y, pt.x, pt.y );
            }  // end if
        }  // end if:  aLinkMoveInProgress
        else {
            n = graph.getSelectedNode( );
            if ( n != null)  {
                pf = subtractPoints(n.getCenter( ), offSet);
                pt = movingSSPoint;
                g.setColor ( linkSelectColor );
                g.drawLine ( pf.x, pf.y, pt.x, pt.y );
            }  // end if
        }  // end else: aLinkBeingAdded
  }  // end paintLinkDrag

  public void paintLinks ( Graphics g )
    {
        Node from, to;
        Link l, selectedL;
        Point pf, pt;

        boolean hasCutNode=false;

        l = graph.getFirstLink ();
        selectedL = graph.getSelectedLink( );
        while ( l != null)  {
            if ( (l.getValid( ) & !aLinkMoveInProgress) ||
                 (l.getValid( ) & (l != graph.getSelectedLink())) )  {
                from = l.getFrom( );
                to = l.getTo( );

                ////
                if (  ! ( ( from.getValid() || from.getForwarded()) &&  ( to.getValid() || to.getForwarded())) )
                          //      hasMovedNode = true;
                          //    else hasMovedNode = false;
                        {l=graph.getNextLink(); continue;}
                //////
                if (from.getForwarded() || to.getForwarded()) hasCutNode = true;
                         else hasCutNode = false;
                //// invisible moved node's link ???????


                if ( (!graphWindow.getDisplayMoveNode()) && hasCutNode ) {l=graph.getNextLink(); continue;}

                pf = subtractPoints( from.getCenter( ), offSet );
                pt = subtractPoints( to.getCenter( ), offSet );
                if ( l == selectedL )
                g.setColor ( linkSelectColor );
                else g.setColor ( linkColor );

                if  (hasCutNode) g.setColor(ForwardedLabelColor);  //// if forwarded node, marked special

                g.drawLine ( pf.x, pf.y, pt.x, pt.y );
            }  // end if valid
            l = graph.getNextLink( );
        }  // end while loop

  }  // end paintLinks

  public void paintNodes ( Graphics g )  {
    Node n;
    Point p;
    int x, y;
    int w, h;
    int xlabeloff, ylabeloff;
    String label;

    n = graph.getFirstNode ();
    while ( n != null ) {

    //// invisible forwarded node
    if (  (n.getForwarded()) && (!graphWindow.getDisplayMoveNode()) ) {
        n = graph.getNextNode ();
        continue; }


    //// reset the label with correct size
    label = n.getLabel ();
    FontMetrics fm;
    fm = g.getFontMetrics ();
    w = fm.stringWidth(label);
    h = fm.getAscent();
    n.setLabel(label, w, h);

    p = n.getPosition ();
    x = p.x - offSet.x;
    y = p.y - offSet.y;
    p = n.getWh ();
    w = p.x;
    h = p.y;
    ////label = n.getLabel ();
    p = n.getLabelOffset ();
    xlabeloff = p.x - offSet.x;
    ylabeloff = p.y - offSet.y;


    // compute on the fly

    //// compute box width and height on the fly
    /*
    label = n.getLabel();
    int BORDERXX, BORDERYY;
    BORDERXX=3; BORDERYY=3;
    p = n.getPosition();
    x= p.x;
    y= p.y;
    FontMetrics fm;
    fm = g.getFontMetrics ();
    w = fm.stringWidth(label)+2*BORDERXX;
    h = fm.getAscent()+2*BORDERYY;
    xlabeloff = x+BORDERXX;
    ylabeloff = y+h/2+ 2*BORDERYY;
    */


    g.setColor ( nodeColor);
    g.draw3DRect ( x, y, w, h, !n.getSelected() );
    g.fill3DRect ( x, y, w, h, !n.getSelected() );
    //System.out.println("width:"+w);
    //System.out.println("str"+label+" width"+fm.stringWidth(label));

    // draw Node in different color
    if (n.getContent()==null) g.setColor ( labelColor );
          else { g.setColor(ContentedLabelColor); }
    // forwarded content
    if (n.getForwarded()) g.setColor(ForwardedLabelColor);
    g.drawString ( label, xlabeloff, ylabeloff );
    n = graph.getNextNode ();
    }
  }  // end paintNodes



// ***************************** Mouse Events

    Point selectedSSPoint = new Point ( 0, 0 );
    Point selectedGSPoint = new Point ( 0, 0 );
    Point movingGSPoint = new Point ( 0, 0 );
    Point movingSSPoint = new Point ( 0, 0 );
    Point dragGSPoint = new Point ( 0, 0 );
    Point dragSSPoint = new Point ( 0, 0 );
    Point offSet = new Point ( 0, 0 );
    Point moveOffset = new Point ( 0, 0 );
    Node linkDragFromNode;
    int mouseSingleClickTime = 250;
    int mouseDoubleClickTime= 400;
    boolean aLinkMoveInProgress = false;
    boolean aLinkBeingAdded = false;
    Node addLinkFrom, addLinkTo;
    int linkMargin = 10;  // area for link select



// for mouseListener Interface

public void mouseClicked(MouseEvent e) {
        //System.out.println("mouse Clicked");

        /*Node n;
        Link l;
        int x,y;
        x=e.getX();
        y=e.getY();
        selectedSSPoint = new Point( x, y );
        selectedGSPoint = addPoints(selectedSSPoint, offSet );
        n = graph.nodeSelect ( selectedGSPoint );
        if ( n != null)  {
            moveOffset = subtractPoints( selectedGSPoint, n.getPosition() );
            graph.linkUnSelect();
        }  // end if
        else  {
        l = graph.linkSelect ( selectedGSPoint, linkMargin );
            if ( l != null)  {
                linkDragFromNode = l.getClosestNode( selectedGSPoint );
                graph.nodeUnSelect ();
            }  // end if
        }  // end else
        updateTime ();
        */
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
        //System.out.println("mousePressed");
        notfrommenu=true;
        Node n;
        Link l;
        int x,y;
        x=e.getX();
        y=e.getY();
        selectedSSPoint = new Point( x, y );
        selectedGSPoint = addPoints(selectedSSPoint, offSet );
        n = graph.nodeSelect ( selectedGSPoint );
        if ( n != null)  {
            moveOffset = subtractPoints( selectedGSPoint, n.getPosition() );
            graph.linkUnSelect();
        }  // end if
        else  {
        l = graph.linkSelect ( selectedGSPoint, linkMargin );
            if ( l != null)  {
                linkDragFromNode = l.getClosestNode( selectedGSPoint );
                graph.nodeUnSelect ();
            }  // end if
        }  // end else
        updateTime ();

}
public void mouseReleased(MouseEvent e) {
      if (notfrommenu) {

        /*********paste operation*************************************/
       /* int pasteMode = graphWindow.getPasteMode();
        if (pasteMode!= GraphWindow.PASTE_FINISHED) {
           if (pasteMode ==MyClipBoard.CLONE_REFERENCE)
               {
                if (pasteNodeByReference())
                     graphWindow.showMessage("Paste Succeeded.");
                  else
                     graphWindow.showMessage("Paste Failed.");
               }
               else
               {
                if (pasteNodeByValue(pasteMode))
                     graphWindow.showMessage("Paste Succeeded.");
                  else
                     graphWindow.showMessage("Paste Failed.");

               }
        graphWindow.setPasteMode(GraphWindow.PASTE_FINISHED);
        return;

        }
      */
        /******** paste operation end *******************************/

        //System.out.println("mouse released");
        if ( (System.currentTimeMillis() - lastLastTime) < mouseDoubleClickTime) {
            mouseDoubleClick ( e );
            return;
        } // end 2-click
        else if ( (System.currentTimeMillis() - lastTime) < mouseSingleClickTime) {
            mouseSingleClick ( e );
            return ;
        } // end 1-click
        else  {
            mouseSlowClick ( e );
            return;
        }  // end 0-click
      }
       else notfrommenu=true;
}

// for mouseMotionListener Interface
public void mouseDragged(MouseEvent e) {
        //System.out.println("mouse draged");
    if (!graphWindow.isWrite()) {//graphWindow.showMessage("In Read Mode");
                                  return;}
    if (graphEngine.isSpecialWorking() ) {graphWindow.showMessage("In special mode."); return;}

    Node n, f, t;
    Link l;
    Point p;
        int x,y;
        x=e.getX();
        y=e.getY();

    dragSSPoint = new Point( x, y );
    dragGSPoint = addPoints( dragSSPoint, offSet );
    n = graph.getSelectedNode( );
    if ( n != null )  {
        p = subtractPoints( dragGSPoint, moveOffset );
        n.setPosition ( p );
        return;
    }  // end selected node drag
    l = graph.getSelectedLink( );
    if ( l != null )  {
        if ( ! aLinkMoveInProgress ) aLinkMoveInProgress = true;
        return ;
    }  // end selected link drag
}

public void mouseMoved(MouseEvent e) {
        //System.out.println("mouse moved");
    if (!graphWindow.isWrite()) {//graphWindow.showMessage("In Read Mode");
                                 return;}
    if (graphEngine.isSpecialWorking() ) {//graphWindow.showMessage("In special mode.");
                                        return;}

        int x,y;
        x=e.getX();
        y=e.getY();
    movingSSPoint = new Point( x, y );
    movingGSPoint = addPoints( movingSSPoint, offSet );
    aLinkMoveInProgress = false;
}


  void mouseSingleClick (MouseEvent evt)
    {
        Node n;
        Link l;
        n = graph.getSelectedNode( );
        if ( n != null )  {
            if ( aLinkBeingAdded )  {
                addLinkTo = n;
                LinkAdd( );
            }  // end aLinkBeingAdded
            graph.linkUnSelect( );
            aLinkMoveInProgress = false;
            return;
        }  // end node processing
        else l = graph.getSelectedLink( );
        if ( l != null )  {
            graph.nodeUnSelect( );
            return;
        }  // end link processing
        aLinkMoveInProgress = false;
    }  // end mouseSingleClick

  void mouseDoubleClick ( MouseEvent evt )
    {

    if ( graph.aNodeIsSelected )
        {
            NodeOpen( );
            return;
        }
    if ( ! graph.aNodeIsSelected && ! graph.aLinkIsSelected)
        {
            NodeAdd( );
            return;
        }

  }  // end mouseDoubleClick

  void mouseSlowClick (MouseEvent evt)
    {
        Link l;
        Node n;
        Point localSSPoint;
        Point localGSPoint;

        localSSPoint = new Point( evt.getX(), evt.getY() );
        localGSPoint = addPoints( localSSPoint, offSet );
        if ( aLinkMoveInProgress ) {
            l = graph.getSelectedLink( );
            n = graph.nodeSelect( localGSPoint );
            if ( l != null )  {  // valid link move taking place
                if ( n != null )  {
                    graph.moveLink( l ,linkDragFromNode, n );  // move one end of link
                }  // end link move, valid
                else  {
                }  // end link move, invalid
            }  // end if
        }  // end aLinkMoveInProgress
        graph.nodeUnSelect( );
        graph.linkUnSelect( );
        aLinkMoveInProgress = false;
    }  // end mouseSlowClick

    void updateTime ( )
    {
        diffTime = System.currentTimeMillis () - lastTime;
        lastLastTime = lastTime;
        lastTime += diffTime;
    }  // end updateTime ( )
    long diffTime;
    long lastTime = 0;
    long lastLastTime = 0;




// ***************************** Menu Action Methods

protected static final int NODE_LABEL = 1;


/******************
    Old Copy and Paste
*******************/

/*public void lostOwnership(Clipboard clipboard, Transferable oldcontents) {
    System.out.println("This Panel lose the ownership of the clipboard");
}

Copy Node
public boolean copyObject() {
    Node n = graph.getSelectedNode();
    if ( n !=null )  {
      // put to the public clipboard
      Clipboard cb=null;
      if ( (cb=getClipboard()) != null) {
        System.out.println("get clipboard");
        //NodeSelection ns=new NodeSelection(new TestClass("Hello. Morning"));
        //cb.setContents(ns, this);
        //System.out.println("Object Copied");
        cb.setContents(new NodeSelection("Hello World!"), this);
        //cb.setContents(new StringSelection("Hello World!"), this);
        return true;
      }
    }
    return false;
}
 */
/** Paste Object
public boolean pasteObject() {
    // get a Node froom public clipboard
    Clipboard cb=null;
    if ( (cb=getClipboard()) != null) {
        System.out.println("get clipboard");
        Transferable data= cb.getContents(this);
        if (data == null) System.out.println("Empty Transfered Data!!!");
        Node pastenode=null;
        try {
          //pastenode=(Node) data.getTransferData( new DataFlavor("application/x-java-serialized-object; class=Graph.Node","NodeClass"));
          //pastenode=(Node) data.getTransferData( new DataFlavor(Class.forName("Graph.Node"),"NodeClass") );
          //TestClass tc=(TestClass) data.getTransferData( new DataFlavor(Class.forName("TestClass"),"TestClass") );

          //String temp=(String) data.getTransferData(new DataFlavor("application/x-java-serialized-object; class=java.lang.String","StringClass"));
          String temp=(String) data.getTransferData(DataFlavor.stringFlavor);

          //System.out.println("Cruel:"+tc.test);
          System.out.println("Cruel:"+temp);
        } catch (ClassNotFoundException e) {
           System.out.println("TestClass not found!");
           return false;
         }
         catch (UnsupportedFlavorException e2) {
          System.out.println("in pasteObject UnsupportedFlavorException!");
         }
         catch (IOException e3) {
          System.out.println("IOException");
         }
        System.out.println("Node get!");
 if (pastenode == null) {
    System.out.println("Node Get Error!");
    return false;
 }
 Node newnode=graph.addNode();
    Graphics g;
    int x,y;
    g = this.getGraphics ();
    FontMetrics fm = offGraphics.getFontMetrics ();
    String label=pastenode.getLabel();
    x = fm.stringWidth(label);
    y= fm.getAscent();
    newnode.setLabel(label,x,y);
    newnode.setContentType(pastenode.getContentType());
    newnode.setContent(pastenode.getContent());

        return true;
      }
    return false;
}

*/
/* get the application clipboard
public Clipboard getClipboard() {
  try {
    //SecurityManager sm = SecurityManager.getSecurityManager();
    //if (sm != null) sm.checkSystemClipboardAccess();
  Clipboard cb =  Toolkit.getDefaultToolkit().getSystemClipboard();
  return cb;//... handle clipboard

  }
   catch (SecurityException e) {
    System.err.println("Cannot access the system clipboard");
    return null;
  }
}*/


/* get the application clipboard*/
public MyClipBoard getMyClipboard() {
  //try {
    //SecurityManager sm = SecurityManager.getSecurityManager();
    //if (sm != null) sm.checkSystemClipboardAccess();
    MyClipBoard cb =  graphWindow.source.clipboard;    //Toolkit.getDefaultToolkit().getSystemClipboard();
    return cb;//... handle clipboard

  //}
  // catch (SecurityException e) {
  //  System.err.println("Cannot access the system clipboard");
 //   return null;
 // }
}


/******************
    New Copy and Paste  Use Application level psydo Clipboard to implement copy/paste
*******************/

/*Copy Node */
public boolean copyNode(int mode) {
 /*    return copyObject(); */
   Node node = graph.getSelectedNode();
    if ( node ==null )  return false;
    /** put to the public clipboard
    //  MyClipBoard cb=null;
    //  if ( (cb=getMyClipboard()) == null) return false;
    //    System.out.println("get clipboard");
    //    cb.setContents(n, this, mode);
    //    System.out.println("Node Object Copied");

    //if (mode==MyClipBoard.CUT) this.NodeDelete();
    **/

            MIME_Type mt=node.getContentType();
            if (mt==null)           // if content is null, treat it as having content
               { graphEngine.setContents(node, this.graphWindow,GraphEngine.PASTECONTENTMODE);
                 return true; }
            if (mt.getType()==MIME_Type.GRAPH) {
                // Node content is graph
                //if (graphEngine==null) System.out.println("null graphengine");
                graphEngine.setContents(node, this.graphWindow,GraphEngine.PASTEGRAPHMODE);
                }
               else {
                //Node content is non-graph
                graphEngine.setContents(node, this.graphWindow,GraphEngine.PASTECONTENTMODE);
                }

    return true;
}

public boolean moveNode(int mode) {
   Node node = graph.getSelectedNode();
    if ( node ==null )  return false;
            MIME_Type mt=node.getContentType();
            /* if (mt==null)           // if content is null, treat it as having content
                graphEngine.setContents(node, this.graphWindow,GraphEngine.MOVECONTENTMODE); */
            if (mt.getType()==MIME_Type.GRAPH) {
                // Node content is graph
                graphEngine.setContents(node, this.graphWindow,GraphEngine.MOVEGRAPHMODE);
                }
             else {
                //Node content is non-graph
                graphEngine.setContents(node, this.graphWindow,GraphEngine.MOVECONTENTMODE);
                }
        System.out.println("!!! movenode graphpanel method");

    return true;

}

/** Paste Object by value */
public boolean pasteNodeByValue(int mode, boolean pasteORmove) {

    // get a Node froom public clipboard
    ////MyClipBoard cb=null;
    ///if ( (cb=getMyClipboard()) == null) return false;
    ///synchronized (cb) {
    ////  System.out.println("get clipboard");
     Object data= graphEngine.getContents(this);
     if (data == null) System.out.println("Empty Transfered Data!!!");
     if ( !(data instanceof Node)) return false;
     Node pastenode=null;
     pastenode=(Node) data;
     System.out.println("Node get!");
     if (pastenode == null) {
       System.out.println("Node Get Error!");
       return false;
     }

     // clone a new node
     /*Node newnode=graph.addNode();
     Graphics g;
     int x,y;
     g = this.getGraphics ();
     FontMetrics fm = offGraphics.getFontMetrics ();
     String label=pastenode.getLabel();
     x = fm.stringWidth(label);
     y= fm.getAscent();
     newnode.setLabel(label,x,y);
     newnode.setContentType(pastenode.getContentType());
     newnode.setContent(pastenode.getContent());


      MIME_Type type = pastenode.getContentType();
      if ( type.getType() != MIME_Type.GRAPH ) {
        System.out.println("Clone non-graph content.");
      // get source content
        ContentObject sourceContent =null, targetContent =null ;
        try  {
            sourceContent = graphWindow.domainservice.openGraphContent ( pastenode.getContent() );
            // clone the content
            targetContent = new ContentObject ( graph );
            targetContent.setType ( sourceContent.getType() );
            targetContent.setContent ( sourceContent.getContent() );
            // save the content
            graphWindow.domainservice.saveGraphContent( targetContent );

            newnode.setContent(sourceContent.getUID() );
       graphWindow.showMessage("Clone the non-Graph Content Finished");

        } catch (DomainException e) {
            graphWindow.showError("Open Graph Content Fail."+e.getMessage());
        } // end catch
      return true;
      }

      if ( type.getType() == MIME_Type.GRAPH) {
      //  if graph; get graph
        Graph sourceGraph=null,targetGraph=null;
        try {
            sourceGraph = (Graph) graphWindow.domainservice.openGraph( pastenode.getContent() );

            //build a new graph and copy all the content
            targetGraph = cloneGraph(sourceGraph);
            graphWindow.domainservice.saveGraph(targetGraph);
            newnode.setContent( targetGraph.getUID() );
        } catch (DomainException e) {
            graphWindow.showError("Operation Fail:"+e.getMessage());
           }
       graphWindow.showMessage("Clone the Graph Content Finished");
      }
     */

    Node newnode = graphEngine.cloneNodeByContent(graph, pastenode, mode, pasteORmove);
    /*
    // if Cut; change original pastenode
    if (cb.getMode()==MyClipBoard.CUT) {
        pastenode.setValid(false);
        pastenode.setForwarded(true);
        pastenode.setForwardURL(newnode.getUID());
        newnode.setBackwardURL(pastenode.getUID());
    }
    */
    newnode.setPosition ( selectedGSPoint );
   //}



  return true;
}
/*
public Graph cloneGraph(Graph sourceGraph) {
  Graph targetGraph=null;

  try {
    graphWindow.showMessage("Clone the Graph");
    targetGraph=graphWindow.domainservice.createGraph( graph.getUID() );

    // copy the content of the Graph

    // copy the node
    Node sourcenode=null, targetnode=null;
    Link sourcelink=null, targetlink=null;

    Hashtable map = new Hashtable();

    graphWindow.showMessage("Clone the Nodes");
    sourcenode = sourceGraph.getFirstNode();

    while( sourcenode != null) {
     targetnode=targetGraph.addNode();

     Graphics g;
     int x,y;
     g = this.getGraphics ();
     FontMetrics fm = offGraphics.getFontMetrics ();
     String label=sourcenode.getLabel();
     x = fm.stringWidth(label);
     y= fm.getAscent();
     targetnode.setLabel(label,x,y);
     targetnode.setContentType(sourcenode.getContentType());
     targetnode.setContent(sourcenode.getContent());

     map.put(sourcenode, targetnode);

     sourcenode = sourceGraph.getNextNode();
    }

    // copy the links
    graphWindow.showMessage("Clone the links");
    sourcelink = sourceGraph.getFirstLink();
    while (sourcelink !=null) {
        Node snode,tnode;
        snode = (Node) map.get(sourcelink.getFrom());
        tnode = (Node) map.get(sourcelink.getTo());
        targetlink = targetGraph.addLink(snode,tnode);

        sourcelink = sourceGraph.getNextLink();
    }

  } catch (DomainException e) {
        graphWindow.showError("Operation Fail:"+e.getMessage());
      }
  return targetGraph;
}

*/

public boolean pasteNodeByReference(boolean pasteORmove){
    ////MyClipBoard cb=null;
    ////if ( (cb=getMyClipboard()) == null) return false;
    ////synchronized (cb) {
    //// System.out.println("get clipboard");
    //// Object data= cb.getContents(this);
    Object data = graphEngine.getContents(this);
     if (data == null) System.out.println("Empty Transfered Data!!!");
     if ( !(data instanceof Node)) return false;
     Node pastenode=null;
     pastenode=(Node) data;
     if (pastenode == null) {
       System.out.println("Node Get Error!");
       return false;
     }
     System.out.println("Node get!");

     // clone the node
     /*
     Node newnode = graph.addNode();
     Graphics g;
     int x,y;
     g = this.getGraphics ();
     FontMetrics fm = offGraphics.getFontMetrics ();
     String label=pastenode.getLabel();
     x = fm.stringWidth(label);
     y= fm.getAscent();
     newnode.setLabel(label,x,y);
     newnode.setContentType(pastenode.getContentType());
     newnode.setContent(pastenode.getContent());
     */

     Node newnode = graphEngine.cloneNodeByReference(graph,pastenode,pasteORmove);

    // if Cut; change original pastenode
    /*
    if (cb.getMode()==MyClipBoard.CUT) {
        pastenode.setValid(false);
        pastenode.setForwarded(true);
        pastenode.setForwardURL(newnode.getUID());
        newnode.setBackwardURL(pastenode.getUID());
    }
    */
    newnode.setPosition ( selectedGSPoint );
return true;
}
/***********************************************************/




// ********** System Menu

public void systemSave () {

}  // end systemSave

// ********** Graph Menu

  public void GraphAutoLayout () {
System.out.println ("GraphAutoLayout in GraphPanel");
  }  // end GraphAutoLayout

// ********** Node Menu

  public void NodeAdd () {
    Node n;
    Graphics g;

    if (!graphWindow.isWrite()) {graphWindow.showMessage("In Read Mode"); return;}
    if (graphEngine.isSpecialWorking() ) {graphWindow.showMessage("In special mode."); return;}

    n = graph.addNode ();
    n.setPosition ( selectedGSPoint );
    //n.setLabel( "Null" );
    //
    //n.setNodeSize ( g, nodeMargin );
    int x,y;
    g = this.getGraphics ();
    FontMetrics fm = offGraphics.getFontMetrics ();
    String label="Null";
    x = fm.stringWidth(label);
    y= fm.getAscent();
    n.setLabel(label,x,y);
    URL u = n.getUID();
    System.out.println("Node UID = "+u);
  }  // end NodeAdd


  public boolean NodeDelete () {
    Node n;
    System.out.println ("NodeDelete in GraphPanel");

    if (graph.aNodeIsSelected )  {
    System.out.println ("NodeDelete in GraphPanel: node is selected");

        n = graph.getSelectedNode( );
        graph.deleteNode( n );
        graphWindow.addDeleteNode(n);
        return true;
    }
    return false;
  }  // end NodeDelete


  public void NodeOpen() {
    Node n = graph.getSelectedNode();
    if ( graph.aNodeIsSelected )  {
        //// URL u = n.getContent();        hacking with Forwarding Mechanism ???
        URL u = graphEngine.getContentURL(n);

        // add control
        if ( u == null ) {
            graphWindow.SystemNew( n );
      /*LabelDialog ld=new LabelDialog((Frame)this.getParent(),"Error!","No CONTENT Created!");
      ld.show();
      return;*/
            //forbidden direct creating; use popup menu instead!!!!!!
        }
        else {
            MIME_Type t = n.getContentType();
            if ( t.getType() == MIME_Type.GRAPH ) graphWindow.SystemOpen( u );
            else graphWindow.OpenContent();
        }  // end else
    }  // end if
    return;
  }  // end NodeOpen




 /*
  * New Method added for content show test
  *
  */
  public void ShowContent() {
    System.out.println ("NodeOpen in GraphPanel");
    Node n = graph.getSelectedNode();
    if ( graph.aNodeIsSelected )  {

        /****************open content of node*******/
        // URL u = n.getContent();hacking with Forwarding Mechanism ???
        URL u = graphEngine.getContentURL(n);


        System.out.println ("  url = "+u);
                if ( u == null ) graphWindow.SystemNew( n );
        else graphWindow.SystemOpen( u );

        /******************************************/

    }  // end if
    return;
  }  // end NodeOpen


  public void NodeHyperlinks () {
System.out.println ("NodeHyperlinks in GraphPanel");
  }  // end NodeHyperlinks

  public void NodeLabel () {
    Node node;
    String lbl;

    node = graph.getSelectedNode();
    if ( node != null ) {
        lbl = node.getLabel();
        int x, y;
        x=node.getPosition().x+this.graphWindow.getLocation().x+this.getLocation().x+node.getWh().x;
        y=node.getPosition().y+this.graphWindow.getLocation().y+this.getLocation().y+node.getWh().y;
        DialogBox db = new DialogBox( "Edit Node Label", 30, lbl, this, NODE_LABEL, node , x, y );
            }
  }  // end NodeLabel

  public void nodeLabelFinish( String s ) {
    Node node;
    Graphics g;
    node = graph.getSelectedNode();
    if ( node != null ) {
        /*node.setLabel( s );
        g = this.getGraphics ();
        node.setNodeSize ( g, nodeMargin ); */

            int x,y;
    //g = this.getGraphics ();
    FontMetrics fm = offGraphics.getFontMetrics ();
    x = fm.stringWidth(s);
    y= fm.getAscent();
    node.setLabel(s,x,y);
    }
  }  // end NodeLabelFinish

  public void nodeLabelFinish( Node node,String s) {
    //Node node;
    Graphics g;
    //node = graph.getSelectedNode();
    if ( node != null ) {
        /*node.setLabel( s );
        g = this.getGraphics ();
        node.setNodeSize ( g, nodeMargin ); */

            int x,y;
    //g = this.getGraphics ();
    FontMetrics fm = offGraphics.getFontMetrics ();
    x = fm.stringWidth(s);
    y= fm.getAscent();
    node.setLabel(s,x,y);
    }
  }  // end NodeLabelFinish


  public void NodeColor () {
System.out.println ("NodeColor in GraphPanel");
  }  // end NodeColor

// ********** Link Menu

  public void LinkAdd () {
    if ( addLinkTo == null )  {
        addLinkFrom = graph.getSelectedNode( );
        aLinkBeingAdded = true;
    }  // start of linking process
    else {
        if ( addLinkFrom == null )  {
            System.out.println("User Error in LinkAdd:  node not selected");
            addLinkTo = null;
            aLinkBeingAdded = false;
            return;
        }  // end error condition
        graph.addLink ( addLinkFrom, addLinkTo );
        addLinkFrom = null;
        addLinkTo = null;
        aLinkBeingAdded = false;
    }  // end of linking process
  }  // end LinkAdd

  public boolean LinkDelete () {
    Link l;
    if (graph.aLinkIsSelected )  {
        l = graph.getSelectedLink( );
        graph.deleteLink( l );
        return true;
    }
    return false;
  }  // end LinkDelete

// ********** Help Menu


// ***********************************************************
// ********************* Utility Classes **********************
// ***********************************************************


// ********** handleEvents

//key listener

public void keyPressed(KeyEvent e) {
}

public void keyReleased(KeyEvent e) {
}

public void keyTyped(KeyEvent e) {
	    if ( e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE )  {
	        if ( NodeDelete() ) return;
	        if ( LinkDelete() ) return;
	    } // end backspace/delete
}

////public void actionPerformed(AWTEvent evt) {
////
////}

/*
public boolean handleEvent(Event evt) {

	if ( evt.id == Event.KEY_PRESS )  {
	    if ( evt.key == Event.DELETE || evt.key == Event.BACK_SPACE )  {
	        if ( NodeDelete() ) return true;
	        if ( LinkDelete() ) return true;
	    } // end backspace/delete

	    return false;
	}  // end key event
	return super.handleEvent( evt );

}  // end handleEvent

*/
// ********** ScrollBar OffSets


	public void setOffScreenX(int i) {
		offSet.x = i;
	}  // end setOffScreenX

	public int bumpOffScreenX(int i) {
		offSet.x += i;
		offSet.x = Math.max ( offSet.x, 0 );
		offSet.x = Math.min ( offSet.x, maxX );
		return offSet.x;
	}  // end bumpOffScreenX

	public void setOffScreenY(int i) {
		offSet.y = i;
		}  // end setOffScreenX

	public int bumpOffScreenY(int i) {
		offSet.y += i;
		offSet.y = Math.max ( offSet.y, 0 );
		offSet.y = Math.min ( offSet.y, maxY );
		return offSet.y;
	}  // end bumpOffScreenY

	public Point addPoints ( Point a, Point b )  {
	    Point c = new Point ( 0, 0 );
	    c.x = a.x + b.x;
	    c.y = a.y + b.y;
	    return c;
	}  // end addPoints

	public Point subtractPoints ( Point a, Point b )  {
	    Point c = new Point ( 0, 0 );
	    c.x = a.x - b.x;
	    c.y = a.y - b.y;
	    return c;
	}  // end addPoints


// ********** Receive Data from DialogBoxes

    public void receiveData ( String s, int t )  {
        if ( t == NODE_LABEL )
        nodeLabelFinish( s );
    }  // end receiveData






//// Cut and Paste Data
    PopupMenu   pasteGraphPopup,pasteContentPopup, moveGraphPopup, moveContentPopup;

    MenuItem    pasteGraphPopupReference,
                pasteGraphPopup11LevelReference,
                pasteGraphPopup11LevelValue,
                pasteGraphPopupNNLevelReference,
                pasteGraphPopupNNLevelValue,
                pasteGraphPopupCancel;

    MenuItem    pasteContentPopupReference,
                pasteContentPopupValue,
                pasteContentPopupCancel;

    MenuItem    moveGraphPopupReference,
                moveGraphPopup11LevelReference,
                moveGraphPopup11LevelValue,
                moveGraphPopupNNLevelReference,
                moveGraphPopupNNLevelValue,
                moveGraphPopupCancel;

    MenuItem    moveContentPopupReference,
                moveContentPopupValue,
                moveContentPopupCancel;


    public void createPopupMenu() {

        ////
        pasteGraphPopup = new PopupMenu();
        pasteGraphPopupReference= new MenuItem ( "Paste Node only" );
        pasteGraphPopup11LevelReference= new MenuItem ( "Paste Node with One Level Graph" );
        pasteGraphPopup11LevelValue = new MenuItem("Paste Node with One Level Graph and Content");
        pasteGraphPopupNNLevelReference = new MenuItem("Paste Node with N Level Graph");
        pasteGraphPopupNNLevelValue = new MenuItem("Paste Graph by N Level Graph and Content");
        pasteGraphPopupCancel = new MenuItem("Cancel");

        pasteGraphPopup.add(pasteGraphPopupReference);
        pasteGraphPopup.addSeparator();
        pasteGraphPopup.add(pasteGraphPopup11LevelReference);
        pasteGraphPopup.add(pasteGraphPopup11LevelValue);
        pasteGraphPopup.add(pasteGraphPopupNNLevelReference);
        pasteGraphPopup.add(pasteGraphPopupNNLevelValue);
        pasteGraphPopup.addSeparator();
        pasteGraphPopup.add(pasteGraphPopupCancel);
        ////
        pasteContentPopup = new PopupMenu();
        pasteContentPopupReference = new MenuItem("Paste by Reference");
        pasteContentPopupValue = new MenuItem("Paste by Value");
        pasteContentPopupCancel = new MenuItem("Cancel");

        pasteContentPopup.add(pasteContentPopupReference);
        pasteContentPopup.addSeparator();
        pasteContentPopup.add(pasteContentPopupValue);
        pasteContentPopup.addSeparator();
        pasteContentPopup.add(pasteContentPopupCancel);

        ////
        moveGraphPopup = new PopupMenu();
        moveGraphPopupReference= new MenuItem ( "Move Node only" );
        moveGraphPopup11LevelReference= new MenuItem ( "Move Node with One Level Graph" );
        moveGraphPopup11LevelValue = new MenuItem("Move Node with One Level Graph and Content");
        moveGraphPopupNNLevelReference = new MenuItem("Move Node with N Level Graph");
        moveGraphPopupNNLevelValue = new MenuItem("Move Node with N Level Graph and Content");
        moveGraphPopupCancel = new MenuItem("Cancel");


        moveGraphPopup.add(moveGraphPopupReference);
        //moveGraphPopup.addSeparator();
        //moveGraphPopup.add(moveGraphPopup11LevelReference);
        //moveGraphPopup.add(moveGraphPopup11LevelValue);
        //moveGraphPopup.add(moveGraphPopupNNLevelReference);
        //moveGraphPopup.add(moveGraphPopupNNLevelValue);
        moveGraphPopup.addSeparator();
        moveGraphPopup.add(moveGraphPopupCancel);

        ////
        moveContentPopup = new PopupMenu();
        moveContentPopupReference = new MenuItem("Move by Reference");
        moveContentPopupValue = new MenuItem("Move by Value");
        moveContentPopupCancel = new MenuItem("Cancel");

        moveContentPopup.add(moveContentPopupReference);
        moveContentPopup.addSeparator();
        moveContentPopup.add(moveContentPopupValue);
        moveContentPopup.addSeparator();
        moveContentPopup.add(moveContentPopupCancel);

        ////
        add(pasteGraphPopup);
        add(pasteContentPopup);
        add(moveGraphPopup);
        add(moveContentPopup);


        pasteGraphPopupReference.addActionListener(this);
        pasteGraphPopup11LevelReference.addActionListener(this);
        pasteGraphPopup11LevelValue.addActionListener(this);
        pasteGraphPopupNNLevelReference.addActionListener(this);
        pasteGraphPopupNNLevelValue.addActionListener(this);
        pasteGraphPopupCancel.addActionListener(this);

        pasteContentPopupReference.addActionListener(this);
        pasteContentPopupValue.addActionListener(this);
        pasteContentPopupCancel.addActionListener(this);

        moveGraphPopupReference.addActionListener(this);
        /*
        moveGraphPopup11LevelReference.addActionListener(this);
        moveGraphPopup11LevelValue.addActionListener(this);
        moveGraphPopupNNLevelReference.addActionListener(this);
        moveGraphPopupNNLevelValue.addActionListener(this);
        */
        moveGraphPopupCancel.addActionListener(this);
        moveContentPopupReference.addActionListener(this);
        /*
        moveContentPopupValue.addActionListener(this);
        */
        moveContentPopupCancel.addActionListener(this);

        createNodePopup();
    }


    PopupMenu   nodePopup;

    MenuItem    nodeDelete,
                nodeOpenEdit,
                nodeOpenDisplay,
                nodeProperty,
                nodeLabel,
                copyNode,
                moveNode;
    Menu        newContentType;
    MenuItem    graphNet,
                textPlain,
                textHTML;

    private void createNodePopup() {
        Runtime.getRuntime().gc();
        nodePopup = new PopupMenu("Node Menu");
        nodeDelete = new MenuItem("Delete");
        nodeOpenEdit = new MenuItem("Edit Content");
        nodeOpenDisplay = new MenuItem("Display Content");
        nodeProperty = new MenuItem("Node Property");
        nodeLabel = new MenuItem("Node Label");
        copyNode = new MenuItem("Copy");
        moveNode = new MenuItem("Move");

        newContentType = new Menu("New Content");
        graphNet = new MenuItem("Graph");
        textPlain = new MenuItem("Plain text");
        textHTML = new MenuItem("HTML text");
        newContentType.add(graphNet);
        newContentType.add(textPlain);
        newContentType.add(textHTML);

        nodePopup.add(nodeOpenEdit);
        nodePopup.add(nodeOpenDisplay);
        nodePopup.add(nodeProperty);
        nodePopup.add(nodeLabel);
        nodePopup.addSeparator();
        nodePopup.add(newContentType);
        nodePopup.addSeparator();
        nodePopup.add(copyNode);
        nodePopup.add(moveNode);
        nodePopup.addSeparator();
        nodePopup.add(nodeDelete);

        add(nodePopup);

        NodePopupListener nodepopuplistener = new NodePopupListener(this);


        nodeOpenEdit.addActionListener(nodepopuplistener);
        nodeOpenDisplay.addActionListener(nodepopuplistener);
        nodeProperty.addActionListener(nodepopuplistener);
        nodeLabel.addActionListener(nodepopuplistener);
        graphNet.addActionListener(nodepopuplistener);
        textPlain.addActionListener(nodepopuplistener);
        textHTML.addActionListener(nodepopuplistener);
        copyNode.addActionListener(nodepopuplistener);
        moveNode.addActionListener(nodepopuplistener);
        nodeDelete.addActionListener(nodepopuplistener);
        System.out.println("WATCH OUT. NODE POPUP IS CREATED");
    }

    public void setNodePopup(boolean mode) {
        nodeOpenEdit.setEnabled(mode);
        moveNode.setEnabled(mode);
        newContentType.setEnabled(mode);
        nodeDelete.setEnabled(mode);
    }

    class NodePopupListener implements ActionListener {
        GraphPanel graphpanel;
        GraphWindow graphwindow;

        public NodePopupListener(GraphPanel panel) {
            this.graphpanel = panel;
            graphwindow = panel.graphWindow;
        }

      public void actionPerformed(ActionEvent e) {
            Object esource = e.getSource();
         // Node Menu Items

         if ( esource == nodeOpenEdit ) {
           graphpanel.notfrommenu=false;
           graphwindow.NodeOpenEdit ();
         }  //  end NodeOpenEdit

         else if ( esource == nodeOpenDisplay ) {
           graphpanel.notfrommenu=false;
           graphwindow.NodeOpenDisplay();
         }  //  end nodeOpenDisplay
         else if (esource == nodeLabel ) {
           graphpanel.notfrommenu=false;
           graphpanel.NodeLabel ();
         }  //  end NodeLabel
         else if ( esource == nodeProperty) {
           graphpanel.notfrommenu=false;
           graphwindow.showNodeProperty();
         }
         else if ( esource == nodeDelete ) {
            graphwindow.showMessage("want to Delete Node");
            graphpanel.NodeDelete ();
          }  //  end NodeDelete
         else if ( esource == copyNode ) {
            graphwindow.showMessage("Want to Copy Object");
            if ( graphpanel.copyNode(GraphEngine.COPY) ) graphwindow.showMessage("Copying...");
              else  graphwindow.showMessage("Copy Operation Failed!");
          }

         else  if (esource == moveNode) {
            graphwindow.showMessage("want to move Object");
            if (graphpanel.moveNode(GraphEngine.MOVE) ) showMessage("Moving...");
              else  graphwindow.showMessage("Move Operation Failed!");
          }
         else  if ( esource == graphNet   ||
           esource == textPlain  ||
           esource == textHTML) {
           MIME_Type mt = new MIME_Type();
            if ( esource == graphNet ) mt.setBoth(MIME_Type.GRAPH, MIME_Type.NET);
            if ( esource == textPlain ) mt.setBoth(MIME_Type.TEXT, MIME_Type.PLAIN);
            if ( esource == textHTML ) mt.setBoth(MIME_Type.TEXT, MIME_Type.HTML);
            System.out.println("******: MIME_Type="+mt.getType()+"/"+mt.getSubtype());
            graphpanel.notfrommenu=false;
            graphwindow.NodeCreateContent ( mt,"NULL");
        }  //  end nodeCreateContent

        }
    }

    protected void processMouseEvent(MouseEvent e)
    {
        //System.out.println("In new ProcessMouseEvent");
          if (e.isPopupTrigger() )
            {

          /*if (graphWindow.isWrite()) {
            }
            else {
            }
          */
             switch (graphEngine.getWorkingMode()) {    // determine which popup menu to use
              case GraphEngine.PASTEGRAPHMODE:
                System.out.println("show pasteGraphPopup");
                pasteGraphPopup.show(this, e.getX(), e.getY());
                break;
              case GraphEngine.PASTECONTENTMODE:
                System.out.println("show pasteContentPopup");
                pasteContentPopup.show(this, e.getX(), e.getY());
                break;
              case GraphEngine.MOVEGRAPHMODE:
                System.out.println("show moveGraphPopup");
                moveGraphPopup.show(this, e.getX(), e.getY());
                break;
              case GraphEngine.MOVECONTENTMODE:
                System.out.println("show moveContentPopup");
                moveContentPopup.show(this, e.getX(), e.getY());
                break;
              default:
                if (graph.aNodeIsSelected )  {
                    nodePopup.show(this,e.getX(),e.getY());
                } else System.out.println("No popup menu triggered");
             }
            //}
            // else showMessage("Read Mode. Operation failed."); return;
        }
       else  super.processMouseEvent(e);

  }

private void showMessage(String msg) {
    graphWindow.showMessage(msg);
}

}  // end GraphPanel

