
package shapeUtil;

import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border.*;
import DrawTop.*;
import shape.*;
import menu.*;
import util.*;


public class ModifyShape extends JDialog{
    ModifyShapeAction action=null;
    ModifyShapeLS modifyShapeLS=new ModifyShapeLS();
    ShapeContainer targerContainer=null;
    JLabel messageLabel1=null;
    JLabel messageLabel2=null;
    MRadioButton moveButton=null;
    MRadioButton addPointButton=null;
    MRadioButton deletePointButton=null;
    MRadioButton smoothButton=null;
    MRadioButton cuspButton=null;
    MRadioButton disconnectButton=null;
    JButton exitButton=null;
    private Dimension dialogDimension=new Dimension(300,80);

    public ModifyShape(){
        super(ObjectTable.getDrawMain(), "ModifyShape");
        this.setName("ModifyShape");  
        this.action=new ModifyShapeAction(this);
        //createDialog();
    }

    public void showDialog(){
//check selected shape
        ContainerManager manager=ObjectTable.getContainerManager("ModifyShape");
        ShapeContainer[] containers=manager.getSelectedContainers();
        if(containers==null||containers.length==0){
            JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), 
            "Shape not selected!  Select one.", "", 
            JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        if(containers.length>1){
            for(int i=1;i<containers.length;i++) containers[i].setSelected(false);
         }
         if(containers[0].getContainerType()==ShapeContainer.GROUP){
              JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), 
                   "Group was selected!  Select one shape.", "", 
                   JOptionPane.INFORMATION_MESSAGE);
               return;
        }
        this.targerContainer=(ShapeContainer)containers[0];
//set mouseListener
        this.modifyShapeLS.start(this.targerContainer);
        this.targerContainer.setMode(Command.MODIFYING_SHAPE_MODE);
        ObjectTable.getDrawPanel("").repaint("ModifyShape");
//set dialog position
        //this.dialog=new JDialog(ObjectTable.getDrawMain(), "ModifyShape");
        double scale=DrawParameters.Scale;
        DrawPanel drawPanel=ObjectTable.getDrawPanel("");
        Component owner=this.getOwner();
        Rectangle2D rect=this.targerContainer.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);
//set dialog
        //ModifyShapeAction action=new ModifyShapeAction();
        this.addWindowListener(action);
        Container contentPane=this.getContentPane();
        Box box=Box.createVerticalBox();
        contentPane.add(box);
        
        JPanel messagePanel=new JPanel();
        messagePanel.setPreferredSize(dialogDimension);
        GridLayout basePanelLayout=new GridLayout(3,1);
        basePanelLayout.setHgap(20);
        basePanelLayout.setVgap(5);
        messagePanel.setLayout(basePanelLayout);
        messagePanel.setPreferredSize(dialogDimension);
        JLabel instructionLabel=new JLabel("   Modify shape.  Select button !");
        messageLabel1=new JLabel(" ");
        messageLabel2=new JLabel(" ");
        messagePanel.add(instructionLabel);
        messagePanel.add(this.messageLabel1);
        messagePanel.add(this.messageLabel2);
    //RadioButton
        JPanel radioButtonPanel=new JPanel();
        //radioButtonPanel.setLayout(new BoxLayout(radioButtonPanel, BoxLayout.X_AXIS));
        radioButtonPanel.setLayout(new GridLayout(2,3,5,5));
        this.moveButton=new MRadioButton("move");
        this.addPointButton=new MRadioButton("add point");
        this.deletePointButton=new MRadioButton("delete point");
        this.smoothButton=new MRadioButton("smooth");
        this.cuspButton=new MRadioButton("cusp");
        this.disconnectButton=new MRadioButton("disconnect");
        this.moveButton.addActionListener(this.action);
        this.addPointButton.addActionListener(this.action);
        this.deletePointButton.addActionListener(this.action);
        this.smoothButton.addActionListener(this.action);
        this.cuspButton.addActionListener(this.action);
        this.disconnectButton.addActionListener(this.action);
        this.moveButton.setSelected(true);
        String tipText="Move a small rectangle on a curve or a tangent line."
                + "\n • Mark filled in blue: node point. "
                + "\n • Mark filled in white: center of line/arc or ends of tangent.";
        this.moveButton.setToolTipText(tipText);
        //this.moveButton.setToolTipFont(Font.BOLD);
        tipText="Click on a curve to add a new node point on the curve.";
        this.addPointButton.setToolTipText(tipText);
        tipText="Click near a node point (blue mark) to delete it.";
        this.deletePointButton.setToolTipText(tipText);
        tipText="Click on a cusp node point to connect a curve smoothly.\n"
                + "At least, one of the curves connecting at the cusp point must be cubic.";
        this.smoothButton.setToolTipText(tipText);
        tipText="Click on a smooth node point to change it cusp point.";
        this.cuspButton.setToolTipText(tipText);
        tipText="Click on a node point to disconnect a curve.";
        this.disconnectButton.setToolTipText(tipText);
        
        if(this.targerContainer.getElement().getTypeE()==Command.ROUND_RECTANGLE){
            this.addPointButton.setEnabled(false);
            this.deletePointButton.setEnabled(false);
            this.smoothButton.setEnabled(false);
            this.cuspButton.setEnabled(false);
            this.disconnectButton.setEnabled(false);
        }
        ButtonGroup group=new ButtonGroup();
        group.add(this.moveButton); 
        group.add(this.addPointButton);
        group.add(this.deletePointButton);
        group.add(this.smoothButton);
        group.add(this.cuspButton);
        group.add(this.disconnectButton);
        radioButtonPanel.add(this.moveButton);
        radioButtonPanel.add(this.addPointButton);
        radioButtonPanel.add(this.deletePointButton);
        radioButtonPanel.add(this.smoothButton);
        radioButtonPanel.add(this.cuspButton);
        radioButtonPanel.add(this.disconnectButton);
    //OK, Cancel Button    
        JPanel buttonPanel=new JPanel();
        this.exitButton=new JButton("Exit");
        this.exitButton.setActionCommand("Exit");
        this.exitButton.addActionListener(this.action);
        buttonPanel.add(this.exitButton);
// layout the dialog
        box.add(Box.createVerticalStrut(5));
        box.add(messagePanel);
        box.add(Box.createVerticalStrut(5));
        box.add(radioButtonPanel);
        box.add(Box.createVerticalStrut(5));
        box.add(buttonPanel);
        this.pack();
        this.setVisible(true);
// set initial state
        
        int type=this.targerContainer.getElement().getTypeE();
        this.showMessage(1,"  move button selected (shift/ctrl key available)");
        if(type==Command.POLYLINE){
            this.showMessage(2,"   => move blue point or edge !");
        } else {
            this.showMessage(2,"   => move blue point or tangent !");
        }
        return;
    }
    
    protected void showMessage(int id, String message){
        if(id==1){
            this.messageLabel1.setForeground(Color.BLUE);
            this.messageLabel1.setFont(DrawParameters.Font12Bold);
            this.messageLabel1.setText(message);
        } else{
            this.messageLabel2.setForeground(Color.BLUE);
            this.messageLabel2.setFont(DrawParameters.Font14Bold);
            this.messageLabel2.setText(message);
        }
    }
    
    protected ShapeContainer getTargetContainer(){
        return this.targerContainer;
    }
    
    protected ModifyShapeLS getModifyShapeLS(){
        return this.modifyShapeLS;
    }
    
} //end of DialogOfConnectCurves

class ModifyShapeAction extends AbstractAction implements WindowListener {
    ModifyShape dialog=null;
    int debug=0;
    
    public ModifyShapeAction(ModifyShape dialog){
        this.dialog=dialog;
    }
    
    public void actionPerformed(ActionEvent e) {
        int debug=0;
        String commandName=e.getActionCommand();
        String componentClassName=""; 
        componentClassName=e.getSource().getClass().getSimpleName();
        String componentName=((Component)e.getSource()).getName();
        if(debug>0) System.out.println("- ModifyShapeAction.actionPerformed  " +
                "commandName="+commandName+
                ", source component name="+componentName+
                ", source class simple name="+componentClassName);
        ShapeContainer targerContainer=this.dialog.getTargetContainer();
        ModifyShapeLS modifyShapeLS=this.dialog.getModifyShapeLS();
        if(commandName.equals("move")){
            //System.out.println("** move button selected");
            modifyShapeLS.setCommand(Command.MOVE);
            int type=targerContainer.getElement().getTypeE();
            this.dialog.showMessage(1,"  move button selected (shift/ctrl key available)");
            if(type==Command.POLYLINE){
                this.dialog.showMessage(2,"   => move blue point or edge !");
            } else {
                this.dialog.showMessage(2,"   => move blue point or tangent !");
            }
            return;   
        }
        if(commandName.equals("add point")){
            //System.out.println("** add point button selected");
            modifyShapeLS.setCommand(Command.ADD_POINT);
            this.dialog.showMessage(1,"  add point button selected");
            int type=targerContainer.getElement().getTypeE();
            if(type==Command.POLYLINE){
                this.dialog.showMessage(2, "   => click on edge !");
            } else{
                this.dialog.showMessage(2, "   => click on curve !");
            }
             return;   
        }
        if(commandName.equals("delete point")){
            //System.out.println("** delete point button selected");
            modifyShapeLS.setCommand(Command.DELETE_POINT);
            this.dialog.showMessage(1,"  delete point button selected");
            this.dialog.showMessage(2, "   => click blue point !");

             return;   
        }
        if(commandName.equals("smooth")){
            //System.out.println("** smooth selected");
            modifyShapeLS.setCommand(Command.SMOOTH);
            this.dialog.showMessage(1,"  smooth button selected");
            this.dialog.showMessage(2, "   => click blue point !");
             return;   
        }
        if(commandName.equals("cusp")){
            //System.out.println("** cusp button selected");
            modifyShapeLS.setCommand(Command.CUSP);
            this.dialog.showMessage(1,"  cusp button selected");
            this.dialog.showMessage(2, "   => click blue point !");
             return;   
        }
        if(commandName.equals("disconnect")){
            //System.out.println("** disconnect button selected");
            modifyShapeLS.setCommand(Command.DISCONNECT);
            this.dialog.showMessage(1,"  disconnect button selected");
            this.dialog.showMessage(2, "   => click blue point !");
             return;   
        }
        if(commandName.equals("Exit")){
            closeDialog();
            return;
        }
    }//End of actionPerformed
 
    private void closeDialog(){
        ShapeContainer targerContainer=this.dialog.getTargetContainer();
        ModifyShapeLS modifyShapeLS=this.dialog.getModifyShapeLS();
        targerContainer.setMode(Command.NORMAL_MODE);
        this.dialog.setVisible(false);
        modifyShapeLS.end();
        return;
    }
    
    public void windowActivated(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}
    public void windowClosing(WindowEvent e) {
        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