import * as Inputs from "../../api/inputs/inputs";
export class ShapeGettersService {
    constructor(occ, enumService, iteratorService) {
        this.occ = occ;
        this.enumService = enumService;
        this.iteratorService = iteratorService;
    }
    getNumSolidsInCompound(shape) {
        if (!shape ||
            this.enumService.getShapeTypeEnum(shape) !== Inputs.OCCT.shapeTypeEnum.compound ||
            shape.IsNull()) {
            throw new Error("Shape is not a compound or is null.");
        }
        let solidsFound = 0;
        this.iteratorService.forEachSolid(shape, () => { solidsFound++; });
        return solidsFound;
    }
    getSolidFromCompound(shape, index) {
        if (!shape ||
            shape.ShapeType() > this.occ.TopAbs_ShapeEnum.TopAbs_COMPSOLID ||
            shape.IsNull()) {
            console.error("Not a compound shape!");
            return shape;
        }
        if (!index) {
            index = 0;
        }
        let innerSolid = shape;
        let solidsFound = 0;
        this.iteratorService.forEachSolid(shape, (i, s) => {
            if (i === index) {
                innerSolid = this.occ.TopoDS.Solid_1(s);
            }
            solidsFound++;
        });
        if (solidsFound === 0) {
            console.error("NO SOLIDS FOUND IN SHAPE!");
        }
        innerSolid.hash = shape.hash + 1;
        return innerSolid;
    }
    getEdges(inputs) {
        if (inputs.shape && this.enumService.getShapeTypeEnum(inputs.shape) === Inputs.OCCT.shapeTypeEnum.edge) {
            return [inputs.shape];
        }
        if (!inputs.shape || inputs.shape.IsNull()) {
            throw (new Error("Shape is not provided or is of incorrect type"));
        }
        const edges = [];
        this.iteratorService.forEachEdge(inputs.shape, (i, edge) => {
            edges.push(edge);
        });
        return edges;
    }
    getEdge(inputs) {
        if (!inputs.shape || (inputs.shape.ShapeType && inputs.shape.ShapeType() > this.occ.TopAbs_ShapeEnum.TopAbs_WIRE) || inputs.shape.IsNull()) {
            throw (new Error("Edge can not be found for shape that is not provided or is of incorrect type"));
        }
        if (!inputs.index) {
            inputs.index = 0;
        }
        let innerEdge = {};
        let foundEdge = false;
        this.iteratorService.forEachEdge(inputs.shape, (i, s) => {
            if (i === inputs.index) {
                innerEdge = s;
                foundEdge = true;
            }
        });
        if (!foundEdge) {
            throw (new Error(`Edge can not be found for shape on index ${inputs.index}`));
        }
        else {
            return innerEdge;
        }
    }
    getWires(inputs) {
        const wires = [];
        this.iteratorService.forEachWire(inputs.shape, (wireIndex, myWire) => {
            wires.push(myWire);
        });
        return wires;
    }
    getWire(inputs) {
        if (!inputs.shape || inputs.shape.IsNull()) {
            throw (new Error("Shape is not provided or is null"));
        }
        const shapeType = this.enumService.getShapeTypeEnum(inputs.shape);
        if ((shapeType === Inputs.OCCT.shapeTypeEnum.wire ||
            shapeType === Inputs.OCCT.shapeTypeEnum.edge ||
            shapeType === Inputs.OCCT.shapeTypeEnum.vertex)) {
            throw (new Error("Shape is of incorrect type"));
        }
        if (!inputs.index) {
            inputs.index = 0;
        }
        let innerWire;
        this.iteratorService.forEachWire(inputs.shape, (i, s) => {
            if (i === inputs.index) {
                innerWire = this.occ.TopoDS.Wire_1(s);
            }
        });
        if (!innerWire) {
            throw (Error("Wire not found"));
        }
        return innerWire;
    }
    getFaces(inputs) {
        const faces = [];
        this.iteratorService.forEachFace(inputs.shape, (faceIndex, myFace) => {
            faces.push(myFace);
        });
        return faces;
    }
    getSolids(inputs) {
        const solids = [];
        this.iteratorService.forEachSolid(inputs.shape, (faceIndex, myFace) => {
            solids.push(myFace);
        });
        return solids;
    }
    getFace(inputs) {
        if (!inputs.shape || inputs.shape.IsNull()) {
            throw new Error("Shape is not provided or is null");
        }
        const shapeType = this.enumService.getShapeTypeEnum(inputs.shape);
        if (shapeType === Inputs.OCCT.shapeTypeEnum.wire ||
            shapeType === Inputs.OCCT.shapeTypeEnum.edge ||
            shapeType === Inputs.OCCT.shapeTypeEnum.vertex) {
            throw (new Error("Shape is of incorrect type"));
        }
        if (!inputs.index) {
            inputs.index = 0;
        }
        let innerFace = {};
        let facesFound = 0;
        this.iteratorService.forEachFace(inputs.shape, (i, s) => {
            if (i === inputs.index) {
                innerFace = this.occ.TopoDS.Face_1(s);
            }
            facesFound++;
        });
        if (facesFound < inputs.index || inputs.index < 0) {
            throw (new Error("Face index is out of range"));
        }
        else {
            return innerFace;
        }
    }
    getVertices(inputs) {
        if (inputs.shape && this.enumService.getShapeTypeEnum(inputs.shape) === Inputs.OCCT.shapeTypeEnum.vertex) {
            return [inputs.shape];
        }
        if (!inputs.shape || inputs.shape.IsNull()) {
            throw (new Error("Shape is not provided or is of incorrect type"));
        }
        const vertices = [];
        this.iteratorService.forEachVertex(inputs.shape, (i, vertex) => {
            vertices.push(vertex);
        });
        return vertices;
    }
    getShapesOfCompound(inputs) {
        const shapes = [];
        this.iteratorService.forEachShapeInCompound(inputs.shape, (_, shape) => { shapes.push(shape); });
        return shapes;
    }
}
