import camitk
import json
import os

class MixedComponentExtension(camitk.ComponentExtension):
    _registered_instances = [] # needed to keep the component instance alive in python so that it is always visible in C++

    def getName(self):
        return "Python Mixed Component"
    
    def getDescription(self):
        return "The mixed component extension demonstrates how to create a new extension to managed <tt>.pymixed</tt> files that integrates mha and vtk together in <b>CamiTK</b>."
    
    def getFileExtensions(self):
        return [ "pymixed" ]
    
    def open(self, filename:str):
        MixedComponentExtension._registered_instances.append(MixedComponent(filename))
        camitk.refresh()

    def save(self, component:camitk.Component):
        camitk.warning(f"Saving {component.getName()} in {component.getFileName()} is not implemented yet.")
        return True

class MixedComponent(camitk.Component):
    def __init__(self, file):
        super().__init__(file, "Python Mixed Component from " + file)
    
        # Read the JSON file
        with open(file, 'r') as json_file:
            data = json.load(json_file)

        # Get the directory of the JSON file
        json_dir = os.path.dirname(file)

        # open the files
        self.addChild(camitk.Application.open(os.path.join(json_dir, data['image'])))
        self.addChild(camitk.Application.open(os.path.join(json_dir, data['mesh'])))

        image = self.getChildren()[0]
        mesh = self.getChildren()[1]

        # ensure that children will follow the mixed component frame
        camitk.TransformationManager.addTransformation(image.getFrame(), self.getFrame())
        camitk.TransformationManager.addTransformation(mesh.getFrame(), self.getFrame())
    
        # Force a default from this top level component to the world instead of any other default path
        camitk.TransformationManager.preferredDefaultIdentityToWorldLink(self.getFrame());

        # show only wireframe
        mesh.setRenderingModes(camitk.InterfaceGeometry.RenderingMode.Wireframe | camitk.InterfaceGeometry.RenderingMode.Surface)

        self.setSelected(True)