
import java.awt.Color;
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.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.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.Ellipse2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
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.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.imageio.ImageIO;
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 javax.swing.JPanel;





import java.awt.AWTException;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JMenu;

import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Shape;
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.MouseEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.event.MouseAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.CubicCurve2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


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

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

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

public class TopPanel07 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;
	  	
  	
  	Node  node_selection = null;
	Text  text_selection = null; 
	EdgeObj  edge_selection = null; 
	RectangleObj  rectangle_selection = null; 
	LineObj  line_selection = null; 
  	CircleObj circle_selection = null;
	
	
    String selection_obj = ""; 
  	boolean dragging_mode = false;
	
  	TextDialog dialog;
  	
  	JPopupMenu popupMenu;
    
  	ArrayList<Node>   selected = new ArrayList<Node>();
  	
  	MouseEvent save_evt;
  	
	private ClasseTransfert trans = new ClasseTransfert();
	
    String saisie = "";
    private File fileName;
    
    private JFrame JFrame;
    
    private Node     		dragNode;  
   	private EdgeObj 	  	dragEdge;  
    private Text     		dragText;  
    private RectangleObj   	dragRectangle; 
    private LineObj		    dragLine;
    private CircleObj		dragCircle;
    
    
    private 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;
    
    
    boolean isAlreadyOneClick;
    
    RectangleObj currentShapeObject;
    
    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_refresh = false;
	
	/****************************************************************************************/
	
	public TopPanel07()
	{
		super();
		
		myToolbar = new Toolbar();
		graph02 = new Graph02();
		graph03 = new Graph03();
		graph_line = new Graph_line();
		graph_circle = new Graph_circle();
		
		split02.myArea.setText(" [ INFO ]: Init GUI : OK : revision " + " TopPanel07 "  + "\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);  
	    
	    
	     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();
    }
	
	 /****************************************************************************************/

	void create_popup_menu(MouseEvent e) 
    {
        JMenuItem menuItem;
        JPopupMenu popupMenu = new JPopupMenu();
        ArrayList<Node> liste_node = null ;
        ArrayList<String> liste_node_available = new ArrayList<String>() ;
        selected = graph.selectedNodes();
        boolean menu_extension = false; 
        
        int xmouse = e.getX();
        int ymouse = e.getY();
        
        
        ActionListener menuListener = new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                JMenuItem source = (JMenuItem)(e.getSource());
                String input = source.getText();
                System.out.println(input);
                System.out.println("Popup menu item [" + e.getActionCommand() + "] was pressed.");
                
                // pour ajouter un state
                if(checkStateName(input))
                {
                	String state_start_name = graph.find_selected();
                	String state_end_name = input;
                	Node   state_start_obj   = graph.nodeNamed(state_start_name); 
                	Node   state_end_obj   = graph.nodeNamed(state_end_name);
                	System.out.println("Creation de la transistion entre les states ...");
                	
                	// pour eviter les doublons
                	if( graph.GetEdgeExists(state_start_obj, state_end_obj) == true  )   
                	{
                		System.out.println("existe deja !!!!!!");
                		JOptionPane.showMessageDialog(null,  "Cette transistion existe dèjà !.", "Attention", JOptionPane.ERROR_MESSAGE);
                	          
                	}
                	else
                	{	
                		graph.addEdge(state_start_obj, state_end_obj);
                		repaint();
                	}
                }
                
                
                if(input == "Delete Loopback Transition")
                {
                	selected.get(0).Set_loopback_status(false); 
                	System.out.println("remove loopback");
                	repaint();
                }
                
                if(input == "New Loopback Transition")
                {
                	ArrayList<Node>   selected = new ArrayList<Node>();
                    selected = graph.selectedNodes();
                    
                    if(selected.size() == 1)
                    {
                    	selected.get(0).Set_loopback_status(true);
                        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");
                    
                	repaint();
                }
                
                if(input == "New Free Text")
                {
                  	 TextDialog dialog = new TextDialog();
                  	 dialog.setModal(true);
                  	 dialog.setVisible(true);
                  	 
                  	 // recupération de la saisie
                  	 saisie = dialog.getText();
                  	 System.out.println(saisie);
                  	 
                  	 // creation de l'objet et enregistrement
                  	 Text azer = new Text( saisie, xmouse, ymouse, Color.black );
                     graph02.addText(azer);
                  	 repaint();
                }
                
            }
        };
        
        if(selected.size() == 1)
        {
            String current_selected_state = graph.find_selected();
            System.out.println(current_selected_state);
            
            liste_node = graph.getNodes();
            
            for ( int i = 0;  i < liste_node.size(); i++)
            {
                String tempName = graph.getNodes().get(i).getLabel();
                if( !tempName.equals(current_selected_state) )
                {
                	liste_node_available.add(tempName);
                }
            }
          
            if(liste_node_available.size() >= 1)
            {
            	// creation du sous menu
            	menu_extension = true; 
            }
        }    
        
        /***************************************/
        
        if(menu_extension == true)
        {	
        	
        	 JMenuItem states = new JMenu("New State Transition to ...");
       	  	 popupMenu.add(states);
       	  	 
       	     JMenuItem item;
       	  	 
       	     for(int i = 0; i < liste_node_available.size() ; i++)
       	     {
       	    	 item =  new JMenuItem(   liste_node_available.get(i)	 );
       	    	 item.addActionListener(menuListener);
       	    	 states.add(item);
       	     }
        
        }
        
        /*************************************************/
        if(selected.size() != 0) 
        {
	        if( selected.get(0).Get_loopback_status() == true )
	        {
	        	menuItem = new JMenuItem("Delete Loopback Transition");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
	        
	        else
	        {	
	        	menuItem = new JMenuItem("New Loopback Transition");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
        }
        
        /*************************************************/
        
        if(selected.size() != 0) 
        {
	        if( selected.get(0).Get_reset_status() == true )
	        {
	        	menuItem = new JMenuItem("Delete Reset state");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
	        
	        else
	        {	
	        	menuItem = new JMenuItem("Reset state");
	        	menuItem.setMnemonic(KeyEvent.VK_L);
	        	menuItem.addActionListener(menuListener);
	        	popupMenu.add(menuItem);
	        }
        }
        
        /*************************************************/
        
        menuItem = new JMenuItem("New Free Text");
        menuItem.setMnemonic(KeyEvent.VK_F);
        menuItem.addActionListener(menuListener);
        popupMenu.add(menuItem);
       
        /*************************************************/
        
        menuItem = new JMenuItem("Infos");
        menuItem.setMnemonic(KeyEvent.VK_F);
        menuItem.addActionListener(menuListener);
        popupMenu.add(menuItem);
        
        popupMenu.show(e.getComponent(),  save_evt.getX() ,save_evt.getY());
        
    }
    
	/****************************************************************************************/
	
    void showPopup()  
    {
    	create_popup_menu( save_evt );
    }
    
    /****************************************************************************************/

    private boolean checkStateName(String input)
    {
    	ArrayList<Node> node_obj = graph.getNodes();
    	
        for(int j = 0; j < node_obj.size(); j++)
        {
            if( node_obj.get(j).getLabel().equals(input) )
            {
                return true;
            }
        
        }
        return false;
    }
    
	 /****************************************************************************************/
	    
    @Override
	public void paintComponent(Graphics g) 
	{
    	super.paintComponent(g);
    	
    	graph.new_draw((Graphics2D) g);
	    	
		Graphics2D g2d = (Graphics2D) g;
		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();
                 
                 Graphics2D g2D = (Graphics2D) g;
                 loopback_obj.draw_loopback(g2D, x0, y0, x1, y1);
    		}
    	} 
    	
		
    	/***************** 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;
            int diametre = int_raduis*2;
            g.drawOval( (int)StartPoint.getX() - int_raduis, (int)StartPoint.getY() - int_raduis, diametre, diametre );
            
                        
            System.out.println("Updating circle .... dragged");  
        }
	    
	    
	    /********************************************************************************************/
	    
	    
	    /***************** draw les obj circles enregistrés    ******************/
	    if(circle_current_point_anchar == false)    
	    {
		    for(int i = 0; i < graph_circle.getCircles().size(); i++)    		
			{
			    CircleObj circle = graph_circle.getCircles().get(i);
			    		 
			    if(circle.getsetSelected() == true)
			    {	 
			      	g.setColor(Color.RED);
			      	//int diametre = circle.get_diametre();
			        // anchor 
	   		    	int x = circle.x1;
	   		    	int y = circle.y1; 
	   		    	int	w = circle.get_diametre();
	   		    	int h = w;
	   		    	/*
			      	int w = 0, h = 0;
			    	
			    	if(circle.get_width() > 0 && circle.get_height() > 0)
			    	{
			    		if(circle.get_width() == circle.get_height())
			    		{
			    			w =  circle.get_width();
			    			h =  w;
			    		}
			    		else
			    		{
			    			w =  circle.get_width();
			    			h =  circle.get_height();
			    		}
			    	}
			    	else
			    	{
			    		w = diametre;
			    		h = diametre;
			    				
			    	}
	   		    	*/
	   		    	int SIZE = 12;
	   		    	// coin superieur gauche
	   		        g.fillRect( x - SIZE /2, y - SIZE /2, SIZE, SIZE);
	   		    	// coin inferieur droit
	   		        g.fillRect(x + w - SIZE /2, y + h - SIZE /2, SIZE, SIZE);
	   		        
	   		         System.out.println(" je clicke " + circle.getX1() + "  " + circle.getY1() + " " + w + " " + h);  
	   		        
			    }
			    else
			    {
			    	g.setColor(circle.color);
			   	}
			             
			    int diametre = circle.get_diametre();
			    int radius = diametre /2;

			    // excécuter un seul fois lors de la création du cercle
			    // le dernier cercle dessiné est affiché avec le décalages puis on 
			    // fait la compensation et on desactive circle_refresh qui passe  à false
			    if(circle_refresh == true && i == graph_circle.getCircles().size() - 1)
			    { 
			    	g.drawOval( circle.getX1()  - radius, circle.getY1() - radius, diametre, diametre );	
			    	//g.drawRect( circle.getX1()  - radius, circle.getY1() - radius, diametre, diametre );	
			    	//g.drawRect( circle.getX1()  - 2, circle.getY1() - 2, 4, 4 );	
			    	
			    	// recalculer
			    	int x1_tmp = circle.getX1() - radius;
			    	int y1_tmp = circle.getY1() - radius;
			    	// mise a jour
			    	circle.setX1(x1_tmp);
			    	circle.setY1(y1_tmp);
			    	System.out.println(" compensation " + x1_tmp + "  " + y1_tmp + " " + diametre);  
			    	circle_refresh = false;
			    	
			    }//
			    
			    // en mode normal
			    else
			    {
			    	
			    	
			    	g.drawOval( circle.getX1() , circle.getY1() , diametre , diametre );	
			    	 System.out.println("finish circle .... " + circle.getX1() + " " + circle.getY1() + "  " + diametre);  
			    	//g.drawRect( circle.getX1() , circle.getY1() , diametre, diametre );	
			    	//g.drawRect( circle.getX1() + radius - 2, circle.getY1() + radius - 2, 4, 4 );	
			    } 
			}
	    }
	    
	    
	    if(circle_current_point_anchar == true)
	    {
	    		     g.setColor(Color.green);
	    	
	    			 if(circle_current_point_anchar_selected == 1)
	     			 {
			    				 int width = circle_P1_points_anchar.x - circle_P3_points_anchar.x;
			    				 int height = circle_P1_points_anchar.y - circle_P3_points_anchar.y ; 
		 				    	 if( width < 0 && height < 0) // -- 
		 				    	 {
		 				    		int w = - width;
		 				    	    int h = - height;
			    				    g.drawOval( circle_P1_points_anchar.x , circle_P1_points_anchar.y , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  circle_P1_points_anchar.x;
			    				    rect_y =  circle_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.drawOval( circle_P3_points_anchar.x - w  , circle_P3_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  circle_P3_points_anchar.x - w;
			    				    rect_y =  circle_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.drawOval( circle_P3_points_anchar.x , circle_P1_points_anchar.y , w, h );
			    				    // sauve tmp
			    				    rect_x =  circle_P3_points_anchar.x;
			    				    rect_y =  circle_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.drawOval( circle_P3_points_anchar.x , circle_P1_points_anchar.y - h , w, h ); 
			    				    // sauve tmp
			    				    rect_x = circle_P3_points_anchar.x;
			    				    rect_y =  circle_P1_points_anchar.y - h;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("Zone D ");  
		 				    	 }
 	 				    		 // mise a jour de l'objet
		 				    	 circle_selection.setX1(rect_x);
		 				    	 circle_selection.setY1(rect_y); 
		 				    	 circle_selection.setWidth(rect_width);
		 				    	 circle_selection.setHeight(rect_height);
		 				    	 
		 				    	 System.out.println("resizing circle.... " +  rect_x + " " + rect_y + " " + rect_width + " " + rect_height);  
	     			 	}
	    			 
	    			 	if(circle_current_point_anchar_selected == 3)
	    			 	{
	    				 		 int width = circle_P1_points_anchar.x - circle_P3_points_anchar.x;
	    				 		 int height = circle_P1_points_anchar.y - circle_P3_points_anchar.y ; 
		 				    	 if( width < 0 && height < 0) // - -
		 				    	 {
		 				    		int w = - width;
		 				    	    int h = - height;
		    				    	g.drawOval( circle_P1_points_anchar.x  , circle_P3_points_anchar.y -h   , w , h ); 
			    				    // sauve tmp
			    				    rect_x =  circle_P1_points_anchar.x;
			    				    rect_y =  circle_P3_points_anchar.y-h;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone A " + circle_P1_points_anchar.x + " " + circle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }
		 				    	 if( width > 0 && height < 0) // + -
		 				    	 {
		 				    		int w =  width;
		 				    	    int h = - height;
			    				    g.drawOval( circle_P3_points_anchar.x   , circle_P1_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  circle_P3_points_anchar.x;
			    				    rect_y =  circle_P1_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone B " + circle_P1_points_anchar.x + " " + circle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }
		 				    	 
		 				    	 if( width > 0 && height > 0) // + + 
		 				    	 {
		 				    		int w =  width;
		 				    	    int h =  height;
			    				    g.drawOval( circle_P3_points_anchar.x   , circle_P3_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  circle_P3_points_anchar.x;
			    				    rect_y =  circle_P3_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone C " + circle_P1_points_anchar.x + " " + circle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }

		 				    	 if( width < 0 && height > 0) // - +s
		 				    	 {
		 				    		int w =   - width;
		 				    	    int h =  height;
			    				    g.drawOval( circle_P1_points_anchar.x     , circle_P3_points_anchar.y      , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  circle_P1_points_anchar.x;
			    				    rect_y =  circle_P3_points_anchar.y;
			    				    rect_width = w;
			    				    rect_height = h;
			    				    System.out.println("P3 Zone D " + circle_P1_points_anchar.x + " " + circle_P3_points_anchar.y  + " " + w + " " + h );  
		 				    	 }
		 				    	 
		 				    	 // mise a jour de l'objet
		 				    	 circle_selection.setX1(rect_x);
		 				    	 circle_selection.setY1(rect_y); 
		 				    	 circle_selection.setWidth(rect_width);
		 				    	 circle_selection.setHeight(rect_height);

		 				    	 
		 				    	 System.out.println("resizing circle.... " +  rect_x + " " + rect_y + " " + rect_width + " " + rect_height);  
	    			 	}
	    			 	
	    }
	    
	    
	    /***************** draw les obj circles enregistrés    ******************/
	/*    
	    for(int i = 0; i < graph_circle.getCircles().size(); i++)    		
		{
		    CircleObj circle = graph_circle.getCircles().get(i);
		    		 
		    if(circle.getsetSelected() == true)
		    {	 
		      	g.setColor(Color.RED);
		      	
		        // anchor 
   		    	int x = circle.x1;
   		    	int y = circle.y1; 
   		    	int	w = circle.get_diametre();
   		    	int h = w;
   		    	
   		    	int SIZE = 12;
   		    	// coin superieur gauche
   		        g.fillRect(x - SIZE /2, y - SIZE /2, SIZE, SIZE);
   		    	// coin inferieur droit
   		        g.fillRect(x + w - SIZE /2, y + h - SIZE /2, SIZE, SIZE);
		    }
		    else
		    {
		    	g.setColor(circle.color);
		   	}
		             
		    int diametre = circle.get_diametre();
		    int radius = diametre /2;

		    // excécuter un seul fois lors de la création du cercle
		    // le dernier cercle dessiné est affiché avec le décalages puis on 
		    // fait la compensation et on desactive circle_refresh qui passe  à false
		    if(circle_refresh == true && i == graph_circle.getCircles().size() - 1)
		    { 
		    	g.drawOval( circle.getX1()  - radius, circle.getY1() - radius, diametre, diametre );	
		    	//g.drawRect( circle.getX1()  - radius, circle.getY1() - radius, diametre, diametre );	
		    	//g.drawRect( circle.getX1()  - 2, circle.getY1() - 2, 4, 4 );	
		    	
		    	// recalculer
		    	int x1_tmp = circle.getX1() - radius;
		    	int y1_tmp = circle.getY1() - radius;
		    	// mise a jour
		    	circle.setX1(x1_tmp);
		    	circle.setY1(y1_tmp);
		    	System.out.println(" compensation " + x1_tmp + "  " + y1_tmp + " " + diametre);  
		    	circle_refresh = false;
		    	
		    }//
		    
		    // en mode normal
		    else
		    {
		    	g.drawOval( circle.getX1() , circle.getY1() , diametre, diametre );	
		    	//g.drawRect( circle.getX1() , circle.getY1() , diametre, diametre );	
		    	//g.drawRect( circle.getX1() + radius - 2, circle.getY1() + radius - 2, 4, 4 );	
		    } 
		}
	    */
	}

	/****************************************************************************************/
    
    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) 
	{  
        String val_toolbar = split02.return_action_selected();
		
		node_selection = graph.nodeAt(e.getX(), e.getY());
    	edge_selection = graph.New_edgeAt(e.getX(), e.getY());
        text_selection  = graph02.textAt(e.getX(), e.getY());
        rectangle_selection  = graph03.rectangleAt(e.getX(), e.getY());
        line_selection = getClickedLine(e.getX(), e.getY());
		circle_selection = graph_circle.new_CircleAt(e.getX(), e.getY());
        
    	ArrayList<Node>   selected_nodes = new ArrayList<Node>();
    	selected_nodes = graph.selectedNodes();
    	
    	ArrayList<EdgeObj>   selected_edges = new ArrayList<EdgeObj>();
    	selected_edges = graph.selectedEdges();
        
    	ArrayList<Text>   selected_texts = new ArrayList<Text>();
    	selected_texts = graph02.selectedTexts();
        
    	ArrayList<RectangleObj>   selected_rects = new ArrayList<RectangleObj>();
    	selected_rects = graph03.selectedRects();
        
    	int total_selected_obj = selected_nodes.size() + selected_edges.size() + selected_texts.size() + selected_rects.size();
    	
    	// un seul obj déplacer en même temps
        
		if (isAlreadyOneClick) 
		{
	        System.out.println("double click");
	        
	        if (node_selection == null && edge_selection == null && text_selection == null && rectangle_selection == null && isAlreadyOneClick == true ) 
	        {
	    		System.out.println("Node creation");
	    		saisir_state(new Point2D.Double( e.getX(),e.getY() ) );
	        }
	        
	        isAlreadyOneClick = false;
	    } 
		else 
		{
	        isAlreadyOneClick = true;
	        
	        //////////    selection des objets ///////
	        
	        Point p = e.getPoint();
	        
	        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 (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;
	        }
			  
	        
	        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;
	 		    offsetx = e.getX() - dragRectangle.getX1();
	            offsety = e.getY() - dragRectangle.getY1();
	            
	            System.out.println(" -----  " +  e.getX() + "  " + e.getY() + "  " +  offsetx + "  " + offsety + "  " + +  dragRectangle.getX1() + " " + dragRectangle.getY1() + " " + dragRectangle.getX2() + " " + dragRectangle.getY2() 
	            + " " + dragRectangle.getWidth() + " " + dragRectangle.getHeight());
	            
	        }
	        
	        if(circle_selection != null)
       		{
	        	 System.out.println(" youpi  ");
	        	 selection_obj = "CIRCLE";
	        	 circle_selection.toggleSelected();
	        	 dragCircle = circle_selection; 	
		         dragging_mode = true;
		         
		       
		         offsetx = e.getX() - dragCircle.getX1();
		         offsety = e.getY() - dragCircle.getY1();
		         
		         int x = circle_selection.getX1();
			     int y = circle_selection.getY1();
			     int w = circle_selection.get_diametre();
			     int h = w;
			    	
			     int SIZE = 12;
			    	
                 Rectangle2D P1_area = new Rectangle2D.Double(x - SIZE /2, y - SIZE /2, SIZE, SIZE);     
	             Rectangle2D P3_area = new Rectangle2D.Double(x + w - 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");
	    	        	circle_current_point_anchar = true;
	    	        	circle_current_point_anchar_selected = 1;  // point p1
	                }
	             
	             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");
	    	        	circle_current_point_anchar = true;
	    	        	circle_current_point_anchar_selected = 3;  // point p3
	                }
       		}
	        
	        //////////    action  avec la toolbar ///////
	        //val_toolbar = split02.return_action_selected();
	        if(val_toolbar == "RECTANGLE")
	        {
	        	drag_rectangle = true;
	        	StartPoint = new Point2D.Double(e.getX(), e.getY());
	        	EndPoint = StartPoint;	
	        
	        	currentShapeObject = new RectangleObj(  (int)StartPoint.getX() , (int)StartPoint.getY(), (int)StartPoint.getX() , (int)StartPoint.getY() , Color.BLUE);
	        	//currentShapeObject = new RectangleObj( 0, e.getX() , e.getY(), e.getX() , e.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() );
	        	     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();
	        	 }
	        }
	        
	        if(val_toolbar == "LINE")
	        {
	        	 System.out.println(" -----  Draw line"   );
	        	 drag_line = true;
		         StartPoint = new Point2D.Double(e.getX(), e.getY());
		        
	        }
	        
	        if(val_toolbar == "CIRCLE")
	        {
	        	 System.out.println(" -----  Draw Circle"   );
	        	 drag_circle = true;
		         StartPoint = new Point2D.Double(e.getX(), e.getY());
		         EndPoint = StartPoint; 
		        
	        }
	        
	  /*    work 04  et proj gui  
	        _state = State.DRAGGING;   // Assume we're starting a drag.
	        
	        _start = e.getPoint();     // Save start point, and also initially
	        _end   = _start;           // as end point, which drag will change.
	        
	  */     
	        //LineObj clickedLine = getClickedLine(e.getX(), e.getY());

	        /************************/
	        // 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

		dragPoint = new Point2D.Double(e.getX(), e.getY());
    	  
	}  
	
	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 )
	    {
    		EndPoint = new Point2D.Double(e.getX(), e.getY());
    		// 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 )
	    {
    		EndPoint = new Point2D.Double(e.getX(), e.getY());
    		// enregistre l'objet
    		graph_circle.addcircle( new CircleObj( (int)StartPoint.getX(), (int)StartPoint.getY(), (int)EndPoint.getX(), (int)EndPoint.getY() , Color.BLUE ) );
			drag_circle = false;
	      	// desactive l'action en cours
	        split02.stop_action_selected();
	        // pour compenser le decalage du cercle 
	        circle_refresh = true;
	    }  
          
        
        dragNode = null;  

        dragging_mode = false;
        
        dragRectangle = null;
        
        dragCircle = 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;
    	
        // prend le focus sur le panel pour utiliser le listener du panel
        requestFocus();
        
        repaint();
	}
	
	@Override
	public void mouseDragged(MouseEvent e) 
	{
		split02.mouse_position(e.getX(), e.getY());
		
		if(    dragging_mode == true)
    	{
    		// System.out.print("---- DRAGGING MODE \n" + e.getX() + " " + e.getY() );
    		 
    		 if(selection_obj.equals("NODE") )
    		 {
                 if (dragNode.isSelected()) 
                 {
                     for (Node n:  graph.selectedNodes()) 
                     {
                         n.setLocation(n.getLocation().getX() + e.getX() - dragPoint.getX(),  n.getLocation().getY() + e.getY() - dragPoint.getY());
                     }
                     dragPoint = new Point2D.Double(e.getX(), e.getY());
                 }
             }
    		 
    		 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(selection_obj.equals("TEXT") )
    		 {
    			 text_selection.setX(e.getX());
    			 text_selection.setY(e.getY());
    		 }
    		
    		 
    		 if(selection_obj.equals("CIRCLE") )
    		 {
    			 dragCircle.setX1( e.getX() - offsetx );  
    			 dragCircle.setY1( e.getY() - offsety );
    		 }
    		 
    		 if(selection_obj.equals("RECTANGLE"))
    		 {
    			 if(dragRectangle != null )
    			 {
    				 if(dragRectangle.isSelected())
    				 {
    					 dragRectangle.setX1( e.getX() - offsetx );  
    					 dragRectangle.setY1( e.getY() - offsety );
    				 }
    			 }
    		 }
    		 
    		 if(selection_obj.equals("LINE"))
    		 {
    			 if(dragLine != null )
    			 {
    				 if(dragLine.isSelected())
    				 {
    					 System.out.println("Press Drag line");
    					 if(line_orientation == 1)
    					 {
    						 dragLine.setX1( e.getX() - offsetx );  
        					 dragLine.setY1( e.getY() + offsety );
        					 dragLine.setX2( e.getX() + offsetx );  
        					 dragLine.setY2( e.getY() - offsety );
        					 System.out.println("AAAA" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 if(line_orientation == 2)
    					 {
    						 dragLine.setX1( e.getX() + offsetx );  
        					 dragLine.setY1( e.getY() - offsety );
        					 dragLine.setX2( e.getX() - offsetx );  
        					 dragLine.setY2( e.getY() + offsety );
        					 System.out.println("BBBB" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 if(line_orientation == 3)
    					 {
       						 dragLine.setX1( e.getX() + offsetx );  
           					 dragLine.setY1( e.getY() + offsety );
           					 dragLine.setX2( e.getX() - offsetx );  
           					 dragLine.setY2( e.getY() - offsety );
           					 System.out.println("CCCCC" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 if(line_orientation == 4)
    					 {
       						 dragLine.setX1( e.getX() - offsetx );  
           					 dragLine.setY1( e.getY() - offsety );
            				 dragLine.setX2( e.getX() + offsetx );  
              				 dragLine.setY2( e.getY() + offsety );
              			 	 System.out.println("DDDDD" +  dragLine.getX1() + " " +  dragLine.getY1()  + " " + dragLine.getX2() + " " +  dragLine.getY2());  
    					 }
    					 
    				 }
    			 }
    		 }
    		 
    	}
		
		String val = split02.return_action_selected();

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

		// anchar rectangle
		if (rectangle_current_point_anchar == true) 
		{	
			
			if(rectangle_current_point_anchar_selected == 1)
			{
				rectangle_P1_points_anchar = e.getPoint(); 
				System.out.println("TRACE anchar 1");  
			}
			
			if(rectangle_current_point_anchar_selected == 3)
			{
				rectangle_P3_points_anchar = e.getPoint(); 
				System.out.println("TRACE anchar 3");  
			}
		}
		
		// anchar circle
		if (circle_current_point_anchar == true) 
		{	
					
			if(circle_current_point_anchar_selected == 1)
			{
				circle_P1_points_anchar = e.getPoint(); 
				System.out.println("TRACE anchar 1");  
			}
					
			if(circle_current_point_anchar_selected == 3)
			{
				circle_P3_points_anchar = e.getPoint(); 
				System.out.println("TRACE anchar 3");  
			}
		}
    	
    	repaint();
	}
	
	@Override
	public void mouseMoved(MouseEvent e) 
	{
		//System.out.println("Mouse Moved");  
		save_evt = e;
	    split02.mouse_position(e.getX(), e.getY());
		
	}  
	 
    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();
	        
	     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();
        	 }
		 
	     }  
	        
	 }
	 
	 /****************************************************************************************/
  
	 @Override
	 public void keyPressed(KeyEvent arg0) 
	 {
	 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	    }

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

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

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

	    }

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

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

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

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

	        public boolean isDataFlavorSupported(DataFlavor arg0) 
	        {
	            return (arg0 == DataFlavor.imageFlavor);
	        }
	    }
	    
	    /****************************************************************************************/
	     
	    public void export_image(String extension)
	    {
	         
	    	int aaa = this.getWidth();
	        int bbb = getHeight();
	         BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
	        // paints into image's Graphics
	        this.paint(image.getGraphics());
	        
	        try
	        {
          		ImageIO.write(image, "jpeg", new File("d:/zzz." + extension));
		    	split02.myArea.append(" [ INFO ]: Create image ..."  + "\n");
	        }
	        
	        catch(IOException e)
	        {
	        }
	         
	     }
	 
	    /****************************************************************************************/
}


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

class axxxxaawwwBBBbraphicsUtil {
    public static final int H_LEFT = -1;
    public static final int H_CENTER = 0;
    public static final int H_RIGHT = 1;
    public static final int V_TOP = -1;
    public static final int V_CENTER = 0;
    public static final int V_BASELINE = 1;
    public static final int V_BOTTOM = 2;

    static public void switchToWidth(Graphics g, int width) {
        if(g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke((float) width));
        }
    }

    static public void drawCenteredArc(Graphics g, int x, int y,
            int r, int start, int dist) {
        g.drawArc(x - r, y - r, 2 * r, 2 * r, start, dist);
    }

    static public Rectangle getTextBounds(Graphics g, Font font,
            String text, int x, int y, int halign, int valign) {
        if(g == null) return new Rectangle(x, y, 0, 0);
        Font oldfont = g.getFont();
        if(font != null) g.setFont(font);
        Rectangle ret = getTextBounds(g, text, x, y, halign, valign);
        if(font != null) g.setFont(oldfont);
        return ret;
    }
    static public Rectangle getTextBounds(Graphics g, String text,
            int x, int y, int halign, int valign) {
        if(g == null) return new Rectangle(x, y, 0, 0);
        FontMetrics mets = g.getFontMetrics();
        int width = mets.stringWidth(text);
        int ascent = mets.getAscent();
        int height = ascent + mets.getDescent();
        Rectangle ret = new Rectangle(x, y, width, height);
        
        switch(halign) {
            case H_CENTER: ret.translate(-(width / 2), 0); break;
            case H_RIGHT:  ret.translate(-width, 0); break;
            default: ;
        }
        switch(valign) {
            case V_TOP:      break;
            case V_CENTER:   ret.translate(0, -(ascent / 2)); break;
            case V_BASELINE: ret.translate(0, -ascent); break;
            case V_BOTTOM:   ret.translate(0, -height); break;
            default: ;
        }
        return ret;
    }

    static public void drawText(Graphics g, Font font,
            String text, int x, int y, int halign, int valign) {
        Font oldfont = g.getFont();
        if(font != null) g.setFont(font);
        drawText(g, text, x, y, halign, valign);
        if(font != null) g.setFont(oldfont);
    }
    static public void drawText(Graphics g, String text,
            int x, int y, int halign, int valign) {
        if(text.length() == 0) return;
        Rectangle bd = getTextBounds(g, text, x, y, halign, valign);
        g.drawString(text, bd.x, bd.y + g.getFontMetrics().getAscent());
    }
    static public void drawCenteredText(Graphics g, String text,
            int x, int y) {
        drawText(g, text, x, y, H_CENTER, V_CENTER);
    }

    static 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);
    }
}

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

