# core libs
import os,sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import vtk

#gui stuff
import fsFlatPy_ui as fs_ui
from fsFlatVTKFrameGui import QVtkInteractorWidget
from fsFlatColorTools import *
from fsFlatRefreshCurrentData import *
from fsFlatActionHandler import handleActions
from fsFlatQListWidgetFix import listWidgetOrderEventFilter
from fsFlatGenerateLUT import generateLUT
from fsGenerateRGBALayer import fsGenerateRGBALayer


#data handlers
from loadFsFlatAnatomy import loadFsFlatAnatomy
from loadFsOverlay import loadFsOverlay



#main program
class fsFlatPyLaunch(QMainWindow, fs_ui.Ui_myMainWindow):

    def testRGBA(self):
        pass


    def processRGBA(self):
        if len(self.loadedSurfaceTracker) < 5:
            print 'Cant do this .. need at least 1 base and 4 overlay layers to combine'
        else:
            print 'assuming you want the last 4 loaded layers represented as R G B A .. processing a new layer'
            new_surf_actor, new_lut, new_scalars =  fsGenerateRGBALayer(self, self.anatomyPolyData, self.listWidget.count())

            index_pos = self.listWidget.count() #NB before new item added so omit (-1)
            #change the rendering depth using SetPosition of vtkActor
            new_surf_actor.SetPosition(0,0,index_pos*1)
            new_surf_actor.Modified()
            self.loadedSurfaceTracker.append(new_surf_actor)
            self.ren.AddActor(new_surf_actor)

            ##print new_surf_actor

            #add to window list
            self.loadedOverlayList.append([QListWidgetItem(self.loadedSurfaceTracker[-1].meta['listTxt']), self.loadedSurfaceTracker[-1].meta['dataIndex']])
            self.listWidget.addItem(self.loadedOverlayList[-1][0])
            self.listWidget.item(self.listWidget.count()-1).my_index_tracker = self.listWidget.count()-1
            self.listWidget.setCurrentRow(self.listWidget.count()-1) 
            #refreshColourPanel(self, self.listWidget.count()-1)

            self.ren.GetCullers().GetLastItem().SetSortingStyleToBackToFront()

            

    def toggleBinary(self):
        if self.pushButtonBinariseLUT.isChecked() == True:
            self.pushButtonBinariseLUT.setText('Values below min = same colour as min')
            ColourMapClip(self, 0)
        else:
            self.pushButtonBinariseLUT.setText('Values below min = transparent')
            ColourMapClip(self, 1)
        #either way, update the LUT
        


    def ItemVisibilityToggled(self):
        currLine = self.listWidget.currentRow()
        selectedDataIndex = self.listWidget.item(currLine).my_index_tracker
        if self.loadedSurfaceTracker[selectedDataIndex].meta['visibleState'] == True:
            self.listWidget.item(self.listWidget.currentRow()).setTextColor(QColor(255,0,0))
            self.loadedSurfaceTracker[selectedDataIndex].meta['visibleState'] = False
            self.loadedSurfaceTracker[selectedDataIndex].VisibilityOff()
            self.loadedSurfaceTracker[selectedDataIndex].Modified()
            self.ren.Render()
        else:
            self.listWidget.item(self.listWidget.currentRow()).setTextColor(QColor(0,0,0))
            self.loadedSurfaceTracker[selectedDataIndex].meta['visibleState'] = True
            self.loadedSurfaceTracker[selectedDataIndex].VisibilityOn()
            self.loadedSurfaceTracker[selectedDataIndex].Modified()
            self.ren.Render()

    def UpdateCurrentItem(self):
        #check the original index matching
        selectedDataIndex = self.listWidget.item(self.listWidget.currentRow()).my_index_tracker
        refreshColourPanel(self, selectedDataIndex)


    def orderChanged(self):
        for i in range(self.listWidget.count()):
            index_pos = self.listWidget.item(i).my_index_tracker
            #change the rendering depth using SetPosition of vtkActor
            self.loadedSurfaceTracker[index_pos].SetPosition(0,0,i*1)
            self.loadedSurfaceTracker[index_pos].Modified()
            self.ren.Render()

            self.ren.GetCullers().GetLastItem().SetSortingStyleToBackToFront()


    def toggle2D3D(self):
        if self.pushButton2D3Dswitch.isChecked() == True:
            self.pushButton2D3Dswitch.setText('Switch to 2D rendering (currently 3D)')
            self.iwidget_3d.interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
        else:
            self.pushButton2D3Dswitch.setText('Switch to 3D rendering (currently 2D)')
            self.iwidget_3d.interactor.SetInteractorStyle(vtk.vtkInteractorStyleRubberBand2D())
            self.initCam.SetPosition(self.initCameraSettings['GetPosition'])
            self.initCam.SetRoll(self.initCameraSettings['GetRoll'])
            self.initCam.SetViewAngle(self.initCameraSettings['GetViewAngle'])
            self.initCam.SetViewUp(self.initCameraSettings['GetViewUp'])
            self.initCam.SetFocalPoint(self.initCameraSettings['GetFocalPoint'])


    def DataRangeChanged(self):
        newDataLow = float(self.lineEditDataMin.text())
        newDataHigh = float(self.lineEditDataMax.text())
        updateScalarRange(self,  self.listWidget.currentRow(), [newDataLow, newDataHigh])


    def MinOpacityChanged(self):
        if self.checkBoxJointOpacity.isChecked() == True:
            self.lineEditDataOpacityMax.setText(self.lineEditDataOpacityMin.text())
        else:
            pass

        #either way, update the LUT
        newAlphaLow = float(self.lineEditDataOpacityMin.text())
        NewAlphaHigh = float(self.lineEditDataOpacityMax.text())

        #check the original index matching
        selectedDataIndex = self.listWidget.item(self.listWidget.currentRow()).my_index_tracker
        updateAlphas(self, selectedDataIndex, newAlphaLow, NewAlphaHigh)


    def MaxOpacityChanged(self):
        newAlphaLow = float(self.lineEditDataOpacityMin.text())
        newAlphaHigh = float(self.lineEditDataOpacityMax.text())

        #check the original index matching
        selectedDataIndex = self.listWidget.item(self.listWidget.currentRow()).my_index_tracker
        updateAlphas(self, selectedDataIndex, newAlphaLow, newAlphaHigh)



    def JointOpacityChanged(self):
        if self.checkBoxJointOpacity.isChecked() == True:
            self.lineEditDataOpacityMax.setText(self.lineEditDataOpacityMin.text())
            self.lineEditDataOpacityMax.setEnabled(False)
            self.labelOpacityMax.setEnabled(False)
            self.labelOpacityMin.setEnabled(False)
            #in this case .. update the LUT to lower value ?Dialog to tell the user

            newAlphaLow = float(self.lineEditDataOpacityMin.text())
            NewAlphaHigh = float(self.lineEditDataOpacityMax.text())

            #either way, update the LUT
            updateAlphas(self, self.listWidget.currentRow(), newAlphaLow, NewAlphaHigh)
                      
        else:
            self.lineEditDataOpacityMax.setEnabled(True)
            self.labelOpacityMax.setEnabled(True)
            self.labelOpacityMin.setEnabled(True)


    def changeBackground(self):
        changeMainWindowBackground(self)


    def PrintList(self):
        print self.listWidget.currentRow()


    def newColourMapLower(self):
        #check the original index matching
        selectedDataIndex = self.listWidget.item(self.listWidget.currentRow()).my_index_tracker
        selectNewColour(self, self.FrameStartColour, selectedDataIndex, 'Lower')
        print self.listWidget.currentRow()


    def newColourMapUpper(self):
        #check the original index matching
        selectedDataIndex = self.listWidget.item(self.listWidget.currentRow()).my_index_tracker
        selectNewColour(self, self.FrameEndColour, selectedDataIndex, 'Upper')
        print self.listWidget.currentRow()


    def LoadNewAnatomy(self):
        fPointsName = unicode(QFileDialog.getOpenFileName(self, "Open flat file", "Open file", self.tr("ASCII point File (*.asc)")))

        if fPointsName != '':
            fCurvName = unicode(QFileDialog.getOpenFileName(self, "Open curv file", "Open file", self.tr("Curvature File (*.curv)")))

            if fCurvName != '':
                self.anatomyActor, self.anatomyOrigNumpyScalars = loadFsFlatAnatomy(fPointsName, fCurvName)
                self.anatomyActor.SetPosition(0,0,0)
                self.anatomyActor.Modified()
                #get the poydata out so we can use it for overlay surfaces        
                self.anatomyPolyData = self.anatomyActor.GetMapper().GetInput()
                self.loadedSurfaceTracker.append(self.anatomyActor)
                self.ren.AddActor(self.anatomyActor)

                #add to window list
                self.loadedOverlayList.append([QListWidgetItem(self.anatomyActor.meta['listTxt']), self.anatomyActor.meta['dataIndex']])
                self.listWidget.addItem(self.loadedOverlayList[0][0])
                self.listWidget.item(self.listWidget.count()-1).my_index_tracker = self.listWidget.count()-1
                self.listWidget.setCurrentRow(self.listWidget.count()-1)
                refreshColourPanel(self, self.listWidget.count()-1)

                self.ren.GetCullers().GetLastItem().SetSortingStyleToBackToFront()
           
                
    def LoadNewOverlay(self):
        fName = unicode(QFileDialog.getOpenFileName(self, "Open overlay file", "Open new file", self.tr("MGH Files (*.MGH)")))
        if fName != '':
            new_surf_actor, new_lut, new_scalars, new_surf_actor_NEG, new_lut_NEG, new_scalars_NEG = loadFsOverlay(fName, self.anatomyPolyData, self.listWidget.count())
            self.UpdateOverlayInfo(new_surf_actor, new_lut, new_scalars)
            if new_surf_actor_NEG != None:
                self.UpdateOverlayInfo(new_surf_actor_NEG, new_lut_NEG, new_scalars_NEG)
                

    def UpdateOverlayInfo(self, new_surf_actor, new_lut, new_scalars):
            index_pos = self.listWidget.count() #NB before new item added so omit (-1)
            #change the rendering depth using SetPosition of vtkActor
            new_surf_actor.SetPosition(0,0,index_pos*1)
            new_surf_actor.Modified()
            self.loadedSurfaceTracker.append(new_surf_actor)
            self.ren.AddActor(new_surf_actor)

            #add to window list
            self.loadedOverlayList.append([QListWidgetItem(self.loadedSurfaceTracker[-1].meta['listTxt']), self.loadedSurfaceTracker[-1].meta['dataIndex']])
            self.listWidget.addItem(self.loadedOverlayList[-1][0])
            self.listWidget.item(self.listWidget.count()-1).my_index_tracker = self.listWidget.count()-1
            self.listWidget.setCurrentRow(self.listWidget.count()-1) 
            refreshColourPanel(self, self.listWidget.count()-1)

            self.ren.GetCullers().GetLastItem().SetSortingStyleToBackToFront()



    def __init__(self, text, parent=None):
        super(fsFlatPyLaunch, self).__init__(parent)
        self.__text = unicode(text)
        self.__index = 0
        self.setupUi(self)

        self.listWidget.setSortingEnabled(False)       

        self.myfilter = listWidgetOrderEventFilter(self.listWidget)
        self.listWidget.installEventFilter(self.myfilter)

        self.Frame3d = QFrame(self)
        self.Frame3d.setFrameShape(QFrame.StyledPanel)

        self.iwidget_3d = QVtkInteractorWidget(self.Frame3d)

        self.horizontalLayout.addWidget(self.iwidget_3d)

        self.ren = vtk.vtkRenderer()
        self.iwidget_3d.interactor.GetRenderWindow().AddRenderer(self.ren)
        self.iwidget_3d.interactor.SetInteractorStyle(vtk.vtkInteractorStyleRubberBand2D())
        
        #now use parallel projection so we don't get any 'depth' issues
        self.ren.GetActiveCamera().SetParallelProjection(1)

        #create a holder for our loaded_file_list that can map to our data arrays (next)
        self.loadedOverlayList = []

        #creat a holder for our loaded data arrays
        self.loadedSurfaceTracker = []

        ##Add the base data
        self.LoadNewAnatomy()

        ### ------------------------------------------------ 
        # observers / actions
        handleActions(self)


if __name__ == "__main__":
    import sys
    text = "Python viewer for FreeSurfer flat pathces .. "
    app = QApplication(sys.argv)
    dv3dMain = fsFlatPyLaunch(text)
    dv3dMain.show()
    dv3dMain.ren.ResetCamera()
    dv3dMain.iwidget_3d.interactor.Render()
    dv3dMain.initCam = dv3dMain.ren.GetActiveCamera()
    dv3dMain.initCameraSettings = {'GetPosition':dv3dMain.initCam.GetPosition(), 
                                        'GetRoll':dv3dMain.initCam.GetRoll(),
                                        'GetViewAngle':dv3dMain.initCam.GetViewAngle(),
                                        'GetViewUp':dv3dMain.initCam.GetViewUp(), 
                                        'GetFocalPoint':dv3dMain.initCam.GetFocalPoint()}
    app.exec_()


