// Path: CutletLib/src/main/java/com/cutlet/lib/model/Dimension.java
// @ToString
// public class Dimension implements Serializable{
// 
//     private double length;
//     private double width;
// 
//     public Dimension(final double length, final double width) {
//         this.length = length;
//         this.width = width;
//     }
// 
//     public double getLength() {
//         return length;
//     }
// 
//     public void setLength(final double length) {
//         this.length = length;
//     }
// 
//     public double getWidth() {
//         return width;
//     }
// 
//     public void setWidth(final double width) {
//         this.width = width;
//     }
// 
//     public double getArea() {
//         return getLength() * getWidth();
//     }
// 
//     public boolean canHold(@NonNull final Dimension other) {
//         return other.getLength() <= this.getLength() && other.getWidth() <= this.getWidth();
//     }    
//     
//     public Dimension rotated() {
//         return new Dimension(width, length);
//     }
// }
// 
// Path: CutletLib/src/main/java/com/cutlet/lib/model/PanelInstance.java
// @ToString(exclude = "sheet")
// public class PanelInstance implements Serializable {
// 
//     private final String title;
//     private final StockSheet sheet;
//     private final Dimension dimension;
//     private final boolean canRotate;
//     private final int instanceId;
// 
//     public String getTitle() {
//         return title;
//     }
// 
//     public PanelInstance(@NonNull final StockSheet sheet,
//             @NonNull final Dimension dimension,
//             @NonNull final String title,
//             final int instanceId,
//             final boolean canRotate) {
// 
//         this.sheet = sheet;
//         this.title = title;
//         this.dimension = dimension;
//         this.canRotate = canRotate;
//         this.instanceId = instanceId;
// 
//         if (dimension.getWidth() > sheet.getDimension().getWidth() || dimension.getLength() > sheet.getDimension().getLength()) {
//             throw new RuntimeException("panel too large for sheet");
//         }
//     }
// 
//     public StockSheet getSheet() {
//         return sheet;
//     }
// 
//     public Dimension getDimension() {
//         return dimension;
//     }
// 
//     public int getInstanceId() {
//         return instanceId;
//     }
// }
// 
// Path: CutletLib/src/main/java/com/cutlet/lib/model/Position.java
// @ToString
// public class Position implements Serializable {
// 
//     private double x, y;
// 
//     public Position(final double x, final double y) {
//         this.x = x;
//         this.y = y;
//     }
// 
//     public double getX() {
//         return x;
//     }
// 
//     public void setX(final double x) {
//         this.x = x;
//     }
// 
//     public double getY() {
//         return y;
//     }
// 
//     public void setY(final double y) {
//         this.y = y;
//     }
// 
// }


import com.cutlet.lib.model.Position;
import lombok.NonNull;
import com.cutlet.lib.model.Dimension;
import com.cutlet.lib.model.PanelInstance;

/*
 * Copyright (C) 2017 rudolf.muehlbauer@gmail.com
 */

package com.cutlet.lib.data.cuttree;


/**
 *
 * @author rmuehlba
 */
public class FreeNode extends AbstractCutTreeNode {

    public FreeNode(@NonNull CutTreeNode parent, @NonNull Position position, @NonNull Dimension dimension) {
        super(parent, position, dimension);
    }

    @Override
    public void replaceChild(@NonNull CutTreeNode from, @NonNull CutTreeNode to) {
        throw new UnsupportedOperationException("Not supported: Freepanel.replace.");
    }

    public CutNode cut(double bladeWidth, double cutPosition, @NonNull CutNode.Direction direction) {
        final CutTreeNode parent = this.getParent();
        final CutNode cut = new CutNode(parent,
                bladeWidth, cutPosition, direction,
                getPosition(),
                getDimension());

        parent.replaceChild(this, cut);

        return cut;
    }


// Path: CutletLib/src/main/java/com/cutlet/lib/model/Dimension.java
// @ToString
// public class Dimension implements Serializable{
// 
//     private double length;
//     private double width;
// 
//     public Dimension(final double length, final double width) {
//         this.length = length;
//         this.width = width;
//     }
// 
//     public double getLength() {
//         return length;
//     }
// 
//     public void setLength(final double length) {
//         this.length = length;
//     }
// 
//     public double getWidth() {
//         return width;
//     }
// 
//     public void setWidth(final double width) {
//         this.width = width;
//     }
// 
//     public double getArea() {
//         return getLength() * getWidth();
//     }
// 
//     public boolean canHold(@NonNull final Dimension other) {
//         return other.getLength() <= this.getLength() && other.getWidth() <= this.getWidth();
//     }    
//     
//     public Dimension rotated() {
//         return new Dimension(width, length);
//     }
// }
// 
// Path: CutletLib/src/main/java/com/cutlet/lib/model/PanelInstance.java
// @ToString(exclude = "sheet")
// public class PanelInstance implements Serializable {
// 
//     private final String title;
//     private final StockSheet sheet;
//     private final Dimension dimension;
//     private final boolean canRotate;
//     private final int instanceId;
// 
//     public String getTitle() {
//         return title;
//     }
// 
//     public PanelInstance(@NonNull final StockSheet sheet,
//             @NonNull final Dimension dimension,
//             @NonNull final String title,
//             final int instanceId,
//             final boolean canRotate) {
// 
//         this.sheet = sheet;
//         this.title = title;
//         this.dimension = dimension;
//         this.canRotate = canRotate;
//         this.instanceId = instanceId;
// 
//         if (dimension.getWidth() > sheet.getDimension().getWidth() || dimension.getLength() > sheet.getDimension().getLength()) {
//             throw new RuntimeException("panel too large for sheet");
//         }
//     }
// 
//     public StockSheet getSheet() {
//         return sheet;
//     }
// 
//     public Dimension getDimension() {
//         return dimension;
//     }
// 
//     public int getInstanceId() {
//         return instanceId;
//     }
// }
// 
// Path: CutletLib/src/main/java/com/cutlet/lib/model/Position.java
// @ToString
// public class Position implements Serializable {
// 
//     private double x, y;
// 
//     public Position(final double x, final double y) {
//         this.x = x;
//         this.y = y;
//     }
// 
//     public double getX() {
//         return x;
//     }
// 
//     public void setX(final double x) {
//         this.x = x;
//     }
// 
//     public double getY() {
//         return y;
//     }
// 
//     public void setY(final double y) {
//         this.y = y;
//     }
// 
// }


// Path: CutletLib/src/main/java/com/cutlet/lib/data/cuttree/FreeNode.java
import com.cutlet.lib.model.Position;
import lombok.NonNull;
import com.cutlet.lib.model.Dimension;
import com.cutlet.lib.model.PanelInstance;

/*
 * Copyright (C) 2017 rudolf.muehlbauer@gmail.com
 */

package com.cutlet.lib.data.cuttree;


/**
 *
 * @author rmuehlba
 */
public class FreeNode extends AbstractCutTreeNode {

    public FreeNode(@NonNull CutTreeNode parent, @NonNull Position position, @NonNull Dimension dimension) {
        super(parent, position, dimension);
    }

    @Override
    public void replaceChild(@NonNull CutTreeNode from, @NonNull CutTreeNode to) {
        throw new UnsupportedOperationException("Not supported: Freepanel.replace.");
    }

    public CutNode cut(double bladeWidth, double cutPosition, @NonNull CutNode.Direction direction) {
        final CutTreeNode parent = this.getParent();
        final CutNode cut = new CutNode(parent,
                bladeWidth, cutPosition, direction,
                getPosition(),
                getDimension());

        parent.replaceChild(this, cut);

        return cut;
    }


    public PanelNode setPanel(@NonNull PanelInstance panel) {
