#Process for dealing with cross-referencing co-ordinates between a loaded reference
# volume and the original loaded planes

import wx
import os
import time
from numpy import *


class ProcessCoords:
    def __init__(self, parent, frame_parent):
 
        self.frame_parent = frame_parent


def calculateMM(self, frame_parent):

    self.frame_parent = frame_parent
    
    r = self.frame_parent.cursor_curr_slice_num
    # output the current mm position (corresponding to the slice position)
    x = self.frame_parent.my_loaded_volumes[0][0].data_s_row_x[0] * r[0] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_x[1] * r[1] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_x[2] * r[2] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_x[3]

    y = self.frame_parent.my_loaded_volumes[0][0].data_s_row_y[0] * r[0] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_y[1] * r[1] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_y[2] * r[2] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_y[3]

    z = self.frame_parent.my_loaded_volumes[0][0].data_s_row_z[0] * r[0] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_z[1] * r[1] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_z[2] * r[2] \
      + self.frame_parent.my_loaded_volumes[0][0].data_s_row_z[3]
    
    print r,x,y,z
    return x,y,z


def calculate_ref_MM(self, frame_parent):

    self.frame_parent = frame_parent

    r = self.frame_parent.cursor_curr_slice_num
    p1=array(list(r)+[1])*array(list(self.frame_parent.my_loaded_volumes[0][0].data_spacing)+[1])
    T = self.frame_parent.ref_transform
    ref_slice_num=dot(T,p1)/array(list(self.frame_parent.ref_dims)+[1])

    # go from REF (slices) to REF (mm)
    ref_mm =  dot(self.frame_parent.ref_s_form,ref_slice_num)
    
    # go from REF (mm) to Talairach (mm)
    self.frame_parent.tal_mm_raw = dot(self.frame_parent.MTT_pooled, ref_mm)
    
    ref_slice_num = str('(%s, %s, %s)' %(int(ref_slice_num[0]),int(ref_slice_num[1]),int(ref_slice_num[2])))
    ref_mm = str('(%s, %s, %s)' %(int(ref_mm[0]),int(ref_mm[1]),int(ref_mm[2])))
    tal_mm = str('(%s, %s, %s)' %(int(self.frame_parent.tal_mm_raw[0]),int(self.frame_parent.tal_mm_raw[1]),int(self.frame_parent.tal_mm_raw[2])))
    print ref_slice_num, ref_mm, tal_mm
    return ref_slice_num, ref_mm, tal_mm


def lookup_tal_location(self, frame_parent):

    self.frame_parent = frame_parent
    
    print self.frame_parent.tal_mm_raw[0],self.frame_parent.tal_mm_raw[1], self.frame_parent.tal_mm_raw[2]
    
    tal_x_slice, tal_y_slice, tal_z_slice = int(self.frame_parent.tal_mm_raw[0]-self.frame_parent.my_loaded_volumes[1][0].data_s_row_x[3]),    \
                                            int(self.frame_parent.tal_mm_raw[1]-self.frame_parent.my_loaded_volumes[1][0].data_s_row_y[3]),    \
                                            int(self.frame_parent.tal_mm_raw[2]-self.frame_parent.my_loaded_volumes[1][0].data_s_row_z[3])

    
    bounds = self.frame_parent.my_loaded_volumes[1][0].data_bounds
    
    #print '/n'
    #print self.frame_parent.my_loaded_volumes[1][0].data_s_row_x[3]
    #print self.frame_parent.my_loaded_volumes[1][0].data_s_row_y[3]
    #print self.frame_parent.my_loaded_volumes[1][0].data_s_row_z[3]
    tal_x_slice = -tal_x_slice
    print 'bounds', bounds
    print 'tal slice num ', tal_x_slice, tal_y_slice, tal_z_slice
    #print '/n'
    
    if (tal_x_slice < bounds[0]) or \
        (tal_x_slice > bounds[1]) or \
        (tal_y_slice < bounds[2]) or \
        (tal_y_slice > bounds[3]) or \
        (tal_z_slice < bounds[4]) or \
        (tal_z_slice > bounds[5]):
        ref_string = 'outside brain area'
    else:
        ref_string_value = self.frame_parent.my_loaded_volumes[1][0].volume_data.GetOutput().GetScalarComponentAsFloat(-tal_x_slice,tal_y_slice,tal_z_slice,0)
        ref_string = self.frame_parent.tal_ref_list[int(ref_string_value)]
    return tal_x_slice, tal_y_slice, tal_z_slice, ref_string


def display_coords(self, frame_parent):
    self.frame_parent = frame_parent

    base_slice = self.frame_parent.cursor_curr_slice_num
    base_mm = calculateMM(self.frame_parent, self)
    base_mm_x, base_mm_y, base_mm_z = calculateMM(self.frame_parent, self)
    self.frame_parent.SetStatusText(str(self.frame_parent.cursor_curr_slice_num))
    self.frame_parent.textCtrl1.SetValue('data slice: %s\ndata mm: %.1f, %.1f %.1f' \
         %(str(base_slice),base_mm_x, base_mm_y, base_mm_z))
    if self.frame_parent.ref_loaded == 1:
       if self.frame_parent.ShowRefTransform == 1:
           ref_slice_num, ref_mm , self.frame_parent.tal_mm = calculate_ref_MM(self.frame_parent, self)
           self.frame_parent.textCtrl1.AppendText('\n\nRef slice: %s\nRef mm: %s' %(ref_slice_num, ref_mm))
           if self.frame_parent.ShowTalTransform == 1:
               t_x, t_y, t_z, tal_location_text = lookup_tal_location(self.frame_parent, self)
               self.frame_parent.textCtrl1.AppendText('\n\nTalairach slice: (%s, %s, %s)' %(t_x, t_y, t_z))
               self.frame_parent.textCtrl1.AppendText('\nTalairach mm: %s' %self.frame_parent.tal_mm)
               self.frame_parent.textCtrl1.AppendText('\nTalairach position: \n%s' %tal_location_text)






