
import wx
import os
import wx.lib.buttons

import globalvar as globalvar
from utils import *
from dv3dTreeCtrl import *
from common_functions import *

class PlanesTab(wx.Panel):
    def __init__(self, parent, frame_parent):
        wx.Panel.__init__(self, parent, -1)


        self.frame_parent = frame_parent
        self.planes_rotate = wx.StaticBox(id=-1,
              label='rotate', name='planes_rotate', parent=self,
              pos=wx.Point(4, 0), size=wx.Size(80, 80), style=0)


        self.planes_rot_R = wx.BitmapButton(bitmap=wx.Bitmap(u'./images/right1.bmp',
              wx.BITMAP_TYPE_BMP), id=-1,
              name='planes_rot_R', parent=self, pos=wx.Point(60, 40),
              size=wx.Size(16, 16), style=wx.BU_AUTODRAW)
        self.planes_rot_R.Bind(wx.EVT_BUTTON, self.OnPlanes_rot_RButton,
              id=-1)


        self.planes_rot_L = wx.BitmapButton(bitmap=wx.Bitmap(u'./images/left1.bmp',
              wx.BITMAP_TYPE_BMP), id=-1,
              name='planes_rot_L', parent=self, pos=wx.Point(12, 40),
              size=wx.Size(16, 16), style=wx.BU_AUTODRAW)
        self.planes_rot_L.Bind(wx.EVT_BUTTON, self.OnPlanes_rot_LButton,
              id=-1)


        self.planes_rot_U = wx.BitmapButton(bitmap=wx.Bitmap(u'./images/up1.bmp',
              wx.BITMAP_TYPE_BMP), id=-1,
              name='planes_rot_U', parent=self, pos=wx.Point(36, 24),
              size=wx.Size(16, 16), style=wx.BU_AUTODRAW)
        self.planes_rot_U.Bind(wx.EVT_BUTTON, self.OnPlanes_rot_UButton,
              id=-1)


        self.planes_rot_D = wx.BitmapButton(bitmap=wx.Bitmap(u'./images/down1.bmp',
              wx.BITMAP_TYPE_BMP), id=-1,
              name='planes_rot_D', parent=self, pos=wx.Point(36, 56),
              size=wx.Size(16, 16), style=wx.BU_AUTODRAW)
        self.planes_rot_D.Bind(wx.EVT_BUTTON, self.OnPlanes_rot_DButton,
              id=-1)

        self.window_WL = wx.StaticBox(id=-1,
              label='window width/level', name='window_WL', parent=self,
              pos=wx.Point(92, 0), size=wx.Size(212, 80), style=0)


        self.slider1 = wx.Slider(id=-1, maxValue=self.frame_parent.my_loaded_volumes[0][0].data_max,
              minValue=0, name='slider1', parent=self, pos=wx.Point(116,
              48), size=wx.Size(180, 16), style=wx.SL_HORIZONTAL, value=50)
        self.slider1.Bind(wx.EVT_SLIDER, self.OnSlider1,
              id=-1)


        self.slider2 = wx.Slider(id=-1, maxValue=self.frame_parent.my_loaded_volumes[0][0].data_max,
              minValue = 0, name='slider2', parent=self, pos=wx.Point(116,
              24), size=wx.Size(180, 16), style=wx.SL_HORIZONTAL, value=50)
        self.slider2.Bind(wx.EVT_SLIDER, self.OnSlider2,
              id=-1)


        self.W = wx.StaticText(id=-1, label='W', name='W',
              parent=self, pos=wx.Point(100, 24), size=wx.Size(10, 13),
              style=0)


        self.L = wx.StaticText(id=-1, label='L', name='L',
              parent=self, pos=wx.Point(101, 45), size=wx.Size(8, 13),
              style=0)

        self.staticBox2 = wx.StaticBox(id=-1,
              label='view from:', name='staticBox2', parent=self,
              pos=wx.Point(312, 0), size=wx.Size(128, 80), style=0)

        self.planes_VF_top = wx.RadioButton(id=-1,
              label='top', name='planes_VF_top', parent=self,
              pos=wx.Point(320, 24), size=wx.Size(40, 13), style=0)
        self.planes_VF_top.SetValue(True)
        self.planes_VF_top.Bind(wx.EVT_RADIOBUTTON,
              self.OnPlanes_VF_topRadiobutton, id=-1)


        self.planes_VF_bottom = wx.RadioButton(id=-1,
              label='bottom', name='planes_VF_bottom', parent=self,
              pos=wx.Point(320, 40), size=wx.Size(56, 13), style=0)
        self.planes_VF_bottom.SetValue(False)
        self.planes_VF_bottom.Bind(wx.EVT_RADIOBUTTON,
              self.OnPlanes_VF_bottomRadiobutton,
              id=-1)


        self.planes_VF_left = wx.RadioButton(id=-1,
              label='left', name='planes_VF_left', parent=self,
              pos=wx.Point(320, 56), size=wx.Size(40, 13), style=0)
        self.planes_VF_left.SetValue(False)
        self.planes_VF_left.Bind(wx.EVT_RADIOBUTTON,
              self.OnPlanes_VF_leftRadiobutton, id=-1)


        self.planes_VF_right = wx.RadioButton(id=-1,
              label='right', name='planes_VF_right', parent=self,
              pos=wx.Point(384, 56), size=wx.Size(48, 13), style=0)
        self.planes_VF_right.SetValue(False)
        self.planes_VF_right.Bind(wx.EVT_RADIOBUTTON,
              self.OnPlanes_VF_rightRadiobutton, id=-1)


        self.planes_VF_back = wx.RadioButton(id=-1,
              label='back', name='planes_VF_back', parent=self,
              pos=wx.Point(384, 40), size=wx.Size(40, 13), style=0)
        self.planes_VF_back.SetValue(False)
        self.planes_VF_back.Bind(wx.EVT_RADIOBUTTON,
              self.OnPlanes_VF_backRadiobutton, id=-1)


        self.planes_VF_front = wx.RadioButton(id=-1,
              label='front', name='planes_VF_front', parent=self,
              pos=wx.Point(384, 24), size=wx.Size(48, 13), style=0)
        self.planes_VF_front.SetValue(False)
        self.planes_VF_front.Bind(wx.EVT_RADIOBUTTON,
              self.OnPlanes_VF_frontRadiobutton, id=-1)

        self.planes_reset = wx.Button(id=-1, label='Reset views',
              name='planes_reset', parent=self, pos=wx.Point(464, 10),
              size=wx.Size(75, 23), style=0)
        self.planes_reset.Bind(wx.EVT_BUTTON,
              self.OnPlanes_resetbutton, id=-1)

        self.cycleBGColor = wx.Button(self, -1, 'B/G colour', (464,40))
        self.Bind(wx.EVT_BUTTON, self.CycleBGColorButton, self.cycleBGColor)
        
        self.ValueLimited = wx.ToggleButton(self, -1, 'Limit values', (564,40))
        self.Bind(wx.EVT_TOGGLEBUTTON, self.OnValueLimitedButton, self.ValueLimited)
        self.ValueLimited.SetToolTipString('Clicking this button will set a threshold in your data -all values below this become invisible/visible')

        self.LimitValue = wx.TextCtrl(id=-1, name='textCtrl1',
              parent=self, pos=wx.Point(624,40), size=wx.Size(50, 20),
              style=wx.TE_LEFT, value='0')


        self.PlaneEdgesVisible= wx.ToggleButton(self, -1, 'Plane edges on/off', (564,10))
        self.Bind(wx.EVT_TOGGLEBUTTON, self.OnPlaneEdgesVisible, self.PlaneEdgesVisible)
        self.PlaneEdgesVisible.SetToolTipString('Turn the colored edges of the planes on/off')

        self.LightSwitch= wx.ToggleButton(self, -1, 'Lights off', (464,70))
        self.Bind(wx.EVT_TOGGLEBUTTON, self.OnLightSwitch, self.LightSwitch)
        self.LightSwitch.SetToolTipString('Turn the lights of the scene on/off')

        self.ProjectionSwitch= wx.ToggleButton(self, -1, 'Perspective view', (564,70))
        self.Bind(wx.EVT_TOGGLEBUTTON, self.OnProjectionSwitch, self.ProjectionSwitch)
        self.ProjectionSwitch.SetToolTipString('Toggle beteen perspective projection (gives depth) and parallel projection (all objects appear the same distance)')

    def OnProjectionSwitch(self, evt):
        if self.frame_parent.ren.GetActiveCamera().GetParallelProjection() == 1:
            self.frame_parent.ren.GetActiveCamera().ParallelProjectionOff()
            self.ProjectionSwitch.SetLabel('Perspective view')
            self.ProjectionSwitch.Update()
            self.frame_parent.widget.Render()
        else:
            self.frame_parent.ren.GetActiveCamera().ParallelProjectionOn()
            self.ProjectionSwitch.SetLabel('Parallel view')
            self.ProjectionSwitch.Update()
            self.frame_parent.widget.Render()
            
            
    def OnLightSwitch(self, evt):
        if self.frame_parent.light1.GetSwitch() == 1:
            self.frame_parent.light1.SwitchOff()
            self.frame_parent.light2.SwitchOff()
            self.frame_parent.light3.SwitchOff()
            self.frame_parent.light4.SwitchOff()
            self.LightSwitch.SetLabel('Lights off')
            self.LightSwitch.Update()
            self.frame_parent.widget.Render()
        else:
            self.frame_parent.light1.SwitchOn()
            self.frame_parent.light2.SwitchOn()
            self.frame_parent.light3.SwitchOn()
            self.frame_parent.light4.SwitchOn()
            self.LightSwitch.SetLabel('Lights on')
            self.LightSwitch.Update()
            self.frame_parent.widget.Render()


    def OnPlaneEdgesVisible(self, evt):
        state = self.PlaneEdgesVisible.GetValue()
        if state == True:
            self.frame_parent.ortho_windowX.plane1.GetPlaneProperty().SetOpacity(0.0)
            self.frame_parent.ortho_windowY.plane1.GetPlaneProperty().SetOpacity(0.0)
            self.frame_parent.ortho_windowZ.plane1.GetPlaneProperty().SetOpacity(0.0)
            
            for i in range(len(self.frame_parent.ListOfObjects)):
                try:
                    self.frame_parent.ListOfObjects[i].GetPlaneProperty().SetOpacity(0.0)
                except:
                    pass
            
            self.frame_parent.widget.Render()
            self.frame_parent.ortho_windowX.widget1.Render()
            self.frame_parent.ortho_windowY.widget1.Render()
            self.frame_parent.ortho_windowZ.widget1.Render()
            
        else:
            self.frame_parent.ortho_windowX.plane1.GetPlaneProperty().SetOpacity(1.0)
            self.frame_parent.ortho_windowY.plane1.GetPlaneProperty().SetOpacity(1.0)
            self.frame_parent.ortho_windowZ.plane1.GetPlaneProperty().SetOpacity(1.0)
            
            for i in range(len(self.frame_parent.ListOfObjects)):
                try:
                    self.frame_parent.ListOfObjects[i].GetPlaneProperty().SetOpacity(1.0)
                except:
                    pass #todo fix!
            
            self.frame_parent.widget.Render()
            self.frame_parent.ortho_windowX.widget1.Render()
            self.frame_parent.ortho_windowY.widget1.Render()
            self.frame_parent.ortho_windowZ.widget1.Render()                
                
    def OnValueLimitedButton(self, evt):
        state = self.ValueLimited.GetValue()
        if state == True:
            self.frame_parent.original_LU_table = self.frame_parent.ListOfObjects[0].GetLookupTable()
            base_min = float(self.LimitValue.GetValue())
            base_max = float(self.frame_parent.base_data_max)
            self.frame_parent.original_LU_table.SetTableRange(base_min , base_max)
            self.frame_parent.original_LU_table.SetTableValue(0,(0.0,0.0,0.0,0.0))
            self.frame_parent.original_LU_table.Build()
            self.frame_parent.widget.Render()
        else:
            self.frame_parent.original_LU_table = self.frame_parent.ListOfObjects[0].GetLookupTable()
            base_min = self.frame_parent.base_data_min
            base_max = self.frame_parent.base_data_max
            self.frame_parent.original_LU_table.SetTableRange(0.0, base_max)
            self.frame_parent.original_LU_table.SetTableValue(0,(0.0,0.0,0.0,1.0))
            self.frame_parent.original_LU_table.Build()
            self.frame_parent.widget.Render()

            

    def CycleBGColorButton(self, evt):
        
        dialog = wx.ColourDialog(self)
        if dialog.ShowModal() == wx.ID_OK:
            new_colour = dialog.GetColourData().GetColour()
            new_colour = new_colour.Get()
            self.frame_parent.ren.SetBackground(new_colour[0]/255.0, new_colour[1]/255.0, new_colour[2]/255.0)
            self.frame_parent.widget.Render()
            align_all_planes(self.frame_parent)

    def RenderTheVTKWindow(self):
        self.frame_parent.widget.Render()


    def OnPlanes_rot_RButton(self, event):
        self.frame_parent.ren.GetActiveCamera().Azimuth(-5)
        self.RenderTheVTKWindow()


    def OnPlanes_rot_LButton(self, event):
        self.frame_parent.ren.GetActiveCamera().Azimuth(5)
        self.RenderTheVTKWindow()


    def OnPlanes_rot_UButton(self, event):
        self.frame_parent.ren.GetActiveCamera().Elevation(-5)
        self.RenderTheVTKWindow()


    def OnPlanes_rot_DButton(self, event):
        self.frame_parent.ren.GetActiveCamera().Elevation(5)
        self.RenderTheVTKWindow()

    #TODO - all corresponding x/y/z planes not always necessarily turned on with main plane (lookup?)
    def OnPlanes_sagittalCheckbox(self, event):
        toggle_base_plane_from_buttons(self.planes_sagittal, -1, self.frame_parent, 0)

    def OnPlanes_coronalCheckbox(self, event):
        toggle_base_plane_from_buttons(self.planes_coronal, -1, self.frame_parent, 1)

    def OnPlanes_axialCheckbox(self, event):
        toggle_base_plane_from_buttons(self.planes_axial, -1, self.frame_parent, 2)

    def OnPlanes_VF_topRadiobutton(self, event):
        if self.planes_VF_top.GetValue() == True:
            cur_cam = self.frame_parent.ren.GetActiveCamera()
            bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
            cur_cam.SetPosition((bounds[0]+bounds[1])/2,(bounds[2]+bounds[3])/2,(bounds[4]+bounds[5])/2+600)
            cur_cam.SetViewUp(0,1,0)
            cur_cam.SetViewAngle(30)
            event.Skip()
        self.RenderTheVTKWindow()
        event.Skip()


    def OnPlanes_VF_bottomRadiobutton(self, event):
        if self.planes_VF_bottom.GetValue() == True:
            cur_cam = self.frame_parent.ren.GetActiveCamera()
            bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
            cur_cam.SetPosition((bounds[0]+bounds[1])/2,(bounds[2]+bounds[3])/2,(bounds[4]+bounds[5])/2-600)
            cur_cam.SetViewUp(0,1,0)
            cur_cam.SetViewAngle(30)
            event.Skip()
        self.RenderTheVTKWindow()
        event.Skip()


    def OnPlanes_VF_leftRadiobutton(self, event):
        if self.planes_VF_left.GetValue() == True:
            cur_cam = self.frame_parent.ren.GetActiveCamera()
            bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
            cur_cam.SetPosition((bounds[0]+bounds[1])/2-600,(bounds[2]+bounds[3])/2,(bounds[4]+bounds[5])/2)
            cur_cam.SetViewUp(0,0,1)
            cur_cam.SetViewAngle(30)
        self.RenderTheVTKWindow()
        event.Skip()


    def OnPlanes_VF_rightRadiobutton(self, event):
        if self.planes_VF_right.GetValue() == True:
            cur_cam = self.frame_parent.ren.GetActiveCamera()
            bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
            cur_cam.SetPosition((bounds[0]+bounds[1])/2+600,(bounds[2]+bounds[3])/2,(bounds[4]+bounds[5])/2)
            cur_cam.SetViewUp(0,0,1)
            cur_cam.SetViewAngle(30)
        self.RenderTheVTKWindow()
        event.Skip()


    def OnPlanes_VF_backRadiobutton(self, event):
        if self.planes_VF_back.GetValue() == True:
            cur_cam = self.frame_parent.ren.GetActiveCamera()
            bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
            cur_cam.SetPosition((bounds[0]+bounds[1])/2,(bounds[2]+bounds[3])/2-600,(bounds[4]+bounds[5])/2)
            cur_cam.SetViewUp(0,0,1)
            cur_cam.SetViewAngle(30)

        self.RenderTheVTKWindow()
        event.Skip()


    def OnPlanes_VF_frontRadiobutton(self, event):
        if self.planes_VF_front.GetValue() == True:
            cur_cam = self.frame_parent.ren.GetActiveCamera()
            bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
            cur_cam.SetPosition((bounds[0]+bounds[1])/2,(bounds[2]+bounds[3])/2+600,(bounds[4]+bounds[5])/2)
            cur_cam.SetViewUp(0,0,1)
            cur_cam.SetViewAngle(30)
        self.RenderTheVTKWindow()
        event.Skip()


    def OnSlider1(self, event):
        for i in range(len(self.frame_parent.ListOfObjects)):
            if self.frame_parent.ListOfObjects[i].my_type == 'base_imageplanegroup':
                for j in range(len(self.frame_parent.ListOfObjects)):
                    if self.frame_parent.ListOfObjects[j].my_parents_label == self.frame_parent.ListOfObjects[i].my_label:

                        lut_min =  self.frame_parent.original_LU_table.GetTableRange()[0]
                        lut_max =  self.frame_parent.original_LU_table.GetTableRange()[1]
                        try:
                            self.frame_parent.original_LU_table.SetTableRange(lut_min, float(self.slider1.GetValue()))
                        except:
                            pass #todo fix!
                        #self.Level_Value.SetLabel(str(float(self.slider1.GetValue())))
                        align_all_planes(self.frame_parent)
                        event.Skip()


    def OnSlider2(self, event):
        for i in range(len(self.frame_parent.ListOfObjects)):
            if self.frame_parent.ListOfObjects[i].my_type == 'base_imageplanegroup':
                for j in range(len(self.frame_parent.ListOfObjects)):
                    if self.frame_parent.ListOfObjects[j].my_parents_label == self.frame_parent.ListOfObjects[i].my_label:
                
                        lut_min =  self.frame_parent.original_LU_table.GetTableRange()[0]
                        lut_max =  self.frame_parent.original_LU_table.GetTableRange()[1]
                        
                        try:
                            self.frame_parent.original_LU_table.SetTableRange(float(self.slider2.GetValue()), lut_max)
                        except:
                            pass #todo fix!
                        #self.Window_Value.SetLabel(str(float(self.slider2.GetValue())))
                        align_all_planes(self.frame_parent)
                        event.Skip()




    def OnPlanes_resetbutton(self, event):
        for i in range(len(self.frame_parent.ListOfObjects)):
            curr_label = self.frame_parent.ListOfObjects[i].my_label
            if curr_label == 'Sagittal plane':
                self.frame_parent.ListOfObjects[i].SetPlaneOrientationToXAxes()
                self.frame_parent.ListOfObjects[i].SetSliceIndex(self.frame_parent.my_loaded_volumes[0][0].x_slice_pos,)
            elif curr_label == 'Coronal plane':
                self.frame_parent.ListOfObjects[i].SetPlaneOrientationToYAxes()
                self.frame_parent.ListOfObjects[i].SetSliceIndex(self.frame_parent.my_loaded_volumes[0][0].y_slice_pos,)
            elif curr_label == 'Axial plane':
                self.frame_parent.ListOfObjects[i].SetPlaneOrientationToZAxes()
                self.frame_parent.ListOfObjects[i].SetSliceIndex(self.frame_parent.my_loaded_volumes[0][0].z_slice_pos,)
            
        cur_cam = self.frame_parent.ren.GetActiveCamera()
        bounds =  self.frame_parent.my_loaded_volumes[0][0].data_bounds
        cur_cam.SetPosition((bounds[0]+bounds[1])/2,(bounds[2]+bounds[3])/2,(bounds[4]+bounds[5])/2+600)
        cur_cam.SetViewUp(0,1,0)
        cur_cam.SetViewAngle(30)
        self.frame_parent.widget.Render()
        align_all_planes(self.frame_parent)
        event.Skip()
        #EditObjectTree(self.frame_parent)