
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;


public class TopPanel04 extends JPanel  implements MouseListener, MouseMotionListener , KeyListener, Printable
{
	
  	private Toolbar myToolbar ;
  	private Graph    graph;    
  	private Graph02  graph02;
  	private Graph03  graph03;
	  	
  	
  	Node  node_selection = null;
	Text  text_selection = null; 
	EdgeObj  edge_selection = null; 
	RectangleObj  rectangle_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 Point2D  	dragPoint; 
    private Point2D		StartPoint, EndPoint;
    
    ArrayList<RectangleObj> array_rectangle_obj = new ArrayList<RectangleObj>();
  	private boolean drag_rectangle = false;
    
    boolean isAlreadyOneClick;
    
    RectangleObj currentShapeObject;
    
    private int offsetx, offsety;  
    
    private boolean current_point_anchar = false;
    private int current_point_anchar_selected;
	private Point P1_points_anchar;
	private Point P3_points_anchar;
	
	private int rect_x;
	private int rect_y;
	private int rect_width;
	private int rect_height;
    

	
	public TopPanel04()
	{
		super();
		
		myToolbar = new Toolbar();
		graph02 = new Graph02();
		graph03 = new Graph03();
		
		split02.myArea.setText(" [ INFO ]: Init GUI : OK : revision " + " TopPanel04 "  + "\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");
                    
                	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() ); 
           
        }
    	   
    	/** draw les rectangle qui sont dans la Database**/ 
	    for(int i = 0; i < graph03.getRects().size(); i++)    		
	   	{
	    		 RectangleObj rect = graph03.getRects().get(i);
	    		 
	    		 if(current_point_anchar == false)
	    		 {
		    		 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.x1, rect.y1 ,	rect.getWidth() , rect.getHeight() ); 
	    		 }	 
	   		    
	    		 if(current_point_anchar == true)
	    		 {
	    			 
	    			 if(current_point_anchar_selected == 1)
	     			 {
	    				 		// OK
/*	    				 
	    				 		int width = P1_points_anchar.x - P3_points_anchar.x;
	    				    	if( width < 0 )
	    				    	{
	    				    		width = - width;
	    				    		int height = Math.abs(P1_points_anchar.y - P3_points_anchar.y );
		    				    	g.drawRect( P1_points_anchar.x , P1_points_anchar.y , width, height ); 
		    				    	System.out.println("Zone A");  
	    				    	}
	    				    	else
	    				    	{
	    				    		int height = Math.abs(P1_points_anchar.y - P3_points_anchar.y );
		    				    	g.drawRect( P3_points_anchar.x , P1_points_anchar.y , width, height ); 
		    				    	System.out.println("Zone B");  
	    				    		
	    				    	}
*/	    				    
	    				 
			    				 int width = P1_points_anchar.x - P3_points_anchar.x;
			    				 int height = P1_points_anchar.y - P3_points_anchar.y ; 
		 				    	 if( width < 0 && height < 0)
		 				    	 {
		 				    		int w = - width;
		 				    	    int h = - height;
			    				    g.drawRect( P1_points_anchar.x , P1_points_anchar.y , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  P1_points_anchar.x;
			    				    rect_y =  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( P3_points_anchar.x - w  , P3_points_anchar.y  , w, h ); 
			    				    // sauve tmp
			    				    rect_x =  P3_points_anchar.x - w;
			    				    rect_y =  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( P3_points_anchar.x , P1_points_anchar.y , w, h );
			    				    // sauve tmp
			    				    rect_x =  P3_points_anchar.x;
			    				    rect_y =  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( P3_points_anchar.x , P1_points_anchar.y - h , w, h ); 
			    				    // sauve tmp
			    				    rect_x = P3_points_anchar.x;
			    				    rect_y =  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(current_point_anchar_selected == 3)
	     			 {
	    				 		int width = P1_points_anchar.x - P3_points_anchar.x;
	    				 		int height = P1_points_anchar.y - P3_points_anchar.y ; 
		 				    	 if( width < 0 && height < 0)
		 				    	 {
		 				    		int w = - width;
		 				    	    int h =  - height;
		 				    	
		    				    	g.drawRect( P3_points_anchar.x + w , P3_points_anchar.y + h , w , h ); 
		 				    	    
			    				    System.out.println("P3 Zone A");  
		 				    	 }
		 				    	 if( width > 0 && height < 0)
		 				    	 {
		 				    		int w =  -width;
		 				    	    int h =  height;
			    				    g.drawRect( P3_points_anchar.x - w  , P3_points_anchar.y  , w, h ); 
			    				    System.out.println("P3 Zone B");   
		 				    	 }
	    				 
	     			 }
	    			 
	    			 
	    		 }
	    		
	   	}
		
	    /*
    	if(current_point_anchar == true)
    	{
    		 System.out.println(" Resizing .... ");
    		 
    		 if(current_point_anchar_selected == 1)
 			 {
 			
    			 	int width = Math.abs(P1_points_anchar.x - P3_points_anchar.x);
    		    	int height = Math.abs(P1_points_anchar.y - P3_points_anchar.y );
 				
    		    	g.drawRect( P1_points_anchar.x , P1_points_anchar.y , width, height ); 
 				
 			}
 			
 			if(current_point_anchar_selected == 3)
 			{
 				System.out.println("TRACE anchar 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());
        
    	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(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))
                {
                	P1_points_anchar = new Point(x, y);
                	P3_points_anchar = new Point( x + w, y + h);
    	        	System.out.println("P1_area");
    	        	current_point_anchar = true;
    	        	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))
                {
                	P1_points_anchar = new Point(x, y);
                	P3_points_anchar = new Point( x + w, y + h);
    	        	System.out.println("P3_area");
    	        	current_point_anchar = true;
    	        	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());
	            
	        }
	        
	        //////////    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();
	        	 }
	         
	        	
	        }
	        
	        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
		
/*		
	
        if (node_selection == null && edge_selection == null && text_selection == null && isAlreadyOneClick == true ) 
        {
    		System.out.println("Node creation");
    		saisir_state(new Point2D.Double( e.getX(),e.getY() ) );
        }
        
        if (node_selection != null && edge_selection == null && text_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 ) 
        {	
        	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 ) 
        {
        	System.out.println("TEXT selection");
 		    selection_obj = "TEXT";
 		    text_selection.toggleSelected();
 		    dragging_mode = true;
        }
        
		  
    	  if (text_selection != null  ) 
          {
    		System.out.println("TEXT selection");
   		    selection_obj = "TEXT";
   		    text_selection.toggleSelected();
            dragging_mode = true;
            requestFocusInWindow();
          }
           
 */   	  
    	  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 )
        {
        	// enregistre les coordonnées x2 et y2
        	currentShapeObject.setX2(e.getX());
            currentShapeObject.setY2(e.getY());
            currentShapeObject.CalcWidth();
            currentShapeObject.CalcHeight();
            array_rectangle_obj.add(currentShapeObject);
            
            graph03.addRect(currentShapeObject);
            
      	    drag_rectangle = false;
      	    currentShapeObject = null;
      	    // desactive l'action en cours
            split02.stop_action_selected();

            
          	//EndPoint = new Point2D.Double(e.getX(), e.getY());
            //int w = (int)EndPoint.getX() -  (int)StartPoint.getX();
            //int h = (int)EndPoint.getY() -  (int)StartPoint.getY();
          	//RectangleObj rect_obj = new RectangleObj((int)StartPoint.getX() , (int)StartPoint.getY(), w, h, Color.BLUE);
      	    //array_rectangle_obj.add(rect_obj);
      	    //drag_rectangle = false;
      	    
        }
        
      
        
        dragNode = null;  

        dragging_mode = false;
        
    
        
        dragRectangle = null;
        
        
        //
        /*
        if(rectangle_selection != null)
        {	
        	rectangle_selection.setX1(rect_x);
        	rectangle_selection.setY1(rect_y); 
        	rectangle_selection.setWidth(rect_width);
        	rectangle_selection.setHeight(rect_height);
        	
        }*/
    	current_point_anchar = false;

        
        // prend le focus sur le panel pour utiliser le listener du panel
        requestFocus();
        
        repaint();
	}
	
	@Override
	public void mouseDragged(MouseEvent e) 
	{
		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("RECTANGLE"))
    		 {
    			 if(dragRectangle != null )
    			 {
    				 if(dragRectangle.isSelected())
    				 {

    					 dragRectangle.setX1( e.getX() - offsetx );  
    					 dragRectangle.setY1( e.getY() - offsety );
    				       
    					 
    					 
    				     /*  
    				       if (dragRectangle.getX1() < - dragRectangle.getWidth() / 2)
    				    	   dragRectangle.setX1(  - dragRectangle.getWidth() / 2 ); 
    				      
    				       else if (dragRectangle.getX1() + dragRectangle.getWidth()/2 > dragRectangle.getWidth() )
    				    	   dragRectangle.setX1 ( dragRectangle.getWidth() - dragRectangle.getWidth() / 2 );
    				       
    				       if (dragRectangle.getY1() < - dragRectangle.getHeight() / 2)
    				    	   dragRectangle.setY1( - dragRectangle.getHeight() / 2 );
    				       
    				       else if (dragRectangle.getY1() + dragRectangle.getHeight()/2 > dragRectangle.getHeight() )
    				    	   dragRectangle.setY1( dragRectangle.getHeight() - dragRectangle.getHeight() / 2);
    				       */
    					
    					 /*
    					  if (dragRectangle.x1 < - dragRectangle.width / 2)
    						  dragRectangle.x1 = - dragRectangle.width / 2;
    				      
    				       else if (dragRectangle.x + dragRectangle.width/2 >  dragRectangle.width )
    				    	   dragRectangle.x1 = dragRectangle.width - dragRectangle.width / 2;
    				       
    				       if (dragRectangle.y1 < - dragRectangle.height / 2)
    				    	   dragRectangle.y1 = - dragRectangle.height / 2;
    				       
    				       else if (dragRectangle.y1 + dragRectangle.height/2 > dragRectangle.height )
    				    	   dragRectangle.y1 = dragRectangle.height - dragRectangle.height / 2;
    				       
    				       */
    					 
    			    	 //  System.out.print("---- move rectangle \n" + e.getX() + " " + e.getY() );

    					  
    				 }
    			 }
    		 }
    	}
		
		// pour le rectangle
		
		String val = split02.return_action_selected();
		if(val == "RECTANGLE" && drag_rectangle == true )
	    {
			EndPoint = new Point2D.Double(e.getX(), e.getY());
			currentShapeObject.setX2(e.getX());
			currentShapeObject.setY2(e.getY());
	    }  
		
		
		if (current_point_anchar == true) 
		{	
			
			if(current_point_anchar_selected == 1)
			{
				P1_points_anchar = e.getPoint(); 
				System.out.println("TRACE anchar 1");  
			}
			
			if(current_point_anchar_selected == 3)
			{
				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 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();
	        
	     	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); 
	        
	        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);
	     	}   
	    	
	        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);

	    	    	split02.myArea.append(" [ INFO ]: Load file ..." + "\n");
	                
	                file.close();
	                repaint();
	            } 
	            
	            catch (FileNotFoundException ex) 
	            {
	                Logger.getLogger(TopPanel04.class.getName()).log(Level.SEVERE, null, ex);
	            } 
	            
	            catch (IOException ex) 
	            {
	                Logger.getLogger(TopPanel04.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);
	                graph02.saveTo(file);
	                
	    	    	split02.myArea.append(" [ INFO ]: Save file ..." + "\n");
	                
	                file.close();
	                
	            } 
	            
	            catch (IOException ex) 
	            {
	                Logger.getLogger(TopPanel04.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)
	        {
	        }
	         
	     }
	 
	
}


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