
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.AbstractTableModel;



import java.awt.AWTException;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

import java.awt.geom.CubicCurve2D;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.JTextField;

import java.util.Random;

import java.util.Iterator;
import javax.imageio.*;
import javax.imageio.stream.*;

/*
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.io.image.ImageData; 
import com.itextpdf.io.image.ImageDataFactory; 


import com.itextpdf.kernel.pdf.PdfDocument; 
import com.itextpdf.layout.element.*;
import com.itextpdf.text.Rectangle;
*/


//import com.itextpdf.text.Image;



// http://fpl.cs.depaul.edu/jriely/450/index.html  Cay S. Horstmann

// https://github.com/violetumleditor/violetumleditor

/************************************  liens vers des sources ********************************************************/

//https://stackoverflow.com/questions/46831166/adding-itextpdf-libraries-to-eclipse

// https://www.youtube.com/watch?v=sxArv-GskLc

//https://github.com/itext/itextpdf

//https://github.com/itext/itext7    ++++
	
//	https://www.youtube.com/watch?v=OnEkVhAVSjA

//https://jar-download.com/artifacts/com.itextpdf/itextpdf/5.5.9/source-code

// https://www.developpez.net/forums/d715647/java/general-java/debuter/importer-librairie-itext/

// https://www.tutorialspoint.com/design_pattern/design_pattern_resources.htm

// https://github.com/dieforfree/edsebooks/tree/master/ebooks

// http://www.horstmann.com/violet/

// lien
// https://www.journaldev.com/1325/composition-in-java-example
// https://www.geeksforgeeks.org/association-composition-aggregation-java/   composition

// https://www.ukonline.be/cours/java/apprendre-java


/// GRID 

// https://isr.umd.edu/~austin/ence200.d/java-code.d/demo-polygon1.d/

//https://isr.umd.edu/~austin/ence688r.d/java-swing.html

// http://www.java2s.com/Tutorials/Java/Graphics_How_to/Shape/Draw_grid.htm

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


public class TopPanel10 extends JPanel  implements MouseListener, MouseMotionListener , KeyListener, Printable
{
	
  	private Toolbar myToolbar ;
  	private Graph    graph;    
  	private Graph02  graph02;
  	private Graph03  graph03;
  	private Graph_line  graph_line;
  	private Graph_circle  graph_circle;
	  	
	private Graph_Node    graph_node;    
  	
  	Node  node_selection = null;
	Text  text_selection = null; 
	EdgeObj  edge_selection = null; 
	RectangleObj  rectangle_selection = null; 
	LineObj  line_selection = null; 
  	CircleObj circle_selection = null;
  	
  	EdgeObj text_edge_selection = null;
  	
	Node_Rectangular  node_rectangle_selection = null;
  	
  	LoopbackObj loopback_selection = null;
  	
  	EdgeObj save_edge_selection = null;
  	
  	Node_Rectangular node_rectangulare_selection = null;
  	
  	LoopbackObj loop_obj  = null;
  	CubicCurve2D.Double loop;
	
	
    String selection_obj = ""; 
  	boolean dragging_mode = false;
	
  	TextDialog dialog;
  	
  	JPopupMenu popupMenu;
    
  	ArrayList<Node>   selected = new ArrayList<Node>();
  	
  	MouseEvent save_evt;
  	
	private ClasseTransfert trans = new ClasseTransfert();
	
    String saisie = "";
    private File fileName;
    
    private JFrame JFrame;
    
    private Node     		dragNode;  
   	private EdgeObj 	  	dragEdge;  
    private Text     		dragText;  
    private RectangleObj   	dragRectangle; 
    private LineObj		    dragLine;
    private CircleObj		dragCircle;
    private LoopbackObj		dragLoop;
    
    
    private EdgeObj 	  	dragCondition;  
    
    private	Node_Rectangular	dragNodeRectangle;
    
    
    private Point2D  		dragPoint; 
    private Point2D			StartPoint, EndPoint;
    
    //ArrayList<RectangleObj> array_rectangle_obj = new ArrayList<RectangleObj>();
  	
    private boolean drag_rectangle = false;
    private boolean drag_line = false;
    private boolean drag_circle = false;
    private boolean drag_edge = false;
    
    
    boolean isAlreadyOneClick;
    
    RectangleObj currentShapeObject;
    CircleObj CircleCurrentObject;
    
    private int offsetx, offsety;  
    
    // rectangle et polygon
    private boolean rectangle_current_point_anchar = false;
    private int rectangle_current_point_anchar_selected;
	private Point rectangle_P1_points_anchar;
	private Point rectangle_P3_points_anchar;
	
	// line
	private boolean line_current_point_anchar = false;
    private int line_current_point_anchar_selected;
	private Point line_P1_points_anchar;
	private Point line_P2_points_anchar;
	
	// circle
	private boolean circle_current_point_anchar = false;
    private int circle_current_point_anchar_selected;
	private Point circle_P1_points_anchar;
	private Point circle_P3_points_anchar;
	
    int line_orientation;
	
	private int rect_x;
	private int rect_y;
	private int rect_width;
	private int rect_height;
	

	boolean circle_creation = false;
	boolean circle_to_oval = false;
	
    private Point2D[] points;
    private static Random generator = new Random();
    private static int SIZE = 10;
    private int current;
    
	private boolean drag_edge_startPt = false;
	
	private boolean action_draw_connection = false;
	
	
	private int snap_grid = 10;
	
	int snap_x_condition;
	int snap_y_condition;
		
	
	private Node_Rectangular state_start_obj = null;
	private Node_Rectangular state_end_obj = null;
	
	
	
	/****************************************************************************************/
	
	public TopPanel10()
	{
		super();
		
		myToolbar = new Toolbar();
		graph02 = new Graph02();
		graph03 = new Graph03();
		graph_line = new Graph_line();
		graph_circle = new Graph_circle();
		
		graph_node = new Graph_Node();
		
		
		split02.myArea.setText(" [ INFO ]: Init GUI : OK : revision " + " TopPanel10 "  + "\n");
	    	
	    DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	    Date date = new Date();
	    dateFormat.format(date);
	   	
	    split02.myArea.append(" " + dateFormat.format(date) + "\n");
	    split02.myArea.setBackground(Color.yellow);
	    	
	    addMouseListener((MouseListener) this);  
	    addMouseMotionListener(this);  
	    
	    setPreferredSize(new Dimension(2400, 2000));
	    
	     setFocusable(true);
	    // setVisible(true);
	    // requestFocusInWindow();
	     addKeyListener(this);
	      
	    //setFocusable(true);
        //requestFocusInWindow(true);
        //addKeyListener(this);
	    
	    
	    //this.addMouseListener(new MouseListener());
	    //this.addMouseMotionListener(new MotionListener());
	    	
	    this.setBackground(Color.white);
	    		
	    graph = Graph.example();
	
	    
	    //int n = 2;
	    //points = new Point2D[n];
	    //  for (int i = 0; i < n; i++)
	    //  {
	    //     double x = generator.nextDouble() * 800; //getWidth();
	    //     double y = generator.nextDouble() * 700; //getHeight();
	    //     points[i] = new Point2D.Double(x, y);
	    //  }     
    }
	
	 /****************************************************************************************/

	void create_popup_menu(MouseEvent e) 
    {
        JMenuItem menuItem;
        JPopupMenu popupMenu = new JPopupMenu();
        ArrayList<Node> liste_node = null ;
        ArrayList<String> liste_node_available = new ArrayList<String>() ;
        selected = graph.selectedNodes();
        boolean menu_extension = false; 
        
        int xmouse = e.getX();
        int ymouse = e.getY();
        
        
        ActionListener menuListener = new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                JMenuItem source = (JMenuItem)(e.getSource());
                String input = source.getText();
                System.out.println(input);
                System.out.println("Popup menu item [" + e.getActionCommand() + "] was pressed.");
                
                // pour ajouter un state
                if(checkStateName(input))
                {
                	String state_start_name = graph.find_selected();
                	String state_end_name = input;
                	Node   state_start_obj   = graph.nodeNamed(state_start_name); 
                	Node   state_end_obj   = graph.nodeNamed(state_end_name);
                	System.out.println("Creation de la transistion entre les states ...");
                	
                	// pour eviter les doublons
                	if( graph.GetEdgeExists(state_start_obj, state_end_obj) == true  )   
                	{
                		System.out.println("existe deja !!!!!!");
                		JOptionPane.showMessageDialog(null,  "Cette transistion existe dèjà !.", "Attention", JOptionPane.ERROR_MESSAGE);
                	          
                	}
                	else
                	{	
                		graph.addEdge(state_start_obj, state_end_obj);
                		repaint();
                	}
                }
                
                
                if(input == "Delete Loopback Transition")
                {
                	selected.get(0).Set_loopback_status(false); 
                	System.out.println("remove loopback");
                	repaint();
                }
                
                if(input == "New Loopback Transition")
                {
                	ArrayList<Node>   selected = new ArrayList<Node>();
                    selected = graph.selectedNodes();
                    
                    if(selected.size() == 1)
                    {
                    	selected.get(0).Set_loopback_status(true);
                    	//graph.addLoopBack(selected.get(0), xmouse, ymouse);
                        repaint();
                    }
                }
                
                
                if(input == "Delete Reset state")
                {
                	selected.get(0).Set_reset_status(false); 
                	System.out.println("remove delete");
                	repaint();
                }
                
                if(input == "Reset state")
                {
                	System.out.println("Add delete");
                	ArrayList<Node> selected = new ArrayList<Node>();
                    selected = graph.selectedNodes();
                    
                    if(selected.size() == 1)
                    {
                    	selected.get(0).Set_reset_status(true);
                        repaint();
                    }
                }
                
                
                if(input == "Infos")
                {
                	split02.myArea.append(" [ INFO ]: Obj listing " + "\n");
                	
                	ArrayList<Node>  list_nodes  = new ArrayList<Node>();
                    list_nodes = graph.getNodes();
                    split02.myArea.append(" Nb states : " + list_nodes.size() + "\n");
                	
                    ArrayList<EdgeObj>  list_edges  = new ArrayList<EdgeObj>();
                    list_edges = graph.getEdges();
                    split02.myArea.append(" Nb edges : " + list_edges.size()+ "\n");

                    ArrayList<Text>  list_texts  = new ArrayList<Text>();
                    list_texts = graph02.getTexts();
                    split02.myArea.append(" Nb texts : " + list_texts.size() + "\n");
                  
                    ArrayList<RectangleObj>  list_rects  = new ArrayList<RectangleObj>();
                    list_rects = graph03.getRects();
                    split02.myArea.append(" Nb rects : " + list_rects.size() + "\n");
                    
                    ArrayList<LineObj>  list_lines  = new ArrayList<LineObj>();
                    list_lines = graph_line.getLines();
                    split02.myArea.append(" Nb lines : " + list_lines.size() + "\n");
                    
                    ArrayList<CircleObj>  list_circles  = new ArrayList<CircleObj>();
                    list_circles = graph_circle.getCircles();
                    split02.myArea.append(" Nb circles : " + list_circles.size() + "\n");
                    
                    
                    try { 
            			Thread.sleep(120); 
            			Robot r = new Robot(); 

            			// It saves screenshot to desired path 
            			String path = "D:// Shot.jpg"; 

            			// Used to get ScreenSize and capture image 
            			Rectangle capture = 
            			new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); 
            			BufferedImage Image = r.createScreenCapture(capture); 
            			ImageIO.write(Image, "jpg", new File(path)); 
            			System.out.println("Screenshot saved"); 
            		} 
            		catch (AWTException | IOException | InterruptedException ex) { 
            			System.out.println(ex); 
            		} 
  
                    
                    // https://www.concretepage.com/itext/add-image-in-pdf-using-itext-in-java
                    
                    BufferedImage bufferedImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);

                   String toto = "5";
  /*                 
                   Document document = new Document();
                   try {
					PdfWriter.getInstance(document, new FileOutputStream("d://sample1.pdf"));
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (DocumentException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
                   document.open();
                   //Image img = Image.getInstance(bufferedImage);
                   try {
                	   
                	  // Image img1 = Image.getInstance("arvind-rai.png");
                	   
                	   String url = "http://kodejava.org/wp-content/uploads/2017/01/kodejava.png";
                	   Image image = Image.getInstance(url);
                	   document.add(image);
					document.add(new Paragraph("Sample 1: This is simple image demo."));
				} catch (DocumentException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
                   
                   document.close();
                   System.out.println("Done");

                   
                    
                    /*Component myComponent;
                    
                    Dimension size = myComponent.getSize();
                    BufferedImage myImage = 
                      new BufferedImage(size.width, size.height,
                      BufferedImage.TYPE_INT_RGB);
                    Graphics2D g2 = myImage.createGraphics();
                    myComponent.paint(g2);
                    try {
                      OutputStream out = new FileOutputStream("D:// Shot.jpg";);
                      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
                      encoder.encode(myImage);
                      out.close();
                    } catch (Exception e) {
                      System.out.println(e); 
                    }
                    
                    /*
                    
                    BufferedImage image = null;
                    Graphics gc;
                	Graphics2D imageG = null;
                    image = new BufferedImage(getWidth(), getHeight(),	BufferedImage.TYPE_INT_ARGB);
            		imageG = image.createGraphics();
            		
            		File filetoSave = new File("d://test_capture.jpeg");

					ImageWriter writer = null;
					ImageOutputStream ios = null;

					try {
						// Obtain a writer based on the jpeg format.

						Iterator iter;
						iter = ImageIO.getImageWritersByFormatName("jpeg");

						// Validate existence of writer.

						if (!iter.hasNext()) {
							return;
						}

						// Extract writer.

						writer = (ImageWriter) iter.next();

						// Configure writer output destination.

						ios = ImageIO.createImageOutputStream(filetoSave);
						writer.setOutput(ios);

						// Set JPEG compression quality to 95%.

						ImageWriteParam iwp = writer.getDefaultWriteParam();
						iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
						iwp.setCompressionQuality(0.95f);

						// Write the image.

						writer.write(null, new IIOImage((BufferedImage) image,
								null, null), iwp);
					} catch (IOException e2) {
						e2.getMessage();
					} finally {
						try {
							// Cleanup.

							if (ios != null) {
								ios.flush();
								ios.close();
							}

							if (writer != null)
								writer.dispose();
						} catch (IOException e2) {
						}
					}

            		
    /*                
     * 
     * 
                    
                    Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
                    
                    ImageWriter writer = (ImageWriter)iter.next();
                 // instantiate an ImageWriteParam object with default compression options
                 ImageWriteParam iwp = writer.getDefaultWriteParam();

              

                 iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                 iwp.setCompressionQuality(1);   // an integer between 0 and 1
                 // 1 specifies minimum compression and maximum quality
                    
                 File file = new File("D:// aaaShot.jpg");
                 FileImageOutputStream output = null;
				try {
					output = new FileImageOutputStream(file);
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
                 writer.setOutput(output);
                 
                 Robot r = null;
				try {
					r = new Robot();
				} catch (AWTException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				} 
                 
                 Rectangle capture = 
             			new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); 
             			BufferedImage Image = r.createScreenCapture(capture); 
                 
                 IIOImage image = new IIOImage((RenderedImage) capture, null, null);
                 try {
					writer.write(null, image, iwp);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
                 writer.dispose();
                    
                 */
                 
                    
                	repaint();
                }
                
                if(input == "New Free Text")
                {
                  	 //TextDialog dialog = new TextDialog();
                  	 //dialog.setModal(true);
                  	 //dialog.setVisible(true);
                  	 
                  	 // recupération de la saisie
                  	 //saisie = dialog.getText();
                  	 //System.out.println(saisie);
                  	 
                  	 // creation de l'objet et enregistrement
                  	 //Text azer = new Text( saisie, xmouse, ymouse, Color.black );
                     //graph02.addText(azer);
                  	 //repaint();
                }
                
            }
        };
        
        if(selected.size() == 1)
        {
            String current_selected_state = graph.find_selected();
            System.out.println(current_selected_state);
            
            liste_node = graph.getNodes();
            
            for ( int i = 0;  i < liste_node.size(); i++)
            {
                String tempName = graph.getNodes().get(i).getLabel();
                if( !tempName.equals(current_selected_state) )
                {
                	liste_node_available.add(tempName);
                }
            }
          
            if(liste_node_available.size() >= 1)
            {
            	// creation du sous menu
            	menu_extension = true; 
            }
        }    
        
        /***************************************/
        
        if(menu_extension == true)
        {	
        	
        	 JMenuItem states = new JMenu("New State Transition to ...");
       	  	 popupMenu.add(states);
       	  	 
       	     JMenuItem item;
       	  	 
       	     for(int i = 0; i < liste_node_available.size() ; i++)
       	     {
       	    	 item =  new JMenuItem(   liste_node_available.get(i)	 );
       	    	 item.addActionListener(menuListener);
       	    	 states.add(item);
       	     }
        
        }
        
        /*************************************************/
        if(selected.size() != 0) 
        {
	        if( selected.get(0).Get_loopback_status() == true )
	        {
	        	menuItem = new JMenuItem("Delete Loopback Transition");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
	        
	        else
	        {	
	        	menuItem = new JMenuItem("New Loopback Transition");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
        }
        
        /*************************************************/
        
        if(selected.size() != 0) 
        {
	        if( selected.get(0).Get_reset_status() == true )
	        {
	        	menuItem = new JMenuItem("Delete Reset state");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
	        
	        else
	        {	
	        	menuItem = new JMenuItem("Reset state");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
        }
        
        /*************************************************/
        
        //menuItem = new JMenuItem("New Free Text");
        //menuItem.setMnemonic(KeyEvent.VK_F);
        //menuItem.addActionListener(menuListener);
        //popupMenu.add(menuItem);
       
        /*************************************************/
        
        menuItem = new JMenuItem("Infos");
        menuItem.setMnemonic(KeyEvent.VK_F);
        menuItem.addActionListener(menuListener);
        popupMenu.add(menuItem);
        
        popupMenu.show(e.getComponent(),  save_evt.getX() ,save_evt.getY());
        
    }
    
	/****************************************************************************************/
	
    void showPopup()  
    {
    	create_popup_menu( save_evt );
    }
    
    /****************************************************************************************/

    private boolean checkStateName(String input)
    {
    	ArrayList<Node> node_obj = graph.getNodes();
    	
        for(int j = 0; j < node_obj.size(); j++)
        {
            if( node_obj.get(j).getLabel().equals(input) )
            {
                return true;
            }
        
        }
        return false;
    }
    
	 /****************************************************************************************/
	    
    @Override
	public void paintComponent(Graphics g) 
	{
    	super.paintComponent(g);
    	
    	System.out.print("Refresh \n");

        Graphics2D g2d = (Graphics2D) g;
    	
        ////////////////////////////////////////////////////

    	//Set  anti-alias!
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,   RenderingHints.VALUE_ANTIALIAS_ON); 

       // Set anti-alias for text
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,  RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
        
        ////////////////////////////////////////////////////
    	g2d.setColor(Color.black);
    	
    	int panel_width = getWidth();
    	int panel_height = getHeight();
    	        
        for(int i = 0 ; i <= (panel_width / snap_grid )  ; i++)
	    {	
	        for(int j = 0; j <= (panel_height / snap_grid)  ; j++)
	        {
	        	int x = snap_grid * i;
	        	int y = snap_grid * j;
	        	//g.fillOval( x-1, y-1, 2, 2);
	        	g.drawLine(x, y, x, y);
	        }   
	      }
        
        ////////////////////////////////////////////////////
    	
    	//if (points == null) return;
        //Graphics2D g2 = (Graphics2D) g;
        //for (int i = 0; i < points.length; i++)
        //{
        //   double x = points[i].getX() - SIZE / 2;
        //   double y = points[i].getY() - SIZE / 2;
        //   g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE));
        //}
        //Ellipse2D s = new Ellipse2D.Double();
        //s.setFrameFromDiagonal(points[0], points[1]);
        //g2.draw(s);
    	
/*    	
        
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        int w = getWidth();
        int h = getHeight();
        int x = w/3;
        int y = h/4;
        int rectW = w*3/8;
        int rectH = h/4;
        g.setColor(Color.red);
        g.drawRect(x, y, rectW, rectH);
        Font font = g2.getFont().deriveFont(16f);
        g2.setFont(font);
        String text = "hello world";
        FontRenderContext frc = g2.getFontRenderContext();
        int textWidth = (int)font.getStringBounds(text, frc).getWidth();
        LineMetrics lm = font.getLineMetrics(text, frc);
        int textHeight = (int)(lm.getAscent() + lm.getDescent());
        int sx = x + (rectW - textWidth)/2;
        int sy = (int)(y + (rectH + textHeight)/2 - lm.getDescent());
        g.setColor(Color.blue);
        g.drawString(text, sx, sy);
        */
        
        /************************************************************************/
    	 /*       
        int numberOfLines=0;

        for (String line : str.split("\n")) 
        {
        	g2d.drawString(line, x , y + (numberOfLines * height));
        	numberOfLines++;
        }

        g2d.drawRect(x - 2, y - height + 2, width + 4, height * numberOfLines);
        
        
        https://stackoverflow.com/questions/23729944/java-how-to-visually-center-a-specific-string-not-just-a-font-in-a-rectangle?noredirect=1&lq=1
        
        https://stackoverflow.com/questions/27706197/how-can-i-center-graphics-drawstring-in-java
        
        http://www.java2s.com/Tutorial/Java/0261__2D-Graphics/Drawtexttothecenter.htm
        
        
    	/************************************************************************/
    	
        /*
        String text = "this is a test";
        
       // Graphics2D g2d = (Graphics2D) g.create();

        g2d.setColor(Color.RED);
        g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
        g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);

        Font font = new Font("Arial", Font.BOLD, 48);
        g2d.setFont(font);
        FontMetrics fm = g2d.getFontMetrics();
        int x = ((getWidth() - fm.stringWidth(text)) / 2);
        int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();

        g2d.setColor(Color.BLACK);
        g2d.drawString(text, x, y);
        
        */
        
       
        FontMetrics fm = g2d.getFontMetrics();
        System.out.println(fm.stringWidth("This is a simple test"));
        
        
      //  FontMetrics metrics = graphics.getFontMetrics(font);
      //  int width = metrics.stringWidth("Hello world!");
        
        
       // Graphics2D g2d = ...
       // 		Font font = ...
       // 		Rectangle2D r = font.getStringBounds("hello world!", g2d.getFontRenderContext());
       // 		System.out.println("(" + r.getWidth() + ", " + r.getHeight() + ")");
        
        
        		g.setFont( new Font( "Helvetica", Font.PLAIN, 12 ) );
        		FontMetrics obj_fm = g.getFontMetrics( );
        		Rectangle2D rect_bounds1 = obj_fm.getStringBounds("Hello World!", null);  
         	    int widthInPixels1 = (int) rect_bounds1.getWidth(); 	
         	    int heightInPixels1 = (int) rect_bounds1.getHeight(); 
        	    System.out.println(" WWWWW  " + widthInPixels1 + " " + heightInPixels1);

        		
        		Font font = new Font("Verdana", Font.PLAIN, 10);  
        	    FontMetrics metrics = new FontMetrics(font) {       	    };  
        	    Rectangle2D rect_bounds = metrics.getStringBounds("Hello World!", null);  
        	    int widthInPixels = (int) rect_bounds.getWidth(); 	
        	    int heightInPixels = (int) rect_bounds.getHeight(); 	
        	    System.out.println(" WWWWW  " + widthInPixels + " " + heightInPixels);
        	  //  int width = g.getFontMetrics().stringWidth("Hello World!");
        	  //  int height = g.getFontMetrics().getHeight().("Hello World!");
        	    
        	  
        	    
        	    int xc = 450;
        	    int yc = 350;
        	    
        	    g.drawString("Hello World!", xc, yc);
        	    
        	    int xa =  xc - 25;
        	    int ya =  yc -  heightInPixels - 25;
        	    
        	    int xb =  xc + widthInPixels + 25;
        	    int yb =  yc + 25;
        	    
        	    int largeur = xb - xa;
        	    int hauteur = yb - ya;
        	    g.drawRect( xa, ya , largeur, hauteur );
        	    
        	    
        	    String text = "un jour le soleit\npuis le chien du voisin\navec un ballon";
        	    
        	    int xx = 600;
        	    int yy = 555;
        	    
        	    for (String line : text.split("\n"))
        	        g.drawString(line, xx, yy += g.getFontMetrics().getHeight());
        		
        
    	 if(drag_edge_startPt == true )
    	 {
        	 graph.dynamic_draw((Graphics2D) g);
	    	 System.out.println("dynamic");  
    	 }
    	
    	 if(drag_edge_startPt == false ) // && dragging_mode == true 
    	 {
    		 if(dragging_mode == true )
    		 {	     boolean recalculation = true;
    		    	 graph.new_draw((Graphics2D) g, recalculation   );
    		    	 //graph.affiche_draw((Graphics2D) g, recalculation   );

    		    	 System.out.println("normal");
    		    	 recalculation = false;
    		 }
    		 else
    		 {
    			 boolean recalculation = false;
		    	 graph.new_draw((Graphics2D) g, recalculation   );
		    	 //graph.new_draw((Graphics2D) g, recalculation   );
		    	 
		    	 
		    	 
		    	 System.out.println("normal");
		    	 recalculation = false;
    		 }
    	 }
    	
    	/************************************************************************/
	    	
		
		g2d.setColor(Color.orange);
		g2d.fillOval(0, 0, 30, 30);
		g2d.drawOval(0, 50, 30, 30);		
		g2d.fillRect(50, 0, 30, 30);
		g2d.drawRect(50, 50, 30, 30);

		g2d.draw(new Ellipse2D.Double(0, 100, 30, 30));
		
	//	BBBGraphicsUtil.drawArrow(g2d, 200, 200, 400, 500, 30, 20);
			
		/***************** draw loopback  ******************/
		
		ArrayList<Node>   tmp = new ArrayList<Node>();
	       
    	
    	for(int i = 0; i < graph.getNodes().size(); i++)
    	{
    		tmp = graph.getNodes();
    		
    		if( tmp.get(i).Get_loopback_status()  == true )
    		{
    			/*
    			 int xcentre = (int) tmp.get(i).getLocation().getX();
                 int ycentre = (int) tmp.get(i).getLocation().getY();
             
                 int radius = 50;
                 int x0  = xcentre - radius;
                 int y0  = ycentre - radius;
                 int x1  = xcentre + radius;
                 int y1 =  ycentre + radius;
   				
                 LoopbackObj loopback_obj = new LoopbackObj();

                 // récupére l'objet
                 loop_obj = new LoopbackObj();
                 loop =  loop_obj.get_loop();
                 
                 Graphics2D g2D = (Graphics2D) g;
                 loopback_obj.draw_loopback(g2D, x0, y0, x1, y1);*/
    			
 //   			il faut recalculer l'arc de cercle du loopback lorsque l'on move un state
    			
    			 LoopbackObj loopback_obj = new LoopbackObj();
    			 loopback_obj = tmp.get(i).getloopback();
    			 Graphics2D g2D = (Graphics2D) g;
    			 //loopback_obj.draw_loopback(g2D); 
    			loopback_obj.draw_loopback(g2D); 
    			 
    		}
    	} 
    	
		
    	/***************** draw text  ******************/
    	
		ArrayList<Text>   tmp_texts = new ArrayList<Text>();
        
    	/**/
    	for(int i = 0; i < graph02.getTexts().size(); i++)
    	{
    		tmp_texts = graph02.getTexts();
    		
     		// calcul
    		Rectangle2D bounds = graph02.getBounds(g2d, tmp_texts.get(i).getText() );
     		// extraction
     		int width = (int) bounds.getWidth();
     		int height = (int) bounds.getHeight();
     		// enregistre
     		tmp_texts.get(i).setWidth(width);
     		tmp_texts.get(i).setHeight(height);
     		  
     		if(tmp_texts.get(i).getSelected() == true)
    	   	{
     			g.setColor(Color.RED);
    	   	}
    	   	else
    	   	{	 
    	   		// couleur enregistrée
    	   		g.setColor( tmp_texts.get(i).getColor() );
    	   	}
    		 
     		// ghost
     		//g2D.drawRect (tmp_texts.get(i).getX(),  tmp_texts.get(i).getY(), width, height);  
     		 
    		 graph02.drawString(g2d, tmp_texts.get(i).getText() , tmp_texts.get(i).getX(),  tmp_texts.get(i).getY() );  
    		
    	} 
    	
    	
    	/***************** draw rectangle interactif pendant le dragmode afin d'avoir un tracé multi direction  ******************/
    	
        if (currentShapeObject!=null)
        {	
    	    g.drawRect( currentShapeObject.getUpperLeftX(), currentShapeObject.getUpperLeftY() ,	currentShapeObject.CalcWidth() , currentShapeObject.CalcHeight() ); 
    	    System.out.println("Draw interactif");  
        }
    	   
        /** draw les rectangles qui sont dans la Database**/ 
		for(int i = 0; i < graph03.getRects().size(); i++)    		
		{
		    		 RectangleObj rect = graph03.getRects().get(i);
		    		 
		    		 if(rect.getsetSelected() == true)
		   		     {	 
		   		    	g.setColor(Color.RED);
		   		    	
		   		    	// anchor 
		   		    	int x = rect.x1;
		   		    	int y = rect.y1; 
		   		    	int	w = rect.getWidth();
		   		    	int h = rect.getHeight();
		   		    	
		   		    	int SIZE = 12;
		   		    	
		   		        g.fillRect(x - SIZE /2, y - SIZE /2, SIZE, SIZE);
		   		      //  g.fillRect(x + w - SIZE /2, y - SIZE /2, SIZE, SIZE);
		   		        g.fillRect(x + w - SIZE /2, y + h - SIZE /2, SIZE, SIZE);
		   		      //  g.fillRect(x - SIZE /2 , y + h - SIZE /2, SIZE, SIZE);
		   		    	 
		   		     }
		   		     else
		   		     {
		   		    	 g.setColor(rect.color);
		   		     }
		   		    
		    		  //g.drawRect( rect.getUpperLeftX(), rect.getUpperLeftY() ,	rect.getWidth() , rect.getHeight() ); 
		    		 g.drawRect( rect.x1, rect.y1 ,	rect.getWidth() , rect.getHeight() ); 
		    		 
		    		// g.drawRect( rect.getUpperLeftX(), rect.getUpperLeftY() ,	rect.CalcWidth() , rect.CalcHeight() ); 
		}
    	
	    // redimensiontement dynamique 
		
		
		if(line_current_point_anchar == true)
	    {
			line_selection.setX1( (int) line_P1_points_anchar.getX() );
			line_selection.setY1( (int) line_P1_points_anchar.getY() );
			
			line_selection.setX2( (int) line_P2_points_anchar.getX() );
			line_selection.setY2( (int) line_P2_points_anchar.getY() );
	    }
		
	   		    
	    if(rectangle_current_point_anchar == true)
	    {
	    			 
	    			 if(rectangle_current_point_anchar_selected == 1)
	     			 {
			    				 int width = rectangle_P1_points_anchar.x - rectangle_P3_points_anchar.x;
			    				 int height = rectangle_P1_points_anchar.y - rectangle_P3_points_anchar.y ; 
		 				    	 if( width < 0 && height < 0) // -- 
		 				    	 {
		 				    		int w = - width;
		 				    	    int h = - height;
			    				    g.drawRect( rectangle_P1_points_anchar.x , rectangle_P1_points_anchar.y , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  rectangle_P1_points_anchar.x;
			    				    rect_y =  rectangle_P1_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("Zone A");  
		 				    	 }
		 				    	 if( width < 0 && height > 0) // - +
		 				    	 {
		 				    		int w =  -width;
		 				    	    int h =  height;
			    				    g.drawRect( rectangle_P3_points_anchar.x - w  , rectangle_P3_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  rectangle_P3_points_anchar.x - w;
			    				    rect_y =  rectangle_P3_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("Zone B ");  
		 				    	 }
		 				    	 if( width > 0 && height < 0) // + -
		 				    	 {
		 				    		int w =  width;
		 				    	    int h =  -height;
		 				    	    g.drawRect( rectangle_P3_points_anchar.x , rectangle_P1_points_anchar.y , w, h );
			    				    // sauve tmp
			    				    rect_x =  rectangle_P3_points_anchar.x;
			    				    rect_y =  rectangle_P1_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("Zone C " );  
		 				    	 }
		 				    	 if( width > 0 && height > 0) // + + 
		 				    	 {
		 				    		int w =  width;
		 				    	    int h =  height;
		 				    	    g.drawRect( rectangle_P3_points_anchar.x , rectangle_P1_points_anchar.y - h , w, h ); 
			    				    // sauve tmp
			    				    rect_x = rectangle_P3_points_anchar.x;
			    				    rect_y =  rectangle_P1_points_anchar.y - h;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("Zone D ");  
		 				    	 }
 	 				    		 // mise a jour de l'objet
		 				    	 rectangle_selection.setX1(rect_x);
		 			        	 rectangle_selection.setY1(rect_y); 
		 			        	 rectangle_selection.setWidth(rect_width);
		 			        	 rectangle_selection.setHeight(rect_height);
	     			 	}
	    			 
	    			 	if(rectangle_current_point_anchar_selected == 3)
	    			 	{
	    				 		 int width = rectangle_P1_points_anchar.x - rectangle_P3_points_anchar.x;
	    				 		 int height = rectangle_P1_points_anchar.y - rectangle_P3_points_anchar.y ; 
		 				    	 if( width < 0 && height < 0) // - -
		 				    	 {
		 				    		int w = - width;
		 				    	    int h = - height;
		    				    	g.drawRect( rectangle_P1_points_anchar.x  , rectangle_P3_points_anchar.y -h   , w , h ); 
			    				    // sauve tmp
			    				    rect_x =  rectangle_P1_points_anchar.x;
			    				    rect_y =  rectangle_P3_points_anchar.y-h;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone A " + rectangle_P1_points_anchar.x + " " + rectangle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }
		 				    	 if( width > 0 && height < 0) // + -
		 				    	 {
		 				    		int w =  width;
		 				    	    int h = - height;
			    				    g.drawRect( rectangle_P3_points_anchar.x   , rectangle_P1_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  rectangle_P3_points_anchar.x;
			    				    rect_y =  rectangle_P1_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone B " + rectangle_P1_points_anchar.x + " " + rectangle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }
		 				    	 
		 				    	 if( width > 0 && height > 0) // + + 
		 				    	 {
		 				    		int w =  width;
		 				    	    int h =  height;
			    				    g.drawRect( rectangle_P3_points_anchar.x   , rectangle_P3_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  rectangle_P3_points_anchar.x;
			    				    rect_y =  rectangle_P3_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone C " + rectangle_P1_points_anchar.x + " " + rectangle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }

		 				    	 if( width < 0 && height > 0) // - +s
		 				    	 {
		 				    		int w =   - width;
		 				    	    int h =  height;
			    				    g.drawRect( rectangle_P1_points_anchar.x     , rectangle_P3_points_anchar.y      , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  rectangle_P1_points_anchar.x;
			    				    rect_y =  rectangle_P3_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone D " + rectangle_P1_points_anchar.x + " " + rectangle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }
		 				    	 
		 				    	 // mise a jour de l'objet
			 				     rectangle_selection.setX1(rect_x);
			 			         rectangle_selection.setY1(rect_y); 
			 			         rectangle_selection.setWidth(rect_width);
			 			         rectangle_selection.setHeight(rect_height);
	    			 	}
	    			 	
	    }
	    
	    /*******************************************************************************************/
	    /***************** draw line interactive   ******************/
	    
	    if (drag_line == true) 
	 	{
            g.setColor(Color.RED);
        	drawArrow(g2d, (int)StartPoint.getX() , (int)StartPoint.getY(), (int)EndPoint.getX(), (int)EndPoint.getY(), 30, 20);
        	
        	//Rectangle2D prostokat = new Rectangle2D.Double();
            //prostokat.setFrameFromDiagonal ((int)StartPoint.getX() , (int)StartPoint.getY(), (int)EndPoint.getX(), (int)EndPoint.getY());
            //((Graphics2D) g).draw(prostokat);
        	
            //g.drawLine((int)StartPoint.getX() , (int)StartPoint.getY(), (int)EndPoint.getX(), (int)EndPoint.getY());
            System.out.println("TRACE line");  
        }
	    
	    /***************** draw les obj lines enregistrés   ******************/
	    for(int i = 0; i < graph_line.getLines().size(); i++)    		
		{
		    		 LineObj line = graph_line.getLines().get(i);
		    		 
		    		 if(line.getsetSelected() == true)
		   		     {	 
		   		    	g.setColor(Color.RED);
		   		    	// draw anchor
		   		    	int SIZE = 12;
		   		        g.fillRect(line.getX1() - SIZE /2, line.getY1() - SIZE /2, SIZE, SIZE);
		   		        g.fillRect(line.getX2() - SIZE /2, line.getY2() - SIZE /2, SIZE, SIZE);
		   		        
		   		        // milieu de la ligne
		   		        int xmid = ( line.getX1() + line.getX2() ) / 2;
		   		        int ymid = ( line.getY1() + line.getY2() ) / 2;
		   		        g.fillRect(xmid - SIZE /2, ymid - SIZE /2, SIZE, SIZE);

		   		     }
		   		     else
		   		     {
		   		    	 g.setColor(line.color);
		   		     }
		    		 
		         	drawArrow(g2d, line.getX1() , line.getY1() , line.getX2(), line.getY2() , 30, 20);

		}
	    
	 
	    /*******************************************************************************************/
	    
	    /***************** draw circle interactive  ******************/
	    if (drag_circle == true) 
	 	{
            g.setColor(Color.RED);
        	
            int xdiff = (int)StartPoint.getX() - (int)EndPoint.getX() ;
            int ydiff = (int)StartPoint.getY() - (int)EndPoint.getY() ;

            double radius = Math.sqrt(Math.pow(xdiff, 2)+Math.pow(ydiff, 2));
            int int_raduis = ( (int) radius  / snap_grid ) * snap_grid;
            
////            doit être mise à jour dans la partie release qui est sauvé car il existe un decalage
           
            //int int_raduis = (int) radius;
            int diametre = int_raduis*2;
            g.drawOval( (int)StartPoint.getX() - int_raduis, (int)StartPoint.getY() - int_raduis, diametre, diametre );
            System.out.println("Create circle with mouse..  " + int_raduis + " " + diametre + "   " + StartPoint.getX() + "  " + StartPoint.getY());  
        }
	    
	    
	    /********************************************************************************************/
	    
	    
	    if(selection_obj.equals("CONDITION") )
		{
			 
	    	//dragCondition
			//int snap_x = ( e.getX() / snap_grid ) * snap_grid;
			//int snap_y = ( e.getY() / snap_grid ) * snap_grid;
 			 
 			//g.drawString("equation", text_edge_selection.getX() , text_edge_selection.getY());
	    	//System.out.println(" REFRESH " + text_edge_selection.getX() + "  " + text_edge_selection.getY());  
	    	  
	 		g.drawString("abc..", snap_x_condition , snap_y_condition);
		    System.out.println(" REFRESH " + snap_x_condition + "  " + snap_y_condition);  

		 }
	    
	    
	    /***************** draw les obj circles enregistrés    ******************/
	    /** draw les rectangles qui sont dans la Database**/ 
	    
	    for(int i = 0; i < graph_circle.getCircles().size(); i++)    		
		{
		    CircleObj circle = graph_circle.getCircles().get(i);
 			
	   		int x1 = circle.getX1();
	   		int y1 = circle.getY1(); 
	   		int x2 = circle.getX2();
	   		int y2 = circle.getY2(); 
	   		int w = circle.getWidth();
	   		int h = circle.getHeight();
		    		 
		   	if(circle.getsetSelected() == true)
		   	{	 
		   		g.setColor(Color.RED);
		   		int SIZE = 12;
		   		g.fillRect(x1 - SIZE /2, y1 - SIZE /2, SIZE, SIZE);
   		        g.fillRect(x1 + w - SIZE /2, y1 + h - SIZE /2, SIZE, SIZE);
   		     }
   		     else
   		     {
   		    	 g.setColor(circle.color);
   		     }
		   		    
		    //circle_creation 
	    	 //g.drawOval( circle.getX1(), circle.getY1() ,	circle.CalcWidth() , circle.CalcHeight() ); 
		    if(circle_creation == true) 
		    { 
		    	g.drawOval( circle.getX1(), circle.getY1() ,	circle.get_diametre() , circle.get_diametre() ); 
		    	System.out.println("Mode dessin circle");  
		    	circle_creation = false;
		    }
		    
		    else
		    {   
		    	
		    	if( circle == circle_selection && circle_current_point_anchar == true)
		    	{
		    		g.setColor(Color.green);
			 		 
	    			  x1 = circle_P1_points_anchar.x; 
	    			  y1 = circle_P1_points_anchar.y; 
	    			  x2 = circle_P3_points_anchar.x;
                      y2 = circle_P3_points_anchar.y;
			 		 int width =  Math.abs( circle_P1_points_anchar.x - circle_P3_points_anchar.x );
                     int height = Math.abs( circle_P1_points_anchar.y - circle_P3_points_anchar.y );
	    	
	    			 if(circle_current_point_anchar_selected == 1)
	     			 {
		 				    	 if(x1 < x2 && y1 < y2)
		 				    	 {
		 				    		g.drawOval( circle_P1_points_anchar.x  , circle_P1_points_anchar.y  , width , height ); 
			 				    	circle_selection.setX1(circle_P1_points_anchar.x);
			 				    	circle_selection.setY1(circle_P1_points_anchar.y); 
		    				    	//System.out.println("P1 - Q2 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
		 				    	if(x1 < x2 && y2 < y1)
		 				    	{
		 				    		g.drawOval( circle_P3_points_anchar.x - width   , circle_P3_points_anchar.y  , width, height ); 
			 				    	circle_selection.setX1(circle_P3_points_anchar.x -width );
			 				    	circle_selection.setY1(circle_P3_points_anchar.y); 
		    				    	//System.out.println("P1 - Q3 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
		 				    	if(x1 > x2 && y1 < y2)
		 				    	{
		 				    		g.drawOval( circle_P3_points_anchar.x   , circle_P3_points_anchar.y - height , width, height ); 
				 				    circle_selection.setX1(circle_P3_points_anchar.x);
				 				    circle_selection.setY1(circle_P3_points_anchar.y - height); 
		    				    	//System.out.println("P1 - Q1 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
		 				    	if(x1 > x2 && y1 > y2)
		 				    	{
		 				    		g.drawOval( circle_P3_points_anchar.x    , circle_P3_points_anchar.y  , width, height ); 
				 				    circle_selection.setX1(circle_P3_points_anchar.x );
				 				    circle_selection.setY1(circle_P3_points_anchar.y ); 
		    				    	//System.out.println("P1 - Q4 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
		 				    	// mise a jour de l'objet
		 				    	circle_selection.setWidth(width);
		 				    	circle_selection.setHeight(height);
		 				    	//System.out.println("resizing circle.... " +  circle_selection.getX1() + " " + circle_selection.getY1() + " " + circle_selection.getWidth() + " " + circle_selection.getHeight());  
	     			 	}
	    			 
	    			 	if(circle_current_point_anchar_selected == 3)
	    			 	{
	    			 		    if(x1 < x2 && y1 < y2)
		 				    	{
		    				    	g.drawOval( circle_P1_points_anchar.x  , circle_P1_points_anchar.y  , width , height ); 
		    				    	circle_selection.setX1(circle_P1_points_anchar.x);
			 				    	circle_selection.setY1(circle_P1_points_anchar.y); 
			 				    	System.out.println("P3 - Q4 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
	    			 		    if(x1 < x2 && y2 < y1)
		 				    	{
		    				    	g.drawOval( circle_P3_points_anchar.x - width  , circle_P1_points_anchar.y - height , width , height ); 
		    				    	circle_selection.setX1(circle_P3_points_anchar.x - width);
			 				    	circle_selection.setY1(circle_P1_points_anchar.y - height); 
			 				    	System.out.println("P3 - Q1 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
	    			 		    if(x1 > x2 && y1 < y2)
		 				    	{
		    				    	g.drawOval( circle_P3_points_anchar.x   , circle_P1_points_anchar.y   , width , height ); 
		    				    	circle_selection.setX1(circle_P3_points_anchar.x );
			 				    	circle_selection.setY1(circle_P1_points_anchar.y ); 
		    				    	System.out.println("P3 - Q3 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	}
	    			 		    if(x1 > x2 && y2 < y1)
		 				    	{
	    			 			    g.drawOval( circle_P1_points_anchar.x  -width  , circle_P1_points_anchar.y - height , width , height ); 
		    				    	circle_selection.setX1(circle_P1_points_anchar.x - width);
			 				    	circle_selection.setY1(circle_P1_points_anchar.y - height); 
		    				    	System.out.println("P3 - Q2 " + circle_P1_points_anchar.x + " " + circle_P1_points_anchar.y  + " " + circle_P3_points_anchar.x + " " + circle_P3_points_anchar.y );  
		 				    	} 
		 				    	// mise a jour de l'objet
		 				    	circle_selection.setWidth(width);
		 				    	circle_selection.setHeight(height);
		 				    	//System.out.println("resizing circle.... " +  circle_selection.getX1() + " " + circle_selection.getY1() + " " + circle_selection.getWidth() + " " + circle_selection.getHeight());  
	    			 	}
		    	}
		    		
		    	else
		    	{	
				    	
				    	if(circle.getWidth() != circle.getHeight())
				    	{	
				    		g.drawOval( circle.getX1(), circle.getY1() ,	circle.getWidth() , circle.getHeight() ); 
				    		//System.out.println(" Ellipse " + circle.getX1() + " " + circle.getY1() + " " + circle.getX2() + " " + circle.getY2()  );  
				    	}
				    	else
				    	{	
				    		g.drawOval( circle.getX1(), circle.getY1() ,	circle.get_diametre() , circle.get_diametre() ); 
				    		//System.out.println(" Cercle " + circle.get_diametre() + "  " + circle.get_diametre() + " " + circle.get_diametre() );  
				    	}
		    	
		    	}
		    	
		    	
		    }
		    
		 
		}
	    
	    
	    /**********************************************/
	    
	    Graphics2D g2 = (Graphics2D) g;
	    graph_node.draw(g2);
	    
	   /* 
	    for(int i = 0; i < graph_node.getNodeRectangle().size(); i++)    		
		{
	    	Node_Rectangular obj =  graph_node.getNodeRectangle().get(i);
		    
	    	g.setColor(Color.blue);
	    	
	    	int x1 = obj.getX1();
	   		int y1 = obj.getY1(); 
	   		int w = obj.getWidth();
	   		int h = obj.getHeight();
	    	
	    	g.drawRect( x1 , y1  , w, h ); 

	    	ArrayList<Edge_transition>  list_edges  = new ArrayList<Edge_transition>();
	    	
	    	list_edges = graph_node.getEdges();
	    	
	    	if( list_edges.size() != 0)
   			{
	    		System.out.print("Bingo...");
	    		
	    		for(int j = 0; j < list_edges.size() ; j++)    		
	    		{
	    			Node_Rectangular node_start = list_edges.get(j).getStart();
	    			Node_Rectangular node_end = list_edges.get(j).getEnd();
		    		System.out.println(" Start to end node  " + node_start.getX1() + "  " + node_start.getY1() + " " + node_end.getX1() + "  " + node_end.getY1() );  
		    		g.setColor(Color.GREEN);
		    		g.drawLine(node_start.getX1(), node_start.getY1(), node_end.getX1(), node_end.getY1());
	    		}
   			}
	    	
		    
		}    
	    */
	    
		if(action_draw_connection == true)
		{
	         g.setColor(Color.orange);
	         ((Graphics2D) g).draw(new Line2D.Double(StartPoint, EndPoint));
			
		}

	    /*if (rubberBandStart != null)
	      {
	         Color oldColor = g2.getColor();
	         g2.setColor(PURPLE);
	         g2.draw(new Line2D.Double(rubberBandStart, lastMousePoint));
	         g2.setColor(oldColor);
	      }*/
	    
	 
	}

	/****************************************************************************************/
    
    public void drawArrow(Graphics g, int x0, int y0, int x1, int y1,  int headLength, int headAngle) 
    {
        double offs = headAngle * Math.PI / 180.0;
        double angle = Math.atan2(y0 - y1, x0 - x1);
        int[] xs = { x1 + (int) (headLength * Math.cos(angle + offs)), x1,  x1 + (int) (headLength * Math.cos(angle - offs)) };
        int[] ys = { y1 + (int) (headLength * Math.sin(angle + offs)), y1,  y1 + (int) (headLength * Math.sin(angle - offs)) };
        g.drawLine(x0, y0, x1, y1);
        g.drawPolyline(xs, ys, 3);
    }
    
	/****************************************************************************************/
   
    public void mouseClicked(MouseEvent e) 
	{  
		//System.out.println("Mouse Clicked");  
		split02.mouse_compter_click();
	
		/*
		if (e.getClickCount() == 2 && !e.isConsumed()) {
		     e.consume();
		     //handle double click event.
		}
		
		
		//Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
		/*
		if (e.getClickCount() == 1) 
		{
			System.out.println("Single Click");
        }

        if (e.getClickCount() == 2) 
        {
            System.out.println("Double Click");
        }
        */        
     
        // scrute si une action est en cours
/*		
        String val = split02.return_action_selected();
        if(val == "TEXT")
        {
        	// ajouter un texte a la position du click
        	// puis creation de l'objet et enregistrement
        	
        	 if( split02.transfert_get().length()  == 0)
        	 {
        		 JOptionPane.showMessageDialog(null,  "Le champ est vide !", "Attention", JOptionPane.ERROR_MESSAGE);
        	 }
        	 else
        	 {	 
        		 System.out.println(" -----  " +  split02.transfert_get() );
        	     Text text_obj = new Text(  split02.transfert_get() , e.getX(), e.getY(), Color.black );
                 graph02.addText(text_obj);
        	 }
         
        	
        }
        
        // desactive l'action en cours
        split02.stop_action_selected();
        
      //  split02.frame_focus();
        
     //   requestFocusInWindow();
*/        
        // prend le focus sur le panel pour utiliser le listener du panel
        requestFocus();
        
   	 	repaint();
        
	}  
	
	public void mouseEntered(MouseEvent e) 
	{  
		split02.mouse_inside();
	}  
	
	public void mouseExited(MouseEvent e) 
	{  
		split02.mouse_exit_panel();
	}  
	
	public void mousePressed(MouseEvent e) 
	{  
        Point p = e.getPoint();
		
		String val_toolbar = split02.return_action_selected();
        
		node_rectangulare_selection = graph_node.nodeAt(e.getX(), e.getY());
   	    node_selection = graph.nodeAt(e.getX(), e.getY()); //???????
		edge_selection = graph.New_edgeAt(e.getX(), e.getY());
		text_edge_selection = graph.textEdgeAt(e.getX(), e.getY());  
    	loopback_selection = graph.LoopAt(e.getX(), e.getY());
        text_selection  = graph02.textAt(e.getX(), e.getY());
        rectangle_selection  = graph03.rectangleAt(e.getX(), e.getY());
        line_selection = getClickedLine(e.getX(), e.getY());
		circle_selection = graph_circle.new_CircleAt(e.getX(), e.getY());
        
    	ArrayList<Node>   selected_nodes = new ArrayList<Node>();
    	selected_nodes = graph.selectedNodes();
    	
    	ArrayList<EdgeObj>   selected_edges = new ArrayList<EdgeObj>();
    	selected_edges = graph.selectedEdges();
        
    	ArrayList<Text>   selected_texts = new ArrayList<Text>();
    	selected_texts = graph02.selectedTexts();
        
    	ArrayList<RectangleObj>   selected_rects = new ArrayList<RectangleObj>();
    	selected_rects = graph03.selectedRects();
        
    	int total_selected_obj = selected_nodes.size() + selected_edges.size() + selected_texts.size() + selected_rects.size();
    	
    	// un seul obj déplacer en même temps
        
		if (isAlreadyOneClick) 
		{
	        System.out.println("double click");
	        
	        if (node_selection == null && edge_selection == null && text_selection == null && rectangle_selection == null && isAlreadyOneClick == true ) 
	        {
	    		System.out.println("Node creation");
	    		int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	    		int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	    		//saisir_state(new Point2D.Double( e.getX(),e.getY() ) );
	    		saisir_state(new Point2D.Double( snap_x , snap_y  ) );
		        System.out.println("***** " + e.getX() + " " + e.getY() + " " + snap_x + " " + snap_y);
	        }
	        
	        isAlreadyOneClick = false;
	    } 
		else 
		{
	        isAlreadyOneClick = true;
	        
	        //////////    selection des objets ///////
	        
	        
	        if(line_selection != null)
	        {
	        	int x1 = line_selection.getX1();
	        	int y1 = line_selection.getY1();
	        	int x2 = line_selection.getX2();
	        	int y2 = line_selection.getY2();
	        	
	        	System.out.println("TRACE");
	        	 
	        	int SIZE = 12;
			    	
                Rectangle2D P1_area = new Rectangle2D.Double(x1 - SIZE /2, y1 - SIZE /2, SIZE, SIZE);     
                Rectangle2D P2_area = new Rectangle2D.Double(x2 - SIZE /2, y2 - SIZE /2, SIZE, SIZE);

                // milieu de la ligne
   		        int xmid = ( x1 + x2 ) / 2;
   		        int ymid = ( y1 + y2 ) / 2;
                Rectangle2D Pmiddle_area = new Rectangle2D.Double(xmid - SIZE /2, ymid - SIZE /2, SIZE, SIZE);
                
                if (P1_area.contains(p))
                {
                	line_P1_points_anchar = new Point(x1, y1);
                	line_P2_points_anchar = new Point(x2, y2 );
    	        	System.out.println("P1_area");
    	        	line_current_point_anchar = true;
    	        	line_current_point_anchar_selected = 1;  // point p1
                }
                
                if (P2_area.contains(p))
                {
                	line_P1_points_anchar = new Point(x1, y1);
                	line_P2_points_anchar = new Point(x2, y2 );
                	System.out.println("P2_area");
    	        	line_current_point_anchar = true;
    	        	line_current_point_anchar_selected = 2;  // point p2
                }
                
                
                if(Pmiddle_area.contains(p))
                {
                	// calcul les distances x et y du milieu au point P1
                	
                	// orientation 
                	if(x1 < xmid && x2 > xmid & y1 > y2 ) // 45 haut
                	{
                		System.out.println("Orient 1");  
                		line_orientation = 1;
                	}
                	if(x1 > xmid && x2 < xmid & y1 < y2 )// 45 bas
                	{
                		System.out.println("Orient 2");  
                		line_orientation = 2;
                	}
                	
                	if(x2 < xmid && x1 > xmid & y1 > y2 ) // 135 haut
                	{
                		System.out.println("Orient 3");  
                		line_orientation = 3;
                	}
                	if(x1 < xmid && x2 > xmid & y1 < y2 ) // 135 bass
                	{
                		System.out.println("Orient 4");  
                		line_orientation = 4;
                	}
                	
                	offsetx = Math.abs( x1 - xmid );
                    offsety = Math.abs( y1 - ymid );
                    line_selection.toggleSelected();
                    dragging_mode = true;
                    dragLine = line_selection;
                	selection_obj = "LINE";
                    //dragRectangle = rectangle_selection;
                    System.out.println("Press Drag line");
                }
                
	        }
	                
	        
	        if(rectangle_selection != null)
	        {
	        	
	            int x = rectangle_selection.x1;
		    	int y = rectangle_selection.y1; 
		    	int	w = rectangle_selection.getWidth();
		    	int h = rectangle_selection.getHeight();
		    	
		    	int SIZE = 12;
		    	
                Rectangle2D P1_area = new Rectangle2D.Double(x - SIZE /2, y - SIZE /2, SIZE, SIZE);     
                //Rectangle2D P2_area = new Rectangle2D.Double(x + w - SIZE /2, y - SIZE /2, SIZE, SIZE);
                Rectangle2D P3_area = new Rectangle2D.Double(x + w - SIZE /2, y + h - SIZE /2, SIZE, SIZE);
                //Rectangle2D P4_area = new Rectangle2D.Double(x - SIZE /2 , y + h - SIZE /2, SIZE, SIZE);
		          
                if (P1_area.contains(p))
                {
                	rectangle_P1_points_anchar = new Point(x, y);
                	rectangle_P3_points_anchar = new Point( x + w, y + h);
    	        	System.out.println("P1_area");
    	        	rectangle_current_point_anchar = true;
    	        	rectangle_current_point_anchar_selected = 1;  // point p1
                }
                //if (P2_area.contains(p))
                //{
    	        //	System.out.println("P2_area");
    	        //	current_point_anchar = 2;
                //}
                if (P3_area.contains(p))
                {
                	rectangle_P1_points_anchar = new Point(x, y);
                	rectangle_P3_points_anchar = new Point( x + w, y + h);
    	        	System.out.println("P3_area");
    	        	rectangle_current_point_anchar = true;
    	        	rectangle_current_point_anchar_selected = 3;  // point p2
                }
                //if (P4_area.contains(p))
                //{
    	        //	System.out.println("P4_area");
    	        //	current_point_anchar = 4;
                //}
	        }
	        
	        if(circle_selection != null)
       		{
	        	 System.out.println(" youpi un cercle ");
	        	 selection_obj = "CIRCLE";
	        	 circle_selection.toggleSelected();
	        	 dragCircle = circle_selection; 	
		         dragging_mode = true;
		         
				 int snap_x = ( e.getX() / snap_grid) * snap_grid;
				 int snap_y = ( e.getY() / snap_grid) * snap_grid;
		         // offsetx = e.getX() - dragCircle.getX1();
		         // offsety = e.getY() - dragCircle.getY1();
		         offsetx = snap_x - dragCircle.getX1();
		         offsety = snap_y - dragCircle.getY1();
		    
			     int w = circle_selection.get_diametre();
			     int h;
			     int x1 = circle_selection.getX1();
	 		     int y1 = circle_selection.getY1(); 
			    
	 		     
	 		    // on a un cercle
		    	if(circle_selection.getWidth() == circle_selection.getHeight())
		    	{
		    			w =  circle_selection.get_diametre();
		    			h =  w;
		    	}
		    		// on a une ellipse
		    	else
		    		{
		    			w =  circle_selection.getWidth();
		    			h =  circle_selection.getHeight();
		    		}
	 		     
	 		     /*
		    	 if(circle_selection.getWidth() > 0 && circle_selection.getHeight() > 0)
			     {
		    		    // on a un cercle
			    		if(circle_selection.getWidth() == circle_selection.getHeight())
			    		{
			    			w =  circle_selection.getWidth();
			    			h =  w;
			    		}
			    		// on a une ellipse
			    		else
			    		{
			    			w =  circle_selection.getWidth();
			    			h =  circle_selection.getHeight();
			    		}
			    }
			    else
			    {
			    	w = circle_selection.get_diametre();
			    	h = circle_selection.get_diametre();
			    }
			     */
			    	
			     int SIZE = 12;
			    	
                 Rectangle2D P1_area = new Rectangle2D.Double(x1 - SIZE /2, y1 - SIZE /2, SIZE, SIZE);     
	             Rectangle2D P3_area = new Rectangle2D.Double(x1 + w - SIZE /2, y1 + h - SIZE /2, SIZE, SIZE);
		         
	             if (P1_area.contains(p))
	                {
	            	 	circle_to_oval = true;
	            	 	circle_P1_points_anchar = new Point(x1, y1);
	            	 	circle_P3_points_anchar = new Point( x1 + w, y1 + h);
	    	        	System.out.println("P1_area");
	    	        	circle_current_point_anchar = true;
	    	        	circle_current_point_anchar_selected = 1;  // point p1
	                }
	             
	             if (P3_area.contains(p))
	                {
	            	 	circle_to_oval = true;
	            	 	circle_P1_points_anchar = new Point(x1, y1);
	            	 	circle_P3_points_anchar = new Point( x1 + w, y1 + h);
	    	        	System.out.println("P3_area");
	    	        	circle_current_point_anchar = true;
	    	        	circle_current_point_anchar_selected = 3;  // point p3
	                }
       		}
	        
	        
	        if(loopback_selection != null)
	        {
	        	selection_obj = "LOOPBACK";
	    		loopback_selection.LooptoggleSelected();
	    		loopback_selection.setSelectStatus(e.getX(), e.getY());
	            dragLoop = loopback_selection; 	
	            dragging_mode = true;
	            //System.out.println("Loopback selection ");
	        }
	        
/////////////////////////////	        
	        
	    	if(text_edge_selection != null)
	    	{	
	    		edge_condition();
	    		//selection_obj = "CONDITION";
	    		//dragCondition = text_edge_selection;  
		        //dragging_mode = true;
	    		//System.out.println("Selection du text transistion");
	    	}
///////////////////////////////////	    	
	        /**************************************/
	        
	        if (node_selection != null && edge_selection == null && text_selection == null && rectangle_selection == null) 
	        {	
	    		System.out.println("Node selection");
	    		selection_obj = "NODE";
	    		node_selection.toggleSelected();
	            dragNode = node_selection; 	
	            dragging_mode = true;
	        }
	        
	        if (node_selection == null && edge_selection != null && text_selection == null && rectangle_selection == null) 
	        {	
	        	System.out.println("Edge selection");
	        	selection_obj = "EDGE";
	        	edge_selection.toggleSelected();
	        	dragEdge = edge_selection;
	        	dragging_mode = true;
	        	
	        	Point startPt = edge_selection.startPt;
	        	Point endPt = edge_selection.endPt;
	        	Point startCtrlPt = edge_selection.startCtrlPt;
	        	Point endCtrlPt = edge_selection.endCtrlPt;
	        	
	        	System.out.println("----" + startPt.getX() + " "
	        							  + startPt.getY() + " "
	        							  + endPt.getX() + " "
	        							  + endPt.getY() + " "
	        							  + startCtrlPt.getX() + " "
	        							  + startCtrlPt.getY() + " "
	        							  + endCtrlPt.getX() + " "
	        							  + endCtrlPt.getY() 
	        			);
	        	
	        	Rectangle2D rect_startPt = new Rectangle2D.Double(startPt.getX() -3, startPt.getY() -3, 7, 7);   
	        	Rectangle2D rect_endPt = new Rectangle2D.Double(endPt.getX() -3, endPt.getY() -3, 7, 7);   
	        	Rectangle2D rect_startCtrlPt = new Rectangle2D.Double(startCtrlPt.getX() -3, startCtrlPt.getY() -3, 7, 7);   
	        	Rectangle2D rect_endCtrlPt = new Rectangle2D.Double(endCtrlPt.getX() -3, endCtrlPt.getY() -3, 7, 7);   
	        	
	        	if (rect_startPt.contains(p))
	            {
	        		System.out.println("rect_startPt");
	        		drag_edge_startPt = true;
	        		
	            }
	        	if (rect_endPt.contains(p))
	            {
	        		System.out.println("rect_endPt");
	            }
	        	if (rect_startCtrlPt.contains(p))
	            {
	        		System.out.println("rect_startCtrlPt");
	            }
	        	if (rect_endCtrlPt.contains(p))
	            {
	        		System.out.println("rect_endCtrlPt");
	            }
	        	
	        	/////////////////////////////////
	        	//selection de la zone de text du edge
	        	
	        }
			  
	        
	        if (node_selection == null && edge_selection == null && text_selection != null && rectangle_selection == null ) 
	        {
	        	System.out.println("TEXT selection");
	 		    selection_obj = "TEXT";
	 		    text_selection.toggleSelected();
	 		    dragText = text_selection;
	 		    dragging_mode = true;
	        }
	        
	        if (node_selection == null && edge_selection == null && text_selection == null && rectangle_selection != null) 
	        {
	        	System.out.println("Rectangle selection");
	 		    selection_obj = "RECTANGLE";
	 		    rectangle_selection.toggleSelected();
	 		    dragRectangle = rectangle_selection;
	 		    dragging_mode = true;
	 		    
				int snap_x = ( e.getX() / snap_grid ) * snap_grid;
				int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	 		    //offsetx = e.getX() - dragRectangle.getX1();
	            //offsety = e.getY() - dragRectangle.getY1();
	 		    offsetx = snap_x - dragRectangle.getX1();
	            offsety = snap_y - dragRectangle.getY1();
	            
	            System.out.println(" -----  " +  e.getX() + "  " + e.getY() + "  " +  offsetx + "  " + offsety + "  " + +  dragRectangle.getX1() + " " + dragRectangle.getY1() + " " + dragRectangle.getX2() + " " + dragRectangle.getY2() 
	            + " " + dragRectangle.getWidth() + " " + dragRectangle.getHeight());
	            
	        }
	        
	        
	        if(node_rectangulare_selection != null ) //&& val_toolbar == null ) 
	        {
	        	
	        	System.out.println("Node rectangular selection");
	 		    selection_obj = "NODE_RECTANGLE";
	 		    node_rectangulare_selection.toggleSelected();
	 		    dragNodeRectangle = node_rectangulare_selection;
	 		    dragging_mode = true;
	 		    
	 		    
				int snap_x = ( e.getX() / snap_grid ) * snap_grid;
				int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	 		    offsetx = snap_x - dragNodeRectangle.getX1();
	            offsety = snap_y - dragNodeRectangle.getY1();
	            
	            
	          //  dragNodeRectangle.setCentreX(5);
	          //  dragNodeRectangle.setCentreY(8);
	            
	        	
	        	/*java.awt.Container c = getParent();  
   	    	 	while (!(c instanceof javax.swing.JFrame) && (c!=null)) 
   	    	 	{  
   	    	         c = c.getParent();  
   	    	 	}  
   	    	 	if (c!=null) 
   	    	 	{ 
   	    	 		JFrame frame_parent =(javax.swing.JFrame) c;  
   	    	 		Dialog_properties dialog_windows = new Dialog_properties(frame_parent, true, node_rectangulare_selection.getName() );
   	    	 		dialog_windows.setVisible(true);
   	    	 		Object [] retour = dialog_windows.getDonnees();
   	    	 		String return_textarea = (String)retour[0];
   	    	 		System.out.print(" Saisie de la textarea  \n " + return_textarea );
   	    	 		node_rectangulare_selection.setName(return_textarea);
   	    	 		repaint();
   	    	 	}*/
	        	
	        }
	        
	        
	        //////////    action  avec la toolbar ///////
	        //val_toolbar = split02.return_action_selected();
	        
	        
	        
	        if(val_toolbar == "RECTANGLE")
	        {
	        	System.out.println(" -----  Draw Rectangle"   );
	        	drag_rectangle = true;
	        	
	 			int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	 			int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	        	//StartPoint = new Point2D.Double(e.getX(), e.getY());
	        	StartPoint = new Point2D.Double(snap_x, snap_y );
	        	EndPoint = StartPoint;	
	        	currentShapeObject = new RectangleObj(  (int)StartPoint.getX() , (int)StartPoint.getY(), (int)StartPoint.getX() , (int)StartPoint.getY() , Color.BLUE);
	        }
	        
	        //val_toolbar = split02.return_action_selected();
	        if(val_toolbar == "TEXT")
	        {
	        	// ajouter un texte a la position du click
	        	// puis creation de l'objet et enregistrement
	        	
	        	 if( split02.transfert_get().length()  == 0)
	        	 {
	        		 JOptionPane.showMessageDialog(null,  "Le champ est vide !", "Attention", JOptionPane.ERROR_MESSAGE);
	        	 }
	        	 else
	        	 {	 
	        		 System.out.println(" -----  " +  split02.transfert_get() );
	        		 int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	 	 			 int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	        	     //Text text_obj = new Text(  split02.transfert_get() , e.getX(), e.getY(), Color.black );
	        	     Text text_obj = new Text(  split02.transfert_get() , snap_x, snap_y , Color.black );
	        	     graph02.addText(text_obj);
	                 // desactive l'action en cours
	                 split02.stop_action_selected();
	        	 }
	        }
	        
	        if(val_toolbar == "LINE")
	        {
	        	 System.out.println(" -----  Draw line"   );
	        	 drag_line = true;
	        	 int snap_x = ( e.getX() / snap_grid ) * snap_grid;
		    	 int snap_y = ( e.getY() / snap_grid ) * snap_grid;
		    	 //StartPoint = new Point2D.Double(e.getX(), e.getY());
		         StartPoint = new Point2D.Double(snap_x, snap_y);
	        }
	        
	        if(val_toolbar == "CIRCLE")
	        {
	        	 System.out.println(" -----  Draw Circle"   );
	        	 drag_circle = true;
				 int snap_x = ( e.getX() / snap_grid) * snap_grid;
				 int snap_y = ( e.getY() / snap_grid) * snap_grid;
				 //StartPoint = new Point2D.Double(e.getX(), e.getY());
		         StartPoint = new Point2D.Double(snap_x, snap_y);
		         EndPoint = StartPoint; 
		         CircleCurrentObject = new CircleObj( (int)StartPoint.getX() , (int)StartPoint.getY(), (int)StartPoint.getX() , (int)StartPoint.getY() , Color.BLUE);
	        }
	        
	        if(val_toolbar == "DELETE")
	        {
	        	//launch_appli();
	        	//System.out.println(" -----  PDF Debug mode ");
	        } 
	        
	        if(val_toolbar == "STATE")
	        {
	        	System.out.println(" -----  Draw rectangular STATE"   );
        	
	 			int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	 			int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	        	StartPoint = new Point2D.Double(snap_x, snap_y );
	        	EndPoint = StartPoint;	
	        	
	        	Node_Rectangular obj = new Node_Rectangular( "text", StartPoint );
	        	graph_node.addNode(obj);
	        	
	        	split02.stop_action_selected();
	        	
	        }
	        
	        if(val_toolbar == "CONNECTION")
	        {
	        	System.out.println(" -----  Draw CONNECTION"   );
	        	
	        	action_draw_connection = true;
	        	
	 			int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	 			int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	 			StartPoint = new Point2D.Double(snap_x, snap_y );
	        	EndPoint = StartPoint;	
	        
	        }	
	        
	        
	        if(val_toolbar == "PROPERTIES")
	        {
	        	System.out.println(" -----  Properties panel"   );
	        }	
	 			
	        /************************/
	        // timer de 350ms pour le double click
	        Timer t = new Timer("doubleclickTimer", false);
	        t.schedule(new TimerTask() {
		        							@Override
		        							public void run() 
		        							{
		        								isAlreadyOneClick = false;
		        							}
	        							}, 350);
	    }
		
	
		Integer timerinterval = (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
		// https://stackoverflow.com/questions/4577424/distinguish-between-a-single-click-and-a-double-click-in-java

		
		int snap_x = ( e.getX() / snap_grid ) * snap_grid;
		int snap_y = ( e.getY() / snap_grid ) * snap_grid;
		//dragPoint = new Point2D.Double(e.getX(), e.getY());
		dragPoint = new Point2D.Double( snap_x, snap_y );
    	  
	}  
	
	public void mouseReleased(MouseEvent e) 
	{  
		Node     aNode = graph.nodeAt(e.getX(), e.getY());
        // Check to see if we have let go on a node
        if ((dragNode != null) && (aNode != null) && (aNode != dragNode))
        {
            graph.addEdge(dragNode, aNode);
        }
           
        String val = split02.return_action_selected();
        if(val == "RECTANGLE" && drag_rectangle == true )
        {
			if(StartPoint.getX() < EndPoint.getX() && StartPoint.getY() < EndPoint.getY() ) 
			{
				System.out.println(" --Q4--  ");  
			}
        	
        	if(StartPoint.getX() < EndPoint.getX() && StartPoint.getY() > EndPoint.getY() ) 
			{
				int w = (int) Math.abs( StartPoint.getX() - EndPoint.getX() ) ;
				int h = (int) Math.abs( StartPoint.getY() - EndPoint.getY() ) ;
				int p1x = (int) StartPoint.getX();
				int p1y = (int) EndPoint.getY();
				int p2x = p1x + w;
				int p2y = p1y + h;
	        	// positionne les infos
				currentShapeObject.setX1( p1x);
				currentShapeObject.setY1( p1y);
				currentShapeObject.setX2( p2x);
				currentShapeObject.setY2( p2y);
				currentShapeObject.setWidth( w );  
				currentShapeObject.setHeight( h );  
				System.out.println(" --Q1--  "   );  
			}
        	
        	if(StartPoint.getX() > EndPoint.getX() && StartPoint.getY() > EndPoint.getY() ) 
			{
				int w = (int) Math.abs( StartPoint.getX() - EndPoint.getX() ) ;
				int h = (int) Math.abs( StartPoint.getY() - EndPoint.getY() ) ;
				int p1x = (int) EndPoint.getX();
				int p1y = (int) EndPoint.getY();
				int p2x = p1x + w;
				int p2y = p1y + h;
	        	// positionne les infos
				currentShapeObject.setX1( p1x);
				currentShapeObject.setY1( p1y);
				currentShapeObject.setX2( p2x);
				currentShapeObject.setY2( p2y);
				currentShapeObject.setWidth( w );  
				currentShapeObject.setHeight( h );  
				System.out.println(" --Q2--  "   );  
			}
        	
        	if(StartPoint.getX() > EndPoint.getX() && StartPoint.getY() < EndPoint.getY() ) 
			{
				int w = (int) Math.abs( StartPoint.getX() - EndPoint.getX() ) ;
				int h = (int) Math.abs( StartPoint.getY() - EndPoint.getY() ) ;
				int p1x = (int) EndPoint.getX();
				int p1y = (int) StartPoint.getY();
				int p2x = p1x + w;
				int p2y = p1y + h;
	        	// positionne les infos
				currentShapeObject.setX1( p1x);
				currentShapeObject.setY1( p1y);
				currentShapeObject.setX2( p2x);
				currentShapeObject.setY2( p2y);
				currentShapeObject.setWidth( w );  
				currentShapeObject.setHeight( h );  
				System.out.println(" --Q3--  "   );  
			}
        	
        	// enregistre l'objet
			//array_rectangle_obj.add(currentShapeObject);
	        graph03.addRect(currentShapeObject);
	        // désactive les variables     
	        drag_rectangle = false;
	        currentShapeObject = null;
	      	// desactive l'action en cours
	        split02.stop_action_selected();
      	    
        }
        
    	if(val == "LINE" &&  drag_line == true )
	    {
    		int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	    	int snap_y = ( e.getY() / snap_grid ) * snap_grid;
    		//EndPoint = new Point2D.Double(e.getX(), e.getY());
    		EndPoint = new Point2D.Double(snap_x, snap_y);
    		// enregistre l'objet
    		graph_line.addLines( new LineObj((int)StartPoint.getX(), (int)StartPoint.getY(), (int)EndPoint.getX(), (int)EndPoint.getY() , Color.BLUE ) );
			System.out.println("DRAW stop");  
			drag_line = false;
	      	// desactive l'action en cours
	        split02.stop_action_selected();

	    }  
      
    	
    	if(val == "CIRCLE" &&  drag_circle == true )
	    {
    		int snap_x = ( e.getX() / snap_grid ) * snap_grid;
     		int snap_y = ( e.getY() / snap_grid ) * snap_grid; 
    		//EndPoint = new Point2D.Double(e.getX(), e.getY());
    		EndPoint = new Point2D.Double(snap_x, snap_y);
    		
    		//int xdiff = (int)StartPoint.getX() - (int)EndPoint.getX() ;
            //int ydiff = (int)StartPoint.getY() - (int)EndPoint.getY() ;
            //double radius = Math.sqrt(Math.pow(xdiff, 2)+Math.pow(ydiff, 2));
            //int int_raduis = (int) radius;
            //int diametre = int_raduis*2;
            
            
            int xdiff = (int)StartPoint.getX() - (int)EndPoint.getX() ;
            int ydiff = (int)StartPoint.getY() - (int)EndPoint.getY() ;
            double radius = Math.sqrt(Math.pow(xdiff, 2)+Math.pow(ydiff, 2));
            int int_raduis = ( (int) radius  / snap_grid ) * snap_grid;
            int diametre = int_raduis*2;	
            
    		
            int x1 = (int) (StartPoint.getX() - int_raduis);
            int y1 = (int) (StartPoint.getY() - int_raduis);
            int x2 = x1 + diametre;
            int y2 = y1 + diametre;
            
      //      rectangle_P1_points_anchar contient les coordonnées du point qui se déplace
            
    		CircleCurrentObject.setX1( x1 );
			CircleCurrentObject.setY1( y1 );
			CircleCurrentObject.setX2( x2 );
			CircleCurrentObject.setY2( y2 );
			CircleCurrentObject.set_diametre(diametre);
			CircleCurrentObject.setWidth(diametre);
			CircleCurrentObject.setHeight(diametre);
			
			graph_circle.addCircle(CircleCurrentObject);
			drag_circle = false;
	     	// desactive l'action en cours
	        split02.stop_action_selected();
	        // pour compenser le decalage du cercle 
	        circle_creation = true;
	    }  
    	//aaa
    	//dragCondition
    	
    	
    	if(val == "CONNECTION")
        {
	        	System.out.println(" -----  Enregistre CONNECTION"   );
	        	// desactive le tracé
	        	action_draw_connection = false;
	        	
	 			int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	 			int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	 			EndPoint = new Point2D.Double(snap_x, snap_y );
	        	
	 			// enregiste 
	 			graph_node.buildEdge( StartPoint, EndPoint);
	 			
	        }	
    	
    	
    	if(dragCondition != null)
    	{
   		    int snap_x = ( e.getX() / snap_grid ) * snap_grid;
    		int snap_y = ( e.getY() / snap_grid ) * snap_grid;
    		text_edge_selection.setX(snap_x);
    		text_edge_selection.setX(snap_y);
    	}
    	

          
    	// current = -1;
        
        dragNode = null;  

        dragging_mode = false;
        
        dragRectangle = null;
        
        dragCircle = null;
        
        dragCondition = null;
        
        dragNodeRectangle = null;
        
      //  dragLine = null;             // on se trouve drag text ....???? a revoir
        
        rectangle_current_point_anchar = false;
    	
    	line_current_point_anchar = false;

    	circle_current_point_anchar = false;
    	
    	
    	drag_edge_startPt = false;
    	
        // prend le focus sur le panel pour utiliser le listener du panel
        requestFocus();
        
        repaint();
	}
	
	@Override
	public void mouseDragged(MouseEvent e) 
	{
		// affichage des coordonnées de la souris dans le status panel
		//split02.mouse_position(e.getX(), e.getY());
		
		 //if (current == -1) return;
         //points[current] = e.getPoint();
		
		if(    dragging_mode == true)
    	{
    		// System.out.print("---- DRAGGING MODE \n" + e.getX() + " " + e.getY() );
    		 
    		 if(selection_obj.equals("NODE") )
    		 {
                 if (dragNode.isSelected()) 
                 {
                	 int cpt = 0;
                	 
                     for (Node n:  graph.selectedNodes()) 
                     {
                 		int snap_x = ( e.getX() / snap_grid ) * snap_grid;
                 		int snap_y = ( e.getY() / snap_grid ) * snap_grid; 

                 		//n.setLocation(n.getLocation().getX() + e.getX() - dragPoint.getX(),  n.getLocation().getY() + e.getY() - dragPoint.getY());
                 		n.setLocation(n.getLocation().getX() + snap_x - dragPoint.getX(),  n.getLocation().getY() + snap_y - dragPoint.getY());
                 		
                        ArrayList<Node>   selected = new ArrayList<Node>();
                        selected = graph.selectedNodes();
                                        
                        LoopbackObj loopback_obj = new LoopbackObj();
                        // on récupére les infos
                    	loopback_obj = selected.get(cpt).getLoopBack();
                		int a = loopback_obj.getLoopStartPtX();
                    	int b = loopback_obj.getLoopStartPtY();
                    	int c = loopback_obj.getLoopEndPtX();
                    	int d = loopback_obj.getLoopEndPtY();

        	        	// on recalcule les points
        	        	int r = 50;
        	        	double t1 = loopback_obj.getAngleStart();
                    	double t2 = loopback_obj.getAngleEnd();
                    	int xcentre = (int) n.getLocation().getX();
                		int ycentre = (int) n.getLocation().getY(); 

                		//System.out.print("---- centre  " + xcentre + " " + ycentre ); 
        	        	//System.out.println(" -----  Debug mode "  + e.getX() + " " + e.getY() + " " +  a + " " + b + " " + c + " " + d  );
                    	
                    	int new_LoopStartPtX = (int) Math.floor( xcentre + r*  Math.cos(t1) )  ;
                    	int new_LoopStartPtY = (int) Math.floor( ycentre + r * Math.sin(t1) );
                    	int new_LoopEndPtX = (int) Math.floor( xcentre + r*  Math.cos(t2) );
                    	int new_LoopEndPtY = (int) Math.floor( ycentre + r * Math.sin(t2) );

                    	loopback_obj.x0 = (int) n.getLocation().getX() - r;
                    	loopback_obj.y0 = (int) n.getLocation().getY() - r;
                    	loopback_obj.x1 = (int) n.getLocation().getX() + r;
                    	loopback_obj.y1 = (int) n.getLocation().getY() + r;
                    	
                    	
                    	System.out.println(" -----  DRAGGED  "  + xcentre + " " + ycentre + " " + new_LoopStartPtX  + " " + new_LoopStartPtY + " " + new_LoopEndPtX + " " + new_LoopEndPtY  );
                    	
                    	// enregistre
                    	loopback_obj.startPt.setLocation(new_LoopStartPtX, new_LoopStartPtY);
                    	loopback_obj.endPt.setLocation(new_LoopEndPtX, new_LoopEndPtY);

                    	// 
                    	//graph.recalculation(selected.get(cpt)); 
                    	graph.recalculation(n); 
                    	
                    	cpt = cpt + 1;
                   
                        // fonctionnel
                        //graph.updateLoopBack(n); 
                        
                        // test 1
                        //graph.blablaLoopBack(n); 
                         
                        // test 2
                       // graph.debug_loop(n);
                     }
                     //dragPoint = new Point2D.Double(e.getX(), e.getY());
                 	 int snap_x = ( e.getX() / snap_grid ) * snap_grid;
            		 int snap_y = ( e.getY() / snap_grid ) * snap_grid;
            		 //dragPoint = new Point2D.Double(e.getX(), e.getY());
            		 dragPoint = new Point2D.Double( snap_x, snap_y );
                     
                 }
             }
    		 
    		 if(selection_obj.equals("EDGE") )
    		 {
    			 if (dragEdge != null) 
    			 {
                     if (dragEdge.isSelected()) 
                     {
                         dragEdge.getStartNode().setLocation(    dragEdge.getStartNode().getLocation().getX() + e.getX() - dragPoint.getX(),
                                 								 dragEdge.getStartNode().getLocation().getY() + e.getY() - dragPoint.getY());
                         dragEdge.getEndNode().setLocation(      dragEdge.getEndNode().getLocation().getX() + e.getX() - dragPoint.getX(),
                                 								 dragEdge.getEndNode().getLocation().getY() + e.getY() - dragPoint.getY());
                         
                         dragPoint = new Point2D.Double(e.getX(), e.getY());
                     }
                 }
    		 }
    		 
    		if(drag_edge_startPt == true)
    		{
    			 System.out.println("Drag le point ..... sur le cercle");  
    			 
    			 dragEdge.adjustShapeOrPosition(e.getX(), e.getY());
    			 
    		}

    		 
    		 if(selection_obj.equals("LOOPBACK") )
    		 {
    			 
    			//	Point2D c =  node_selection.getLocation();
    			 
    			// loopback_selection.adjustPosition( e.getX(), e.getY() , (int)c.getX(), (int)c.getY());
    			 
    			 
        	//	 loopback_selection.adjustPosition( e.getX(), e.getY() , (int)dragNode.getLocation().getX(), (int)dragNode.getLocation().getY());
    		//	 n.setLocation(n.getLocation().getX() + e.getX() - dragPoint.getX(),  n.getLocation().getY() + e.getY() - dragPoint.getY());
    			
    			 
    		//	 loopback_selection.adjustPosition( e.getX(), e.getY() , 400, 350);
	 
    			 
    			//int a = (int) (dragNode.getLocation().getX() + e.getX() - dragPoint.getX());
    			//int b = (int) (dragNode.getLocation().getY() + e.getY() - dragPoint.getY());
    			 
    			// recherche le node qui posséde le label 
    			String label = loopback_selection.label;
    			Node node_obj = graph.nodeNamed(label); 
    			Point2D pt_state_centre = node_obj.getLocation(); 
    			
    			//loopback_selection.adjustPosition( e.getX(), e.getY() ,     loopback_selection.x ,  loopback_selection.y );
    			
    			loopback_selection.adjustPosition( e.getX(), e.getY() ,    (int)pt_state_centre.getX()  ,  (int)pt_state_centre.getY() );
    			
    			System.out.println("DRAG LOOPBACK.. " + e.getX() +  " " +  e.getY() +  " " +  loopback_selection.x  +  " " +  loopback_selection.y + " " + pt_state_centre.getX() + " "+ pt_state_centre.getY() );   /// ?????
    		 }
    		 
    		 
    		 if(selection_obj.equals("CONDITION") )
 	    	 {	
   			    snap_x_condition = ( e.getX() / snap_grid ) * snap_grid;
	 			snap_y_condition = ( e.getY() / snap_grid ) * snap_grid;
	 			//text_edge_selection.setX(snap_x);
	 			//text_edge_selection.setX(snap_y);
    			System.out.println("DRAG condition.. " + snap_x_condition + "  " + snap_y_condition );   
 	    	 }
    		 
    		 if(selection_obj.equals("TEXT") )
    		 {
    			 
    			 int snap_x = ( e.getX() / snap_grid ) * snap_grid;
 	 			 int snap_y = ( e.getY() / snap_grid ) * snap_grid;
    			 //text_selection.setX(e.getX());
    			 //text_selection.setY(e.getY());
    			 text_selection.setX(snap_x);
    			 text_selection.setY(snap_y);
    		 }
    		
    		 
    		 if(selection_obj.equals("CIRCLE") )
    		 {
    			 int snap_x = ( e.getX() / snap_grid) * snap_grid;
				 int snap_y = ( e.getY() / snap_grid) * snap_grid;
    			 //dragCircle.setX1( e.getX() - offsetx );  
    			 //dragCircle.setY1( e.getY() - offsety );
    			 dragCircle.setX1( snap_x - offsetx );  
    			 dragCircle.setY1( snap_y - offsety );

    		 }
    		 
    		 if(selection_obj.equals("RECTANGLE"))
    		 {
    			 if(dragRectangle != null )
    			 {
    				 if(dragRectangle.isSelected())
    				 {
    					 int snap_x = ( e.getX() / snap_grid) * snap_grid;
    					 int snap_y = ( e.getY() / snap_grid) * snap_grid;
    					 //dragRectangle.setX1( e.getX() - offsetx );  
    					 //dragRectangle.setY1( e.getY() - offsety );
    					 dragRectangle.setX1( snap_x - offsetx );  
    					 dragRectangle.setY1( snap_y - offsety );
    				 }
    			 }
    		 }
    		 
    		 
    		 if(selection_obj.equals("NODE_RECTANGLE")) 
    		 {
    			 
    			 if(dragNodeRectangle != null )
    			 {
    				 if(dragNodeRectangle.isSelected())
    				 {
    					 int snap_x = ( e.getX() / snap_grid) * snap_grid;
    					 int snap_y = ( e.getY() / snap_grid) * snap_grid;
    					 dragNodeRectangle.setX1( snap_x - offsetx );  
    					 dragNodeRectangle.setY1( snap_y - offsety );
    					 
    					 
    			           dragNodeRectangle.setCentreX();
    			            dragNodeRectangle.setCentreY();

    					 
    					 System.out.println("DRAG Node rectangle" );  
    				 }
    			 }
    		 }
    		 
    		 if(selection_obj.equals("LINE"))
    		 {
    			 if(dragLine != null )
    			 {
    				 if(dragLine.isSelected())
    				 {
    					 int snap_x = ( e.getX() / snap_grid ) * snap_grid;
    				     int snap_y = ( e.getY() / snap_grid ) * snap_grid;
    					 
    					 System.out.println("Press Drag line");
    					 if(line_orientation == 1)
    					 {
    						 dragLine.setX1( snap_x - offsetx );  
        					 dragLine.setY1( snap_y + offsety );
        					 dragLine.setX2( snap_x + offsetx );  
        					 dragLine.setY2( snap_y - offsety );
        					 System.out.println("AAAA" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 if(line_orientation == 2)
    					 {
    						 dragLine.setX1( snap_x + offsetx );  
        					 dragLine.setY1( snap_y - offsety );
        					 dragLine.setX2( snap_x - offsetx );  
        					 dragLine.setY2( snap_y + offsety );
        					 System.out.println("BBBB" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 if(line_orientation == 3)
    					 {
       						 dragLine.setX1( snap_x + offsetx );  
           					 dragLine.setY1( snap_y + offsety );
           					 dragLine.setX2( snap_x - offsetx );  
           					 dragLine.setY2( snap_y - offsety );
           					 System.out.println("CCCCC" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 if(line_orientation == 4)
    					 {
       						 dragLine.setX1( snap_x - offsetx );  
           					 dragLine.setY1( snap_y - offsety );
            				 dragLine.setX2( snap_x + offsetx );  
              				 dragLine.setY2( snap_y + offsety );
              			 	 System.out.println("DDDDD" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 
    				 }
    			 }
    		 }
    		 
    	}
		
		String val = split02.return_action_selected();

		// pour le dessin interactif d'une line
		if(val == "LINE" &&  drag_line == true )
	    {
			System.out.println("DRAW line 2");  
    		int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	    	int snap_y = ( e.getY() / snap_grid ) * snap_grid;
			//EndPoint = new Point2D.Double(e.getX(), e.getY());
			EndPoint = new Point2D.Double(snap_x, snap_y);
	    }  
		
		// pour le dessin interactif d'un rectangle
		if(val == "RECTANGLE" && drag_rectangle == true )
	    {
			int snap_x = ( e.getX() / snap_grid) * snap_grid;
			int snap_y = ( e.getY() / snap_grid) * snap_grid;
			//EndPoint = new Point2D.Double(e.getX(), e.getY());
			EndPoint = new Point2D.Double(snap_x, snap_y);
			//currentShapeObject.setX2(e.getX());
			//currentShapeObject.setY2(e.getY());
			currentShapeObject.setX2(snap_x);
			currentShapeObject.setY2(snap_y);
	    }  
		
		
		// pour le dessin interactif d'un circle
		if(val == "CIRCLE" && drag_circle == true )
	    {
			//EndPoint = e.getPoint();  
			int snap_x = ( e.getX() / snap_grid) * snap_grid;
			int snap_y = ( e.getY() / snap_grid) * snap_grid;
			//EndPoint = new Point2D.Double(e.getX(), e.getY());
			EndPoint = new Point2D.Double(snap_x, snap_y);
			//CircleCurrentObject.setX2(e.getX());
			//CircleCurrentObject.setY2(e.getY());
			CircleCurrentObject.setX2(snap_x);
			CircleCurrentObject.setY2(snap_y);
	    }  
		
		
		// anchar line
		if (line_current_point_anchar == true) 
		{	
			
			if(line_current_point_anchar_selected == 1)
			{
				int snap_x = ( e.getX() / snap_grid) * snap_grid;
				int snap_y = ( e.getY() / snap_grid) * snap_grid;
				//line_P1_points_anchar = e.getPoint(); 
				line_P1_points_anchar = new Point(snap_x, snap_y); 
				System.out.println("TRACE anchar 1");  
			}
			
			if(line_current_point_anchar_selected == 2)
			{
				int snap_x = ( e.getX() / snap_grid) * snap_grid;
				int snap_y = ( e.getY() / snap_grid) * snap_grid;
				//line_P2_points_anchar = e.getPoint(); 
				line_P2_points_anchar = new Point(snap_x, snap_y); 
				System.out.println("TRACE anchar 2");  
			}
		}

		// anchar rectangle
		if (rectangle_current_point_anchar == true) 
		{	
			
			if(rectangle_current_point_anchar_selected == 1)
			{
				int snap_x = ( e.getX() / snap_grid) * snap_grid;
				int snap_y = ( e.getY() / snap_grid) * snap_grid;
				//rectangle_P1_points_anchar = e.getPoint(); 
				rectangle_P1_points_anchar = new Point(snap_x, snap_y); 
				System.out.println("TRACE anchar 1");  
			}
			
			if(rectangle_current_point_anchar_selected == 3)
			{
				int snap_x = ( e.getX() / snap_grid) * snap_grid;
				int snap_y = ( e.getY() / snap_grid) * snap_grid;
				//rectangle_P3_points_anchar = e.getPoint(); 
				rectangle_P3_points_anchar = new Point(snap_x, snap_y); 
				System.out.println("TRACE anchar 3");  
			}
		}
		
		// anchar circle
		if (circle_current_point_anchar == true) 
		{	
					
			if(circle_current_point_anchar_selected == 1)
			{
				int snap_x = ( e.getX() / snap_grid) * snap_grid;
				int snap_y = ( e.getY() / snap_grid) * snap_grid;
				//circle_P1_points_anchar = e.getPoint(); 
				circle_P1_points_anchar = new Point(snap_x, snap_y); 
				System.out.println("TRACE anchar 3:  " + circle_P1_points_anchar.getX() + " " + circle_P1_points_anchar.getY() );  
			}
					
			if(circle_current_point_anchar_selected == 3)
			{
				int snap_x = ( e.getX() / snap_grid) * snap_grid;
				int snap_y = ( e.getY() / snap_grid) * snap_grid;
				//circle_P3_points_anchar = e.getPoint(); 
				circle_P3_points_anchar = new Point(snap_x, snap_y); 
				System.out.println("TRACE anchar 3:  " + circle_P3_points_anchar.getX() + " " + circle_P3_points_anchar.getY() );  
			}
		}
		
		
		if(val == "CONNECTION")
	    {
	 			int snap_x = ( e.getX() / snap_grid ) * snap_grid;
	 			int snap_y = ( e.getY() / snap_grid ) * snap_grid;
	 			EndPoint = new Point2D.Double(snap_x, snap_y );
	    }	
		
    	
    	repaint();
	}
	
	@Override
	public void mouseMoved(MouseEvent e) 
	{
		//System.out.println("Mouse Moved");  
		save_evt = e;
		
		int snap_x = ( e.getX() / snap_grid) * snap_grid;
		int snap_y = ( e.getY() / snap_grid) * snap_grid;
	    //split02.mouse_position(e.getX(), e.getY());
	    split02.mouse_position(snap_x, snap_y);
	    
	    /*
	    Robot robot = null;
		try {
			robot = new Robot();
		} catch (AWTException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
        //robot.setAutoDelay(50);
        //robot.waitForIdle();
        //robot.delay(200);

        robot.mouseMove(snap_x, snap_y);*/
	    
	}  
	 
    public LineObj getClickedLine(int x, int y) 
    {
    	
    	int k = 30;
    	
    	for (LineObj line : graph_line.getLines() ) 
    	{
    		  Rectangle net = new Rectangle(k,k);
    		
    		  Line2D.Double aqw = new Line2D.Double(line.getX1() , line.getY1() , line.getX2() , line.getY2());
    		  
    		  net.setFrameFromCenter(x, y, x+(k/2), y+(k/2) );
              if(aqw.intersects(net)) 
              {
            	 line.toggleSelected();
            	 line_selection = line;
                 System.out.println("Bingo"); 
                 return line;
              }
    		 
    	}
    	return null;

    }
	
	/****************************************************************************************/
	
	public void saisir_state(Point2D.Double er) 
	{
	        String text = JOptionPane.showInputDialog(JFrame,"Create new state",
	                                                  "Nom du state :", JOptionPane.PLAIN_MESSAGE);
	        
	        if(text == null )
	        {
	              //JOptionPane.showMessageDialog(null,  "Abandon  !", "Attention", JOptionPane.ERROR_MESSAGE);
	        }
	        
	        else
	        {
	            int len = text.length();
	            if(len == 0)    
	            {    
	              JOptionPane.showMessageDialog(null,  "Le champ est vide, le state n'a pas Ã©tÃ© crÃ©er !", "Attention", JOptionPane.ERROR_MESSAGE);
	            }  
	            else
	            {    
	               
	                ArrayList<Node>   tmp = new ArrayList<Node>();
	                tmp = graph.getNodes();
	                boolean flag_doublon = false;
	               
	                for(int i = 0; i < graph.getNodes().size(); i++)
	                {
	                    String existing_state_name = tmp.get(i).getLabel().toLowerCase();
	                    String new_state_name = text.toLowerCase();

	                    if(existing_state_name.equals( new_state_name ) )
	                    {
	                        JOptionPane.showMessageDialog(null,  "Deux Ã©tats be peuvent avoir le mÃªme nom \nCe nom existe dÃ©jÃ  !.", "Attention", JOptionPane.ERROR_MESSAGE);
	                        flag_doublon = true;
	                        break;
	                    }
	                } 
	                
	                if( flag_doublon == false)
	                {    
	                    graph.addNode(new Node( text, er ) );
	                    
	                    //graph.getNodes().get( position ).setLabel(s1);
	                    System.out.println("Nouveau nom du state : --> " + text); 
	                    repaint();
	                }
	            }
	        }    
	      
	 }        
	
	 /****************************************************************************************/

	 public void query()
	 {
		
		 ArrayList<Text>   selected_text = new ArrayList<Text>();
		 selected_text = graph02.selectedTexts();
		 
		 ArrayList<Node>  selected_node = new ArrayList<Node>();
		 selected_node = graph.selectedNodes();
		 
		 ArrayList<Node_Rectangular>  selected_node_rectangular = new ArrayList<Node_Rectangular>();
		 selected_node_rectangular = graph_node.selectedNodes();
		 
		 
		 ArrayList<EdgeObj>   selected_edges = new ArrayList<EdgeObj>();
	     selected_edges = graph.selectedEdges();
		 
	     if(selected_edges.size() == 1)
	     {
	    	 System.out.println("Edition du edge");
	    	 	    	 
	    	 java.awt.Container c = this.getParent();  
	    	 while (!(c instanceof javax.swing.JFrame) && (c!=null)) 
	    	 {  
	    	         c = c.getParent();  
	    	 }  
	    	 if (c!=null) 
	    	 { 
	    	    JFrame owner=(javax.swing.JFrame) c;  
	    	 	titi dialog_windows = new titi(owner, true, selected_edges.get(0));
	 			// ne change rien
	    	 	//dialog_windows.pack();
	 			
	    	 	// not used
	 			//dialog_windows.initialise(new Object[]{12345, "vincent"});
	 			
	 			//dialog_windows.show();
	 			dialog_windows.setVisible(true);
		 			
	 			Object [] retour = dialog_windows.getDonnees();
	 			Boolean return_state = (Boolean)retour[0];
	 			//int i = (Integer)retour[1];
	         	//String nom = (String)retour[2];
	 			
	 			// recuperation des datas renvoyées par la jdialog
	 			if(return_state == true)
	         	{
	 				if( selected_edges.get(0).get_shift_mode_manual() == true)
	 				{
		         		selected_edges.get(0).setX(   selected_edges.get(0).getX() + selected_edges.get(0).get_shift_text_X()  );
			         	selected_edges.get(0).setY(   selected_edges.get(0).getY() + selected_edges.get(0).get_shift_text_Y()  );
			         	selected_edges.get(0).config_text_condition(true);
			         	repaint();
	 				}
	 				
	 				if( selected_edges.get(0).get_shift_mode_manual() == false)
	 				{
			         	selected_edges.get(0).config_text_condition(false);
			         	repaint();
	 				}
	 				
	         	}
	 			else
	         	{
	         		System.out.println("debug Close - no action");
	         	}

	    	 }
	    	 
	     }
		 
	     if(selected_text.size() == 1)
	     {
	    	 // chargement avec valeur qui est dèjà stockée
	    	 dialog = new TextDialog( selected_text.get(0).getText() );
        	 dialog.setModal(true);
        	 dialog.setVisible(true);
         	
        	 // récupére la valeur       	 
        	 String saisie = dialog.getText();
        	 
        	 if( saisie.length()  == 0)
        	 {
        		 JOptionPane.showMessageDialog(null,  "Le champ est vide !", "Attention", JOptionPane.ERROR_MESSAGE);
        	 }
        	 else
        	 {	 
        		 // enregistrement
            	 selected_text.get(0).setText( saisie );

            	 repaint();
        	 }
		 
	     } 
	     
	     /************************/
	     if(selected_node.size() == 1)
	     {
	    	 System.out.println("Edition du state");
	    	 
			 // liste de tous les nodes
			 ArrayList<Node>  all_nodes = new ArrayList<Node>();
			 all_nodes = graph.getNodes();
			 
			 String selected_state_name = graph.find_selected();
			 Node   state_start_obj  = graph.nodeNamed(selected_state_name); 
			 int position = graph.nodePosition(selected_state_name);
			 
			 // remove celui qui est selectionné en créant une copie de all_nodes
			 ArrayList<Node>  copy_all_nodes = new ArrayList<Node>();
			 
			 for(int i = 0; i < all_nodes.size(); i++)
             {
				 if(i != position)
				 {
					 copy_all_nodes.add(  all_nodes.get(i) );
				 }
             }
	    	 
	    	 java.awt.Container c = this.getParent();  
	    	 while (!(c instanceof javax.swing.JFrame) && (c!=null)) 
	    	 {  
	    	         c = c.getParent();  
	    	 }  
	    	 if (c!=null) 
	    	 { 
	    	    JFrame frame_parent =(javax.swing.JFrame) c;  
	    	 	SettingsStates dialog_windows = new SettingsStates(frame_parent, true, selected_node.get(0) ) ; //, copy_all_nodes);
	    	 	dialog_windows.initialise(new Object[]{copy_all_nodes }); // , node_selection.get_state_color(), node_selection.get_text_color() });
	    	 	dialog_windows.setVisible(true);
	    		Object [] retour = dialog_windows.getDonnees();
	    		String state_name = (String)retour[0];
	    		Boolean return_state = (Boolean)retour[1];
	    		Color state_color = (Color)retour[2];
	    		Color text_color = (Color)retour[3];
	    		
	 			// recuperation des datas renvoyées par la jdialog
	 			if(return_state == true)
	         	{
	 				System.out.println("debug OK - Changement du nom du state : --> " + state_name + " " + state_color + " " + text_color); 
	 				node_selection.setLabel(state_name);
            		// changement du lien pour le loopback 
            		LoopbackObj loopback_obj = new LoopbackObj();
            		loopback_obj = node_selection.getloopback();
            		loopback_obj.setLabel(state_name);
            		
            		node_selection.set_state_color(state_color);
            		node_selection.set_text_color(text_color);
            		
            		// redessiner 
                    repaint();
	         	}
	 			else
	         	{
	         		System.out.println("debug Close - no action");
	         	}
	    		
	    	 }	
	    	 
	     }
	     
	     /************************/
	     
	     if(selected_node_rectangular.size() == 1)
	     {
	    	 	java.awt.Container c = getParent();  
	    	 	while (!(c instanceof javax.swing.JFrame) && (c!=null)) 
	    	 	{  
	    	         c = c.getParent();  
	    	 	}  
	    	 	if (c!=null) 
	    	 	{ 
	    	 		JFrame frame_parent =(javax.swing.JFrame) c;  
	    	 		Dialog_properties dialog_windows = new Dialog_properties(frame_parent, true, node_rectangulare_selection.getName() );
	    	 		dialog_windows.setVisible(true);
	    	 		Object [] retour = dialog_windows.getDonnees();
	    	 		String return_textarea = (String)retour[0];
	    	 		System.out.print(" Saisie de la textarea  \n " + return_textarea );
	    	 		node_rectangulare_selection.setName(return_textarea);
	    	 		repaint();
	    	 	}
	     } 	 	
	     
	     /************************/
	     
	     if(selected_node.size() == 555555)
	     {
	    	 System.out.println("Edition du state");
	    	 
			 // liste de tous les nodes
			 ArrayList<Node>  all_nodes = new ArrayList<Node>();
			 all_nodes = graph.getNodes();
			 
			 String selected_state_name = graph.find_selected();
			 Node   state_start_obj  = graph.nodeNamed(selected_state_name); 
			 int position = graph.nodePosition(selected_state_name);
			 
			 // remove celui qui est selectionné en créant une copie de all_nodes
			 ArrayList<Node>  copy_all_nodes = new ArrayList<Node>();
			 
			 for(int i = 0; i < all_nodes.size(); i++)
             {
				 if(i != position)
				 {
					 copy_all_nodes.add(  all_nodes.get(i) );
				 }
             }
			 // ne marche pas 
			 /////copy_all_nodes.remove(position);
	    	 
	    	 String text = (String) JOptionPane.showInputDialog(JFrame,"Nom du state:", "Edition du state", JOptionPane.PLAIN_MESSAGE, null, null, selected_state_name  );

	    	 if(text == null )
	    	 {
	    		 //	JOptionPane.showMessageDialog(null,  "Abandon  !", "Attention", JOptionPane.ERROR_MESSAGE);
	    	 }
	    	 
	    	 else
	         {
	             int len = text.length();
	             if(len == 0)    
	             {    
	               JOptionPane.showMessageDialog(null,  "Le champ est vide, le state n'a pas été mis à jour !", "Attention", JOptionPane.ERROR_MESSAGE);
	             }  
	             else
	             {    
	            	 boolean flag_doublon = false;
	            	 
	            	 for(int i = 0; i < copy_all_nodes.size(); i++)
	                 {
	            		 String existing_state_name = all_nodes.get(i).getLabel().toLowerCase();
		                 String new_state_name = text.toLowerCase();
		                 if(existing_state_name.equals( new_state_name ) )
	                     {
	                         JOptionPane.showMessageDialog(null,  "Deux états be peuvent avoir le même nom \nCe nom existe déjà !.", "Attention", JOptionPane.ERROR_MESSAGE);
	                         flag_doublon = true;
	                         break;
	                     }
	                 }
	            	 
	            	 if( flag_doublon == false)
	                 {    
	                	
	            		node_selection.setLabel(text);
	            		// changement lien pour le loopback 
	            		LoopbackObj loopback_obj = new LoopbackObj();
	            		loopback_obj = node_selection.getloopback();
	            		loopback_obj.setLabel(text);
	                    System.out.println("Changement du nom du state : --> " + text); 
	                    repaint();
	                 }
	            	 
	               
	                 
	             }
	         }    
	    	 
	     }
	     
	        
	 }
	 
	 public void edge_condition()
	 {
		 String label = text_edge_selection.getEquation();
		 String text = (String) JOptionPane.showInputDialog(JFrame,"Condition:", "Edition de la transistion", JOptionPane.PLAIN_MESSAGE, null, null, text_edge_selection.getEquation()   );

    	 if(text == null )
    	 {
    		
    	 }
    	 
    	 else
         {
             int len = text.length();
             if(len == 0)    
             {    
               JOptionPane.showMessageDialog(null,  "Le champ est vide, la condition n'a pas été mis à jour !", "Attention", JOptionPane.ERROR_MESSAGE);
             }  
             else
             {    
            	 text_edge_selection.setEquation(text);
            	 repaint();
             }
         }    

		 
	 }
	 
	 /****************************************************************************************/
  
	 @Override
	 public void keyPressed(KeyEvent arg0) 
	 {
	 }

	 @Override
	 public void keyTyped(KeyEvent arg0) 
	 {
	 }
	   
	 @Override
	 public void keyReleased(KeyEvent e) 
	 {
		   System.out.println("xxxxxx");
		 
		   if (e.getKeyCode() == KeyEvent.VK_DELETE) 
		   {
			   effacer_selection();
		   }
	    
		   if (e.getKeyCode() == KeyEvent.VK_Q) 
		   {
			   query();
		   }

		   if (e.getKeyCode() == KeyEvent.VK_U) 
		   {
			   unselect_all();
		   }

		   if (e.getKeyCode() == KeyEvent.VK_T) 
		   {
			   System.out.println("Add text");
		   }
	     
		   if (e.getKeyCode() == KeyEvent.VK_M) 
		   {
			   showPopup();
		   }
		  
	 }
	   
	 /****************************************************************************************/

	 public void effacer_tout()
	 {
	        
	        System.out.println("Clean de toute la vue");
	        graph.effacer_tout();
	        graph02.effacer_tout();
	        graph03.effacer_tout();
	        graph_line.effacer_tout();
	        graph_circle.effacer_tout();
	        
	     	split02.myArea.append(" [ INFO ]: Clear area" + "\n");
	        
	        repaint();
	 }
	 
	 /****************************************************************************************/
	 
	 public void effacer_selection()
	 {
	        System.out.println("Effacer selection");
	        
	      	split02.myArea.append(" [ INFO ]: Delete obj selected ..." + "\n");
	        
	        for (EdgeObj e:  graph.selectedEdges())
	               graph.deleteEdge(e);
	        
	        for (Node n:  graph.selectedNodes())
	              graph.deleteNode(n);
	        
	        for (Text t:  graph02.selectedTexts())
	            graph02.deleteText(t); 
	        
	        for (RectangleObj r:  graph03.selectedRects() )
	            graph03.deleteRect(r); 
	        
	        for (LineObj l:  graph_line.selectedLines() )
	            graph_line.deleteLine(l); 
	        
	        for (CircleObj c:  graph_circle.selectedcircles() )
	            graph_circle.deleteCircles(c); 
	        
	        repaint();
	 }
	 
	 /****************************************************************************************/

	 public void unselect_all()
	 {
	    	
	    	for (Node n:  graph.selectedNodes())
	    	{
	    		n.setUnSelected(false);
	    	}
	    	
	    	
	    	for (EdgeObj e:  graph.selectedEdges())
	    	{
	     		e.setUnSelected(false);
	     	}    
	    
	    	for (Text t:  graph02.selectedTexts())
	    	{
	     		t.setUnSelected(false);
	     	}       
	    	
	    	for (RectangleObj r:  graph03.selectedRects())
	    	{
	     		r.setUnSelected(false);
	     	}   
	    	
	    	for (LineObj l:  graph_line.selectedLines())
	    	{
	     		l.setUnSelected(false);
	     	}   
	    	
	    	for (CircleObj c:  graph_circle.selectedcircles())
	    	{
	     		c.setUnSelected(false);
	     	}   
	    	
	        repaint();
	 }
	 
	 /****************************************************************************************/

	    public void ouvrir_fichier()
	    {
	        
	        System.out.println("ouvrir un fichier");     
	        
	        JFileChooser fileChooser = new JFileChooser();
	        int returnValue = fileChooser.showOpenDialog(null);
	        if (returnValue == JFileChooser.APPROVE_OPTION)
	        {
	            File selectedFile = fileChooser.getSelectedFile();
	            BufferedReader file;
	            try 
	            {
	                file = new BufferedReader(new FileReader(selectedFile.getAbsolutePath()));
	                graph = Graph.loadFrom(file);
	                graph02 = Graph02.loadFrom(file);
	                graph03 = Graph03.loadFrom(file);
	                graph_line = Graph_line.loadFrom(file);
	                graph_circle = Graph_circle.loadFrom(file);
	                
	    	    	split02.myArea.append(" [ INFO ]: Load file ..." + "\n");
	                
	                file.close();
	                repaint();
	            } 
	            
	            catch (FileNotFoundException ex) 
	            {
	                Logger.getLogger(TopPanel10.class.getName()).log(Level.SEVERE, null, ex);
	            } 
	            
	            catch (IOException ex) 
	            {
	                Logger.getLogger(TopPanel10.class.getName()).log(Level.SEVERE, null, ex);
	            }
	        }
	    }    
	            
	    /****************************************************************************************/
	      
	    public void sauver_fichier()
	    {
	        System.out.println("Sauver un fichier");
	        
	        JFileChooser fileChooser = new JFileChooser();
	        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);	
	        int result = fileChooser.showSaveDialog(null);
		
	        if(result == JFileChooser.CANCEL_OPTION) return;
				
	        fileName = fileChooser.getSelectedFile();

	        if(fileName == null || fileName.getName().equals(""))
	        	JOptionPane.showMessageDialog(null,"Invalid File Name"," Message",JOptionPane.ERROR_MESSAGE);
	        else
	        {
	            PrintWriter file = null;
	            
	            try 
	            {
	                file = new PrintWriter(new FileWriter(fileName.getAbsolutePath()));
	                graph.saveTo(file);   // node & edge
	                graph02.saveTo(file); // text
	                graph03.saveTo(file); // rectangle
	                graph_line.saveTo(file); // lines
	                graph_circle.saveTo(file); // circles
	                
	    	    	split02.myArea.append(" [ INFO ]: Save file ..." + "\n");
	                
	                file.close();
	                
	            } 
	            
	            catch (IOException ex) 
	            {
	                Logger.getLogger(TopPanel10.class.getName()).log(Level.SEVERE, null, ex);
	            } 
	            
	            finally 
	            {
	                file.close();
	            }
	        }
	    }
	    
	    /****************************************************************************************/
	    
	    @Override
	    public int print(Graphics g, PageFormat pf, int page) throws PrinterException 
	    {
	      //  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
	        
	        if (page > 0) 
	        {
	        	return NO_SUCH_PAGE;
	        }

	        Graphics2D g2d = (Graphics2D) g;
	        g2d.translate(pf.getImageableX(), pf.getImageableY());
	        this.printAll(g);
	        return PAGE_EXISTS;
	    }
	    
	    /****************************************************************************************/

	    public void imprimer_fichier()
	    {
	    	PrinterJob printJob = PrinterJob.getPrinterJob();
	    	
	    	DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	 	    Date date = new Date();
	 	    dateFormat.format(date);
	    	
	        //printJob.setJobName("Patoche_appli_Printout_" + dateFormat.format(date) );
	        printJob.setJobName("Patoche_appli_Printout");
	        
	        printJob.setPrintable((Printable) this );
	        
	        if (printJob.printDialog())
	            try 
	        	{
	                printJob.print();
	    	    	split02.myArea.append(" [ INFO ]: Send to printer ..." + "\n");
	            } 
	        	catch (PrinterException pe)
	        	{
	                //System.out.println("Error printing: " + pe);
	                split02.myArea.append(" [ INFO ]: Error printing: " + pe  + "\n");
	            }
	    }
	      
	    /****************************************************************************************/

	    public void clipboard()
	    {
	       
	        BufferedImage bufferedImage = new BufferedImage( getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
	        Graphics2D tempG = bufferedImage.createGraphics();
	        //this.unselectObjs();
	        this.paintComponent(tempG);

	        //get rid of white space
	        int lX = -1;
	        int rX = -1;
	        int tY = -1;
	        int bY = -1;
	        int h = bufferedImage.getHeight()-1;
	        int w = bufferedImage.getWidth()-1;

	        //get top
	        for(int y = 0; y < h; y++)
	            for(int x = 0; x < w; x++)
	                if(bufferedImage.getRGB(x, y) != -1)
	                    bY = y;

	        // get bottom
	        for(int y = h; y >= 0; y--)
	            for(int x = 0; x < w; x++)
	                if(bufferedImage.getRGB(x, y) != -1)
	                    tY = y;

	        //get left
	        for(int x = 0; x < w; x++)
	            for(int y = 0; y < h; y++)
	                if(bufferedImage.getRGB(x, y) != -1)
	                    rX = x;

	        //get right
	        for(int x = w; x >= 0; x--)
	            for(int y = 0; y < h; y++)
	                if(bufferedImage.getRGB(x, y) != -1)
	                    lX = x;

	        //if it worked correctly, make a cropped bufferedimage
	        if(lX != -1 && rX != -1 && tY != -1 && bY != -1)
	        {
	            //System.out.println(lX +" "+rX+" "+tY+" "+bY);
	            //if(lX-1<0)
	            //    lX=1;
	            //if(tY-1<0)
	            bufferedImage = bufferedImage.getSubimage(lX, tY, rX-lX+3, bY-tY+3);

//				si lX = 0 et tY = 0 alors lX-1 et lY-1 font planter l'appli	            
//	            bufferedImage = bufferedImage.getSubimage(lX-1, tY-1, rX-lX+3, bY-tY+3);
	        }

	        ImageToClip imageToClip = new ImageToClip(bufferedImage);
	    	
	    	split02.myArea.append(" [ INFO ]: Clipboard OK : ctrl + v to past on windows" + "\n");

	    }

	    /****************************************************************************************/
	    
	    class ImageToClip implements ClipboardOwner
	    {
	        private Clipboard clip;

	        public ImageToClip(BufferedImage bi)
	        {
	            clip = Toolkit.getDefaultToolkit().getSystemClipboard();
	            BiToClip clipIm = new BiToClip(bi);
	            clip.setContents(clipIm, this);
	        }

	        public void lostOwnership(Clipboard arg0, Transferable arg1) 
	        {
	        }

	    }

	    /****************************************************************************************/
	    
	    class BiToClip implements Transferable
	    {
	        private DataFlavor[] myFlavors = new DataFlavor[]{DataFlavor.imageFlavor};
	        private BufferedImage image;

	        public BiToClip(BufferedImage bi)
	        {
	            image = bi;
	        }

	        public Object getTransferData(DataFlavor arg0)  throws UnsupportedFlavorException, IOException 
	        {
	            if (arg0 != DataFlavor.imageFlavor) 
	            {
	                throw new UnsupportedFlavorException(arg0);
	            }
	            return image;
	        }

	        public DataFlavor[] getTransferDataFlavors() 
	        {
	            return myFlavors;
	        }

	        public boolean isDataFlavorSupported(DataFlavor arg0) 
	        {
	            return (arg0 == DataFlavor.imageFlavor);
	        }
	    }
	    
	    /****************************************************************************************/
	     
	    public void export_image(String extension)
	    {
	         
	    	int aaa = this.getWidth();
	        int bbb = getHeight();
	         BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
	        // paints into image's Graphics
	        this.paint(image.getGraphics());
	        
	        try
	        {
          		ImageIO.write(image, "jpeg", new File("d:/zzz." + extension));
		    	split02.myArea.append(" [ INFO ]: Create image ..."  + "\n");
	        }
	        
	        catch(IOException e)
	        {
	        }
	         
	     }
	 
	    
	    public void set_preferences()
	    {
	    	
	    	//Dialog_preferences dlg = new Dialog_preferences();
	    	
	    	//JFrame parentFrame = (JFrame) myContenPane.getParent()
	    	
	    	//		(JFrame)this.getRootpane().getParent();
	    			
	    	//new Dialog_preferences(JFrame);
	    	
	    	
	    	MonDialogue md1 = new MonDialogue(getFrame(),  "exemple avec JDialog modal",   true);
	    	md1.pack();

	    	int i = 5;
	    	String nom = "patoche";
	
	    	md1.initialise(new Object[]{i, nom});
	    	md1.show();
	    	
	    	Object [] retour = md1.getDonnees();
	    	i = (Integer)retour[0];
	    	nom = (String)retour[1];
	    	
	    }
	    
	    
	   public  Frame getFrame() 
	   { // récupération de la frame de l'applet

	        Component component=this;

	        do{

	           component=component.getParent();

	        } while(!(component instanceof Frame));

	        return (Frame)component;

	     }

	    
	    
	    /****************************************************************************************/
	 
	    public void launch_appli()
	    {
			    
	    		/*try
		        { 
		            // Command to create an external process 
		            String command = "d://chrome.exe"; 
		  
		            // Running the above command 
		            Runtime run  = Runtime.getRuntime(); 
		            Process proc = r.exec(command); 
		        } 
		  
		        catch (IOException e) 
		        { 
		            e.printStackTrace(); 
		        } */
	    	
	    	 Runtime runtime = Runtime.getRuntime();     //getting Runtime object
	    	 
	         try
	         {
	        	 
	        	 //java -jar <jar-file-name>.jar
	        	 
	             runtime.exec("d:/java -jar appli.jar");        //opens "sample.txt" in notepad
	         }
	         catch (IOException e)
	         {
	             e.printStackTrace();
	         }
	    
	    }
}


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