#!/usr/bin/python
#dv3d_data_LoadNiftiVolume_Planes.py
#Generates pale actors of volumetric nifti data
#DV3D refactor 2
#AG 25/07/2013

#import libraries
import vtk
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import os

from dv3dVTKFrameGui import QVtkInteractorWidget
from dv3dNiftiHandler import *
from dv3d_data_emptyPlanesClass import PlanesGroup
from dv3d_dialogs_plane_properties_panel import *
from dv3d_data_Create_Planes import *
from dv3d_data_ColorLookupTable import *
from dv3d_gui_updateCurrentInteractions import *

# function
def dv3d_data_LoadNiftiVolume_Planes(the_parent_window, theNiftiFileName):

    tpw = the_parent_window #for brevity

    #create a new holder for the group of planes   
    thisPlanesGroup = PlanesGroup()

    # .. and assign it to the Planes list of the main app
    tpw.Planes.append(thisPlanesGroup)

    #load some data
    try:
        vol, dMax, dMin, bounds, x_slice_pos, y_slice_pos, z_slice_pos, srow_x, srow_y, srow_z, spacing = niftiToVTKImageData(theNiftiFileName)
    except:
        print ".. failed to load data .. User cancelled or incorrect file format. Quitting here"
        tpw.Planes = tpw.Planes[:-1]
        return
        
    #print 'dmax dmin', dMax, dMin

    # also extract just the filename so we can use that to label the planes
    myDataLabel = os.path.basename(theNiftiFileName)

    # create the planes and their pickers at tpw.Planes[-1]
    dv3d_data_Create_Planes(tpw, vol, x_slice_pos, y_slice_pos, z_slice_pos)
 

    ### ------------------------------------------------ 

    #create or update the property panel so the user can adjust the data
    if tpw.PlaneLoaded == 0: #i.e. this is the first set of plane data loaded    
        tpw.PlaneLoaded = 1
        tpw.PlanePropertyPanel = planePropertyPanel('Planes', tpw) #create a panel passing the parent window into its scope

        #big breakthrough here - use window flag as Qt.Window rather than Qt.Dialog to allow minimise button
        # TODO - check cross-platform stability of the this call
        tpw.PlanePropertyPanel.setWindowFlags(Qt.Window|Qt.WindowMinimizeButtonHint)
        tpw.PlanePropertyPanel.show()
        tpw.PlanePropertyPanel.raise_()

        #first load so enable the surfaces item in the list tree
        tpw.ItemList_QTreeWidget.Planes.setDisabled(0)        

    else: 
        pass #it's already created .. just update the info

    tpw.PlanePropertyPanel.lineEditDataSource.setText(theNiftiFileName)
    tpw.PlanePropertyPanel.labelDataMaxValue.setText('%.3f' %(float(dMax)))
    tpw.PlanePropertyPanel.labelDataMinValue.setText('%.3f' %(float(dMin)))
    tpw.PlanePropertyPanel.spinboxDataVisibleMax.setMinimum(float(dMin))
    tpw.PlanePropertyPanel.spinboxDataVisibleMax.setMaximum(float(dMax))
    tpw.PlanePropertyPanel.update()
    tpw.PlanePropertyPanel.repaint()
    tpw.PlanePropertyPanel.show()
    tpw.PlanePropertyPanel.spinboxDataVisibleMax.setValue(float(dMax))
    tpw.PlanePropertyPanel.spinboxDataVisibleMin.setMinimum(float(dMin))
    tpw.PlanePropertyPanel.spinboxDataVisibleMin.setMaximum(float(dMax))
    tpw.PlanePropertyPanel.update()
    tpw.PlanePropertyPanel.repaint()
    tpw.PlanePropertyPanel.show()
    tpw.PlanePropertyPanel.spinboxDataVisibleMin.setValue(float(dMax)*0.1) #10% of positive Max by default
    tpw.PlanePropertyPanel.spinboxDataOpacity.setMinimum(0.0)
    tpw.PlanePropertyPanel.spinboxDataOpacity.setMaximum(1.0)
    tpw.PlanePropertyPanel.update()
    tpw.PlanePropertyPanel.repaint()
    tpw.PlanePropertyPanel.show()
    tpw.PlanePropertyPanel.spinboxDataOpacity.setValue(1.0)
    tpw.PlanePropertyPanel.update()
    tpw.PlanePropertyPanel.repaint()
    tpw.PlanePropertyPanel.show()


    ### ------------------------------------------------ 

    # add the object to the item list
    child_planeset = QTreeWidgetItem([myDataLabel])
    child_planeset.setCheckState(0,Qt.Checked)
    child_planeset.setFlags(child_planeset.flags()|Qt.ItemIsEditable) #allow renaming
    
    #also append a pointer to the data this item represents so we can 
    # manipluate the data if we click the list item
    setattr(child_planeset, 'dv3dDataType', 'planes')
    setattr(child_planeset, 'planeDataIndex', len(tpw.Planes)-1)
    child_planeset.emitDataChanged()

    #add it to the main list
    tpw.ItemList_QTreeWidget.Planes.addChild(child_planeset) 

    #tell the object list that data has been loaded and is visible
    tpw.ItemList_QTreeWidget.Planes.setCheckState(0,Qt.Checked)

    #highlight the correct item in the tree (set focus on current item)
    tpw.ItemList_QTreeWidget.setItemExpanded(tpw.ItemList_QTreeWidget.Planes, 1) #make sure its visible
    tpw.ItemList_QTreeWidget.clearSelection() #deselect all currently selected

    tpw.ItemList_QTreeWidget.setCurrentItem(child_planeset) #set current and then ...
    child_planeset.setSelected(1) #and highlight it
    tpw.ItemList_QTreeWidget.update() #update
    tpw.ItemList_QTreeWidget.repaint() #redraw
    child_planeset.setSelected(1) #and highlight it

    #create a default lookup table - greyscale if first volume, red to yellow if subsequent
    if len(tpw.Planes) == 1:
        rgbMin = (0,0,0)
        rgbMax = (255,255,255) #default greyscale
    elif len(tpw.Planes) > 1:
        rgbMin = (255,0,0)
        rgbMax = (255,255,0) #default red-yellow
    else:
        pass #for now 

    clipMin = dMax*0.1 #10% of max to start
    clipMax = dMax
       
    dv3d_data_ColorLookupTable(tpw, tpw.Planes[-1], clipMin, clipMax, rgbMin, rgbMax, 1.0)   

    #let's keep track of some values for update / reference later
    # NB some already set in dv3d_data_ColorLookupTable
    setattr(tpw.Planes[-1], 'dataPath', theNiftiFileName) 
    setattr(tpw.Planes[-1], 'dMax', dMax)
    setattr(tpw.Planes[-1], 'dMin', dMin)
    setattr(tpw.Planes[-1], 'bounds', bounds)
    setattr(tpw.Planes[-1], 'x_slice_pos', x_slice_pos)
    setattr(tpw.Planes[-1], 'y_slice_pos', y_slice_pos)
    setattr(tpw.Planes[-1], 'z_slice_pos', z_slice_pos)
    setattr(tpw.Planes[-1], 'volumeData', vol)
    setattr(tpw.Planes[-1], 'dataLabel', myDataLabel)
    setattr(tpw.Planes[-1], 'enforceLowClip', 1)
    setattr(tpw.Planes[-1], 'enforceHighClip', 0)

    #turn the planes on and render!
    tpw.Planes[-1].planeWidget_3dX.On()
    tpw.Planes[-1].planeWidget_3dY.On()
    tpw.Planes[-1].planeWidget_3dZ.On()
    tpw.Planes[-1].planeWidget_2dX.On()
    tpw.Planes[-1].planeWidget_2dY.On()
    tpw.Planes[-1].planeWidget_2dZ.On()

    tpw.iwidget_3d.interactor.Render()
    tpw.ren1.ResetCamera()
    tpw.ren2.ResetCamera()
    tpw.ren3.ResetCamera()

    tpw.iwidget_2dX.interactor.Render()
    tpw.iwidget_2dY.interactor.Render()
    tpw.iwidget_2dZ.interactor.Render()

    #keep track of planes so we can sync them all!
    tpw.X_plane_list.append(tpw.Planes[-1].planeWidget_3dX)
    tpw.Y_plane_list.append(tpw.Planes[-1].planeWidget_3dY)
    tpw.Z_plane_list.append(tpw.Planes[-1].planeWidget_3dZ)
    tpw.X_plane_list.append(tpw.Planes[-1].planeWidget_2dX)
    tpw.Y_plane_list.append(tpw.Planes[-1].planeWidget_2dY)
    tpw.Z_plane_list.append(tpw.Planes[-1].planeWidget_2dZ)

    tpw.runSyncPlanes()

    dv3d_gui_updateCurrentInteractions(tpw, 'planes')  


    

    
    
    






