import vtk
from dv3dObjectsToRender import AddVTKObjectWithAttributes
from dv3dPropertyFrames import *
from numpy import array, reshape

def ActivationCone(the_parent_frame):
    cone = vtk.vtkCylinderSource()
    cone.SetHeight(100)
    cone.SetRadius(20)
    cone.SetResolution(50)
    
    coneMapper = vtk.vtkPolyDataMapper()
    coneMapper.SetInput(cone.GetOutput())
    
    coneActor = vtk.vtkActor()
    coneActor.SetMapper(coneMapper)
    coneActor.GetProperty().SetColor(1.0,1.0,0.0)
    coneActor.GetProperty().SetOpacity(0.5)
    
    AddVTKObjectWithAttributes(coneActor,\
                            the_parent_frame,\
                            'TMS Ray',\
                            'TMS Ray',\
                            None,\
                            None,\
                            0,\
                            1,\
                            1,\
                            'tool',\
                            None,\
                            'None',\
                            1,\
                            'TMSRayProperties',\
                            None)
    
    the_parent_frame.ren.AddActor(the_parent_frame.ListOfObjects[-1])
        
    new_actor = the_parent_frame.tree.AppendItem(the_parent_frame.tools, the_parent_frame.ListOfObjects[-1].my_label)
    #add the newly created treeitem as an atribute of the plane_group
    the_parent_frame.ListOfObjects[-1].my_treeitem = new_actor

    the_parent_frame.tree.Refresh()
    

    the_parent_frame.ray_transform = vtk.vtkTransform()
            
    the_parent_frame.rayActor = the_parent_frame.ListOfObjects[-1]
    
    #magic martix that aligns the ray to  the centre of the coil - hard coded TODO? auto?
    a = array((-0.00956527, -0.241935, 0.990634, -17.0767,
                   1.01494,-0.313879, -0.0150914, 207.699,
                   0.182687, 1.73113, 0.13571, 105.401,
                   0, 0, 0, 1)).reshape(4,4)
    
    the_parent_frame.ray_transform_origmatrix = vtk.vtkMatrix4x4()
    for i in range(4):
        for j in range(4):
            the_parent_frame.ray_transform_origmatrix.SetElement(i,j,a[i][j])
    
    the_parent_frame.ray_transform.SetMatrix(the_parent_frame.ray_transform_origmatrix)
    the_parent_frame.rayActor.SetUserTransform(the_parent_frame.ray_transform)
        
    # .. create a properties window for the plane set ...
    # we pass the parent frame and the newly created object as args
    frame = MyPropertyFrame(the_parent_frame, the_parent_frame.ListOfObjects[-1], 0)
    frame.Show(True)
    
    # ... and apply it to the relevant list object
    the_parent_frame.ListOfObjects[-1].my_property_frame_instance = frame    



def LoadTMSCoil(the_parent_frame):
    reader = vtk.vtkOBJReader()
    reader.SetFileName('./DV3D_essentials/tms_coils/tms_coil.obj')
    reader.Update()
    
    tms_mapper = vtk.vtkPolyDataMapper()
    tms_mapper.SetInput(reader.GetOutput())
        
    tms_actor = vtk.vtkActor()
    tms_actor.SetMapper(tms_mapper)
    tms_actor.GetProperty().SetColor(0.278,0.55,1.0)
    
    AddVTKObjectWithAttributes(tms_actor,\
                            the_parent_frame,\
                            'TMS Coil',\
                            'TMS Coil',\
                            None,\
                            None,\
                            0,\
                            1,\
                            1,\
                            'tool',\
                            None,\
                            'None',\
                            1,\
                            'TMSCoilProperties',\
                            None)
    
    the_parent_frame.ren.AddActor(the_parent_frame.ListOfObjects[-1])
        
    new_actor = the_parent_frame.tree.AppendItem(the_parent_frame.tools, the_parent_frame.ListOfObjects[-1].my_label)
    #add the newly created treeitem as an atribute of the plane_group
    the_parent_frame.ListOfObjects[-1].my_treeitem = new_actor


    the_parent_frame.tree.Refresh()
    
    #add a boxwidget so we can manipulate the position of the tms coil
    the_parent_frame.TMS_Widget = vtk.vtkBoxWidget()
    
    the_parent_frame.TMS_Widget.SetInteractor(the_parent_frame.widget)
    the_parent_frame.TMS_Widget.SetPlaceFactor(0.5)
    the_parent_frame.tms_transform = vtk.vtkTransform()
    def TransformActor(obj, event):
        obj.GetTransform(the_parent_frame.tms_transform)
        the_parent_frame.tmsActor.SetUserTransform(the_parent_frame.tms_transform)
        the_parent_frame.ray_transform.SetMatrix(the_parent_frame.ray_transform_origmatrix)
        the_parent_frame.ray_transform.PostMultiply()
        the_parent_frame.ray_transform.Concatenate(the_parent_frame.tms_transform.GetMatrix())
        the_parent_frame.rayActor.SetUserTransform(the_parent_frame.ray_transform)
            
    the_parent_frame.tmsActor = the_parent_frame.ListOfObjects[-1]
        
    the_parent_frame.TMS_Widget.SetProp3D(the_parent_frame.tmsActor)
    the_parent_frame.TMS_Widget.PlaceWidget()
    the_parent_frame.TMS_Widget.SetKeyPressActivationValue('g')
        
    the_parent_frame.TMS_Widget.AddObserver("InteractionEvent", TransformActor)
    
    
    # .. create a properties window for the plane set ...
    # we pass the parent frame and the newly created object as args
    frame = MyPropertyFrame(the_parent_frame, the_parent_frame.ListOfObjects[-1], 0)
    frame.Show(True)
    
    # ... and apply it to the relevant list object
    the_parent_frame.ListOfObjects[-1].my_property_frame_instance = frame
    
    align_all_planes(the_parent_frame)
    
    ActivationCone(the_parent_frame)