/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   Redistribution in source and binary forms, with or without modification, are not permitted.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.File;
import javax.swing.event.MouseInputAdapter;

// vertical toolbar
public class GraphicToolBar extends JToolBar {
    
    private static final int WIDTH=24;
    private static final int HEIGHT=24;
    
    private static final int CURSOR_WIDTH=32;
    private static final int CURSOR_HEIGHT=32;
    //private static final int CURSOR_WIDTH=32*3;
    //private static final int CURSOR_HEIGHT=32*3;
    
    private static final double REDUCTION_FACTOR=0.25;

    //Thomas
    //private static final ImageIcon CUT_IMAGE=new ImageIcon("icons"+File.separator+"cut.gif");
    //private static final ImageIcon COPY_IMAGE=new ImageIcon("icons"+File.separator+"copy.gif");
    //private static final ImageIcon PASTE_IMAGE=new ImageIcon("icons"+File.separator+"paste.gif");
    //private static final ImageIcon DELETE_IMAGE=new ImageIcon("icons"+File.separator+"delete.gif");
    //private static final ImageIcon EDIT_IMAGE=new ImageIcon("icons"+File.separator+"edit.gif");
    private static final ImageIcon CUT_IMAGE=new ImageIcon(ClassLoader.getSystemResource("icons"+File.separator+"cut.gif"));
    private static final ImageIcon COPY_IMAGE=new ImageIcon(ClassLoader.getSystemResource("icons"+File.separator+"copy.gif"));
    private static final ImageIcon PASTE_IMAGE=new ImageIcon(ClassLoader.getSystemResource("icons"+File.separator+"paste.gif"));
    private static final ImageIcon DELETE_IMAGE=new ImageIcon(ClassLoader.getSystemResource("icons"+File.separator+"delete.gif"));
    private static final ImageIcon EDIT_IMAGE=new ImageIcon(ClassLoader.getSystemResource("icons"+File.separator+"edit.gif"));

    private Cursor oldCursor;
    private GraphicPanel currentPanel = null;
    private String currentType;
    private MouseInputAdapter currentListener;

    //static in order to access those variables from outside
    //there will never be two GraphicToolBars.
    protected static boolean panelListenerRemoved=false;
    protected static boolean panelMotionListenerRemoved=false;
    
    private ButtonGroup group;
    
    private AbstractButton bDefault,bTask,bAND,bOR,bXOR,bLink,bCut,bCopy,bPaste,bDelete,bEdit;
    // private AbstractButton bCustom;
    
    private Cursor taskCursor,booleanConnectorCursor,linkCursor;
    private Image taskImage,booleanConnectorImage,linkImage;
    
    public GraphicToolBar() {
        super(VERTICAL);
        
        taskImage = Task.getComponentCursor(CURSOR_WIDTH,CURSOR_HEIGHT);
        booleanConnectorImage = BooleanConnector.getComponentCursor(CURSOR_WIDTH,CURSOR_HEIGHT);
        linkImage = Link.getComponentCursor(CURSOR_WIDTH,CURSOR_HEIGHT);
        
        try {
            taskCursor=Toolkit.getDefaultToolkit().createCustomCursor(taskImage,new Point(0,0),"TASK");
        } catch (IndexOutOfBoundsException e){System.err.println(e);}
        try {
            booleanConnectorCursor=Toolkit.getDefaultToolkit().createCustomCursor(booleanConnectorImage,new Point(0,0),"BOOL");
        } catch (IndexOutOfBoundsException e){System.err.println(e);}
        try {
            linkCursor=Toolkit.getDefaultToolkit().createCustomCursor(linkImage,new Point(0,0),"LINK");
        } catch (IndexOutOfBoundsException e){System.err.println(e);}
        ButtonModel m;
        group=new ButtonGroup();
        
        bDefault=new JToggleButton(getDefaultIcon(WIDTH,HEIGHT,true));
        bDefault.setSelectedIcon(getDefaultIcon(WIDTH,HEIGHT,false));
        bDefault.setToolTipText("Selection mode");
        bDefault.setMargin(new Insets(0,0,0,0));
        bDefault.setActionCommand("Default");
        group.add(bDefault);
        
        bTask=new JToggleButton(Task.getIcon(WIDTH,HEIGHT,true));
        bTask.setSelectedIcon(Task.getIcon(WIDTH,HEIGHT,false));
        bTask.setToolTipText("Click here to select a Task");//.\nThen click on the selected panel to create a task.\nYou can create multiple tasks by pressing the shift key.");
        bTask.setMargin(new Insets(0,0,0,0));
        bTask.setActionCommand("Task");
        group.add(bTask);
        
        bAND=new JToggleButton(BooleanConnector.getIcon(WIDTH,HEIGHT,"AND",true));
        bAND.setSelectedIcon(BooleanConnector.getIcon(WIDTH,HEIGHT,"AND",false));
        bAND.setToolTipText("Click here to select a boolean connector");//.\nThen click on the selected panel to create a boolean connector.\nYou can create multiple boolean connectors by pressing the shift key.");
        bAND.setMargin(new Insets(0,0,0,0));
        bAND.setActionCommand("AND");
        group.add(bAND);
        
        bOR=new JToggleButton(BooleanConnector.getIcon(WIDTH,HEIGHT,"OR",true));
        bOR.setSelectedIcon(BooleanConnector.getIcon(WIDTH,HEIGHT,"OR",false));
        bOR.setToolTipText("Click here to select a boolean connector");//.\nThen click on the selected panel to create a boolean connector.\nYou can create multiple boolean connectors by pressing the shift key.");
        bOR.setMargin(new Insets(0,0,0,0));
        bOR.setActionCommand("OR");
        group.add(bOR);
        
        bXOR=new JToggleButton(BooleanConnector.getIcon(WIDTH,HEIGHT,"XOR",true));
        bXOR.setSelectedIcon(BooleanConnector.getIcon(WIDTH,HEIGHT,"XOR",false));
        bXOR.setToolTipText("Click here to select a boolean connector");//.\nThen click on the selected panel to create a boolean connector.\nYou can create multiple boolean connectors by pressing the shift key.");
        bXOR.setMargin(new Insets(0,0,0,0));
        bXOR.setActionCommand("XOR");
        group.add(bXOR);
        
        /*
        bCustom=new JToggleButton(BooleanConnector.getIcon(WIDTH,HEIGHT,"",true));
        bCustom.setSelectedIcon(BooleanConnector.getIcon(WIDTH,HEIGHT,"",false));
        bCustom.setToolTipText("Click here to select a boolean connector");//.\nThen click on the selected panel to create a boolean connector.\nYou can create multiple boolean connectors by pressing the shift key.");
        bCustom.setMargin(new Insets(0,0,0,0));
        bCustom.setActionCommand("");
        group.add(bCustom);
        */
        
        bLink=new JToggleButton(Link.getIcon(WIDTH,HEIGHT,true));
        bLink.setSelectedIcon(Link.getIcon(WIDTH,HEIGHT,false));
        bLink.setToolTipText("Click here to select a link");//.\nThen click on the selected panel to create a boolean connector.\nYou can create multiple boolean connectors by pressing the shift key.");
        bLink.setMargin(new Insets(0,0,0,0));
        bLink.setActionCommand("Link");
        group.add(bLink);
                
        bPaste=new JToggleButton(PASTE_IMAGE);
        bPaste.setEnabled(false);
        bPaste.setToolTipText("Click here to paste a component");
        bPaste.setMargin(new Insets(0,0,0,0));
        bPaste.setActionCommand("Paste");
        group.add(bPaste);

        bCut=new JButton(CUT_IMAGE);
        bCut.setToolTipText("Click here to cut a component");
        bCut.setMargin(new Insets(0,0,0,0));
        bCut.setActionCommand("Cut");
        
        bCopy=new JButton(COPY_IMAGE);
        bCopy.setToolTipText("Click here to copy a component");
        bCopy.setMargin(new Insets(0,0,0,0));
        bCopy.setActionCommand("Copy");
        
        bDelete=new JButton(DELETE_IMAGE);
        bDelete.setToolTipText("Click here to delete a component");
        bDelete.setMargin(new Insets(0,0,0,0));
        bDelete.setActionCommand("Delete");
        
        bEdit=new JButton(EDIT_IMAGE);
        bEdit.setToolTipText("Click here to edit a component");
        bEdit.setMargin(new Insets(0,0,0,0));
        bEdit.setActionCommand("Edit");

        ActionListener listener = new ActionListener() {
    	    public void actionPerformed(ActionEvent e) {
                String s = e.getActionCommand();
                
                if ((s.equals("Task"))||(s.equals("AND"))||(s.equals("OR"))||(s.equals("XOR"))||
                	(s.equals(""))||(s.equals("Link"))||(s.equals("Cut"))||(s.equals("Paste"))) {
                    
                    JInternalFrame frame = Manager.desktop.getSelectedFrame();
                    if (frame != null) {
                    	cancelOperation();
                        GraphicPanel cPanel = ((ComponentInternalFrame)frame).gpanel;
                    	if (cPanel != null) {
                    	    newOperation(cPanel,s);
                    	}
                    }
                }
                if (s.equals("Default")) cancelOperation(); 
            }
        };
        
        bDefault.addActionListener(listener);
        bTask.addActionListener(listener);
        bAND.addActionListener(listener);
        bOR.addActionListener(listener);
        bXOR.addActionListener(listener);
        //bCustom.addActionListener(listener);
        bLink.addActionListener(listener);
        bPaste.addActionListener(listener);
        
        bCut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //TMUtility.display("GraphicToolBar","Cut");
            	CutManager.cut();
            }
        });
        bCopy.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //TMUtility.display("GraphicToolBar","Copy");
            	CopyManager.copy();
            }
        });
        bDelete.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //TMUtility.display("GraphicToolBar","Delete");
            	DeleteManager.delete();
            }
        });
        bEdit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //TMUtility.display("GraphicToolBar","Edit");
            	EditManager.edit(true);
            }
        });
        
        add(bDefault);
        add(bTask);
        add(bAND);
        add(bOR);
        add(bXOR);
        //add(bCustom);
        add(bLink);
        addSeparator();
        add(bPaste);
        addSeparator();
        addSeparator();
        add(bCut);
        add(bCopy);
        add(bDelete);
        addSeparator();
        add(bEdit);
        
        bDefault.setSelected(true);
    }
    
    protected void unsetClipboard() {
        bPaste.setIcon(PASTE_IMAGE);
        bPaste.setSelectedIcon(PASTE_IMAGE);
    	bPaste.setEnabled(false);
    }
    
    protected void setClipboard(String type) {
        if (type.equals("Task")) {
            bPaste.setIcon(Task.getReductedIcon(WIDTH,HEIGHT,REDUCTION_FACTOR,true));
            bPaste.setSelectedIcon(Task.getReductedIcon(WIDTH,HEIGHT,REDUCTION_FACTOR,false));
        }
        else {
            bPaste.setIcon(BooleanConnector.getReductedIcon(WIDTH,HEIGHT,REDUCTION_FACTOR,type,true));
            bPaste.setSelectedIcon(BooleanConnector.getReductedIcon(WIDTH,HEIGHT,REDUCTION_FACTOR,type,false));
        }
    	bPaste.setEnabled(true);
    }
    
    private void cancelOperation() {
    	if (currentPanel!=null) {
            if (currentListener!=null) {
            	currentPanel.removeMouseListener(currentListener);
            }          
            if (panelListenerRemoved) {
            	currentPanel.addMouseListener(currentPanel);
                panelListenerRemoved=false;
            }
            if (panelMotionListenerRemoved) {
            	currentPanel.addMouseMotionListener(currentPanel);
                panelMotionListenerRemoved=false;
            }
    	    currentPanel.setCursor(oldCursor);
 	        currentPanel=null;
 	    }
 	    currentType=null;
        currentListener=null;
 	    //System.out.println("Cancel operation !");
    }
    
    private void newOperation(GraphicPanel cPanel,String s) {
    	if (cPanel != null) {
 	        //TMUtility.display("newOperation",s);
    	    currentPanel = cPanel;
            currentType = s;
    	    oldCursor = currentPanel.getCursor();
    	    currentPanel.setCursor(getCCursor(currentType));
            Cursor cur = currentPanel.getCursor();                        
            //System.out.println("current panel cursor: "+cur.getName()+"   "+cur.toString());
            
            if ((!panelListenerRemoved)&&(!panelMotionListenerRemoved)) {
                if (currentType.equals("Link")) {
                    //System.out.println("MAdapterLink");
                    currentListener = new MAdapterLink(oldCursor,currentPanel);
                }
                else if ((currentType.equals("Task")) || (currentType.equals("AND")) || 
                    (currentType.equals("AND")) || (currentType.equals("OR")) || 
                    (currentType.equals("XOR")) || (currentType.equals("")) || 
                    (currentType.equals("Paste")))
                        currentListener = new MAdapter(currentType,oldCursor,currentPanel);
                //else if ((currentType.equals("Cut"))) currentListener=new MAdapterScissors(currentType,oldCursor,currentPanel);
            }
        }
    }

    private Cursor getCCursor(String type) {
        //TMUtility.display("getCCursor",type);
        
    	Cursor result = new Cursor(Cursor.CROSSHAIR_CURSOR);
    	
        try {
            if (type.equals("Task")) 
            	result = taskCursor;                        
            else if ((type.equals("AND"))||(type.equals("OR"))||(type.equals("XOR"))||(type.equals(""))) {
            	//result = taskCursor;
                result = booleanConnectorCursor;
            }else if (type.equals("Link")) 
            	result = linkCursor;
            else if (type.equals("Paste")) 
            	result = taskCursor;
        } 
        catch (IndexOutOfBoundsException e) {
        	System.err.println(e);
        }
        
        return result;
    }
    

class MAdapter extends MouseInputAdapter {
    private Cursor cursor;
    private GraphicPanel panel;
    private String type;
    
    public MAdapter(String type,Cursor cursor,GraphicPanel panel) {
    	this.cursor=cursor;
    	this.panel=panel;
    	this.type=type;
        
    	panel.removeMouseMotionListener(panel);
    	GraphicToolBar.panelMotionListenerRemoved=true;
        panel.addMouseListener(this);
    }
    
    public void mousePressed(MouseEvent e) {
    	int posx=e.getX();
    	int posy=e.getY();
    	int m=e.getModifiers();

        Component comp = panel.getComponentAt(posx,posy);

    	if (!(comp instanceof CompositeComponent)) {
            if (type.equals("Task")) NewManager.newTask(posx,posy);
            else if (type.equals("AND")) NewManager.newBooleanConnector("AND",posx,posy);
            else if (type.equals("OR")) NewManager.newBooleanConnector("OR",posx,posy);
            else if (type.equals("XOR")) NewManager.newBooleanConnector("XOR",posx,posy);
            else if (type.equals("")) NewManager.newBooleanConnector("",posx,posy);
            else if (type.equals("Paste")) PasteManager.paste(posx,posy);
        }
        else {
            if (type.equals("Task")) NewManager.newTask();
            else if (type.equals("AND")) NewManager.newBooleanConnector("AND");
            else if (type.equals("OR")) NewManager.newBooleanConnector("OR");
            else if (type.equals("XOR")) NewManager.newBooleanConnector("XOR");
            else if (type.equals("")) NewManager.newBooleanConnector("");
            else if (type.equals("Paste")) PasteManager.paste();
        }
        
     	if (((m&InputEvent.SHIFT_MASK)==0) || (type.equals("Paste"))) {
            panel.setCursor(cursor);
            
            panel.removeMouseListener(this);
    	    panel.addMouseMotionListener(panel);
    	    GraphicToolBar.panelMotionListenerRemoved = false;
            
            bDefault.setSelected(true);
        }
    }
}

class MAdapterLink extends MouseInputAdapter {
    private Cursor cursor;
    private GraphicPanel panel;
    
    private LinkableComponent lc1 = null;
    private LinkableComponent lc2 = null;
    
    private Graphics2D g2 = null;
    
    private int cursorx = 0;
    private int cursory = 0;
    
    public MAdapterLink(Cursor cursor,GraphicPanel panel) {
    	this.cursor = cursor;
    	this.panel = panel;
        
    	panel.removeMouseListener(panel);
    	GraphicToolBar.panelListenerRemoved = true;
        
    	panel.removeMouseMotionListener(panel);
    	GraphicToolBar.panelMotionListenerRemoved = true;
        
        Graphics g = panel.getGraphics();
        g2 = (Graphics2D) g;
        
        panel.addMouseListener(this);
        panel.addMouseMotionListener(this);
    }
    
    public void mousePressed(MouseEvent e) {
        //System.out.println("MAdapterLink : mousePressed.");
        
    	int posx = e.getX();
    	int posy = e.getY();
    	int m = e.getModifiers();
    	
    	Component comp = panel.getComponentAt(posx,posy);

    	if (comp instanceof LinkableComponent) {
    	    lc1 = (LinkableComponent)comp;
        }
    }

    public void mouseDragged(MouseEvent e) {
        //System.out.print(".");

        if (lc1 != null) {
            int x1 = lc1.getX();
            int y1 = lc1.getY();
            
            int x2 = x1 + lc1.getWidth();
            int y2 = y1 + lc1.getHeight();
            
            int posx2 = e.getX();
            int posy2 = e.getY();
            
            int posx1 = findPosX1(x1,y1,x2,y2,posx2,posy2);
            int posy1 = findPosY1(x1,y1,x2,y2,posx2,posy2);

            //System.out.println("posx2 = "+posx2+" posy2 = "+posy2+" cursorx = "+cursorx+" cursory = "+cursory);
            //System.out.println("");
            
            // clear previous grey link only if cursor move a bit
            int distancex = Math.abs(cursorx - posx2);
            int distancey = Math.abs(cursory - posy2);
            if ((distancex+distancey) > 3) {
                panel.repaint();
                
                // remember previous cursor position
                cursorx = posx2;
                cursory = posy2;
            }

            // display the grey link
            displayLink(posx1,posy1,posx2,posy2);
        }
    }
    
    private int findPosX1(int x1,int y1,int x2,int y2,int posx2,int posy2) {
        int result = (x1 + x2) / 2;
        
        if (posx2 <= x1) {
            if ((y1 < posy2) && (posy2 < y2)) result = x1;
        }
        else if (x2 < posx2) {
            if ((y1 < posy2) && (posy2 < y2)) result = x2;
        }
        
        return result;
    }
    
    private int findPosY1(int x1,int y1,int x2,int y2,int posx2,int posy2) {
        int result = (y1 + y2) / 2;
        
        if (posy2 <= y1) {
            result = y1;
        }
        else if (y2 <= posy2) {
            result = y2;
        }
        
        return result;
    }
    
    private void displayLink(int posx1,int posy1,int posx2,int posy2) {
        g2.setColor(Color.gray);
        
        // draw the starting line
        Line2D.Double ln = new Line2D.Double(posx1,posy1,posx2,posy2);
        g2.draw(ln);
        
        // draw the arrow head
        double tempx = posx2 - posx1;
        double tempy = posy2 - posy1;

        double length = Math.sqrt(tempx*tempx+tempy*tempy);

        double slope = Math.atan(tempy/tempx);    // slope of cursor
        
        double DANGLE = Math.PI/6;     // 30 degree
        double arrowHeadLength = 5;

        double arrowHeadx = Math.abs((length - arrowHeadLength) * Math.cos(slope));
        double xarrowHead = posx1 + arrowHeadx;
        if (posx2 < posx1) xarrowHead = posx1 - arrowHeadx;

        double arrowHeady = Math.abs((length - arrowHeadLength) * Math.sin(slope));
        double yarrowHead = posy1 + arrowHeady;
        if (posy2 < posy1) yarrowHead = posy1 - arrowHeady;
        
        double slant = arrowHeadLength / Math.cos(DANGLE);
        
        double xoffset = Math.abs(slant * Math.cos(slope - DANGLE)) - Math.abs(arrowHeadLength * Math.cos(slope));
        double yoffset = Math.abs(arrowHeadLength * Math.sin(slope)) - Math.abs(slant * Math.sin(slope - DANGLE));

        xoffset = Math.abs(xoffset);
        yoffset = Math.abs(yoffset);
        
        //System.out.println("posx1 = "+posx1+" posy1 = "+posy1+" posx2 = "+posx2+" posy2 = "+posy2);
        //System.out.println("tempx = "+tempx+" tempy = "+tempy+" length = "+length+" slope = "+slope+" DANGLE = "+DANGLE);
        //System.out.println("xarrowHead = "+xarrowHead+" yarrowHead = "+yarrowHead+" slant = "+slant+" xoffset = "+xoffset+" yoffset = "+yoffset);
        //System.out.println("");
        
        double xs[] = {posx2,xarrowHead-xoffset,xarrowHead+xoffset};
        double ys[] = {posy2,yarrowHead+yoffset,yarrowHead-yoffset};
        
        Polygon p = new Polygon(round(xs),round(ys),3);
        g2.fill(p);
    }
    
    public void mouseReleased(MouseEvent e) {
        //System.out.println("MAdapterLink : mouseReleased.");
        
    	int posx = e.getX();
    	int posy = e.getY();
    	int m = e.getModifiers();
    	
    	Component comp = panel.getComponentAt(posx,posy);
        
        panel.repaint();  // clear the grey link

    	if ((lc1 != null) && (comp instanceof LinkableComponent)) {
    	    lc2 = (LinkableComponent)comp;
    	    if (lc2 != lc1) NewManager.newLink(lc1,lc2,panel.name);
    	    else {
    	    	lc1 = null;
    	    	lc2 = null;
    	    }
        }
        else {
            lc1 = null;
        }
        
     	if ((m&InputEvent.SHIFT_MASK) == 0) {
            panel.setCursor(cursor);
            
            panel.removeMouseListener(this);
    	    panel.addMouseListener(panel);
            GraphicToolBar.panelListenerRemoved = false;
            
            panel.removeMouseMotionListener(this);
    	    panel.addMouseMotionListener(panel);
    	    GraphicToolBar.panelMotionListenerRemoved = false;
            
            bDefault.setSelected(true);
        }
    }
}

    public static ImageIcon getDefaultIcon(int w,int h,boolean b) {
    	BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
    	Graphics2D g2=image.createGraphics();
    	drawIcon(g2,w,h,b);
    	return new ImageIcon(image);  	
    }
    protected static void drawIcon(Graphics2D g2,int w,int h,boolean b){
        Color BACKGROUND_COLOR=new Color(255,255,255);
        Color BACKGROUND_ICON_COLOR=new Color(200,200,200);
        Color BORDER_COLOR=new Color(100,100,150);
    	g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    	//arrow
    	double ww=w;
    	double hh=h;
    	double xcenter=ww/2;
    	double ycenter=hh/2;
    	double TAN_DEMI_ANGLE=Math.tan(Math.PI/6);
    	double DTHICKNESS_RATIO=0.2;
    	double DTHICKNESS=TAN_DEMI_ANGLE*ycenter*DTHICKNESS_RATIO;
    	double slope=-Math.PI/6;
    	double xs[]={xcenter-DTHICKNESS,xcenter-DTHICKNESS,xcenter-TAN_DEMI_ANGLE*ycenter,xcenter,xcenter+TAN_DEMI_ANGLE*ycenter,xcenter+DTHICKNESS,xcenter+DTHICKNESS};
    	double ys[]={hh,ycenter,ycenter,0,ycenter,ycenter,hh};
    	Area area=new Area(new Polygon(round(xs),round(ys),7));
    	AffineTransform t=new AffineTransform();
    	t.rotate(slope,xcenter,ycenter);
    	area.transform(t);
    	g2.setColor((b)?BACKGROUND_COLOR:(BACKGROUND_COLOR).darker());
    	g2.fill(area);
    	g2.setColor((b)?BORDER_COLOR:(BORDER_COLOR).darker());
    	g2.draw(area);
    }
    
    private static int[] round(double [] t){
    	int [] result=new int[t.length];
    	for (int i=0;i<t.length;i++){
    	    result[i]=(int)Math.round(t[i]);
    	}
    	return result;
    }

    /*public void setEnabled(boolean b){
    	Component [] c=getComponents();
    	for (int i=0;i<c.length;i++) c.setEnabled(b);
    }*/
}

    /*public void notifyIfPossible(){
    	if (w!=null)
    	    synchronized(w){
    	        w.notify();
    	    }
    }*/
                        /*final WaitNotification wn=new WaitNotification(){
                            public void run(){
                                waitNotification();
                                panel.setCursor(cursor);
                                panel.remove
                            }
                        };
                        wn.start();*/