import re

import numpy as np
import dicom

import matplotlib.pyplot as plt
%matplotlib inline

from electroninserts import (
    parameterise_single_insert, display_parameterisation)

print("All modules and functions successfully imported.")

# !pip install --upgrade version_information
# %load_ext version_information
# %version_information dicom, electroninserts, re, numpy, matplotlib, version_information

"""
Explanation: Example shape parameterisation
End of explanation
"""


x = [0.99, -0.14, -1.0, -1.73, -2.56, -3.17, -3.49, -3.57, -3.17, -2.52, -1.76,
    -1.04, -0.17, 0.77, 1.63, 2.36, 2.79, 2.91, 3.04, 3.22, 3.34, 3.37, 3.08, 2.54,
    1.88, 1.02, 0.99]
y = [5.05, 4.98, 4.42, 3.24, 1.68, 0.6, -0.64, -1.48, -2.38, -3.77, -4.81,
    -5.26, -5.51, -5.58, -5.23, -4.64, -3.77, -2.77, -1.68, -0.29, 1.23, 2.68, 3.8,
    4.6, 5.01, 5.08, 5.05]

width, length, poi = parameterise_single_insert(x, y)
print("Width = {0:0.2f} cm\nLength = {1:0.2f} cm".format(width, length))

display_parameterisation(x, y, width, length, poi)

"""
Explanation: Parameterising shapes
Three options to parameterise shapes are given below; from raw coordinates, from an RT-DICOM file, or from a Monaco&reg; 5.10 tel.1 file.
There is also a placeholder for importing directly from Eclipse&trade;. Please let me know  if someone with access to Eclipse&trade; achieves this.
From coordinates
End of explanation
"""


# Change this name to match the dicom file located in the same directory
# as this notebook.
dicom_filename = "example_dicom_file.dcm"  

dcm = dicom.read_file(dicom_filename, force=True)
applicator_string = dcm.BeamSequence[0].ApplicatorSequence[0].ApplicatorID
energy_string = dcm.BeamSequence[0].ControlPointSequence[0].NominalBeamEnergy
ssd_string = dcm.BeamSequence[0].ControlPointSequence[0].SourceToSurfaceDistance

print("Applicator = {} (identifier name)".format(applicator_string))
print("Energy = {} (nominal)".format(energy_string))
print("SSD = {} (dicom units)\n".format(ssd_string))

block_data = np.array(dcm.BeamSequence[0].BlockSequence[0].BlockData)
x = np.array(block_data[0::2]).astype(float)/10
y = np.array(block_data[1::2]).astype(float)/10

width, length, poi = parameterise_single_insert(x, y)
print("Width = {0:0.2f} cm".format(width))
print("Length = {0:0.2f} cm".format(length))

display_parameterisation(x, y, width, length, poi)

"""
Explanation: From RT-DICOM
If you are using the online version of this notebook you will likely want to deidentify your dicom files. http://www.dicompyler.com/ can be used to do this however I am not in a position to guarantee it will do this adequately. You need to check this yourself.
To upload the dicom file go to notebook home and click the "upload button" located at the top right of the dashboard.
End of explanation
"""


# patientID = '00000'.zfill(6)
# string_search_pattern = r'\\MONACODA\FocalData\YOURDIRECTORYHERE\1~Clinical\*{}\plan\*\*tel.1'.format(patientID)
# string_search_pattern

# filepath_list = glob(string_search_pattern)
# filepath_list

telfilepath = "example_monaco510_telfile"
electronmodel_regex = "YourMachineName - \d+MeV"  # \d+ stands for any positive integer

with open(telfilepath, "r") as file:
    telfilecontents = np.array(file.read().splitlines())

electronmodel_index = []
for i, item in enumerate(telfilecontents):
    if re.search(electronmodel_regex, item):
        electronmodel_index += [i]

print("Located applicator and energy strings for plans within telfile:")
applicator_tel_string = [
    telfilecontents[i+12]  # applicator string is located 12 lines below electron model name
    for i in electronmodel_index]
print(applicator_tel_string)

energy_tel_string = [
    telfilecontents[i]
    for i in electronmodel_index]
print(energy_tel_string)

for i, index in enumerate(electronmodel_index):
    print("Applicator = {}".format(applicator_tel_string[i]))
    print("Energy = {}\n".format(energy_tel_string[i]))
    
    insert_inital_range = telfilecontents[
        index + 51::]  # coords start 51 lines after electron model name
    insert_stop = np.where(
        insert_inital_range=='0')[0][0]  # coords stop right before a line containing 0
    
    insert_coords_string = insert_inital_range[:insert_stop]
    insert_coords = np.fromstring(','.join(insert_coords_string), sep=',')
    x = insert_coords[0::2]/10
    y = insert_coords[1::2]/10
    
    width, length, poi = parameterise_single_insert(x, y)
    print("Width = {0:0.2f} cm".format(width))
    print("Length = {0:0.2f} cm".format(length))
    display_parameterisation(x, y, width, length, poi)

"""
Explanation: Directly from Monaco&reg; 5.10 server
The following code is an example of what can be used to automatically pull and parameterise shapes from the server based off of patient ID. For use in other centres it will need adjustment.
End of explanation
"""


