
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.Polygon;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Shape;
import java.awt.Stroke;
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 TopPanel14 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;    
	private Graph_Decision    graph_decision;    
	
	private GraphObj    graph_chart_obj;    
  	
  	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;
//  	DecisionObj decision_selection = null;
  	
  	ChartObj chart_obj_selection = null;
  	
  	TransitionObj transition_selection = null;
  	
  	PolygonObj polygon_selection = null;
  	
  	LoopbackObj loop_obj  = null;
  	CubicCurve2D.Double loop;
	
  	PolygonSommet obj_polygon_sommet;

	
    String selection_obj = ""; 
  	boolean dragging_mode = false;
	
  	TextDialog dialog;
  	
  	JPopupMenu popupMenu;
    
  	ArrayList<Node>   selected = new ArrayList<Node>();
	//ArrayList<Node_Rectangular>   selected_node_rectangular = new ArrayList<Node_Rectangular>();
	
	
	ArrayList<ChartObj>   selected_chart_obj = new ArrayList<ChartObj>();
		
  	
  	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 DecisionObj			dragDecision;
    
    private ChartObj			dragChartObj;
    
    private	PolygonObj			dragPolygonObj;
    
    
    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;
	
	private String type_selected_obj = null;
	
	private boolean mask_grid = false;
	
	
	
	/*********************/
	 int previousY;
	/*********************/
	
	 private boolean polygonIsNowComplete = false;
	 
	 
	 /**************  drawing segment *****************/
	 
	 Point pointStart = null;
	 Point pointEnd   = null;
	 int nb_clicks = 0;
	 int numberOfClicks = 0;
	 int toto = 0;
	 int[] xCoordinates = new int [100];
	 int[] yCoordinates = new int [100];
	
	/****************************************************************************************/
	
	public TopPanel14()
	{
		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();
		graph_decision = new Graph_Decision();
		
		graph_chart_obj = new  GraphObj();
		
		
		split02.myArea.setText(" [ INFO ]: Init GUI : OK : revision " + " TopPanel 14 "  + "\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>() ;
        
        //ArrayList<Node_Rectangular> liste_node_rectangular = null ;
        //ArrayList<String> liste_node_rectangular_available = new ArrayList<String>() ;
        
        
        ArrayList<ChartObj> liste_chart_obj = null ;
        ArrayList<String> liste_id_chart_obj = new ArrayList<String>() ;
        
        
        selected = graph.selectedNodes();
        //selected_node_rectangular = graph_node.selectedNodes();
        
    	selected_chart_obj = graph_chart_obj.selectedChartObj();
        
        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.");
                
             	if(type_selected_obj.equals("STATE")) 
             	{	
             			// selection d'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);
                    
		                    repaint();
		                }
                
             	}
             	
             	
             	/****************************/
             	
             	if(type_selected_obj.equals("CHART_OBJ")) 
             	{
             		//if(checkID(input))
	                //{
	                	//String state_start_name = graph_node.find_selected();
	                	//String state_end_name = input;
	                	
             			String chart_start_name = graph_chart_obj.getSelected();
	                	String chart_end_name = input;
             			
	                	//Node_Rectangular   state_start_obj   = graph_node.nodeNamed(state_start_name); 
	                	//Node_Rectangular   state_end_obj   = graph_node.nodeNamed(state_end_name);
	                
	                	ChartObj   chart_start_obj   = graph_chart_obj.ChartObjNamed(chart_start_name); 
	                	ChartObj   chart_end_obj   = graph_chart_obj.ChartObjNamed(chart_end_name);
	                	
	                	// pour eviter les doublons
	                	if( graph_chart_obj.GetTransitionExists(chart_start_obj, chart_end_obj) == true  )   
	                	{
	                		System.out.println("existe deja !!!!!!");
	                		JOptionPane.showMessageDialog(null,  "Cette transistion existe dèjà !.", "Attention", JOptionPane.ERROR_MESSAGE);
	                	}
	                	else
	                	{	
	                		// enregiste 
	    	 				//graph_node.buildEdge( StartPoint, EndPoint);
	                		//graph_node.pipoaddEdge(state_start_obj, state_end_obj);
	                		System.out.println("TRACE");
	                		graph_chart_obj.addTransition(chart_start_obj, chart_end_obj);
	                		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; 
             	type_selected_obj = "STATE";
            //}
        }    
                
        if(selected_chart_obj.size() == 1)
        {
        	 String id_selected = graph_chart_obj.getSelected();
             System.out.println(" ID of selected chart Obj " + id_selected);
             liste_chart_obj = graph_chart_obj.getChartObj();
             
             for ( int i = 0;  i < liste_chart_obj.size(); i++)
             {
                 String tempID = graph_chart_obj.getChartObj().get(i).getID();
                 if( !tempID.equals( id_selected ) )
                 {
                	 liste_id_chart_obj.add( tempID );
                 }
             }
           
             //if(liste_id_chart_obj.size() >= 1)
             //{
             	// creation du sous menu
             	menu_extension = true; 
             	type_selected_obj = "CHART_OBJ";
             //}
        	
        }
        
/*    
        if(selected_node_rectangular.size() == 1) 
        {
        	 String id_selected = graph_node.find_selected();
             System.out.println(" ID du rectangular node selected " + id_selected);
             
             liste_node_rectangular = graph_node.getNodeRectangle(); 
             
             for ( int i = 0;  i < liste_node_rectangular.size(); i++)
             {
                 String tempID = graph_node.getNodes().get(i).getID();
                 if( !tempID.equals( id_selected ) )
                 {
                	 liste_node_rectangular_available.add( tempID );
                 }
             }
           
             if(liste_node_rectangular_available.size() >= 1)
             {
             	// creation du sous menu
             	menu_extension = true; 
             	type_selected_obj = "RECTANGULAR";
             }
        }
 */       
        /***************************************/
        
        if(menu_extension == true)
        {	
        	 if(type_selected_obj.equals("STATE")) 
        	 {
	        	 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(type_selected_obj.equals("CHART_OBJ")) 
        	 {
	        	 JMenuItem obj_menu = new JMenu("New Transition to ...");
	       	  	 popupMenu.add(obj_menu);
	       	  	 
	       	     JMenuItem item;
	       	  	 
	       	     for(int i = 0; i < liste_id_chart_obj.size() ; i++)
	       	     {
	       	    	 item =  new JMenuItem(   liste_id_chart_obj.get(i)  );
	       	    	 item.addActionListener(menuListener);
	       	    	 obj_menu.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("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;
    }
    
    
    private boolean checkID(String input)
    {
    /*	ArrayList<Node_Rectangular> node_obj = graph_node.getNodes();
    	
        for(int j = 0; j < node_obj.size(); j++)
        {
            if( node_obj.get(j).getID().equals(input) )
            {
                return true;
            }
        
        }
        return false;*/
    	
    	return true;
    }
	 /****************************************************************************************/
	    
    @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); 
        
        ////////////////////////////////////////////////////
        
        if(mask_grid == false )
        {
	    	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);
		        }   
		    }
        }
        ////////////////////////////////////////////////////
        
        
        int xPoly[] = {150, 250, 325, 375, 450, 275, 100};
        int yPoly[] = {150, 100, 125, 225, 250, 375, 300};

        
        float thickness = 6;
        Stroke stroke = new BasicStroke(thickness);
        //Stroke oldStroke = ((Graphics2D) g).getStroke();
        //g.setStroke(new BasicStroke(thickness));
        ((Graphics2D) g).setStroke(stroke);
        
        Polygon poly = new Polygon(xPoly, yPoly, xPoly.length);
        g.setColor(Color.BLUE);
        g.drawPolygon(poly);
        
        // https://www.sanfoundry.com/java-program-check-whether-given-point-lies-given-polygon/
        
        // https://imagej.nih.gov/ij/source/ij/process/FloatPolygon.java
    	
        //drawPolygone() un polygone fermé
        //drawPolyline() une ligne polygonale 
        
    	//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
        
        
    	/************************************************************************/
/*        
        		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 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 (pointStart != null) 
        {
            g.setColor(Color.RED);
            g.drawLine(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
           
        }
        
        if(pointStart != null)
        {	
	        if(nb_clicks != 0) 
	        {
	        	for(int i=0; i< nb_clicks; i++)
	        	{
	        		
	        		g.drawLine(xCoordinates[i]  , yCoordinates[i] , xCoordinates[i+1]  , yCoordinates[i+1]);
	        	}
	        }
        }	
        
    	 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() );  
				    	}
		    	
		    	}
		    	
		    	
		    }
		    
		 
		}
	    
	    
	    /***************** draw les obj decisiions enregistrés   ******************/
	   /* for(int i = 0; i < graph_decision.getDecisions().size(); i++)    		
		{
		    		 DecisionObj obj_decision = graph_decision.getDecisions().get(i);
		    		 
		    		 if(obj_decision.getsetSelected()   == true)
		   		     {	 
		   		    	g.setColor(Color.RED);
		   		     }
		    		 else
		   		     {
		   		    	 g.setColor(Color.BLACK);
		   		     }

		    		  Graphics2D g2 = (Graphics2D) g;
		    		  graph_decision.draw(g2);
		}
	    
	    */
	    
	    /**********************************************/
	    
	    Graphics2D g2 = (Graphics2D) g;

	    graph_chart_obj.draw(g2);
	    
	    
	    if (polygonIsNowComplete == true)
	    {	
	    	// les points et les segments
	        //graph.draw_polygon_sommet(g2); 
	        
	        
	        
	        System.out.println("******** Affiche sommet polygon ************");
	        graph.draw_polygon(g2);  
	        
	    }
		else
		{	
			// seulement les points
	    	    graph.draw_polygon_sommet(g2); 
	    	    graph.draw_polygon(g2);  
	    	    System.out.println("TRACE points");
		}
	    	    
	  //  graph_node.draw(g2);
	  //  graph_decision.draw(g2);
	  
	    
		if(action_draw_connection == true)
		{
	         g.setColor(Color.orange);
	         ((Graphics2D) g).draw(new Line2D.Double(StartPoint, EndPoint));
			
		}
	    
	 
	}

	/****************************************************************************************/
    
    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();
        
        previousY = e.getY();
              
        
		if(val_toolbar == "SEGMENT")
		{
			System.out.println("TRACE flightline");
			pointStart = e.getPoint();

			xCoordinates[nb_clicks] = e.getX();
			yCoordinates[nb_clicks] = e.getY();
			nb_clicks++;
            System.out.println("Cpt points " + numberOfClicks);
		}	
        
		if(val_toolbar == "CONNECTION")
		{
			System.out.println("TRACE flightline");
			
			chart_obj_selection = null;
			transition_selection = null;
			
			//node_rectangulare_selection = null;
			//decision_selection =  null;
			
	   	    node_selection = null;
			edge_selection = null;
			text_edge_selection = null;  
	    	loopback_selection = null;
	        text_selection  = null;
	        rectangle_selection  = null;
	        line_selection = null;
			circle_selection = null;
			
		}
		else
		{	
			chart_obj_selection = graph_chart_obj.insideObj(e.getX(), e.getY());
			transition_selection = graph_chart_obj.insideTransition(e.getX(), e.getY());

			//node_rectangulare_selection = graph_node.nodeAt(e.getX(), e.getY());
			//decision_selection = graph_decision.decisionAt(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());
			
			polygon_selection = graph.PolyhonAt(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(transition_selection != null)
	    	{
	    		transition_selection.toggleSelected();
	    	}
	    	
	        /**************************************/
	        
	        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(chart_obj_selection != null ) 
	        {
	        	selection_obj = "CHART_OBJ";
	        	chart_obj_selection.toggleSelected();
	        	dragChartObj = chart_obj_selection; 
	 		    dragging_mode = true;
	 		    
	 		    if( chart_obj_selection.getObjType().equals("ACTIVITY_OBJ") )
	 		    {	
					int snap_x = ( e.getX() / snap_grid ) * snap_grid;
					int snap_y = ( e.getY() / snap_grid ) * snap_grid;
		 		    offsetx = snap_x - dragChartObj.getX1();
		            offsety = snap_y - dragChartObj.getY1();
	 		    }
	 		    
	 		   if( chart_obj_selection.getObjType().equals("DECISION_OBJ") )
	 		   {	
					int snap_x = ( e.getX() / snap_grid ) * snap_grid;
					int snap_y = ( e.getY() / snap_grid ) * snap_grid;
		 		    offsetx = snap_x - dragChartObj.getP1().x; 
		            offsety = snap_y - dragChartObj.getP1().y;
	 		   } 
		            
	        }


	        if(polygon_selection != null ) 
	        {
	        	selection_obj = "POLYGON_OBJ";
	        	dragPolygonObj = polygon_selection; 
	 		    dragging_mode = true;
	        }	
	        	
	        //////////    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(" -----  ADD ACTIVITY_OBJ"   );
	 			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;	
	        	
	        	Point pt = new Point();
	        	pt.x = snap_x;
	        	pt.y = snap_y;
	        	
	        	pt.setLocation(snap_x, snap_y);
	        	
	        	//Node_Rectangular obj = new Node_Rectangular( "text", StartPoint );
	        	//graph_node.addNode(obj);
	        	ChartObj obj = new ChartObj("ACTIVITY_OBJ", pt );
	        	graph_chart_obj.addChartObj(obj);
	        	split02.stop_action_selected();
	        }
	        
	        if(val_toolbar == "DECISION")
	        {
	        	//System.out.println(" -----  Draw DECISION"   );
	        	//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;	
	        	//DecisionObj obj = new DecisionObj( "Decision 1", StartPoint );
	        	//graph_decision.addDecision(obj);
	        	// stop
	        	//split02.stop_action_selected();
	        	
	        	System.out.println(" -----  ADD DECISION_OBJ"   );
	 			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;	
	        	
	        	Point pt = new Point();
	        	pt.x = snap_x;
	        	pt.y = snap_y;
	        	
	        	pt.setLocation(snap_x, snap_y);
	        	
	        	ChartObj obj = new ChartObj("DECISION_OBJ", pt );
	        	graph_chart_obj.addChartObj(obj);
	        	split02.stop_action_selected();

	        	
	        }
	        
	        if(val_toolbar == "POLYGON")
	        {
	        
	        	//if (polygonIsNowComplete)
				//{
					//points.clear();
				//}
				//points.add(new Point(x, y));
	        	
				polygonIsNowComplete = false;
	        	PolygonSommet aze = new PolygonSommet(e.getX(), e.getY() );
	        	graph.addPolygonSommet(  aze );
	            repaint();
	        }
	        
/********************/	        
	        
	        // dynamique line
	        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")
        {
	        	// 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 );
	 			
	 			Point pt1 =new Point();
	 			pt1.setLocation((int) StartPoint.getX(), (int) StartPoint.getY() );
	 			
	 			Point pt2 =new Point();
	 			pt2.setLocation((int) EndPoint.getX(), (int) EndPoint.getY() );
	 			
	 			System.out.println(" -----   CONNECTION :  " + pt1 + " " + pt2    );
	 			
	 			Node_Rectangular node_rectangulare_start = graph_node.nodeAt(  (int)pt1.getX(), (int)pt1.getY() );
	 			Node_Rectangular node_rectangulare_end = graph_node.nodeAt(  (int)pt2.getX(), (int)pt2.getY() );
	 			DecisionObj decision_start = graph_decision.decisionAt(  (int)pt1.getX(), (int)pt1.getY()  );
	 			DecisionObj decision_end = graph_decision.decisionAt(  (int)pt2.getX(), (int)pt2.getY()  );
	 			
 				boolean titi = graph_decision.xxx( pt1, pt2,  node_rectangulare_start , node_rectangulare_end , decision_start , decision_end); 
	 			
	 			// enregiste 
	 			/*if( graph_decision.buildEdge( pt1, pt2) == true )
	 			{
	 				System.out.println(" -----  Enregistre CONNECTION"   );
	 			}
	 			else
	 			{
	 				System.out.println(" -----  ERROR CONNECTION"   );
	 			}*/
	 			
	 			split02.stop_action_selected();
	        }	
    	
    	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;
        
        dragDecision = null;
        
        dragChartObj = 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;
    	
    	pointStart = null;
    	
    	
    	
    	xCoordinates[nb_clicks] = e.getX();
		yCoordinates[nb_clicks] = e.getY();
		nb_clicks++;
    	
        // 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();
		
		 int y = e.getY();
		
		if (y < previousY) {
            System.out.println("UP");
        } else if (y > previousY) {
            System.out.println("DOWN");
        }
		
		 previousY = y;
		 
		
		 pointEnd = 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();
                    	
                    	
                    	t1 = loopback_obj.startStateIndex*2*Math.PI/36;
             	        t2 = loopback_obj.endStateIndex*2*Math.PI/36;
                    	
                    	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("DECISION") )
 	    	 {	
   			    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("blablabla... " + 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("CHART_OBJ")) 
    		 {
    			 if(dragChartObj != null )
    			 {
    				 if(dragChartObj.isSelected())
    				 {
    					 
    					 if( dragChartObj.getObjType().equals("ACTIVITY_OBJ") )
    					 {	 
	    					 int snap_x = ( e.getX() / snap_grid) * snap_grid;
	    					 int snap_y = ( e.getY() / snap_grid) * snap_grid;
	    					 dragChartObj.setX1( snap_x - offsetx );  
	    					 dragChartObj.setY1( snap_y - offsety );
	    					 dragChartObj.setCentreX_Activity();
	    					 dragChartObj.setCentreY_Activity();
	    					 System.out.println("DRAG ACTIVITY_OBJ" );  
    					 }
    					 
    					 if( dragChartObj.getObjType().equals("DECISION_OBJ") )
    					 {
    						 
    						 int snap_x = ( e.getX() / snap_grid) * snap_grid;
        					 int snap_y = ( e.getY() / snap_grid) * snap_grid;
        					 
        					 // mise à jour des 4 points et du centre
        					 
        					 Point p1 = new Point( snap_x - offsetx, snap_y - offsety );
        					 Point p2 = new Point(p1.x + ( dragChartObj.getWidth_Decision() /2), p1.y - ( dragChartObj.getHeight_Decision()/2) );
        					 Point p3 = new Point( p1.x +  dragChartObj.getWidth_Decision() ,  p1.y  );
        					 Point p4 = new Point( p1.x +  ( dragChartObj.getWidth_Decision()/2) ,  +  p1.y + (dragChartObj.getHeight_Decision()/2) ) ;
        				    	
        					 dragChartObj.setP1(p1);
        					 dragChartObj.setP2(p2);
        					 dragChartObj.setP3(p3);
        					 dragChartObj.setP4(p4);
        					 
        					 dragChartObj.setCentreX_Decision(p1.x + ( dragChartObj.getWidth_Decision()/2) );
        					 dragChartObj.setCentreY_Decision(p1.y);
        					
        					 // le calcul des points d'ancrage a té supprimés, on verra plus tard
    					 }
    					 
    				 }
    			 }
    		 }
    		 
    		 
    		
    		 
    		 
    		 //
    		 
    		 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());  
    					 }
    					 
    				 }
    			 }
    		 }
    		 
    		 
    		 if(selection_obj.equals("POLYGON_OBJ")) 
    		 {
    			 if(dragPolygonObj != null )
    			 {
    				 int snap_x = ( e.getX() / snap_grid ) * snap_grid;
				     int snap_y = ( e.getY() / snap_grid ) * snap_grid;
					 System.out.println("MODIFY POLYGON_OBJ - moving point" );  
					 int position = dragPolygonObj.getSelectedSommetIndice();
					 graph.PolyhonSetPointSommet(dragPolygonObj, position, snap_x, snap_y);
					 
					 //if (current == -1) return;
		             //  points[current] = event.getPoint();
		       
    			 }
    		 }
    		 
    		/* if(polygon_selection != null ) 
 	        {
 	        	selection_obj = "POLYGON_OBJ";
 	        	dragPolygonObj = polygon_selection; 
 	 		    dragging_mode = true;
 	        }	*/
    		 
    	}
		
		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);
	    
	    pointEnd = e.getPoint();
	    
	    /*
	    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<ChartObj>  selected_chart_obj = new ArrayList<ChartObj>();
		 selected_chart_obj = graph_chart_obj.selectedChartObj();
		 
		 ///// DOIT ETRE CHNAGER !!!!!!!
		 //////////////////////////////////
		 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];
	    		String state_expression = (String)retour[1];
	    		Boolean return_state = (Boolean)retour[2];  // ok = true et cancler = false
	    		Color state_color = (Color)retour[3];
	    		Color text_color = (Color)retour[4];
	    		
	 			// 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);
	 				node_selection.setExpression(state_expression);
	 				
            		// changement du lien pour le loopback 
            		LoopbackObj loopback_obj = new LoopbackObj();
            		loopback_obj = node_selection.getloopback();
            		loopback_obj.setLabel(state_name);
            		
            		node_selection.setStateColor(state_color);
            		node_selection.setTextColor(text_color);
            		
            		// redessiner 
                    repaint();
	         	}
	 			else
	         	{
	         		System.out.println("debug Close - no action");
	         	}
	    		
	    	 }	
	    	 
	     }
	     
	     /************************/
	     
	     if(selected_chart_obj.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, chart_obj_selection.getText() );
	    	 		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 );
	    	 		chart_obj_selection.setText(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) 
	 {
		 
		   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();
		   }
		   
		   if(e.getKeyCode() == KeyEvent. VK_ESCAPE)
		   {
			   System.out.println("Escape key");
			   polygonIsNowComplete = true;
			   
			   
			   //graph.addNode(new PolygonObj( ) );	
			   
			   ArrayList<Point> points_array = graph.get_list_polygon_sommet();
			   
			  // ArrayList<Point> obja = graph.get_list_polygon_sommet();
			   
			   PolygonObj app = new PolygonObj( points_array );
			   
			   graph.addPolygon(app );	
			   
			   graph.clear_list_polygon_sommet();
			   
			   split02.stop_action_selected();
			   repaint();
		   }
		   
		   if(e.getKeyCode() == KeyEvent.VK_SPACE)
		   {
			   System.out.println("Space key");
		   }
		  
	 }
	   
	 /****************************************************************************************/

	 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();
	        graph_chart_obj.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); 
	        
	    	for (ChartObj obj:  graph_chart_obj.selectedChartObj())
	            graph_chart_obj.deleteChartObj(obj); 
	        
	        
	    	for (TransitionObj obj:  graph_chart_obj.selectedTransistion())
	            graph_chart_obj.deleteTransition(obj); 
	        
	    	
	    	
	    	
	        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);
	     	}   
	    	
	    	for (ChartObj obj:  graph_chart_obj.selectedChartObj())
	    	{
	     		obj.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);
	                
	                graph_chart_obj = GraphObj.loadFrom(file);
	                
	    	    	split02.myArea.append(" [ INFO ]: Load file ..." + "\n");
	                
	                file.close();
	                repaint();
	            } 
	            
	            catch (FileNotFoundException ex) 
	            {
	                Logger.getLogger(TopPanel14.class.getName()).log(Level.SEVERE, null, ex);
	            } 
	            
	            catch (IOException ex) 
	            {
	                Logger.getLogger(TopPanel14.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
	                
	                graph_chart_obj.saveTo(file);   // node & edge
	                
	    	    	split02.myArea.append(" [ INFO ]: Save file ..." + "\n");
	                
	                file.close();
	                
	            } 
	            
	            catch (IOException ex) 
	            {
	                Logger.getLogger(TopPanel14.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()
	    {
	        
	    	mask_grid = true;
	    	repaint();
	    	
	        //BufferedImage bufferedImage = new BufferedImage( getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
	        BufferedImage bufferedImage = new BufferedImage( 1100, 640, 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");
	    	
	    	mask_grid = false;
	    	repaint();

	    }

	    /****************************************************************************************/
	    
	    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();
	         }
	    
	    }
}


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

//draw polygon

//http://alumni.cs.ucr.edu/~titus/Polygons.java

// https://eng.umd.edu/~austin/ence200.d/homework03-5.d/PolygonGUI.java

// http://facstaff.cbu.edu/yanushka/j1/j/c5/ShapeDraw.java

// -----> http://qaru.site/questions/6593425/how-to-name-the-coordinates-points-in-java-swing a voir

// -----> http://www.dil.univ-mrs.fr/~tichit/java/jedigraph/JEdigraph.html

// http://oss.mars.asu.edu/svn/jmars/phoenix_cubesat/tags/10_2018_starting_point/edu/asu/ appli
/*
Polygon triangle = new Polygon();
triangle.addPoint(20, 20);
triangle.addPoint(50, 100);
triangle.addPoint(80, 30);
Pass the Polygon object to drawPolygon() to draw it
g.drawPolygon(triangle);*/

// point inside polygon
/*
public void mouseClicked(MouseEvent e) {
    if (myPoly.contains(e.getX(), e.getY()) {
        inside = true;
        repaint();
    }
}
*/

//poly.translate(xdisp, ydisp);

// drawPolygon(int[] xPoints, int[] yPoints, int numPoint);

// http://www.ntu.edu.sg/home/ehchua/programming/java/J4b_CustomGraphics.html

// https://introcs.cs.princeton.edu/java/stdlib/

// Shape appli


/*
public static void main(String... args) throws Exception {
    Robot robot = new Robot();
    Random random = new Random();
    while (true) {
        robot.mouseMove(random.nextInt(MAX_X), random.nextInt(MAX_Y));
        Thread.sleep(FIVE_SECONDS);
    }
}
*/


// morceau de ligne ou segment
// https://www.codemiles.com/java-gui/draw-any-number-of-lines-on-mouse-clicks-t10911.html 

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

// https://stackoverflow.com/questions/35648983/how-to-draw-a-line-with-a-direction-and-a-fixed-length


// http://math.hws.edu/eck/cs124/labs/lab10/SimpleDrawProgram.java

// https://github.com/JoeDavisson/SimplePCB

// https://github.com/bancika/diy-layout-creator/releases/tag/v3.40.0