package cz.fidentis.analyst.icp;

import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.mesh.core.MeshFacetImpl;
import cz.fidentis.analyst.mesh.core.MeshPoint;
import cz.fidentis.analyst.mesh.core.MeshTriangle;
import cz.fidentis.analyst.mesh.core.TriangleFan;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.vecmath.Point3d;

/**
 * Fast adapter to the MeshFacet which reduces the number of vertices used for the ICP computation.
 * The reduction is driven by the undersampling strategy. The most of the original 
 * {@code MeshFacet} methods are not usable anymore.
 * 
 * @author Radek Oslejsek
 */
public class UndersampledMeshFacet extends MeshFacetImpl {
    
    private final List<MeshPoint> reducedVertices;
    
    /**
     * Constructor.
     * 
     * @param origFacet Original facet
     * @param strategy Undersampling strategy
     */
    public UndersampledMeshFacet(MeshFacet origFacet, UndersamplingStrategy strategy) {
        if (origFacet == null) {
            throw new IllegalArgumentException("origFacet");
        }
        
        if (strategy == null) {
            throw new IllegalArgumentException("strategy");
        }
        
        this.reducedVertices = strategy.reduceMeshVertices(origFacet.getVertices());
    }
    
    @Override
    public MeshPoint getVertex(int index) {
        return reducedVertices.get(index);
    }

    /**
     * This method is not supported.
     * 
     * @param point Mesh point
     */
    @Override
    public void addVertex(MeshPoint point) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getNumberOfVertices() {
        return reducedVertices.size();
    }

    @Override
    public List<MeshPoint> getVertices() {
        return Collections.unmodifiableList(reducedVertices);
    }

    /**
     * This method is not supported
     */
    @Override
    public synchronized void calculateVertexNormals() {
       throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @return 
     */
    @Override
    public int getNumTriangles() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     */
    @Override
    public List<MeshTriangle> getTriangles() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @param vertexIndex
     * @return
     */
    @Override
    public List<MeshTriangle> getAdjacentTriangles(int vertexIndex) {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @param point
     * @param vertexIndex
     * @return 
     */
    @Override
    public Point3d getClosestAdjacentPoint(Point3d point, int vertexIndex) {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @param point
     * @param vertexIndex
     * @return 
     */
    @Override
    public double curvatureDistance(Point3d point, int vertexIndex) {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @return 
     */
    @Override
    public Iterator<MeshTriangle> iterator() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @return 
     */
    @Override
    public List<Point3d> calculateVoronoiPoints() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @param vertexIndex
     * @return 
     */
    @Override
    public TriangleFan getOneRingNeighborhood(int vertexIndex) {
        throw new UnsupportedOperationException();
    }
    
    /**
     * This method is not supported
     * @return 
     */
    @Override
    public boolean simplify() {
        throw new UnsupportedOperationException();
    }
    
}
