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

package shapeUtil;

import DrawTop.DrawParameters;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import DrawTop.*;
import shape.*;
import util.*;

public class ModifyShapeLS implements MouseListener, MouseMotionListener{
     ShapeContainer shapeContainer=null;
     ConnectionUtil connectionUtil=new ConnectionUtil();
     int command=Command.MOVE;
     Point2D startPoint=null; 
     Point2D endPoint=null;
     Point2D oldPoint=null;
     DiscreteAngledLine angledLine=null;
     Vector workVector=new Vector();
     public int debug=0;
     
    public ModifyShapeLS(){}
    
    public void start(ShapeContainer shapeContainer){
        DrawParameters.MODE=Command.MODIFYING_SHAPE_MODE;
        ContainerManager containerManager=ObjectTable.getContainerManager("");
        this.shapeContainer=shapeContainer;
        ListenerPanel listenerPanel=ObjectTable.getListenerPanel("ModifyShapeLS");
        listenerPanel=ObjectTable.getListenerPanel("ModifyShapeLS");
        listenerPanel.addMouseListener(this);
        listenerPanel.addMouseMotionListener(this);
        SelectionLS selectionLS=ObjectTable.getSelectionLS();
        selectionLS.end();
/*------------------------------------------------------------------------------*/
        int type=shapeContainer.getElement().getTypeE();
        if(type!=Command.ROUND_RECTANGLE){
            ShapeElement element=shapeContainer.getElement();
            GeneralCurveElement gelement=element.getGeneralCurveElement();
            this.shapeContainer.setElement(gelement);
            this.shapeContainer.setNewShapeId(containerManager, true);
            if(debug>0) {
                String str="\n - ModifyShapeLS start shapeContainer:"+this.shapeContainer.toString();
                System.out.println(str);
            }
        }
/*------------------------------------------------------------------------------*/
        ShapeContainer[] targetContainers=new ShapeContainer[1];
        targetContainers[0]=this.shapeContainer;
        this.connectionUtil.setTargets(targetContainers);
        ShapeContainer[] containers=this.connectionUtil.getTargetsAndConnectors();
      //--------------------- undo setup----------------------------------------//
        containerManager.undoSetupStart(containers);
        int size=0;
        if(containers!=null) size=containers.length;
        for(int i=0;i<size;i++) containers[i].setChangeCode(UndoConstants.SHAPE);
      //------------------------------------------------------------------------//  
        this.command=Command.MOVE;
     }
     public void end(){
        if(debug>0) System.out.println(" - ModifyShapeLS end");
        DrawParameters.MODE=Command.NORMAL_MODE;
        ContainerManager containerManager=ObjectTable.getContainerManager("");
        ListenerPanel listenerPanel=ObjectTable.getListenerPanel("ModifyShapeLS");
        listenerPanel.removeMouseListener(this);
        listenerPanel.removeMouseMotionListener(this);
        SelectionLS selectionLS=ObjectTable.getSelectionLS();
        selectionLS.start();
        if(debug>0) {
            String str="\n - ModifyShapeLS end shapeContainer:"+this.shapeContainer.toString();
            System.out.println(str);
        }
        this.connectionUtil.end(); 
      /*-------------------------------------------------------------*/
      /*   breaking a multi-paths-curve to singl-path-curves         */
      /*-------------------------------------------------------------*/  
        boolean formalVersion=ObjectTable.formalVersion;
        if(formalVersion){
            GeneralCurveElement gelement=(GeneralCurveElement)this.shapeContainer.getElement();
            int index=this.shapeContainer.getContainerIndex();
            PaintStyle paintStyle=this.shapeContainer.getPaintStyle();
            String str="** Test Changing to SimpleElements containerIndex="+index;
            ShapeElement[] elements=gelement.getSimpleShapeElements();
            if(elements.length>0){
                ShapeContainer[] newContainers=new ShapeContainer[elements.length];
                for(int i=0;i<elements.length;i++){
                    newContainers[i]=new ShapeContainer();
                    newContainers[i].setElement(elements[i]);
                    newContainers[i].setNewShapeId(containerManager, false);
                    newContainers[i].setPaintStyle((PaintStyle)paintStyle.clone());
                    str+="\n - newContainer["+i+"]: "+newContainers[i].toShortString();
                }
                if(debug>0) System.out.println(str);
                containerManager.deleteContainer(this.shapeContainer);
                for(int i=0;i<elements.length;i++) {
                    containerManager.addContainer(index, newContainers[i]);
                }
            }
        }
      /*--------------------------------------------------------------------------*/
      //----------------------------------//
        containerManager.undoSetupEnd();
      //----------------------------------// 
    }

    public void setCommand(int command){
        this.command=command;
        ContainerManager containerManager=ObjectTable.getContainerManager();
       //-----------------------------------------------------------------------//
        containerManager.undoSetupEnd();
       //-----------------------------------------------------------------------//  
        ShapeContainer[] containers=this.connectionUtil.getTargetsAndConnectors();
        containerManager.undoSetupStart(containers);
        for(int i=0;i<containers.length;i++) containers[i].setChangeCode(UndoConstants.SHAPE);
       //-----------------------------------------------------------------------//  
    }
    
    public void mousePressed(MouseEvent e) {
        //System.out.println("** ModifyShapeLS mousePressed");
        double scale=DrawParameters.getScale();
        double X = e.getX()/scale;
        double Y = e.getY()/scale;
        int key=e.getModifiersEx();
        int ctrl=0;
        if((key&InputEvent.SHIFT_DOWN_MASK)!=0) ctrl=1;
        if((key&InputEvent.CTRL_DOWN_MASK)!=0) ctrl=2;
        if((key&InputEvent.BUTTON2_DOWN_MASK)!=0) ctrl=3;
        if((key&InputEvent.BUTTON3_DOWN_MASK)!=0) ctrl=3;
        //this.ctrl=ctrl;
        this.startPoint=new Point2D.Double(X,Y);
        this.oldPoint=new Point2D.Double(X,Y);
        this.shapeContainer.getElement().mouseStart(ctrl, this.startPoint);
        this.angledLine=new DiscreteAngledLine(0.0, 90.0, this.startPoint);
    /*----------------------------------------------------------------*/
    /* The next step must be called if the topology has been changed  */
        this.connectionUtil.getTargetsAndConnectors();
    /*----------------------------------------------------------------*/
        ObjectTable.getDrawPanel().repaint("ModifyShape");
     }
     
    public void mouseDragged(MouseEvent e) {
        //System.out.println("** ModifyShapeLS mouseDragged");
        if(this.command!=Command.MOVE) return;
        double scale=DrawParameters.getScale();
        double X = e.getX()/scale;
        double Y = e.getY()/scale;
        int key=e.getModifiersEx();
        int ctrl=0;
        if((key&InputEvent.SHIFT_DOWN_MASK)!=0) ctrl=1;
        if((key&InputEvent.CTRL_DOWN_MASK)!=0) ctrl=2;

        this.endPoint=new Point2D.Double(X,Y);
        ShapeElement shapeElement=this.shapeContainer.getElement();
        Point2D oldPT=this.angledLine.getControlledPT(ctrl, this.oldPoint);
        Point2D endPT=this.angledLine.getControlledPT(ctrl, this.endPoint);
        shapeElement.modify(ctrl, oldPT, endPT);
      //connector resize option  
        int connectorResizeOption=DrawParameters.AUTO_TRACKING_OPTION;
        if(debug>0) System.out.println("** connectorResizeOption="+connectorResizeOption);
        this.connectionUtil.resizeConnectors(connectorResizeOption);
        this.oldPoint=(Point2D)this.endPoint.clone();
        ObjectTable.getDrawPanel().repaint("ModifyShape");
    } //mouseDragged


    public void mouseReleased(MouseEvent e) {
        this.startPoint=null;
        this.endPoint=null;
        this.oldPoint=null;
        this.shapeContainer.getElement().mouseEnd();
        ObjectTable.getDrawPanel().repaint("ModifyShape");
    } 
    
    public void mouseClicked(MouseEvent e) {
        if(debug>0) System.out.println("** ModifyShapeLS mouseClicked this.command="
                +Command.getCommandString(this.command));
        double scale=DrawParameters.getScale();
        double X = e.getX()/scale;
        double Y = e.getY()/scale;

        Point2D point=new Point2D.Double(X,Y);
        ShapeElement shapeElement=this.shapeContainer.getElement();
        int type=shapeElement.getTypeE();
        if(this.command==Command.ADD_POINT){
            shapeElement.modifyPoint(point,"add_point");
        }
        if(this.command==Command.DELETE_POINT){
            shapeElement.modifyPoint(point,"delete_point");
           //connector resize option  
            int connectorResizeOption=Command.TO_NEAREST_PT;
            if(debug>0) System.out.println("** connectorResizeOption="+connectorResizeOption);
            this.connectionUtil.resizeConnectors(connectorResizeOption);
         }
        if(this.command==Command.SMOOTH){
            shapeElement.modifyPoint(point,"smooth");
        }
        if(this.command==Command.CUSP){
            shapeElement.modifyPoint(point,"cusp");
        }
        if(this.command==Command.DISCONNECT){
            System.out.println("ModifyLS disconnect");
            shapeElement.modifyPoint(point,"disconnect");
           //connector resize option  
            int connectorResizeOption=Command.TO_NEAREST_PT;
            if(debug>=0) System.out.println("** connectorResizeOption="
                    +Command.getCommandString(connectorResizeOption));
            this.connectionUtil.resizeConnectors(connectorResizeOption);
        }
        //DrawPanel drawPanel=ObjectTable.getDrawPanel("ModifyShapeLS");
        ObjectTable.getDrawPanel().repaint("ModifyShape");
    } //if(type.equals("MOUSECLICKED"))


    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {} 
} //end of ModifyShapeLS
