/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package menu;

import DrawTop.DrawParameters;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.border.Border.*;
import DrawTop.*;
import shape.*;
import shapeUtil.*;
import geomExtension.*;
import textBox.*;
import util.*;


public class DialogOfShapeFormat extends JDialog{
    ShapeFormatAction action=null;
    JScrollPane dataScrollPane;
    JScrollPane textScrollPane;
    ShapeContainer shapeContainer;
    JRadioButton pixelButton=null;
    JRadioButton mmButton=null;

    //JCheckBox unmovableBox=null;
    JCheckBox resizeBox = null;
    JCheckBox ratioBox = null;
    JCheckBox directionBox = null;
    JCheckBox connectorBox=null;
    JCheckBox ungroupBox=null;
    public static final String RESIZING=Command.getCommandString(Command.ENABLE_RESIZING);
    public static final String ASPECT_RATIO=Command.getCommandString(Command.KEEP_ASPECT_RATIO);
    public static final String LINE_DIRECTION=Command.getCommandString(Command.KEEP_LINE_DIRECTION);
    public static final String CONNECTOR_CONNECTIONS=Command.getCommandString(Command.KEEP_CONNECTOR_CONNECTIONS);
    public static final String UNGROUPING=Command.getCommandString(Command.ENABLE_UNGROUPING);

    Dimension dialogDimension=new Dimension(400,330);
    Dimension buttonSize=new Dimension(80,22);
//Rectangular
    JSpinner[] positionSpinners=new JSpinner[4];
    SpinnerNumberModel[] positionSpinnerModels=new SpinnerNumberModel[4];
    JSpinner[] centerSpinners=new JSpinner[2];
    SpinnerNumberModel[] centerSpinnerModels=new SpinnerNumberModel[2];
    JSpinner[] sizeSpinners=new JSpinner[2];
    SpinnerNumberModel[] sizeSpinnerModels=new SpinnerNumberModel[2];
//Line
    JSpinner[] startSpinners=new JSpinner[2];
    SpinnerNumberModel[] startSpinnerModels=new SpinnerNumberModel[2];
    JSpinner[] endSpinners=new JSpinner[2];
    SpinnerNumberModel[] endSpinnerModels=new SpinnerNumberModel[2];
    JSpinner[] lineSpinners=new JSpinner[2];
    SpinnerNumberModel[] lineSpinnerModels=new SpinnerNumberModel[2];
//Text box
    JSpinner[] marginSpinners=new JSpinner[4];
    SpinnerNumberModel[] marginSpinnerModels=new SpinnerNumberModel[4];
    JSpinner lineSpaceSpinner=null;
    SpinnerNumberModel lineSpaceSpinnerModel=null;
//SpinnersChangeListener listener
    SpinnersChangeListener changeListener=new SpinnersChangeListener(this);
    
    int debug=0;
    
    public DialogOfShapeFormat(){
        super(ObjectTable.getDrawMain(), "Shape Format", true);
        this.setName("DialogOfShapeFormat");  
        this.action=new ShapeFormatAction(this);
        this.addWindowListener(action);
    }

    public void showDialog(ShapeContainer container){
        this.shapeContainer=container;
        int type=this.shapeContainer.getElement().getTypeE();
        ShapeFormatListener shapeFormatListener=new ShapeFormatListener(this);
        this.addComponentListener(shapeFormatListener);
		
     //set dialog position
        double scale=DrawParameters.Scale;
        DrawPanel drawPanel=ObjectTable.getDrawPanel("");
        Component owner=this.getOwner();
        Rectangle2D rect=this.shapeContainer.getBoundingBox();
        int X=(int)(Math.max(0, owner.getX()+scale*(rect.getX()+rect.getWidth()+20)));
        int Y=(int)(Math.max(0, owner.getY()+scale*rect.getY()));
        Point position=SwingUtilities.convertPoint(drawPanel, X, Y, owner);
        this.setLocation(position);
		
        Container contentPane=this.getContentPane();
        contentPane.setLayout(new BorderLayout());
        JTabbedPane tabbedPane=new JTabbedPane();
        contentPane.add(tabbedPane,BorderLayout.NORTH);
        JPanel paintStylePanel=this.createPaintStylePanel();
        JPanel positionSizePanel=null;
        boolean lineType=false;
        if(type>=Command.LINE&&type<=Command.DOUBLE_ARROW) lineType=true;
        if(lineType){
            positionSizePanel=this.createLinePanel();
        } else {
            positionSizePanel=this.createRectangularPanel();
        }
        JPanel propertyPanel=this.createPropertyPanel();
        JPanel dataPanel=this.createDataPanel();
        JPanel textBoxPanel=this.createTextBoxPanel();
        JPanel textInfoPanel=this.createTextInfoPanel();

        tabbedPane.add("position, size", positionSizePanel);
        tabbedPane.add("style", paintStylePanel);
        tabbedPane.add("property", propertyPanel);
        tabbedPane.add("data", dataPanel);
        tabbedPane.add("text box", textBoxPanel);
        tabbedPane.add("text", textInfoPanel);

        if(container.getContainerType()==ShapeContainer.GROUP) tabbedPane.setEnabledAt(4,false);
        else{
            ShapeContainer shapeContainer=(ShapeContainer)container;
            if(shapeContainer.getTextBox()==null) {
                tabbedPane.setEnabledAt(4,false);
                tabbedPane.setEnabledAt(5,false);
            }
        }
        this.setPreferredSize(this.dialogDimension);
        this.pack();
        this.setVisible(true);
        MenuUtil menuUtil=ObjectTable.getMenuUtil();
        DialogOfShapeFormat dialog
                =(DialogOfShapeFormat)menuUtil.getMenuComponent("DialogOfShapeFormat");
        if(dialog!=null) dialog.removeDialog();
        menuUtil.setMenuComponent(this);
    }
    
    protected void removeDialog(){
        this.setVisible(false);
        MenuUtil menuUtil=ObjectTable.getMenuUtil();
        Component component=menuUtil.getMenuComponent(this.getName());
        if(component!=null) menuUtil.removeMenuComponent(component);
    }
    
    protected void setScrollViewPosition(){
        this.dataScrollPane.getViewport().setViewPosition(new Point(0,0));
        if(this.textScrollPane!=null)
             this.textScrollPane.getViewport().setViewPosition(new Point(0,0));
    }

    private JPanel createRectangularPanel(){
        int type=this.shapeContainer.getElement().getTypeE();
        boolean lineType=false;
        if(type>=Command.LINE&&type<=Command.DOUBLE_ARROW) lineType=true;
        if(lineType){
            System.err.println("*** Error DialogOfShapeFormat.createRectangularPanel: "
                    + "The selected shape isn't a rectangular");
            return null;
        }
        JPanel basePanel=new JPanel();
    //uni Panel
        JPanel unitPanel=new JPanel();
        unitPanel.setPreferredSize(new Dimension(100,44));
        TitledBorder titleBorder=BorderFactory.createTitledBorder("unit of length");
        GridLayout unitPanelLayout=new GridLayout(1,2);
        unitPanelLayout.setHgap(20);
        unitPanelLayout.setVgap(5);
        unitPanel.setLayout(unitPanelLayout);
        unitPanel.setBorder(titleBorder);
        ButtonGroup group = new ButtonGroup();
        this.pixelButton = new JRadioButton("pixel");
        this.mmButton = new JRadioButton("mm");
        group.add(this.mmButton);
        group.add(this.pixelButton);
        this.pixelButton.setActionCommand("pixel");
        this.mmButton.setActionCommand("mm");
        this.pixelButton.addActionListener(this.action);
        this.mmButton.addActionListener(this.action);
        unitPanel.add(this.mmButton);
        unitPanel.add(this.pixelButton);
        this.mmButton.setSelected(true);
        Dimension panelSize=new Dimension(120,20);
    //Position Panel
        JPanel positionPanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("position");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        positionPanel.setBorder(titleBorder);
        GridLayout positionPanelLayout=new GridLayout(2,2);
        positionPanelLayout.setHgap(20);
        positionPanelLayout.setVgap(5);
        positionPanel.setLayout(positionPanelLayout);
        JPanel[] xyPanels=new JPanel[4];
        String[] positionLabel={"x-min: ", "x-max: ", "y-min: ", "y-max: "};
        for(int i=0;i<4;i++){
            xyPanels[i]=new JPanel();
            xyPanels[i].setLayout(new BoxLayout(xyPanels[i], BoxLayout.X_AXIS));
            JLabel label=new JLabel(positionLabel[i]);
            xyPanels[i].add(label);
            this.positionSpinnerModels[i]=new SpinnerNumberModel(0d, 0d, 1000d, 1d);
            this.positionSpinners[i]=new JSpinner(this.positionSpinnerModels[i]);
            this.positionSpinners[i].setName(positionLabel[i]);
            xyPanels[i].add(this.positionSpinners[i]);
            xyPanels[i].setPreferredSize(panelSize);
            positionPanel.add(xyPanels[i]);
        }
        for(int i=0;i<4;i++) this.positionSpinners[i].addChangeListener(this.changeListener);
    //Center Panel
        JPanel centerPanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("center point");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        centerPanel.setBorder(titleBorder);
        GridLayout centerPanelLayout=new GridLayout(1,2);
        centerPanelLayout.setHgap(20);
        centerPanelLayout.setVgap(5);
        centerPanel.setLayout(centerPanelLayout);
        JPanel[] centerPanels=new JPanel[2];
        String[] centerLabel={" x: ", " y: "};
        for(int i=0;i<2;i++){
            centerPanels[i]=new JPanel();
            centerPanels[i].setLayout(new BoxLayout(centerPanels[i],BoxLayout.X_AXIS));
            JLabel label=new JLabel(centerLabel[i]);
            centerPanels[i].add(label);
            this.centerSpinnerModels[i]=new SpinnerNumberModel(0d, 0d, 1000d, 1d);
            this.centerSpinners[i]=new JSpinner(this.centerSpinnerModels[i]);
            this.centerSpinners[i].setName(centerLabel[i]);
            centerPanels[i].add(centerSpinners[i]);
            centerPanels[i].setPreferredSize(panelSize);
            centerPanel.add(centerPanels[i]);
        }
        for(int i=0;i<2;i++) this.centerSpinners[i].addChangeListener(this.changeListener);

    //Size Panel
        JPanel sizePanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("size");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        sizePanel.setBorder(titleBorder);
        GridLayout sizePanelLayout=new GridLayout(1,2);
        sizePanelLayout.setHgap(20);
        sizePanelLayout.setVgap(5);
        sizePanel.setLayout(sizePanelLayout);
        JPanel[] sizePanels=new JPanel[2];
        String[] sizeLabel={"width: ", "height: "};
        for(int i=0;i<2;i++){
            sizePanels[i]=new JPanel();
            sizePanels[i].setLayout(new BoxLayout(sizePanels[i],BoxLayout.X_AXIS));
            JLabel label=new JLabel(sizeLabel[i]);
            sizePanels[i].add(label);
            this.sizeSpinnerModels[i]=new SpinnerNumberModel(0d, 0d, 1000d, 1d);
            this.sizeSpinners[i]=new JSpinner(this.sizeSpinnerModels[i]);
            this.sizeSpinners[i].setName(sizeLabel[i]);
            sizePanels[i].add(sizeSpinners[i]);
            sizePanels[i].setPreferredSize(panelSize);
            sizePanel.add(sizePanels[i]);
        }
        for(int i=0;i<2;i++) this.sizeSpinners[i].addChangeListener(this.changeListener);

      //setValue to Spinners
        int unitType=0;
        if(this.mmButton.isSelected()) unitType=1;
        this.showRectangular(unitType);

    // Layout BasePanel
        Box box=Box.createVerticalBox();
        basePanel.add(box);
        box.add(Box.createVerticalStrut(5));
        box.add(unitPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(positionPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(centerPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(sizePanel);
        return basePanel;
    }

    protected void showRectangular(int unitType){
        Rectangle2D boundingBox=this.shapeContainer.getBoundingBox();
        double mm=DrawParameters.InchToMM/DrawParameters.InchToPixels;
        double unit=1.0d;
        if(unitType!=0) unit=mm;
        double x=boundingBox.getX()*unit;
        double y=boundingBox.getY()*unit;
        double w=boundingBox.getWidth()*unit;
        double h=boundingBox.getHeight()*unit;

        this.changeListener.removeChangeListener();
        this.positionSpinners[0].setValue(x);
        this.positionSpinners[1].setValue(x+w);
        this.positionSpinners[2].setValue(y);
        this.positionSpinners[3].setValue(y+h);
        this.centerSpinners[0].setValue(x+w/2);
        this.centerSpinners[1].setValue(y+h/2);
        this.sizeSpinners[0].setValue(w);
        this.sizeSpinners[1].setValue(h);
        
        boolean resizing=this.shapeContainer.getBooleanProperty(RESIZING,"DialogOfShapeFormat");
        boolean connector=this.shapeContainer.getBooleanProperty(CONNECTOR_CONNECTIONS,"DialogOfShapeFormat");
        boolean aspect_ratio=this.shapeContainer.getBooleanProperty(ASPECT_RATIO,"DialogOfShapeFormat");
        boolean line_dir=this.shapeContainer.getBooleanProperty(LINE_DIRECTION,"DialogOfShapeFormat");
        if(!resizing){
            this.sizeSpinners[0].setEnabled(false);
            this.sizeSpinners[1].setEnabled(false);
        }
        this.changeListener.addChangeListener();
    }

    private JPanel createLinePanel(){
        int type=this.shapeContainer.getElement().getTypeE();
        boolean lineType=false;
        if(type>=Command.LINE&&type<=Command.DOUBLE_ARROW) lineType=true;
        if(!lineType){
            System.err.println("*** Error DialogOfShapeFormat.createLinePanel: "
                    + "The selected shape isn't a line");
            return null;
        }
        JPanel basePanel=new JPanel();
    //uni Panel
        JPanel unitPanel=new JPanel();
        unitPanel.setPreferredSize(new Dimension(100,44));
        TitledBorder titleBorder=BorderFactory.createTitledBorder("unit of length");
        GridLayout unitPanelLayout=new GridLayout(1,2);
        unitPanelLayout.setHgap(20);
        unitPanelLayout.setVgap(5);
        unitPanel.setLayout(unitPanelLayout);
        unitPanel.setBorder(titleBorder);
        ButtonGroup group = new ButtonGroup();
        this.pixelButton = new JRadioButton("pixel");
        this.mmButton = new JRadioButton("mm");
        group.add(this.mmButton);
        group.add(this.pixelButton);
        this.pixelButton.setActionCommand("pixel");
        this.mmButton.setActionCommand("mm");
        this.pixelButton.addActionListener(this.action);
        this.mmButton.addActionListener(this.action);
        unitPanel.add(mmButton);
        unitPanel.add(pixelButton);
        this.mmButton.setSelected(true);
        Dimension panelSize=new Dimension(120,20);
    
    //Start point Panel
        JPanel startPanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("start point");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        startPanel.setBorder(titleBorder);
        GridLayout startPanelLayout=new GridLayout(1,2);
        startPanelLayout.setHgap(20);
        startPanelLayout.setVgap(5);
        startPanel.setLayout(startPanelLayout);
        JPanel[] startPanels=new JPanel[2];
        String[] xyLabel={" x: ", " y: "};
        for(int i=0;i<2;i++){
            startPanels[i]=new JPanel();
            startPanels[i].setLayout(new BoxLayout(startPanels[i],BoxLayout.X_AXIS));
            JLabel label=new JLabel(xyLabel[i]);
            startPanels[i].add(label);
            this.startSpinnerModels[i]=new SpinnerNumberModel(0d, 0d, 1000d, 1d);
            this.startSpinners[i]=new JSpinner(this.startSpinnerModels[i]);
            this.startSpinners[i].setName("start"+xyLabel[i]);
            startPanels[i].add(this.startSpinners[i]);
            startPanels[i].setPreferredSize(panelSize);
            startPanel.add(startPanels[i]);
        }
        for(int i=0;i<2;i++) this.startSpinners[i].addChangeListener(this.changeListener);
    //End point Panel
        //Dimension panelSize=new Dimension(120,20);
        JPanel endPanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("end point");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        endPanel.setBorder(titleBorder);
        GridLayout endPanelLayout=new GridLayout(1,2);
        endPanelLayout.setHgap(20);
        endPanelLayout.setVgap(5);
        endPanel.setLayout(endPanelLayout);
        JPanel[] endPanels=new JPanel[2];
        //String[] centerLabel={" x: ", " y: "};
        for(int i=0;i<2;i++){
            endPanels[i]=new JPanel();
            endPanels[i].setLayout(new BoxLayout(endPanels[i],BoxLayout.X_AXIS));
            JLabel label=new JLabel(xyLabel[i]);
            endPanels[i].add(label);
            this.endSpinnerModels[i]=new SpinnerNumberModel(0d, 0d, 1000d, 1d);
            this.endSpinners[i]=new JSpinner(this.endSpinnerModels[i]);
            this.endSpinners[i].setName("end"+xyLabel[i]);
            endPanels[i].add(endSpinners[i]);
            endPanels[i].setPreferredSize(panelSize);
            endPanel.add(endPanels[i]);
        }
        for(int i=0;i<2;i++) this.endSpinners[i].addChangeListener(this.changeListener);

//line Panel
        JPanel linePanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("line (angle: angle to x-axis in degrees)");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        linePanel.setBorder(titleBorder);
        GridLayout linePanelLayout=new GridLayout(1,2);
        linePanelLayout.setHgap(20);
        linePanelLayout.setVgap(5);
        linePanel.setLayout(linePanelLayout);
        JPanel[] linePanels=new JPanel[2];
        String[] lineLabel={"angle: ", "length: "};
        this.lineSpinnerModels[0]=new SpinnerNumberModel(0d, -180d, 180d, 1d);
        this.lineSpinnerModels[1]=new SpinnerNumberModel(1d, 1d, 1000d, 1d);
        for(int i=0;i<2;i++){
            linePanels[i]=new JPanel();
            linePanels[i].setLayout(new BoxLayout(linePanels[i],BoxLayout.X_AXIS));
            JLabel label=new JLabel(lineLabel[i]);
            linePanels[i].add(label);
            this.lineSpinners[i]=new JSpinner(this.lineSpinnerModels[i]);
            this.lineSpinners[i].setName(lineLabel[i]);
            linePanels[i].add(lineSpinners[i]);
            linePanels[i].setPreferredSize(panelSize);
            linePanel.add(linePanels[i]);
        }
        for(int i=0;i<2;i++) this.lineSpinners[i].addChangeListener(this.changeListener);

      //setValue to Spinners
        int unitType=0;
        if(this.mmButton.isSelected()) unitType=1;
       //-----------------------//
        this.showLine(unitType);
       //-----------------------//-
    // Layout BasePanel
        Box box=Box.createVerticalBox();
        basePanel.add(box);
        box.add(Box.createVerticalStrut(5));
        box.add(unitPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(startPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(endPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(linePanel);
        return basePanel;
    }

    protected void showLine(int unitOfLength){
        Point2D[] Pt=this.shapeContainer.getElement().getEndPTs();
        Vector2D vec=Vector2D.sub(Pt[1], Pt[0]);
        double mm=DrawParameters.InchToMM/DrawParameters.InchToPixels;
        double unit=1.0d;
        if(unitOfLength!=0) unit=mm;
        
        this.changeListener.removeChangeListener();
        double startX=Pt[0].getX()*unit;
        double startY=Pt[0].getY()*unit;
        double endX=Pt[1].getX()*unit;
        double endY=Pt[1].getY()*unit;
        this.startSpinners[0].setValue(startX);
        this.startSpinners[1].setValue(startY);
        this.endSpinners[0].setValue(endX);
        this.endSpinners[1].setValue(endY);

        double angle=Math.atan2(-vec.getY(), vec.getX())*180.0/Math.PI;
        double len=Math.sqrt(vec.getX()*vec.getX()+vec.getY()*vec.getY())*unit;
        this.lineSpinners[0].setValue(angle);
        this.lineSpinners[1].setValue(len);

        boolean resizing=this.shapeContainer.getBooleanProperty(RESIZING, "DialogOfShapeFormat");
        boolean line_dir=this.shapeContainer.getBooleanProperty(LINE_DIRECTION, "DialogOfShapeFormat");
        if(line_dir){
            this.lineSpinners[0].setEnabled(false);
        }
        if(!resizing){
            this.lineSpinners[0].setEnabled(false);
            this.lineSpinners[1].setEnabled(false);
        }
        this.changeListener.addChangeListener();

    }

    private JPanel createPaintStylePanel(){
        JPanel basePanel=new JPanel();
    //Color Panel
        JPanel colorPanel=new JPanel();
        TitledBorder titleBorder=BorderFactory.createTitledBorder("Color");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        colorPanel.setBorder(titleBorder);
        Box box=Box.createHorizontalBox();
        colorPanel.add(box);
        //boolean image=false;
        ButtonOfPulldownMenu fillColorButton=
                ButtonOfPulldownMenu.createFillColorChooserButton(false);
        ButtonOfPulldownMenu lineColorButton=
                ButtonOfPulldownMenu.createLineColorChooserButton(false);
        fillColorButton.setPreferredSize(new Dimension(64, MenuConstants.buttonHeight));
        lineColorButton.setPreferredSize(new Dimension(64, MenuConstants.buttonHeight));
        box.add(Box.createHorizontalStrut(5));
        box.add(fillColorButton);
        box.add(Box.createHorizontalStrut(30));
        box.add(lineColorButton);
        box.add(Box.createHorizontalStrut(5));
    //LineStyle Panel
        JPanel lineStylePanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("Line Format");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        lineStylePanel.setBorder(titleBorder);
        box=Box.createHorizontalBox();
        lineStylePanel.add(box);
        ButtonOfPulldownMenu lineStyleButton=ButtonOfPulldownMenu.createLineWidthButton(false);
        ButtonOfPulldownMenu dashedStyleButton=ButtonOfPulldownMenu.createLineStrokeButton(false);
        ButtonOfPulldownMenu arrowStyleButton=ButtonOfPulldownMenu.createArrowStyleButton(false);

        lineStyleButton.setPreferredSize(new Dimension(64, MenuConstants.buttonHeight));
        dashedStyleButton.setPreferredSize(new Dimension(76, MenuConstants.buttonHeight));
        arrowStyleButton.setPreferredSize(new Dimension(76, MenuConstants.buttonHeight));
        box.add(Box.createHorizontalStrut(5));
        box.add(lineStyleButton);
        box.add(Box.createHorizontalStrut(20));
        box.add(dashedStyleButton);
        box.add(Box.createHorizontalStrut(20));
        box.add(arrowStyleButton);
        box.add(Box.createHorizontalStrut(5));
    // Layout BasePanel
        box=Box.createVerticalBox();
        basePanel.add(box);
        box.add(Box.createVerticalStrut(5));
        box.add(colorPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(lineStylePanel);
        box.add(Box.createVerticalStrut(5));

    // set current paintStyle to the menus on this dialog
        ShapeContainer[] shapeContainers=null;
        if(this.shapeContainer.getContainerType()==ShapeContainer.SHAPE){
            shapeContainers=new ShapeContainer[1];
            shapeContainers[0]=(ShapeContainer)this.shapeContainer;
        } else {
            ShapeContainer shapeContainer=(ShapeContainer)this.shapeContainer;
            GroupElement groupElement=(GroupElement)shapeContainer.getElement();
            shapeContainers=groupElement.getGroupedSingleShapeContainers();
        }
        return basePanel;
    }

    private JPanel createPropertyPanel(){
        JPanel basePanel=new JPanel();
        Dimension panelSize=new Dimension(360, 52);
        TitledBorder titleBorder;

    //resize Panel
        JPanel resizePanel=new JPanel();
        resizePanel.setPreferredSize(panelSize);
        titleBorder=BorderFactory.createTitledBorder("resize");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        resizePanel.setBorder(titleBorder);
        FlowLayout resizePanelLayout=new FlowLayout(FlowLayout.LEADING, 0, 0);
        resizePanel.setLayout(resizePanelLayout);
        this.resizeBox=new JCheckBox("enable resizing");
        this.resizeBox.addActionListener(this.action);
        this.resizeBox.addChangeListener(this.action);
        this.resizeBox.setActionCommand(RESIZING);
        
        this.ratioBox=new JCheckBox("keep aspect ratio");
        this.ratioBox.addActionListener(this.action);
        this.ratioBox.addChangeListener(this.action);
        this.ratioBox.setActionCommand(ASPECT_RATIO);
        
        resizePanel.add(this.resizeBox);
        resizePanel.add(this.ratioBox);
        
    //Line panel
        JPanel linePanel=new JPanel();
        linePanel.setPreferredSize(panelSize);
        titleBorder=BorderFactory.createTitledBorder("line");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        linePanel.setBorder(titleBorder);
        FlowLayout linePanelLayout=new FlowLayout(FlowLayout.LEADING, 0, 0);
        linePanel.setLayout(linePanelLayout);
        this.directionBox=new JCheckBox("keep line direction");
        this.directionBox.addActionListener(this.action);
        //this.directionBox.addChangeListener(this.action);
        this.directionBox.setActionCommand(LINE_DIRECTION);
        linePanel.add(this.directionBox);
        
    //connector Panel
        JPanel connectorPanel=new JPanel();
        connectorPanel.setPreferredSize(panelSize);
        titleBorder=BorderFactory.createTitledBorder("connector");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        connectorPanel.setBorder(titleBorder);
        FlowLayout connectorPanelLayout=new FlowLayout(FlowLayout.LEADING, 0, 0);
        connectorPanel.setLayout(connectorPanelLayout);
        this.connectorBox=new JCheckBox("keep connector connections");
        this.connectorBox.addActionListener(this.action);
        this.connectorBox.setActionCommand(CONNECTOR_CONNECTIONS);
        connectorPanel.add(this.connectorBox);

    //group Panel
        JPanel groupPanel=new JPanel();
        groupPanel.setPreferredSize(panelSize);
        titleBorder=BorderFactory.createTitledBorder("group, ungroup");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        groupPanel.setBorder(titleBorder);
        FlowLayout groupPanelLayout=new FlowLayout(FlowLayout.LEADING, 0, 0);
        groupPanel.setLayout(groupPanelLayout);
        this.ungroupBox=new JCheckBox("enable ungrouping");
        this.ungroupBox.addActionListener(this.action);
        this.ungroupBox.setActionCommand(UNGROUPING);
        groupPanel.add(this.ungroupBox);

    //OK, Cancel Button
        JPanel okPanel=new JPanel();
        //Dimension buttonSize=new Dimension(90,20);
        JButton okButton=new JButton("OK");
        JButton cancelButton=new JButton("Cancel");
        okButton.setPreferredSize(this.buttonSize);
        cancelButton.setPreferredSize(this.buttonSize);
        okButton.setActionCommand("OK Property");
        cancelButton.setActionCommand("Cancel Property");
        okButton.addActionListener(this.action);
        cancelButton.addActionListener(this.action);
        okPanel.add(okButton);
        okPanel.add(cancelButton);
    // Layout BasePanel
        Box vbox=Box.createVerticalBox();
        basePanel.add(vbox);
        vbox.add(resizePanel);
        vbox.add(Box.createVerticalStrut(5));
        vbox.add(linePanel);
        vbox.add(Box.createVerticalStrut(5));
        vbox.add(connectorPanel);
        vbox.add(Box.createVerticalStrut(5));
        vbox.add(groupPanel);
        vbox.add(Box.createVerticalStrut(5));
        vbox.add(okPanel);
        vbox.add(Box.createVerticalStrut(5));
    // set current property on the dialog
        this.showProperty();
        return basePanel;
    }

    protected void showProperty(){
        boolean selected;
        selected=this.shapeContainer.getBooleanProperty(RESIZING, "DialogOfShapeFormat");
        this.getResizeBox().setSelected(selected);
        if(!selected) {
            this.getRatioBox().setSelected(false);
            this.getDirectionBox().setSelected(false);
            this.getRatioBox().setEnabled(false);
            this.getDirectionBox().setEnabled(false);
        }

        selected=this.shapeContainer.getBooleanProperty(ASPECT_RATIO, "DialogOfShapeFormat");
        this.getRatioBox().setSelected(selected);

        selected=this.shapeContainer.getBooleanProperty(LINE_DIRECTION, "DialogOfShapeFormat");
        this.getDirectionBox().setSelected(selected);

        selected=this.shapeContainer.getBooleanProperty(CONNECTOR_CONNECTIONS, "DialogOfShapeFormat");
        this.getConnectorBox().setSelected(selected);

        selected=this.shapeContainer.getBooleanProperty(UNGROUPING, "DialogOfShapeFormat");
        this.getUngroupBox().setSelected(selected);

        int type=this.shapeContainer.getElement().getTypeE();
        if(type!=Command.LINE){
            this.getDirectionBox().setEnabled(false);
        }
        if(type==Command.LINE){
            this.getRatioBox().setEnabled(false);
        }
        if(this.shapeContainer.getContainerType()==ShapeContainer.SHAPE){
            this.getUngroupBox().setEnabled(false);
        }

    }

    private JPanel createDataPanel(){
        JPanel basePanel=new JPanel();
    //Information Panel    
        JPanel infoPanel=new JPanel();
        TitledBorder titleBorder=BorderFactory.createTitledBorder("Information");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        infoPanel.setBorder(titleBorder);
        GridLayout inforMationPanelLayout=new GridLayout(1,2);
        inforMationPanelLayout.setHgap(5);
        inforMationPanelLayout.setVgap(5);
        infoPanel.setLayout(inforMationPanelLayout);

        JTextArea textPane=new JTextArea();
		String str=this.shapeContainer.toString();

        if(this.shapeContainer.getContainerType()==ShapeContainer.SHAPE){
            str+="\n - Path :\n"+this.shapeContainer.toPathString();
        }
        if(this.shapeContainer.getContainerType()==ShapeContainer.GROUP){
            ShapeContainer[] containers=this.shapeContainer.getGroupedContainers();
            for(int i=1;i<containers.length;i++){
                str+="\n - Element["+(i-1)+"] : "+containers[i].toShortString();
                str+="\n - Path["+(i-1)+"] :\n"+containers[i].toPathString();
            }
        }
        textPane.setText(str);

        JScrollPane scrollPane=new JScrollPane();
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
                
        //scrollPane.setPreferredSize(this.scrollPaneDimension);
        this.dataScrollPane=scrollPane;
        JViewport viewport=new JViewport();
        scrollPane.setViewport(viewport);
        viewport.setView(textPane);
        viewport.setViewPosition(new Point(0,0));
        infoPanel.add(scrollPane);

    // Layout BasePanel
        Box box=Box.createVerticalBox();
        basePanel.add(box);
        box.add(Box.createVerticalStrut(5));
        box.add(infoPanel);
        return basePanel;
    }

    private JPanel createTextBoxPanel(){
        JPanel basePanel=new JPanel();
        if(this.shapeContainer.getContainerType()==ShapeContainer.GROUP) return basePanel;
        //ShapeContainer shapeContainer=(ShapeContainer)this.shapeContainer;
        if(this.shapeContainer.getTextBox()==null) return basePanel;
    //Text Align
        JPanel alignPanel=new JPanel();
        TitledBorder titleBorder=BorderFactory.createTitledBorder("Text Align");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        alignPanel.setBorder(titleBorder);
        GridLayout alignPanelLayout=new GridLayout(1,2);
        alignPanelLayout.setHgap(30);
        alignPanelLayout.setVgap(5);
        alignPanel.setLayout(alignPanelLayout);
        ButtonOfToggle button=ButtonOfToggle.createButton("text_align_left", false, 
                "text_align_left32T.png", "text_align_left");
        alignPanel.add(button);
        button=ButtonOfToggle.createButton("text_align_center", false, 
                "text_align_center32T.png", "text_align_center");
        alignPanel.add(button);
        button=ButtonOfToggle.createButton("text_align_right", false, 
                "text_align_right32T.png", "text_align_right");
        alignPanel.add(button);
    //TextBox Internal Margin
        JPanel marginPanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("Internal margin (pixels)");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        marginPanel.setBorder(titleBorder);
        //Box box=Box.createHorizontalBox();
        GridLayout marginPanelLayout=new GridLayout(2,2);
        marginPanelLayout.setHgap(20);
        marginPanelLayout.setVgap(5);
        marginPanel.setLayout(marginPanelLayout);
        JPanel[] marginPanels=new JPanel[4];
        String[] positionLabel={"left   : ", "top       : ", "right : ", "bottom: "};
        for(int i=0;i<4;i++){
            marginPanels[i]=new JPanel();
            marginPanels[i].setLayout(new BoxLayout(marginPanels[i], BoxLayout.X_AXIS));
            JLabel label=new JLabel(positionLabel[i]);
            marginPanels[i].add(label);
            this.marginSpinnerModels[i]=new SpinnerNumberModel(0.0d, 0.0d, 10d, 0.1d);
            this.marginSpinners[i]=new JSpinner(marginSpinnerModels[i]);
            marginPanels[i].add(this.marginSpinners[i]);
            marginPanel.add(marginPanels[i]);
            //box.add(Box.createHorizontalStrut(10));
        }
        double top=0, left=0, right=0, bottom=0;
        //double mm=DrawParameters.InchToMM/DrawParameters.InchToPixels;
        if(shapeContainer.getTextBox()!=null){
            Insets insets=shapeContainer.getTextBox().getTextBoxInsets();
            top=insets.top;
            left=insets.left;
            right=insets.right;
            bottom=insets.bottom;
        }
        this.marginSpinnerModels[0].setValue(left);
        this.marginSpinnerModels[1].setValue(top);
        this.marginSpinnerModels[2].setValue(right);
        this.marginSpinnerModels[3].setValue(bottom);
        
    //Textline Space
        JPanel lineSpacePanel=new JPanel();
        titleBorder=BorderFactory.createTitledBorder("Text line space (pixels)");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        lineSpacePanel.setBorder(titleBorder);
        this.lineSpaceSpinnerModel=new SpinnerNumberModel(0.0d, 0.0d, 10d, 0.1d);
        this.lineSpaceSpinner=new JSpinner(lineSpaceSpinnerModel);
        lineSpacePanel.add(this.lineSpaceSpinner);
        double lineSpace=0;
        if(shapeContainer.getTextBox()!=null){
            lineSpace=shapeContainer.getTextBox().getTextLineSpace();
            this.lineSpaceSpinnerModel.setValue(lineSpace);
        }

    //OK, Cancel Button    
        JPanel okPanel=new JPanel();
        JButton okButton=new JButton("OK");
        JButton cancelButton=new JButton("Cancel");
        okButton.setActionCommand("OK TextBox");
        cancelButton.setActionCommand("Cancel TextBox");
        okButton.addActionListener(this.action);
        cancelButton.addActionListener(this.action);
        okPanel.add(okButton);
        okPanel.add(cancelButton);
    // Layout BasePanel
        Box box=Box.createVerticalBox();
        basePanel.add(box);
        box.add(Box.createVerticalStrut(5));
        box.add(alignPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(marginPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(lineSpacePanel);
        box.add(Box.createVerticalStrut(5));
        box.add(okPanel);
        box.add(Box.createVerticalStrut(5));
        return basePanel;
    }
    
    private JPanel createTextInfoPanel(){
        JPanel basePanel=new JPanel();
//Information Panel    
        JPanel infoPanel=new JPanel();
        TitledBorder titleBorder=BorderFactory.createTitledBorder("Text information");
        titleBorder.setTitleColor(Color.BLACK);
        titleBorder.setTitleFont(MenuConstants.MenuFont);
        infoPanel.setBorder(titleBorder);
        GridLayout inforMationPanelLayout=new GridLayout(1,2);
        inforMationPanelLayout.setHgap(5);
        inforMationPanelLayout.setVgap(5);
        infoPanel.setLayout(inforMationPanelLayout);
      //----------- show Attributed String --------------------------------//
        if( this.shapeContainer.getContainerType()==ShapeContainer.GROUP) return basePanel;
        ShapeContainer shapeContainer=(ShapeContainer)this.shapeContainer;
        TextBox textBox=shapeContainer.getTextBox();
        if(textBox==null) return basePanel;
        CommittedTextContainer textContainer=textBox.getCommittedTextContainer();
        AttributedStringUtil attribUtil=new AttributedStringUtil(textContainer.getCommittedText());
        String str="";
        str+=attribUtil.toString();
        int caretPosition=textBox.getTextIndex();
        str+="\n\n-- caret position="+caretPosition;
        if(textBox.hasSelectedText()){
            int start=textBox.getSelectedTextStart();
            int end=textBox.getSelectedTextEnd();
            str+=",  selected text start, end="+start+","+end;
        } else str+=",  selected text is non";
     //------- show MouseListener ------------------------------------------//  
        ListenerPanel listenerPanel=ObjectTable.getListenerPanel("");
        str+="\n\n-- Mouse Listener Info\n  "+listenerPanel.getMouseListenersInfo();
      //--------------------------------------------------------------------//
        JTextPane textPane=new JTextPane();
        textPane.setText(str);
        //textPane.setAutoscrolls(true); 
        //textPane.setPreferredSize(textAreaDimension);

        JScrollPane scrollPane=new JScrollPane();
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        
        //scrollPane.setPreferredSize(scrollPaneDimension);
        JViewport viewport=new JViewport();
        scrollPane.setViewport(viewport);
        this.textScrollPane=scrollPane;
        viewport.setView(textPane);
        viewport.setViewPosition(new Point(0,0));
        infoPanel.add(scrollPane);
        //scrollPane.revalidate();

    // Layout BasePanel
        Box box=Box.createVerticalBox();
        basePanel.add(box);
        box.add(Box.createVerticalStrut(5));
        box.add(infoPanel);
        box.add(Box.createVerticalStrut(5));
        return basePanel;
    }

    public ShapeContainer getShapeContainer(){
        return this.shapeContainer;
    }
    public JScrollPane getDataScrollPane(){
        return this.dataScrollPane;
    }
    public JScrollPane getTextScrollPane(){
        return this.textScrollPane;
    }
    public JSpinner[] getPositionSpinners(){
        return this.positionSpinners;
    }
    public SpinnerNumberModel[] getPositionSpinnerModels(){
        return this.positionSpinnerModels;
    }
    public JSpinner[] getSizeSpinners(){
        return this.sizeSpinners;
    }
    public SpinnerNumberModel[] getSizeSpinnerModels(){
        return this.sizeSpinnerModels;
    }
    public JSpinner[] getCenterSpinners(){
        return this.centerSpinners;
    }
    public SpinnerNumberModel[] getCenterSpinnerModels(){
        return this.centerSpinnerModels;
    }
    public JSpinner[] getStartSpinners(){
        return this.startSpinners;
    }
    public SpinnerNumberModel[] getStartSpinnerModels(){
        return this.startSpinnerModels;
    }
    public JSpinner[] getEndSpinners(){
        return this.endSpinners;
    }
    public SpinnerNumberModel[] getEndSpinnerModels(){
        return this.endSpinnerModels;
    }
    public JSpinner[] getLineSpinners(){
        return this.lineSpinners;
    }
    public SpinnerNumberModel[] getLineSpinnerModels(){
        return this.lineSpinnerModels;
    }
    public JSpinner[] getMarginSpinners(){
        return this.marginSpinners;
    }
    public SpinnerNumberModel[] getMarginSpinnerModels(){
        return this.marginSpinnerModels;
    }
    public JSpinner getLineSpaceSpinner(){
        return this.lineSpaceSpinner;
    }
    public SpinnerNumberModel getLineSpaceSpinnerModels(){
        return this.lineSpaceSpinnerModel;
    }
/*
    public JCheckBox getUnMovableBox(){
        return this.unmovableBox;
    }
*/
    public JCheckBox getResizeBox(){
        return this.resizeBox;
    }
    public JCheckBox getRatioBox(){
        return this.ratioBox;
    }
    public JCheckBox getDirectionBox(){
        return this.directionBox;
    }
    public JCheckBox getConnectorBox(){
        return this.connectorBox;
    }
/*
    public JCheckBox getUsedBox(){
        return this.usedBox;
    }
*/
    public JCheckBox getUngroupBox(){
        return this.ungroupBox;
    }

}
class ShapeFormatListener implements ComponentListener{
    DialogOfShapeFormat dialog=null;
    int debug=0;
    
    ShapeFormatListener(DialogOfShapeFormat dialog){
        this.dialog=dialog;
    }
    
    public void componentResized(ComponentEvent e){
        int marginX=40;
        int marginY=120;
        Dimension sizeOfDialog=this.dialog.getSize();
        if(sizeOfDialog==null) return;
        JScrollPane dataScrollPane=this.dialog.getDataScrollPane();
        JScrollPane textScrollPane=this.dialog.getTextScrollPane();
        Dimension  sizeOfDataScroll=dataScrollPane.getSize();
        Dimension  sizeOfTextScroll=null;
        if(textScrollPane!=null){
            sizeOfTextScroll=textScrollPane.getSize();
        }
        Dimension newSize=new Dimension((int)(sizeOfDialog.getWidth()-marginX), 
                (int)(sizeOfDialog.getHeight()-marginY));
        if(debug>0) System.out.println("** Dialog resized  sizeOfDialog="+Util.Dim(sizeOfDialog)+
                ", scrollPaneSize="+Util.Dim(sizeOfDataScroll)+", newSize="+Util.Dim(newSize));
        dataScrollPane.setPreferredSize(newSize);
        dataScrollPane.revalidate();
        if(textScrollPane!=null&&sizeOfTextScroll!=null){
            newSize=new Dimension((int)(sizeOfDialog.getWidth()-marginX), 
                (int)(sizeOfDialog.getHeight()-marginY));
            textScrollPane.setPreferredSize(newSize);
            textScrollPane.revalidate();
        }
        this.dialog.validate();
    }
    
    public void componentHidden(ComponentEvent e){}
    public void  componentMoved(ComponentEvent e) {}
    public void componentShown(ComponentEvent e){
      //-------------------------------------------------//  
        this.dialog.setScrollViewPosition();
      //-------------------------------------------------//     

    } 
}

class SpinnersChangeListener implements ChangeListener{
    DialogOfShapeFormat dialog;
    ShapeContainer shapeContainer;
        
    public SpinnersChangeListener(DialogOfShapeFormat dialog){
        this.dialog=dialog;

    }
    
    public void stateChanged(ChangeEvent e){
        this.shapeContainer=this.dialog.getShapeContainer();
        int type=this.shapeContainer.getElement().getTypeE();
        boolean lineType=false;
        if(type>=Command.LINE&&type<=Command.DOUBLE_ARROW) lineType=true;
        if(lineType){
            this.lineChanged(e);
        } else {
            this.rectangularChanged(e);
        }
    }

    private void rectangularChanged(ChangeEvent e){
        JSpinner spinner=(JSpinner)e.getSource();
        System.out.println("changedRectangular spinner="+spinner.getName());
        SpinnerNumberModel[] positionSpinnerModels=this.dialog.getPositionSpinnerModels();
        JSpinner[] positionSpinners=this.dialog.getPositionSpinners();
        SpinnerNumberModel[] sizeSpinnerModels=this.dialog.getSizeSpinnerModels();
        JSpinner[] sizeSpinners=this.dialog.getSizeSpinners();
        SpinnerNumberModel[] centerSpinnerModels=this.dialog.getCenterSpinnerModels();
        JSpinner[] centerSpinners=this.dialog.getCenterSpinners();
        boolean resizing=this.shapeContainer.getBooleanProperty(DialogOfShapeFormat.RESIZING,"DialogOfShapeFormat");
        boolean keep_connection=this.shapeContainer.getBooleanProperty(DialogOfShapeFormat.CONNECTOR_CONNECTIONS,"DialogOfShapeFormat");
        boolean aspect_ratio=this.shapeContainer.getBooleanProperty(DialogOfShapeFormat.ASPECT_RATIO, "DialogOfShapeFormat");
       //
        boolean moved=false;
        boolean resized=false;
      //xmin changed
        if(spinner==positionSpinners[0]){
            System.out.println("Rectangular xmin changed");
            double xmin=positionSpinnerModels[0].getNumber().doubleValue();
            double xmax=positionSpinnerModels[1].getNumber().doubleValue();
            double w=sizeSpinnerModels[0].getNumber().doubleValue();
            this.removeChangeListener();
            //positionSpinners[1].setValue(xmin+w);
            sizeSpinners[0].setValue(Math.abs(xmax-xmin));
            centerSpinners[0].setValue(0.5*(xmin+xmax));
            this.addChangeListener();
            moved=true;
        }
       //xmax changed
        if(spinner==positionSpinners[1]){
            System.out.println("Rectangular xmax changed");
            double xmin=positionSpinnerModels[0].getNumber().doubleValue();
            double xmax=positionSpinnerModels[1].getNumber().doubleValue();
            double w=sizeSpinnerModels[0].getNumber().doubleValue();
            this.removeChangeListener();
            sizeSpinners[0].setValue(Math.abs(xmax-xmin));
            centerSpinners[0].setValue(0.5*(xmin+xmax));
            this.addChangeListener();
            moved=true;
        }
      //ymin changed
        if(spinner==positionSpinners[2]){
            System.out.println("Rectangular ymin changed");
            double ymin=positionSpinnerModels[2].getNumber().doubleValue();
            double ymax=positionSpinnerModels[3].getNumber().doubleValue();
            double h=sizeSpinnerModels[1].getNumber().doubleValue();
            this.removeChangeListener();
            sizeSpinners[1].setValue(Math.abs(ymax-ymin));
            centerSpinners[1].setValue(0.5*(ymin+ymax));
            this.addChangeListener();
            moved=true;
        }
      //ymax changed
        if(spinner==positionSpinners[3]){
            System.out.println("Rectangular ymax changed");
            double ymin=positionSpinnerModels[2].getNumber().doubleValue();
            double ymax=positionSpinnerModels[3].getNumber().doubleValue();
            double h=sizeSpinnerModels[1].getNumber().doubleValue();
            this.removeChangeListener();
            sizeSpinners[1].setValue(Math.abs(ymax-ymin));
            centerSpinners[1].setValue(0.5*(ymin+ymax));
            this.addChangeListener();
            moved=true;
        }
      //w changed
        if(spinner==sizeSpinners[0]){
            Rectangle2D box=this.shapeContainer.getBoundingBox();
            double W=box.getWidth();
            double H=box.getHeight();
            double w=sizeSpinnerModels[0].getNumber().doubleValue();
            double h=sizeSpinnerModels[1].getNumber().doubleValue();
            double xmin=positionSpinnerModels[0].getNumber().doubleValue();
            double xmax=positionSpinnerModels[1].getNumber().doubleValue();
            this.removeChangeListener();
            positionSpinners[1].setValue(xmin+w);
            centerSpinners[0].setValue(xmin+0.5*w);
            if(aspect_ratio){
                double ratio=w/W;
                double newH=H*ratio;
                double ymin=positionSpinnerModels[2].getNumber().doubleValue();
                sizeSpinners[1].setValue(newH);
                positionSpinners[3].setValue(ymin+newH);
                centerSpinners[1].setValue(ymin+0.5*newH);
            }
            this.addChangeListener();
            resized=true;
        }
      //h changed
        if(spinner==sizeSpinners[1]){
            Rectangle2D box=this.shapeContainer.getBoundingBox();
            Point2D[] Pts=this.shapeContainer.getElement().getEndPTs();
            double W=box.getWidth();
            double H=box.getHeight();
            double h=sizeSpinnerModels[1].getNumber().doubleValue();
            double ymin=positionSpinnerModels[2].getNumber().doubleValue();
            double ymax=positionSpinnerModels[3].getNumber().doubleValue();
            this.removeChangeListener();
            positionSpinners[3].setValue(ymin+h);
            centerSpinners[1].setValue(ymin+0.5*h);
            if(aspect_ratio){
                double ratio=h/H;
                double newW=W*ratio;
                double xmin=positionSpinnerModels[0].getNumber().doubleValue();
                sizeSpinners[0].setValue(newW);
                positionSpinners[1].setValue(xmin+newW);
                centerSpinners[0].setValue(xmin+0.5*newW);
            }
            this.addChangeListener();
            resized=true;
        }
      //centerX changed
        if(spinner==centerSpinners[0]){
            double centerX=centerSpinnerModels[0].getNumber().doubleValue();
            double w=sizeSpinnerModels[0].getNumber().doubleValue();
            this.removeChangeListener();
            positionSpinners[0].setValue(centerX-0.5*w);
            positionSpinners[1].setValue(centerX+0.5*w);
            this.addChangeListener();
            moved=true;
        }
      //centerY changed
        if(spinner==centerSpinners[1]){
            double centerX=centerSpinnerModels[1].getNumber().doubleValue();
            double h=sizeSpinnerModels[1].getNumber().doubleValue();
            this.removeChangeListener();
            positionSpinners[2].setValue(centerX-0.5*h);
            positionSpinners[3].setValue(centerX+0.5*h);
            this.addChangeListener();
            moved=true;
        }

        Rectangle2D oldBox=this.shapeContainer.getBoundingBox();
        double xmin=positionSpinnerModels[0].getNumber().doubleValue();
        double xmax=positionSpinnerModels[1].getNumber().doubleValue();
        double ymin=positionSpinnerModels[2].getNumber().doubleValue();
        double ymax=positionSpinnerModels[3].getNumber().doubleValue();
        double pixel=DrawParameters.InchToPixels/DrawParameters.InchToMM;
        double unit=1.0d;
        if(this.dialog.mmButton.isSelected()) unit=pixel;
        Rectangle2D newBox=new Rectangle.Double(xmin*unit, ymin*unit,
                (xmax-xmin)*unit, (ymax-ymin)*unit);
        ConnectionUtil.moveResize(this.shapeContainer, oldBox, newBox,
                keep_connection, true);
        ObjectTable.getDrawPanel().repaint();
    }

    private void lineChanged(ChangeEvent e){
        JSpinner spinner=(JSpinner)e.getSource();
        SpinnerNumberModel[] startSpinnerModels=this.dialog.getStartSpinnerModels();
        JSpinner[] startSpinners=this.dialog.getStartSpinners();
        SpinnerNumberModel[] endSpinnerModels=this.dialog.getEndSpinnerModels();
        JSpinner[] endSpinners=this.dialog.getEndSpinners();
        SpinnerNumberModel[] lineSpinnerModels=this.dialog.getLineSpinnerModels();
        JSpinner[] lineSpinners=this.dialog.getLineSpinners();

        double pixel=DrawParameters.InchToPixels/DrawParameters.InchToMM;
      // x*unit: x mm => x pixels
        double unit=1.0d;
        if(this.dialog.mmButton.isSelected()) unit=pixel;
        boolean resizable=this.shapeContainer.getBooleanProperty(DialogOfShapeFormat.RESIZING,"DialogOfShapeFormat");
        boolean line_dir=this.shapeContainer.getBooleanProperty(DialogOfShapeFormat.LINE_DIRECTION,"DialogOfShapeFormat");
        Rectangle2D box=this.shapeContainer.getBoundingBox();
        Point2D[] Pts=this.shapeContainer.getElement().getEndPTs();
        Vector2D Tvec=Vector2D.sub(Pts[1], Pts[0]);
        double angle=Math.atan2(Tvec.getY(), Tvec.getX());
        double length=Vector2D.length(Tvec);
        Point2D[] newPts=new Point2D[2];
        newPts[0]=(Point2D)Pts[0].clone();
        newPts[1]=(Point2D)Pts[1].clone();
        boolean srartChanged=false;
        boolean endChanged=false;
        boolean angleChanged=false;
        boolean lengthChanged=false;

      //Start Point changed
        if(spinner==startSpinners[0]){
            System.out.println("Line startX chenged");
            double startX=startSpinnerModels[0].getNumber().doubleValue()*unit;
            newPts[0]=new Point2D.Double(startX, Pts[0].getY());
            srartChanged=true;
        }
        if(spinner==startSpinners[1]){
            double startY=startSpinnerModels[1].getNumber().doubleValue()*unit;
            newPts[0]=new Point2D.Double(Pts[0].getX(), startY);
            srartChanged=true;
        }
      //endX changed
        if(spinner==endSpinners[0]){
            System.out.println("Line endX chenged");
            double endX=endSpinnerModels[0].getNumber().doubleValue()*unit;
            newPts[1]=new Point2D.Double(endX, Pts[1].getY());
            endChanged=true;
        }
      //endY changed
        if(spinner==endSpinners[1]){
            System.out.println("Line endY chenged");
            double endY=endSpinnerModels[1].getNumber().doubleValue()*unit;
            newPts[1]=new Point2D.Double(Pts[1].getX(), endY);
            endChanged=true;
        }

      //Line angle changed
        if(spinner==lineSpinners[0]){
            double newAngle=lineSpinnerModels[0].getNumber().doubleValue();
            double newEndX=length*Math.cos(newAngle*Math.PI/180.0)+Pts[0].getX();
            double newEndY=length*Math.sin(-newAngle*Math.PI/180.0)+Pts[0].getY();
            newPts[1]=new Point2D.Double(newEndX, newEndY);
            angleChanged=true;
        }

      //Line length changed
        if(spinner==lineSpinners[1]){
            double newLength=lineSpinnerModels[1].getNumber().doubleValue()*unit;
            double newEndX=newLength*Math.cos(angle)+Pts[0].getX();
            double newEndY=newLength*Math.sin(angle)+Pts[0].getY();
            newPts[1]=new Point2D.Double(newEndX, newEndY);
            lengthChanged=true;
        }
        int index=0;
        if(!resizable) index=2;
        if(resizable&&(line_dir&&!angleChanged&&!lengthChanged)) index=2;
        
        switch(index){
          //move end point
            case 0: {
                if(srartChanged){
                    ConnectionUtil.moveEndPoint(this.shapeContainer, 0,
                            Pts[0], newPts[0], true, true);
                } else {
                    ConnectionUtil.moveEndPoint(this.shapeContainer, 1,
                            Pts[1], newPts[1], true, true);
                }
                break;
            }
          //move end point without changing direction
            case 1: {
                Vector2D move=null;
                if(srartChanged){
                    move=Vector2D.sub(newPts[0], Pts[0]);
                    Vector2D moveVec=this.getMoveVector(Tvec, move);
                    newPts[0].setLocation(Pts[0].getX()+moveVec.getX(), Pts[0].getY()+moveVec.getY());
                    ConnectionUtil.moveEndPoint(this.shapeContainer, 0,
                        Pts[0], newPts[0], true, true);
                } else {
                    move=Vector2D.sub(newPts[1], Pts[1]);
                    Vector2D moveVec=this.getMoveVector(Tvec, move);
                    newPts[1].setLocation(Pts[1].getX()+moveVec.getX(), Pts[1].getY()+moveVec.getY());
                    ConnectionUtil.moveEndPoint(this.shapeContainer, 1,
                        Pts[1], newPts[1], true, true);
                }
                break;
            }
           //move shape
            case 2: {
                Vector2D move=new Vector2D();
                if(srartChanged){
                    move=Vector2D.sub(newPts[0], Pts[0]);
                    newPts[1].setLocation(Pts[1].getX()+move.getX(), Pts[1].getY()+move.getY());
                } else {
                    move=Vector2D.sub(newPts[1], Pts[1]);
                    newPts[0].setLocation(Pts[0].getX()+move.getX(), Pts[0].getY()+move.getY());
                }
                Rectangle2D newBox=new Rectangle2D.Double(box.getX()+move.getX(),
                        box.getY()+move.getY(), box.getWidth(), box.getHeight());
                ConnectionUtil.moveResize(this.shapeContainer, box, newBox, true, true);
                break;
            }
        }

        Vector2D newVec=Vector2D.sub(newPts[1], newPts[0]);
        double newAngle=Math.atan2(newVec.getY(), newVec.getX());
        double newLength=Vector2D.length(newVec);

        this.removeChangeListener();
        startSpinners[0].setValue(newPts[0].getX()/unit);
        startSpinners[1].setValue(newPts[0].getY()/unit);
        endSpinners[0].setValue(newPts[1].getX()/unit);
        endSpinners[1].setValue(newPts[1].getY()/unit);
        lineSpinners[0].setValue(-newAngle*180.0/Math.PI);
        lineSpinners[1].setValue(newLength/unit);
        this.addChangeListener();
        ObjectTable.getDrawPanel().repaint();
    }


    private Vector2D getMoveVector(Vector2D Tvec, Vector2D move){
        Vector2D projVec=new Vector2D();
        double sprod=Vector2D.sproduct(move, Tvec);
        double move2=Vector2D.sproduct(move, move);
        if(Math.abs(sprod)==0.0){
            return projVec;
        }
        double t=move2/sprod;
        projVec=Vector2D.multiply(t, Tvec);
        return projVec;
    }

    protected void removeChangeListener(){
        JSpinner[] positionSpinners=this.dialog.getPositionSpinners();
        JSpinner[] sizeSpinners=this.dialog.getSizeSpinners();
        JSpinner[] centerSpinners=this.dialog.getCenterSpinners();
        JSpinner[] startSpinners=this.dialog.getStartSpinners();
        JSpinner[] endSpinners=this.dialog.getEndSpinners();
        JSpinner[] lineSpinners=this.dialog.getLineSpinners();
        for(int i=0;i<4;i++) {
            if(positionSpinners[i]!=null) positionSpinners[i].removeChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(sizeSpinners[i]!=null) sizeSpinners[i].removeChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(centerSpinners[i]!=null) centerSpinners[i].removeChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(startSpinners[i]!=null) startSpinners[i].removeChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(endSpinners[i]!=null) endSpinners[i].removeChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(lineSpinners[i]!=null) lineSpinners[i].removeChangeListener(this);
        }
    }
    
    protected void addChangeListener(){
        JSpinner[] positionSpinners=this.dialog.getPositionSpinners();
        JSpinner[] sizeSpinners=this.dialog.getSizeSpinners();
        JSpinner[] centerSpinners=this.dialog.getCenterSpinners();
        JSpinner[] startSpinners=this.dialog.getStartSpinners();
        JSpinner[] endSpinners=this.dialog.getEndSpinners();
        JSpinner[] lineSpinners=this.dialog.getLineSpinners();
        for(int i=0;i<4;i++) {
            if(positionSpinners[i]!=null) positionSpinners[i].addChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(sizeSpinners[i]!=null) sizeSpinners[i].addChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(centerSpinners[i]!=null) centerSpinners[i].addChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(startSpinners[i]!=null) startSpinners[i].addChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(endSpinners[i]!=null) endSpinners[i].addChangeListener(this);
        }
        for(int i=0;i<2;i++) {
            if(lineSpinners[i]!=null) lineSpinners[i].addChangeListener(this);
        }
    }

}

class ShapeFormatAction extends AbstractAction implements ChangeListener, WindowListener{
    DialogOfShapeFormat dialog;
    ShapeContainer shapeContainer=null;
    boolean lineType=false;
    ExecCommand execCommand=ObjectTable.getExecCommand("DialogOfShapeFormat");
    int debug=0;
    
    public ShapeFormatAction(DialogOfShapeFormat dialog){
        this.dialog=dialog;
    }
    public void actionPerformed(ActionEvent e) {
        String commandName=e.getActionCommand();
        String componentClassName=""; 
        componentClassName=e.getSource().getClass().getSimpleName();
        String componentName=((Component)e.getSource()).getName();
        if(debug>0) System.out.println("- actionPerformed  " +
                "commandName="+commandName+
                ", source component name="+componentName+
                ", source class simple name="+componentClassName);
        //ShapeContainer shapeContainer=this.dialog.getShapeContainer();
        JRadioButton mmButton=this.dialog.mmButton;
        SpinnerNumberModel[] marginSpinnerModels
                =this.dialog.getMarginSpinnerModels();
        SpinnerNumberModel lineSpaceSpinnerModel
                =this.dialog.getLineSpaceSpinnerModels();
        this.shapeContainer=this.dialog.getShapeContainer();
        int type=this.shapeContainer.getElement().getTypeE();
        this.lineType=false;
        if(type>=Command.LINE&&type<=Command.DOUBLE_ARROW) this.lineType=true;
        if(commandName.equals("pixel")||commandName.equals("mm")){
            int unitType=0;
            if(mmButton.isSelected()) unitType=1;
            if(this.lineType) this.dialog.showLine(unitType);
            else this.dialog.showRectangular(unitType);
            System.out.println("pixel or mm button pressed");
        }
        
        if(commandName.equalsIgnoreCase(DialogOfShapeFormat.RESIZING)){
            JCheckBox resizeBox=this.dialog.getResizeBox();
            JCheckBox ratioBox=this.dialog.getRatioBox();
            JCheckBox directionBox=this.dialog.getDirectionBox();
            if(resizeBox.isSelected()){
                ratioBox.setSelected(false);
                directionBox.setSelected(false);
                if(lineType){
                    directionBox.setEnabled(true);
                } else {
                    ratioBox.setEnabled(true);
                }
            } else {
                ratioBox.setSelected(false);
                directionBox.setSelected(false);
                ratioBox.setEnabled(false);
                directionBox.setEnabled(false);
            } 
            this.setProperty();
        }
        
        if(commandName.equalsIgnoreCase(DialogOfShapeFormat.ASPECT_RATIO)){
            this.setProperty();
        }
        if(commandName.equalsIgnoreCase(DialogOfShapeFormat.LINE_DIRECTION)){
            this.setProperty();
        }
        if(commandName.equalsIgnoreCase(DialogOfShapeFormat.CONNECTOR_CONNECTIONS)){
            this.setProperty();
        }
        if(commandName.equalsIgnoreCase(DialogOfShapeFormat.UNGROUPING)){
            this.setProperty();
        }
        
        if(commandName.equals("OK Property")){
            this.removeOldProperty();
            this.closeDialog();
        }

        if(commandName.equals("Cancel Property")){
            this.closeDialog();
        }

        if(commandName.equals("OK TextBox")){
            double left=marginSpinnerModels[0].getNumber().doubleValue();
            double top=marginSpinnerModels[1].getNumber().doubleValue();
            double right=marginSpinnerModels[2].getNumber().doubleValue();
            double bottom=marginSpinnerModels[3].getNumber().doubleValue();
            double lineSpace=lineSpaceSpinnerModel.getNumber().doubleValue();
            Insets insets=new Insets((int)top, (int)left, (int)bottom, (int)right);
            Object[] args=new Object[3];
            args[0]=insets;
            args[1]=-1;
            lineSpace=(int)lineSpace;
            args[2]=lineSpace;
            Command command=new Command(Command.TEXTBOX_LAYOUT, 
                            Command.callFromDialog, args);
            execCommand=ObjectTable.getExecCommand("");
            execCommand.exec(command);
            this.closeDialog();
            return;
        }
        
        if(commandName.equals("Cancel TextBox")){
            this.closeDialog();
            return;
        }

    }//End of actionPerformed
    
    private void setProperty(){
            String str;
            boolean selected;
            str=DialogOfShapeFormat.RESIZING;
            selected=this.dialog.getResizeBox().isSelected();
            if(!selected) {
                this.shapeContainer.setProperty(str, new Boolean(selected),"DialogOfShapeFormat");
            } else {
                this.shapeContainer.removeProperty(str,"DialogOfShapeFormat");
            }

            str=DialogOfShapeFormat.ASPECT_RATIO;
            selected=this.dialog.getRatioBox().isSelected();
            if(selected) {
                this.shapeContainer.setProperty(str, new Boolean(selected),"DialogOfShapeFormat");
            } else {
                this.shapeContainer.removeProperty(str,"DialogOfShapeFormat");
            }

            str=DialogOfShapeFormat.LINE_DIRECTION;
            selected=this.dialog.getDirectionBox().isSelected();
            if(selected) {
                this.shapeContainer.setProperty(str, new Boolean(selected),"DialogOfShapeFormat");
            } else {
                this.shapeContainer.removeProperty(str,"DialogOfShapeFormat");
            }

            str=DialogOfShapeFormat.CONNECTOR_CONNECTIONS;
            selected=this.dialog.getConnectorBox().isSelected();
            if(!selected) {
                this.shapeContainer.setProperty(str, new Boolean(selected),"DialogOfShapeFormat");
            } else {
                this.shapeContainer.removeProperty(str,"DialogOfShapeFormat");
            }

            str=DialogOfShapeFormat.UNGROUPING;
            selected=this.dialog.getUngroupBox().isSelected();
            if(!selected){
                this.shapeContainer.setProperty(str, new Boolean(selected),"DialogOfShapeFormat");
            }else{
                this.shapeContainer.removeProperty(str,"DialogOfShapeFormat");
            }
            ObjectTable.getDrawPanel().repaint();
    }
    
    private void removeOldProperty(){
          // remove the old keys and values.
            this.shapeContainer.removeProperty("MOVABLE","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("UNMOVABLE","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("RESIZABLE","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("UNRESIZABLE","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("ALLOW_CONNECTOR_CONNECTION","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("UNABLE_TO_DRAG_CONNECTORS","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("ALLOW_UNGROUP","DialogOfShapeFormat");
            this.shapeContainer.removeProperty("UNABLE_UNGROUPING","DialogOfShapeFormat");
            //int type=this.shapeContainer.getElement().getTypeE();
            if(this.lineType){
                this.shapeContainer.removeProperty("KEEP_ASPECT_RATIO","DialogOfShapeFormat");
            } else{
                this.shapeContainer.removeProperty("KEEP_LINE_DIRECTION","DialogOfShapeFormat");
            }
    }
    public void stateChanged(ChangeEvent e){
        String componentClassName=e.getSource().getClass().getSimpleName();
        //System.out.println("- stateChenged source="+ componentClassName);
    }
    
    private void closeDialog(){
        this.dialog.setVisible(false);
        MenuUtil menuUtil=ObjectTable.getMenuUtil();
        Component component=menuUtil.getMenuComponent(this.dialog.getName());
        if(component!=null) menuUtil.removeMenuComponent(component);
    }
    public void windowActivated(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}
    public void windowClosing(WindowEvent e) {
        if( debug>0) System.out.println("windowClosing called");
        this.closeDialog();
    }
    public void windowDeactivated(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowOpened(WindowEvent e) {}
} // end of class
