package shape;

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import DrawTop.*;
import util.*;
import geomExtension.*;
import util.UndoConstants;


public class CubicCurveElement extends ShapeElement {

    public CubicCurveElement() {
        super();
    }

//ShapeElement
    public int getTypeE() {
        return Command.CUBIC_CURVE;
    }

    public String getShapeIdString() {
        return "CubicCurve";
    }

    public Rectangle2D createTextArea() {
        if (!this.isClosed()) {
            return null;
        }
        Shape shape = this.getShape();
        double sqrt2 = Math.sqrt(2);
        //---------------------------------------------------------------//
        Rectangle2D textArea = ShapeElementUtil.getInscribedBox(shape, false);
        //---------------------------------------------------------------//
        return textArea;
    }
//ShapeElement
    public SegmentModifier[] getSegmentModifiers(){
        SegmentModifier[] modifiers=new SegmentModifier[0];
        return modifiers;
    }
//ShapeElement
    public Point2D[] getModifierPTs(){
        Point2D[] PTs=new Point2D[0];
        return PTs;
    }

//ShapeElement
    public void create(Rectangle2D boundingBox) {}

    public void create(Point2D startPoint, Point2D currentPoint) {}

    public void create(Point2D[] points) {
        if (points.length >= 2) {
            FergusonCurve2D furgusonCurve = FergusonCurve2D.createNaturalSpline(points);
            this.curve2D = furgusonCurve.getCubicCurve2DE();
        }
    }

    public void moveEndPoint(int ctrl, int movePtIndex, Point2D currentPoint){};

    public void moveEndPoint(int ctrl, int movePtIndex, Point2D oldPoint, Point2D currentPoint) {
        if(ctrl>=3) return;
        this.getShapeContainer().setChangeCode(UndoConstants.SHAPE);
        Point2D newPT = currentPoint;
        Point2D oldPT = oldPoint;
        if (ctrl > 0) {
            newPT = DiscreteAngledLine.getControlledPT(0, 90, oldPoint, newPT);
            oldPT = DiscreteAngledLine.getControlledPT(0, 90, oldPoint, oldPT);
        }
        CubicCurve2DE cubicCurve = (CubicCurve2DE) this.curve2D;
        Point2D[] Q = cubicCurve.getCtrlPoints();
        int size = 0;
        if (Q != null) {
            size = Q.length;
        }
        Point2D[] newQ = new Point2D[size];
        Point2D anchorP = null;
        int numseg = this.curve2D.getNumOfSegments();
        if (movePtIndex == 0) {
            anchorP = this.curve2D.getP(numseg);
        } else {
            anchorP = this.curve2D.getP(0);
        }
        Vector2D r0 = Vector2D.sub(oldPT, anchorP);
        Vector2D r = Vector2D.sub(newPT, anchorP);
        Matrix2D rotationMatrix = Matrix2D.getRotationMatrix(anchorP, r0, r);
        for (int i = 0; i < size; i++) {
            newQ[i] = Matrix2D.transForm(rotationMatrix, Q[i]);
        }
        cubicCurve.setData(newQ);
    }
    
    public void modify(int ctrl, Point2D oldPoint, Point2D currentPoint){};
    public void modifyPoint(Point2D point, String command){};

    public Object clone() {
        CubicCurveElement shapeElement = new CubicCurveElement();
        CubicCurve2DE curve = (CubicCurve2DE) curve2D.clone();
        shapeElement.setCurve2D(curve);
        return shapeElement;
    }
//ShapeElement
    public String toString() {
        String str="";
        if (this.curve2D == null) {
            str += "CubicCurve: not defined";
            return str;
        }
        return this.curve2D.toString();
    }
} 
