export class IteratorService {
    constructor(occ) {
        this.occ = occ;
    }
    forEachWire(shape, callback) {
        let wireIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_WIRE, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_WIRE, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(wireIndex++, this.occ.TopoDS.Wire_2(anExplorer.Current()));
        }
        anExplorer.delete();
    }
    forEachEdge(shape, callback) {
        const edgeHashes = {};
        let edgeIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_EDGE, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_EDGE, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            const edge = this.occ.TopoDS.Edge_1(anExplorer.Current());
            const edgeHash = edge.HashCode(100000000);
            if (!Object.prototype.hasOwnProperty.call(edgeHashes, edgeHash)) {
                edgeHashes[edgeHash] = edgeIndex;
                edgeIndex++;
                callback(edgeIndex, edge);
            }
        }
        anExplorer.delete();
        return edgeHashes;
    }
    forEachEdgeAlongWire(shape, callback) {
        const edgeHashes = {};
        let edgeIndex = 0;
        const anExplorer = new this.occ.BRepTools_WireExplorer_1();
        for (anExplorer.Init_1(shape); anExplorer.More(); anExplorer.Next()) {
            const edge = this.occ.TopoDS.Edge_1(anExplorer.Current());
            const edgeHash = edge.HashCode(100000000);
            if (!Object.prototype.hasOwnProperty.call(edgeHashes, edgeHash)) {
                edgeHashes[edgeHash] = edgeIndex;
                edgeIndex++;
                callback(edgeIndex, edge);
            }
        }
        anExplorer.delete();
        return edgeHashes;
    }
    forEachFace(shape, callback) {
        let faceIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_FACE, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_FACE, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(faceIndex++, this.occ.TopoDS.Face_1(anExplorer.Current()));
        }
        anExplorer.delete();
    }
    forEachShell(shape, callback) {
        let faceIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_SHELL, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_SHELL, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(faceIndex++, this.occ.TopoDS.Shell_1(anExplorer.Current()));
        }
        anExplorer.delete();
    }
    forEachVertex(shape, callback) {
        let faceIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_VERTEX, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_VERTEX, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(faceIndex++, this.occ.TopoDS.Vertex_1(anExplorer.Current()));
        }
        anExplorer.delete();
    }
    forEachSolid(shape, callback) {
        let solidIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_SOLID, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_SOLID, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(solidIndex++, this.occ.TopoDS.Solid_2(anExplorer.Current()));
        }
        anExplorer.delete();
    }
    forEachCompound(shape, callback) {
        let solidIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_COMPOUND, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_COMPOUND, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(solidIndex++, anExplorer.Current());
        }
        anExplorer.delete();
    }
    forEachCompSolid(shape, callback) {
        let solidIndex = 0;
        const anExplorer = new this.occ.TopExp_Explorer_2(shape, this.occ.TopAbs_ShapeEnum.TopAbs_COMPSOLID, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE);
        for (anExplorer.Init(shape, this.occ.TopAbs_ShapeEnum.TopAbs_COMPSOLID, this.occ.TopAbs_ShapeEnum.TopAbs_SHAPE); anExplorer.More(); anExplorer.Next()) {
            callback(solidIndex++, anExplorer.Current());
        }
        anExplorer.delete();
    }
    forEachShapeInCompound(shape, callback) {
        let solidIndex = 0;
        const iterator = new this.occ.TopoDS_Iterator_1();
        for (iterator.Initialize(shape, true, true); iterator.More(); iterator.Next()) {
            callback(solidIndex++, iterator.Value());
        }
        iterator.delete();
    }
}
