#!/usr/bin/env python

import wx
import sys
import vtk
from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
from dv3dPlaneWidgets import *
import time
from common_functions import align_all_planes

class OrthoViews(wx.Frame):
    def __init__(self, frame_parent, p_type=None):#, plane1, plane2, plane3):
        global top_corner
        if p_type == 0:
            top_corner = wx.Point(825,0)
        elif p_type == 1:
            top_corner = wx.Point(825,255)
        elif p_type == 2:
            top_corner = wx.Point(825,480)
            
        wx.Frame.__init__(self, None, wx.ID_ANY, 'DV3D - Orthogonal Views', top_corner)


        #so the main routine can update this window when required
        self.frame_parent = frame_parent

        bg_sizer = wx.BoxSizer(wx.VERTICAL)
        bg_sizer2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_button_spacer = wx.FlexGridSizer(1, 3, 2, 2)
        sizer_button_holder = wx.FlexGridSizer(6, 1, 3, 3)
        sizer_vtk_holder = wx.BoxSizer(wx.HORIZONTAL)
        


        self.panel_button_bg = wx.Panel(self, -1, style=wx.NO_BORDER)
        self.panel_vtk_bg = wx.Panel(self, -1)
	self.panel_vtk_bg.SetSizer(sizer_vtk_holder)
        
	self.Sync_with_main_window = wx.CheckBox(self.panel_button_bg , -1, 'Auto update? (slower)')
        self.Sync_with_main_window.SetValue(True)
        self.Sync_with_main_window.Bind(wx.EVT_CHECKBOX, self.OnSync_with_main_window,
              id=-1)

        self.L_R_flip = wx.CheckBox(self.panel_button_bg , -1, 'L_R_flip')
        self.L_R_flip.SetValue(False)
        self.L_R_flip.Bind(wx.EVT_CHECKBOX, self.OnL_R_flip , id=-1)
	if p_type == 0:
		self.L_R_flip.Enable(0)

        self.enable_planes = wx.CheckBox(self.panel_button_bg , -1, 'Enable plane interaction')
        self.enable_planes.SetValue(False)
        self.enable_planes.Bind(wx.EVT_CHECKBOX, self.OnEnable_planes , id=-1)    

        self.Manual_sync_with_main_window = wx.Button(self.panel_button_bg , -1, 'Manually update now')
        self.Manual_sync_with_main_window.Bind(wx.EVT_BUTTON, self.OnManual_sync_with_main_window,
              id=-1)
        self.Manual_sync_with_main_window.Enable(0)


        self.widget1 = wxVTKRenderWindowInteractor(self.panel_vtk_bg, -1)
    
        widget_list = [self.widget1]
        self.picker = vtk.vtkCellPicker()
        
        self.ortho_planes = []
        
        orthoWidget = create_new_planewidget(widget_list[0],                              \
                          self.frame_parent.my_loaded_volumes[0][0].volume_data.GetOutput(),                                   \
                          self.frame_parent.slice_pos[p_type],   \
                          p_type,self.picker,0,self.frame_parent)
        orthoWidget.SetLookupTable(self.frame_parent.ListOfObjects[0].GetLookupTable())
        self.frame_parent.ortho_planes.append(orthoWidget)

        self.plane1 = self.frame_parent.ortho_planes[-1]

        
        self.plane1.SetInteractor(self.widget1)

        self.ortho_ren1 = vtk.vtkRenderer()
        self.frame_parent.ortho_planes[-1].ortho_ren1 = self.ortho_ren1
	#it makes sense to use parallel projection for 2-d planes and perspective 
	# projection for the 3d views - might  ake this more flexible but can't see
	# why it would be necessary
        self.ortho_ren1.GetActiveCamera().ParallelProjectionOn()

        self.widget1.Enable()

        self.widget1.GetRenderWindow().AddRenderer(self.ortho_ren1)
        self.widget1.GetRenderWindow().SetSize(300,300)

        self.interactor_style1 = vtk.vtkInteractorStyleTrackballCamera()

        self.widget1.SetInteractorStyle(self.interactor_style1)

        self.plane1.On()     
       
        self.widget1.AddObserver("ExitEvent", lambda o,e,f=self: f.Close())

	sizer_vtk_holder.Add(self.widget1, 1, wx.EXPAND)

        bg_sizer2.Add(self.panel_vtk_bg, 1, wx.EXPAND, 0)
        sizer_button_holder.Add(self.Sync_with_main_window, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
        sizer_button_holder.Add(self.L_R_flip, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
        sizer_button_holder.Add(self.enable_planes, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
        sizer_button_holder.Add(self.Manual_sync_with_main_window, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
        #sizer_button_holder.Add(self.label_1, 0, wx.ADJUST_MINSIZE, 0)
        sizer_button_spacer.Add(sizer_button_holder, 1, wx.EXPAND, 0)
        
	self.panel_button_bg.SetSizer(sizer_button_spacer)
        bg_sizer2.Add(self.panel_button_bg, 0, wx.EXPAND, 0)
        bg_sizer.Add(bg_sizer2, 1, wx.EXPAND, 0)
        self.SetSizer(bg_sizer)
        bg_sizer.Fit(self)
        
        self.SetSize((300,150))
        self.Layout()


        bounds = self.frame_parent.my_loaded_volumes[0][0].data_bounds
        
        self.midx = (bounds[1]-bounds[0])/2
        self.midy = (bounds[3]-bounds[2])/2
        self.midz = (bounds[5]-bounds[4])/2
        
        if p_type == 0:
            cur_cam = self.ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(1000, self.midy, self.midz)
            cur_cam.SetFocalPoint(self.midx, self.midy, self.midz)
            cur_cam.SetViewUp(0,0,1)
            
        elif p_type == 1:        
            cur_cam = self.ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(self.midx, 1000, self.midz)
            cur_cam.SetFocalPoint(self.midx, self.midy, self.midz)
            cur_cam.SetViewUp(0,0,1)
            
        elif p_type == 2: 
            cur_cam = self.ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(self.midx, self.midy, -1000)
            cur_cam.SetFocalPoint(self.midx, self.midy, self.midz)
            cur_cam.SetViewUp(0,1,0)
        

        
        self.ortho_ren1.ResetCamera()  
        self.widget1.Render()
        
        self.widget1.Disable()

        self.SetSizeHints(400,200)
        
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
        
        self.frame_parent.SYNC_ortho = 1


    def OnCloseWindow(self, event):
        try:
            # pass False to the close routine to veto the attempt to close
            #  the window .. only close it when the main app widow closes
            self.Close(0)
        except:
            pass #sys.exit()


    def OnManual_sync_with_main_window(self, event):
        self.ortho_ren1.ResetCamera()  
        self.widget1.Render()

    def OnEnable_planes(self, event):
        if self.enable_planes.GetValue() == True:
            self.widget1.Enable()
        else:
            self.widget1.Disable()

    def OnSync_with_main_window(self, event):
        if self.Sync_with_main_window.GetValue() == True:
            self.frame_parent.SYNC_ortho = 1
            self.frame_parent.ortho_windowX.Manual_sync_with_main_window.Enable(0)
	    self.frame_parent.ortho_windowY.Manual_sync_with_main_window.Enable(0)
	    self.frame_parent.ortho_windowZ.Manual_sync_with_main_window.Enable(0)
	    #change the values of all the ortho windows
	    self.frame_parent.ortho_windowX.Sync_with_main_window.SetValue(True)
	    self.frame_parent.ortho_windowY.Sync_with_main_window.SetValue(True)
	    self.frame_parent.ortho_windowZ.Sync_with_main_window.SetValue(True)
        else:
            self.frame_parent.SYNC_ortho = 0
            self.frame_parent.ortho_windowX.Manual_sync_with_main_window.Enable(1)
	    self.frame_parent.ortho_windowY.Manual_sync_with_main_window.Enable(1)
	    self.frame_parent.ortho_windowZ.Manual_sync_with_main_window.Enable(1)
	    #change the values of all the ortho windows
	    self.frame_parent.ortho_windowX.Sync_with_main_window.SetValue(False)
	    self.frame_parent.ortho_windowY.Sync_with_main_window.SetValue(False)
	    self.frame_parent.ortho_windowZ.Sync_with_main_window.SetValue(False)

    def OnL_R_flip(self, event):
        if self.L_R_flip.GetValue() == True:
            cur_cam = self.frame_parent.ortho_planes[2].ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(self.midx, self.midy, +1000)
            self.frame_parent.ortho_planes[2].ortho_ren1.ResetCamera()
            cur_cam = self.frame_parent.ortho_planes[1].ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(self.midx, -1000, self.midz)
            self.frame_parent.ortho_planes[1].ortho_ren1.ResetCamera()
        else:
            cur_cam = self.frame_parent.ortho_planes[2].ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(self.midx, self.midy, -1000)
            self.frame_parent.ortho_planes[2].ortho_ren1.ResetCamera()
            cur_cam = self.frame_parent.ortho_planes[1].ortho_ren1.GetActiveCamera()
            cur_cam.SetPosition(self.midx, 1000, self.midz)
            self.frame_parent.ortho_planes[1].ortho_ren1.ResetCamera()
        self.widget1.Render()


if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_1 = MyFrame(None, -1, "")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()
