import { Point } from "@devexpress/utils/lib/geometry/point";
import { PasteSelectionCommandBase } from "./PasteSelectionCommandBase";
import { DiagramItem } from "../../Model/DiagramItem";
import { Shape } from "../../Model/Shapes/Shape";
import { Connector } from "../../Model/Connectors/Connector";
import { DiagramModel } from "../../Model/Model";

export class PasteSelectionCommand extends PasteSelectionCommandBase {
    protected getEventPositionOffset(items: DiagramItem[], _evtPosition?: Point): Point {
        const { topLeftItem } = items.reduce((acc, item) => {
            const x = item instanceof Shape ? item.position.x : item instanceof Connector ? item.getMinX() : Number.MAX_VALUE;
            const y = item instanceof Shape ? item.position.y : item instanceof Connector ? item.getMinY() : Number.MAX_VALUE;
            if(y < acc.y || (y === acc.y && x < acc.x)) {
                acc.topLeftItem = item;
                acc.x = x;
                acc.y = y;
            }
            return acc;
        }, {
            topLeftItem: items[0],
            x: Number.MAX_VALUE,
            y: Number.MAX_VALUE
        });
        if(topLeftItem instanceof Shape) {
            const newPoint = this.getShapeCorrectedPosition(this.control.model, topLeftItem);
            return new Point(newPoint.x - topLeftItem.position.x, newPoint.y - topLeftItem.position.y);
        }
        else if(topLeftItem instanceof Connector) {
            const newPoints = this.getConnectorCorrectedPoints(this.control.model, topLeftItem);
            return new Point(topLeftItem.points[0].x - newPoints[0].x, topLeftItem.points[0].y - newPoints[0].y);
        }
    }

    protected getShapeCorrectedPosition(model: DiagramModel, shape: Shape): Point {
        const position = shape.position.clone();
        while(model.findShapeAtPosition(position))
            position.offset(PasteSelectionCommandBase.positionOffset, PasteSelectionCommandBase.positionOffset);
        return position;
    }
    protected getConnectorCorrectedPoints(model: DiagramModel, connector: Connector): Point[] {
        const points = connector.points.map(p => p.clone());
        while(model.findConnectorAtPoints(points))
            points.forEach(pt => {
                pt.x += PasteSelectionCommandBase.positionOffset;
                pt.y += PasteSelectionCommandBase.positionOffset;
            });
        return points;
    }
}
