import vtk
from numpy import *

from fsFlatASCIIReader import loadFSPatchASCII
from fsFlatIO import readFSCurvData
from fsFlatGenerateLUT import generateLUT

def loadFsFlatAnatomy(pointfile=None, curvfile=None):
    # SURFACE DATA

    #create a vtk point array to hold our points
    inputPoints = vtk.vtkPoints()

    #load the flat file
    coords, polys = loadFSPatchASCII(pointfile)

    inputPoints = vtk.vtkPoints()
    #read in the data to the point array
    for i in range(len(coords)):
        #append to points list
        inputPoints.InsertPoint(i,coords[i,:])

    triangles = vtk.vtkCellArray()
    for i in range(len(polys)):
      ##Create a triangle
      
        triangle = vtk.vtkTriangle()
        triangle.GetPointIds().SetId(0, polys[i,0]);
        triangle.GetPointIds().SetId(1, polys[i,1]);
        triangle.GetPointIds().SetId(2, polys[i,2]);
        triangles.InsertNextCell(triangle)

    ### HANDLE CURVATURE DATA
    #now extract the scalar values representing curvature
    curv = readFSCurvData(curvfile)
    
    #cant handle neg vals so must transpose
    curv = curv - curv.min()
    np_curv_Scalars = curv

    vtk_curv_scalars = vtk.vtkFloatArray()
    for val in np_curv_Scalars:
        vtk_curv_scalars.InsertNextValue(val)

    #construct a polydata object
    curv_polydata = vtk.vtkPolyData();
    curv_polydata.SetPoints(inputPoints);
    curv_polydata.SetPolys(triangles);
    curv_polydata.GetPointData().SetScalars(vtk_curv_scalars)

    # .. and a mapper
    curv_surfMapper = vtk.vtkPolyDataMapper()
    curv_surfMapper.SetInput(curv_polydata)
    curv_surfMapper.SetUseLookupTableScalarRange(1)

    # .. and an actor
    curv_surfActor = vtk.vtkActor()
    curv_surfActor.SetMapper(curv_surfMapper)


    HSVA_start = [0.0,0.0,1.0,1.0] #White
    HSVA_end = [0.0,0.0,0.0,1.0] #black

    RGBA_start = [255.0, 255.0, 255.0, 1.0] #white
    RGBA_end = [0.0, 0.0, 0.0, 1.0] #black

    #lets construct a metadata holder that allows us to track info about each surface, inlcuding:
    #  append the data to the list and add labels such that:
    #   .dataIndex = index position of corresponding data in loadedData
    #   .dataPath = path to original data source
    #   .listPos = physical position in list and thus layer depth (allows depth rendering)
    #   .listTxt = text description in list
    #   .dataMax = max value in scalar range of data
    #   .dataMin = min value in scalar range of data
    #   .lutStartColor = [H S V A] colour
    #   .lutEndColor = [H S V A] colour
    #   .lutBinary = 0 or 1 -> use a binary colormap? (useful for curvature data)
    #   .lutBinaryCutOff = Scalar val to define midpoint of binary range
    #   .lutVisibleScalarRange = current usr set lower and upper bound of visible scalar values
    #   .visibleState = currently on/off



    curv_surfActor.meta = {}
    curv_surfActor.meta['dataIndex'] = 0
    curv_surfActor.meta['dataPath'] = pointfile
    curv_surfActor.meta['listPos'] = 0
    curv_surfActor.meta['listTxt'] = 'Anatomical surface' 
    curv_surfActor.meta['dataMax'] = curv.max()
    curv_surfActor.meta['dataMin'] = curv.min()
    curv_surfActor.meta['lutHSVAStartColor'] = HSVA_start
    curv_surfActor.meta['lutHSVAEndColor'] = HSVA_end
    curv_surfActor.meta['lutRGBAStartColor'] = RGBA_start
    curv_surfActor.meta['lutRGBAEndColor'] = RGBA_end
    curv_surfActor.meta['lutBinary'] = False
    curv_surfActor.meta['lutBinaryCutOff'] = curv.max()/2.0
    curv_surfActor.meta['lutVisibleScalarRange'] = [0.0,np_curv_Scalars.max()]    
    curv_surfActor.meta['visibleState'] = True
    curv_surfActor.meta['originalScalarArray'] = np_curv_Scalars

    curv_surfActor.GetProperty().SetOpacity(0.999)
    
    #create a lookupTbale for the curv data
    curv_lu = generateLUT(HSVA_start, HSVA_end, curv_surfActor.meta['lutVisibleScalarRange'])
    curv_surfMapper.SetLookupTable(curv_lu)

    return curv_surfActor, vtk_curv_scalars



