from numpy import *

import vtk
from fsFlatIO import readFSScalarData
from fsFlatGenerateLUT import generateLUT
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from numpy import *

def loadFsOverlay(overlay_file_path, anatomyPolyData, new_item_index):

    ### HANDLE SCALAR OVERLAY DATA
    #now extract the scalar values of the overlay
    overlayScalars = readFSScalarData(overlay_file_path)

    overlayScalars_pos = overlayScalars.copy()
    overlayScalars_pos[overlayScalars_pos<=0.0]=0.0

    overlayScalars_neg = overlayScalars.copy()
    overlayScalars_neg[overlayScalars_neg>0.0]=0.0

    if len(overlayScalars_pos)>0:
        pos_overlay_surfActor, pos_overlay_lu, pos_overlayScalars = overlayScalarsToSurface(overlayScalars_pos, anatomyPolyData, new_item_index, overlay_file_path, 'pos')


    if len(overlayScalars_neg)>0:
        neg_or_not = dialogNegativeScalarData()
        if neg_or_not == True:
            overlayScalars_flipped = abs(overlayScalars_neg)
            neg_overlay_surfActor, neg_overlay_lu, neg_overlayScalars = overlayScalarsToSurface(overlayScalars_flipped, anatomyPolyData, new_item_index+1, overlay_file_path, 'neg')
            return pos_overlay_surfActor, pos_overlay_lu, pos_overlayScalars, neg_overlay_surfActor, neg_overlay_lu, neg_overlayScalars
        else:
            return pos_overlay_surfActor, pos_overlay_lu, pos_overlayScalars, None, None, None



def overlayScalarsToSurface(overlayScalars, anatomyPolyData, new_item_index, overlay_file_path, pos_or_neg):
    overlay_sc_scalars = vtk.vtkFloatArray()
    for val in overlayScalars:
        overlay_sc_scalars.InsertNextValue(val)

    #the overlay plane
    overlay_polydata = vtk.vtkPolyData()
    overlay_polydata.DeepCopy(anatomyPolyData)
    overlay_polydata.GetPointData().SetScalars(overlay_sc_scalars)

    overlay_surfMapper = vtk.vtkPolyDataMapper()
    overlay_surfMapper.SetInput(overlay_polydata)
    overlay_surfMapper.SetUseLookupTableScalarRange(1)


    overlay_surfActor = vtk.vtkActor()
    overlay_surfActor.SetMapper(overlay_surfMapper)


    if pos_or_neg == 'pos':
        HSVA_start = [0.0,1.0,1.0,1.0] #red
        HSVA_end = [0.1667,1.0,1.0,1.0] #yellow

        RGBA_start = [255.0, 0.0, 0.0, 1.0] #red
        RGBA_end = [255.0, 255.0, 0.0, 1.0] #yellow
        
    elif pos_or_neg == 'neg':
        HSVA_start = [0.666,1.0,0.5,1.0] #dk blue
        HSVA_end = [0.5,1.0,1.0,1.0] #cyan

        RGBA_start = [0.0, 0.0, 128.0, 1.0] #dk blue
        RGBA_end = [0.0, 255.0, 255.0, 1.0] #cyan


    #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 user set lower and upper bound of visible scalar values
    #   .visibleState = currently on/off


    overlay_surfActor.meta = {}

    overlay_surfActor.meta['dataIndex'] = new_item_index
    overlay_surfActor.meta['dataPath'] = overlay_file_path
    overlay_surfActor.meta['listPos'] = new_item_index
    overlay_surfActor.meta['dataMax'] = overlayScalars.max()
    overlay_surfActor.meta['dataMin'] = overlayScalars.min()
    overlay_surfActor.meta['lutHSVAStartColor'] = HSVA_start
    overlay_surfActor.meta['lutHSVAEndColor'] = HSVA_end
    overlay_surfActor.meta['lutRGBAStartColor'] = RGBA_start
    overlay_surfActor.meta['lutRGBAEndColor'] = RGBA_end
    overlay_surfActor.meta['lutBinary'] = False
    overlay_surfActor.meta['lutBinaryCutOff'] = overlayScalars.max()/2.0
    overlay_surfActor.meta['lutVisibleScalarRange'] = [overlayScalars.max()/10.0,overlayScalars.max()]    
    overlay_surfActor.meta['visibleState'] = True
    overlay_surfActor.SetPosition(0,0,0.1*new_item_index) #for multiple layers
    overlay_surfActor.meta['originalScalarArray'] = overlayScalars

    overlay_surfActor.GetProperty().SetOpacity(0.999)

    if pos_or_neg == 'pos':
        overlay_surfActor.meta['listTxt'] = 'Overlay file %s' %new_item_index
    elif pos_or_neg == 'neg':
        overlay_surfActor.meta['listTxt'] = 'Negative of Overlay %s' %(int(new_item_index)-1)
                                                                                


    #create a lookupTbale for the overlay data
    overlay_lu = generateLUT(HSVA_start, HSVA_end, overlay_surfActor.meta['lutVisibleScalarRange'])
    overlay_lu.SetTableValue(0,(0.0,0.0,0.0,0.0))

    overlay_surfMapper.SetLookupTable(overlay_lu)

    return overlay_surfActor, overlay_lu, overlayScalars


def dialogNegativeScalarData():

    quit_msg = '''The dataset has negative values in it. Click Yes if you
                would like to load this data as an extra layer'''
    reply = QMessageBox.question(None, 'Load Negative data (extra layer)?', 
                     quit_msg, QMessageBox.Yes, QMessageBox.No)

    if reply == QMessageBox.Yes:
        return True
    else:
        return False



