import * as Inputs from "../../api/inputs/inputs";
export class EntitiesService {
    constructor(occ) {
        this.occ = occ;
    }
    createCircle(radius, center, direction, type) {
        const circle = this.gcMakeCircle(center, direction, radius);
        if (type === Inputs.OCCT.typeSpecificityEnum.curve) {
            return circle;
        }
        else {
            const edge = this.bRepBuilderAPIMakeEdge(circle);
            if (type === Inputs.OCCT.typeSpecificityEnum.edge) {
                return edge;
            }
            else {
                const circleWire = this.bRepBuilderAPIMakeWire(edge);
                if (type === Inputs.OCCT.typeSpecificityEnum.wire) {
                    edge.delete();
                    return circleWire;
                }
                else if (type === Inputs.OCCT.typeSpecificityEnum.face) {
                    const face = this.bRepBuilderAPIMakeFaceFromWire(circleWire, true);
                    return face;
                }
            }
        }
        return circle;
    }
    createEllipse(minorRadius, majorRadius, center, direction, type) {
        const ellipse = this.gcMakeEllipse(center, direction, minorRadius, majorRadius);
        if (type === Inputs.OCCT.typeSpecificityEnum.curve) {
            return ellipse;
        }
        else {
            const edge = this.bRepBuilderAPIMakeEdge(ellipse);
            if (type === Inputs.OCCT.typeSpecificityEnum.edge) {
                return edge;
            }
            else {
                const ellipseWire = this.bRepBuilderAPIMakeWire(edge);
                if (type === Inputs.OCCT.typeSpecificityEnum.wire) {
                    edge.delete();
                    return ellipseWire;
                }
                else if (type === Inputs.OCCT.typeSpecificityEnum.face) {
                    const face = this.bRepBuilderAPIMakeFaceFromWire(ellipseWire, true);
                    return face;
                }
            }
        }
        return ellipse;
    }
    makeVertex(pt) {
        const gpPnt = this.gpPnt(pt);
        const vert = new this.occ.BRepBuilderAPI_MakeVertex(gpPnt);
        const vrt = vert.Vertex();
        gpPnt.delete();
        vert.delete();
        return vrt;
    }
    gpPnt2d(point) {
        return new this.occ.gp_Pnt2d_3(point[0], point[1]);
    }
    gpPnt(point) {
        return new this.occ.gp_Pnt_3(point[0], point[1], point[2]);
    }
    gpVec(vec) {
        return new this.occ.gp_Vec_4(vec[0], vec[1], vec[2]);
    }
    gpXYZ(point) {
        return new this.occ.gp_XYZ_2(point[0], point[1], point[2]);
    }
    gpVec2d(vec) {
        return new this.occ.gp_Vec2d_4(vec[0], vec[1]);
    }
    gpDir(direction) {
        return new this.occ.gp_Dir_4(direction[0], direction[1], direction[2]);
    }
    gpDir2d(direction) {
        return new this.occ.gp_Dir2d_4(direction[0], direction[1]);
    }
    gcMakeCircle(center, direction, radius) {
        const circle = new this.occ.GC_MakeCircle_2(this.gpAx2(center, direction), radius);
        const cirVal = circle.Value();
        const cir = cirVal.get();
        circle.delete();
        return cir;
    }
    gcMakeEllipse(center, direction, minorRadius, majorRadius) {
        const ax = this.gpAx2(center, direction);
        const ellipse = new this.occ.GC_MakeEllipse_2(ax, majorRadius, minorRadius);
        if (ellipse.IsDone()) {
            const ellipseVal = ellipse.Value();
            const ell = ellipseVal.get();
            ellipse.delete();
            ax.delete();
            return ell;
        }
        else {
            throw new Error("Ellipse could not be created.");
        }
    }
    bRepBuilderAPIMakeEdge(curve) {
        const crv = this.castToHandleGeomCurve(curve);
        const edge = new this.occ.BRepBuilderAPI_MakeEdge_24(crv);
        const ed = edge.Edge();
        edge.delete();
        crv.delete();
        return ed;
    }
    bRepBuilderAPIMakeWire(edge) {
        const wire = new this.occ.BRepBuilderAPI_MakeWire_2(edge);
        const w = wire.Wire();
        wire.delete();
        return w;
    }
    bRepBuilderAPIMakeShell(face) {
        const srf = this.occ.BRep_Tool.Surface_2(face);
        const makeShell = new this.occ.BRepBuilderAPI_MakeShell_2(srf, false);
        const shell = makeShell.Shell();
        makeShell.delete();
        srf.delete();
        return shell;
    }
    bRepBuilderAPIMakeFaceFromWires(wires, planar, guideFace, inside) {
        let face;
        const faces = [];
        wires.forEach(currentWire => {
            if (faces.length > 0) {
                const faceBuilder = new this.occ.BRepBuilderAPI_MakeFace_22(faces[faces.length - 1], currentWire);
                faces.push(faceBuilder.Face());
                faceBuilder.delete();
            }
            else {
                let faceBuilder;
                if (!guideFace) {
                    faceBuilder = new this.occ.BRepBuilderAPI_MakeFace_15(currentWire, planar);
                }
                else {
                    const surface = this.occ.BRep_Tool.Surface_2(guideFace);
                    faceBuilder = new this.occ.BRepBuilderAPI_MakeFace_21(surface, currentWire, inside);
                }
                faces.push(faceBuilder.Face());
                faceBuilder.delete();
            }
        });
        if (faces.length > 0) {
            face = faces.pop();
            faces.forEach(f => f.delete());
        }
        return face;
    }
    bRepBuilderAPIMakeFaceFromWire(wire, planar) {
        const faceMaker = new this.occ.BRepBuilderAPI_MakeFace_15(wire, planar);
        const face = faceMaker.Face();
        faceMaker.delete();
        return face;
    }
    bRepBuilderAPIMakeFacesFromWiresOnFace(face, wires, inside) {
        const surface = this.occ.BRep_Tool.Surface_2(face);
        const res = wires.map(wire => this.bRepBuilderAPIMakeFaceFromWireOnSurface(surface, wire, inside));
        surface.delete();
        return res;
    }
    bRepBuilderAPIMakeFaceFromWireOnFace(face, wire, inside) {
        const surface = this.occ.BRep_Tool.Surface_2(face);
        const res = this.bRepBuilderAPIMakeFaceFromWireOnSurface(surface, wire, inside);
        surface.delete();
        return res;
    }
    bRepBuilderAPIMakeFaceFromWireOnSurface(surface, wire, inside) {
        const faceMaker = new this.occ.BRepBuilderAPI_MakeFace_21(surface, wire, inside);
        const f = faceMaker.Face();
        faceMaker.delete();
        return f;
    }
    bRepBuilderAPIMakeFaceFromSurface(surface, tolDegen) {
        const hs = new this.occ.Handle_Geom_Surface_2(surface);
        const faceMaker = new this.occ.BRepBuilderAPI_MakeFace_8(hs, tolDegen);
        const face = faceMaker.Face();
        faceMaker.delete();
        hs.delete();
        return face;
    }
    bRepBuilderAPIMakeFaceFromSurfaceAndWire(surface, wire, inside) {
        const hs = new this.occ.Handle_Geom_Surface_2(surface);
        const faceMaker = new this.occ.BRepBuilderAPI_MakeFace_21(hs, wire, inside);
        const face = faceMaker.Face();
        faceMaker.delete();
        hs.delete();
        return face;
    }
    bRepPrimAPIMakeSphere(center, direction, radius) {
        const ax = this.gpAx2(center, direction);
        const sphereMaker = new this.occ.BRepPrimAPI_MakeSphere_9(ax, radius);
        const sphere = sphereMaker.Shape();
        sphereMaker.delete();
        ax.delete();
        return sphere;
    }
    gpAx3_3(point, normal, direction) {
        return new this.occ.gp_Ax3_3(this.gpPnt(point), this.gpDir(normal), this.gpDir(direction));
    }
    gpAx3_4(point, direction) {
        return new this.occ.gp_Ax3_4(this.gpPnt(point), this.gpDir(direction));
    }
    gpAx2(point, direction) {
        return new this.occ.gp_Ax2_3(this.gpPnt(point), this.gpDir(direction));
    }
    gpAx2FromTwoVectors(point, directionFirst, directionSecond) {
        return new this.occ.gp_Ax2_2(this.gpPnt(point), this.gpDir(directionFirst), this.gpDir(directionSecond));
    }
    gpAx1(point, direction) {
        return new this.occ.gp_Ax1_2(this.gpPnt(point), this.gpDir(direction));
    }
    gpAx2d(point, direction) {
        const pt = this.gpPnt2d(point);
        const dir = this.gpDir2d(direction);
        return new this.occ.gp_Ax2d_2(pt, dir);
    }
    gpAx22d(point, direction1, direction2) {
        const pt = this.gpPnt2d(point);
        const dir1 = this.gpDir2d(direction1);
        const dir2 = this.gpDir2d(direction2);
        const ax = new this.occ.gp_Ax22d_2(pt, dir1, dir2);
        dir1.delete();
        dir2.delete();
        pt.delete();
        return ax;
    }
    gpPln(point, direction) {
        const gpPnt = this.gpPnt(point);
        const gpDir = this.gpDir(direction);
        const pln = new this.occ.gp_Pln_3(gpPnt, gpDir);
        gpPnt.delete();
        gpDir.delete();
        return pln;
    }
    bRepPrimAPIMakeCylinder(center, direction, radius, height, angle) {
        const ax = this.gpAx2(center, direction);
        const cylinderMaker = new this.occ.BRepPrimAPI_MakeCylinder_4(ax, radius, height, angle);
        const cylinder = cylinderMaker.Shape();
        cylinderMaker.delete();
        ax.delete();
        return cylinder;
    }
    bRepPrimAPIMakeCylinderBetweenPoints(start, end, radius) {
        const center = this.gpPnt(start);
        const pt = this.gpPnt(end);
        const vec = new this.occ.gp_Vec_5(center, pt);
        const distance = vec.Magnitude();
        const ax = this.gpAx2(start, [vec.X(), vec.Y(), vec.Z()]);
        const cylinderMaker = new this.occ.BRepPrimAPI_MakeCylinder_3(ax, radius, distance);
        const cylinder = cylinderMaker.Shape();
        cylinderMaker.delete();
        ax.delete();
        center.delete();
        pt.delete();
        vec.delete();
        return cylinder;
    }
    bRepPrimAPIMakeBox(width, length, height, center) {
        const pt = this.gpPnt([
            -width / 2 + center[0],
            -height / 2 + center[1],
            -length / 2 + center[2]
        ]);
        const boxMaker = new this.occ.BRepPrimAPI_MakeBox_3(pt, width, height, length);
        const box = boxMaker.Shape();
        boxMaker.delete();
        pt.delete();
        return box;
    }
    castToHandleGeomCurve(curve) {
        return new this.occ.Handle_Geom_Curve_2(curve);
    }
}
