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 geomExtension.*;
import util.*;


public class ExtendCurve extends JDialog implements SelectionListener{
    ExtendCurveLS extendCurveLS=null;
    ExtCurveAction action=null;
    JLabel messageLabel1=new JLabel(" ");
    JLabel messageLabel2=new JLabel(" ");
    Dimension messageDimension=new Dimension(250, 14);
    JButton goButton=null;
    //JButton continueButton=null;
    JButton cancelButton=null;
    Point2D clickedPoint=null;
    MouseHitShape mouseHitShape=null;
    Point dialogLocation=new Point(500, 90);
    int debug=0;
    
    
    public ExtendCurve(){
        super(ObjectTable.getDrawMain(), "Extend curve");
        this.setName("Extend curve");
        this.action=new ExtCurveAction(this);
        this.createDialog();
        this.extendCurveLS=new ExtendCurveLS(this);
    }
    
    public void createDialog(){
        this.addWindowListener(this.action);
        Container contentPane=this.getContentPane();
        Box box=Box.createVerticalBox();
        contentPane.add(box);
        
        JPanel messagePanel=new JPanel();
        messagePanel.setBorder(BorderFactory.createTitledBorder("message:"));
        Box messageBox=Box.createVerticalBox();
        messagePanel.add(messageBox);
        messageBox.add(Box.createVerticalStrut(0));
        messageBox.add(this.messageLabel1);
        messageBox.add(Box.createVerticalStrut(0));
        messageBox.add(this.messageLabel2);
        messageBox.add(Box.createVerticalStrut(0));
        this.messageLabel1.setPreferredSize(this.messageDimension);
        this.messageLabel2.setPreferredSize(this.messageDimension);
        
    //OK, Cancel Button    
        JPanel buttonPanel=new JPanel();
        this.goButton=new JButton("GO !");
        //this.continueButton=new JButton("Continue");
        this.cancelButton=new JButton("Cancel");
        this.goButton.setEnabled(false);
        //this.continueButton.setEnabled(false);
        goButton.setActionCommand("Go");
        //continueButton.setActionCommand("Continue");
        cancelButton.setActionCommand("Cancel");
        //ComputeDistanceAction action=new ComputeDistanceAction();
        goButton.addActionListener(action);
        //continueButton.addActionListener(action);
        cancelButton.addActionListener(action);
        buttonPanel.add(goButton);
        //buttonPanel.add(continueButton);
        buttonPanel.add(cancelButton);
// layout the dialog
        box.add(Box.createVerticalStrut(5));
        box.add(messagePanel);
        box.add(Box.createVerticalStrut(5));
        box.add(buttonPanel);
        //box.add(Box.createVerticalStrut(5));
        //box.add(selectPanel);
    }
    
    public void showDialog(){
        Component owner = this.getOwner();
        Point pos = new Point(owner.getX() + (int)this.dialogLocation.getX(),
                owner.getY() + (int)this.dialogLocation.getY());
        this.setLocation(pos);
        this.pack();
        this.setVisible(true);
        ContainerManager containerManager=ObjectTable.getContainerManager();
        this.mouseHitShape=null;
        ShapeContainer[] containers=containerManager.getSelectedContainers();
        int size=0;
        if(containers!=null) size=containers.length;
       
        if(size>0){
            if(size>1){
                for(int i=1;i<size;i++ ) containers[i].setSelected(false);
            }
            if(this.isSuitable(containers[0])){
                containers[0].setSelected(true);
                //this.showMessage("  Selected curve accepted.  Click point !", Color.BLUE);
                Curve2D curve=containers[0].getElement().getCurve2D();
                Point2D point=curve.getP(0.5*curve.getNumOfSegments());
                if(debug>0) System.out.println("-- ExtendCurve.showDialog calls receive");
                //this.receive(containers[0], point);
            }
        } else {
      //set Receiver
            this.showMessage("  Click target curve !", Color.BLUE);
            SelectionLS selectionLS=ObjectTable.getSelectionLS();
            //------------------------------------------//
            selectionLS.addSelectionListener(this);
            //selectionLS.setReceiver(this, "receive");
            //------------------------------------------//
        }
        return;
    }

    private boolean isSuitable(ShapeContainer container){
        ShapeContainer shapeContainer=(ShapeContainer)container;
        int type=shapeContainer.getElement().getTypeE();
        if(type<Command.AUTO_SHAPE_FIRST||type>Command.AUTO_SHAPE_LAST){
            showMessage("  Error: Not curve, Click again !", Color.RED);
            return false;
        }
        if(container.getElement().isClosed()){
            showMessage("  Error: Closed Curve !", Color.RED);
            return false;
        }
        
        if(container.getContainerType()==ShapeContainer.GROUP){
            showMessage("  Error: Clicked shape is group, Click single shape !", Color.RED);;
            return false;
        }
        return true;
    }
    public void selected(SelectionEvent event){
        Point2D point=event.getClickedPoint();
        ShapeContainer[] containers=event.getSelectedContainers();
      //check shape type
        if(!this.isSuitable(containers[0])) return;
        if(this.mouseHitShape==null) {
            DrawShapeUtil.drawTempShape("ExtendCureve", point, DrawParameters.Mark_SmallSize,
                    "target", Color.RED);
            this.mouseHitShape=new MouseHitShape(containers[0], point);
            showMessage("  Click extending target position !", Color.BLUE);
            // wait cliced point.
           //--------------------------//
            this.extendCurveLS.start();
           //--------------------------//
        }
      // save ClickedData
    }
/*
  // SelectionLS call this method
    public void receive(ShapeContainer container, Point2D point){
        if(debug>0) System.out.println("-- ExtendCurve.receive called  container="+
                container.getShapeId()+", point="+point);
      //check shape type
        if(!this.isSuitable(container)) return;
        if(this.mouseHitShape==null) {
            DrawShapeUtil.drawTempShape("ExtendCureve", point, DrawParameters.Mark_SmallSize,
                    "target", Color.RED);
            this.mouseHitShape=new MouseHitShape(container, point);
            showMessage("  Click extending target position !", Color.BLUE);
            // wait cliced point.
           //--------------------------//
            this.extendCurveLS.start();
           //--------------------------//
        }
      // save ClickedData
    }
*/
   // ExtendCurveLS calls this method
    public void receivePoint(Point2D point){
        this.clickedPoint=point;
        this.drawMark(point);
        if(debug>0) System.out.println("-- ExtendCurve.receive(point)  point="+Util.Pt(point));
        if(this.mouseHitShape!=null) {
            this.showMessage("  Go or Cancel", Color.BLUE);
            this.goButton.setEnabled(true);
        }
        this.extendCurveLS.end();
    }

    public void showMessage(String message, Color color){
        //System.out.println(" -- showMessage message="+message);
        this.messageLabel1.setForeground(color);
        this.messageLabel2.setForeground(color);
        this.messageLabel1.setFont(DrawParameters.Font12Bold);
        this.messageLabel2.setFont(DrawParameters.Font12Bold);
        int index=message.indexOf("\n");
        String str1=message;
        String str2="";
        if(index>=0){
            str1=message.substring(0, index);
            if(index+1<message.length()){
                str2=message.substring(index+1, message.length());
            }
        }
        //System.out.println("showMessage str1="+str1+", str2="+str2);
        this.messageLabel1.setText(str1);
        this.messageLabel2.setText(str2);
    }

    public JButton getGoButton(){
        return this.goButton;
    }

    public MouseHitShape getMouseHitShape(){
        return this.mouseHitShape;
    }

    protected ExtendCurveLS getExtendCurveLS(){
        return this.extendCurveLS;
    }

    public Point2D getClickedPoint(){
        return this.clickedPoint;
    }

    public void drawMark(Point2D PT) {
        DrawShapeUtil.clearTempShape("ExtendCurevePT");
        ObjectTable.getDrawPanel().repaint();
        DrawShapeUtil.drawTempShape("ExtendCurvePT", PT,
                DrawParameters.Mark_SmallSize, "clicked point", Color.RED);
    }

    protected void closeDialog(){
      // clear mark and "selected" on the selected curve
        DrawPanel drawPanel=ObjectTable.getDrawPanel("");
      //-------------------------------//
        DrawShapeUtil.clearAllTempShapes();
        drawPanel.repaint();
        this.extendCurveLS.end();
      //----------------------------------------------------//
        SelectionLS selectionLS=ObjectTable.getSelectionLS("");
        selectionLS.removeSelectionListener(this);

      //---------------------------------------------------//
        selectionLS.start();
        Component owner = this.getOwner();
        Point dialogPT = this.getLocation();
        this.dialogLocation = new Point((int) dialogPT.getX() - owner.getX(),
                (int) dialogPT.getY() - owner.getY());
        this.setVisible(false);
        return;
    }

} //end of DialogOfConnectCurves

class ExtCurveAction extends AbstractAction  implements WindowListener {
    //CrossCurvePT[] crossPTs=null;
    ExtendCurve dialog=null;
    int debug=0;
    
    public ExtCurveAction(ExtendCurve dialog){
        this.dialog=dialog;
    }
    
    public void actionPerformed(ActionEvent e) {
        //int debug=MenuUtil.debug;
        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("- ExtCurveAction.actionPerformed  " +
                "commandName="+commandName+
                ", source component name="+componentName+
                ", source class simple name="+componentClassName);

        if(commandName.equals("Go")){
            this.extendCurve();
            //this.endProcess();
            ObjectTable.getDrawPanel().repaint("extend curve");
            return;   
        }

        if(commandName.equals("Cancel")){
            this.dialog.closeDialog();
            return;
        }
    }//End of actionPerformed

    public void extendCurve(){
        ContainerManager containerManager=ObjectTable.getContainerManager("");
        ShapeContainer[] containers=new ShapeContainer[1];
        MouseHitShape mouseHitShape=this.dialog.getMouseHitShape();
        ShapeContainer targetCurve=mouseHitShape.getShapeContainer();
        containers[0]=targetCurve;
        containerManager.undoSetupStart(containers);
        int size = 0;
        if (containers != null) {
            size = containers.length;
        }
        for (int i = 0; i < size; i++) {
            containers[i].setChangeCode(UndoConstants.SHAPE);
        }
        ShapeContainer extContainer=
                this.extendCurveExec(targetCurve, this.dialog.getClickedPoint());
        if(extContainer!=null){
            targetCurve.setChangeCode(UndoConstants.SHAPE);
            containerManager.deleteContainer(targetCurve);
            containerManager.addContainer(extContainer);
           //----------------------------------//
            containerManager.undoSetupEnd();
           //----------------------------------//
        }
        extContainer.setSelected(true);
        this.dialog.closeDialog();
    }
    
    public ShapeContainer extendCurveExec(ShapeContainer container, Point2D PT){
        if(debug>0) System.out.println("extendCurveExec container="+container.getShapeId()+
                ", point="+Util.Pt(PT));
        int type=container.getElement().getTypeE();
        Curve2D curve=container.getElement().getCurve2D();
        //System.out.println("ExtendCurve curve : "+curve.toString());
        int numseg=curve.getNumOfSegments();
        Point2D p0=curve.getP(0);
        Point2D p1=curve.getP(numseg);
        int pos=0;
        if(Vector2D.dist(PT, p0)>Vector2D.dist(PT, p1)) pos=1;
        Curve2D extCurve=Curve2DUtil.extendCurve2DByPT(curve, PT);
        if(extCurve==null){
            String str="   Selected curve can't be extended."
                    + "\n   The clicked target position is bad !";
            this.dialog.showMessage(str, Color.RED);
            this.dialog.getGoButton().setEnabled(false);
            return null;
        }
        ShapeElement extElement = null;
        if (type == Command.LINE) {
            extElement = new LineElement();
        }
        if (type == Command.POLYLINE) {
            extElement = new PolylineElement();
        }
        if (type == Command.CUBIC_CURVE) {
            extElement = new CubicCurveElement();
        }
        if (type == Command.GENERAL_CURVE) {
            extElement = new GeneralCurveElement();
        }
        ShapeContainer extContainer=new ShapeContainer();
        extElement.setCurve2D(extCurve);
        if(debug>0) System.out.println("ExtendCurve extElement:"+extElement.toString());
        extContainer.setElement(extElement);
        extElement.setShapeContainer(extContainer);

        PaintStyle paintStyle=container.getPaintStyle();
        extContainer.setPaintStyle((PaintStyle)paintStyle.clone());
        ContainerManager manager=ObjectTable.getContainerManager();
        extContainer.setNewShapeId(manager, false);
        extContainer.setSelected(true);
        if(debug>0) System.out.println("extContainer:"+extContainer.toString());
        return extContainer;
    }
/*
    private void endProcess(){
      //-----------------------------------------------------//
        SelectionLS selectionLS=ObjectTable.getSelectionLS("");
        selectionLS.resetReceiver();
      //-----------------------------------------------------//
        this.dialog.showMessage("  Done.", Color.BLUE);
        this.dialog.goButton.setEnabled(false);
        this.dialog.continueButton.setEnabled(true);
    }
*/
    public void windowActivated(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}
    public void windowClosing(WindowEvent e) {
        this.dialog.closeDialog();
    }
    public void windowDeactivated(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowOpened(WindowEvent e) {}

} // end of class