from .. import utils
from ..utils import exporter
from ..utils import caches
from ..cAPI import SimulationAPI
import os
import bpy

class HI_PHY_OT_ClearCache(bpy.types.Operator):
    bl_idname = "hi_phy.clear_cache"
    bl_label = "Hi Phy Clear Cache"
    bl_options = {'REGISTER'}
    solver_name: bpy.props.StringProperty(
        default='',
        name='Active Solver'
    )
    def execute(self, context):
        solver = context.scene.objects[self.solver_name]
        if not solver:
            self.report({"ERROR"}, "No valid hi phy solver")
            return {'CANCELLED'}
        if (solver.name in caches and caches[self.solver_name] and caches[self.solver_name].scene):
            cache = caches[self.solver_name]
            if cache.IsSimulationRunning():
                self.report({"WARNING"}, ("Simulation is still running"))
                return {'CANCELLED'}
            cache.SetToStartFrame()
            cache.Clear()
            return {'FINISHED'}
        self.report({"WARNING"}, ("No active cache to clear"))
        return {'CANCELLED'}

class HI_PHY_OT_SaveCache(bpy.types.Operator):
    bl_idname = "hi_phy.save_cache"
    bl_label = "Hi Phy Save Cache"
    bl_options = {'REGISTER'}
    solver_name: bpy.props.StringProperty(
        default='',
        name='Active Solver'
    )
    file_name: bpy.props.StringProperty(
        default='',
        name='File name',
        subtype='FILE_PATH'
    )
    def execute(self, context):
        abs_path = bpy.path.abspath("//" + self.file_name)
        solver = context.scene.objects[self.solver_name]
        if not solver:
            self.report({"ERROR"}, "No valid hi phy solver")
            return {'CANCELLED'}
        if (solver.name in caches and caches[self.solver_name] and caches[self.solver_name].scene):
            cache = caches[self.solver_name]
            if cache.IsSimulationRunning():
                self.report({"WARNING"}, ("Simulation is still running"))
                return {'CANCELLED'}
            if not cache.scene.Save(abs_path):
                self.report({"ERROR"}, "Failed to save cache file. Is it a valid file path?")
                return {'CANCELLED'}

            return {'FINISHED'}
        self.report({"WARNING"}, ("No active cache to save"))
        return {'CANCELLED'}

class HI_PHY_OT_LoadCache(bpy.types.Operator):
    bl_idname = "hi_phy.load_cache"
    bl_label = "Hi Phy Load Cache"
    bl_options = {'REGISTER'}
    solver_name: bpy.props.StringProperty(
        default='',
        name='Active Solver'
    )
    file_name: bpy.props.StringProperty(
        default='',
        name='File name',
        subtype='FILE_PATH'
    )
    def execute(self, context):
        abs_path = bpy.path.abspath("//" + self.file_name)
        solver = context.scene.objects[self.solver_name]
        if not solver:
            self.report({"ERROR"}, "No valid hi phy solver")
            return {'CANCELLED'}
        scene = SimulationAPI.Scene("simulation")
        if not scene.Load(abs_path):
            self.report({"ERROR"}, "Failed to load cache file. Does the file exists?")
            return {'CANCELLED'}
        if (solver.name in caches) :
            cache = caches[self.solver_name]
            # Set to start to remove deformation from the previous simulation
            cache.SetToStartFrame()
            cache.Clear()
        else:
            caches[self.solver_name] = exporter.Cache()
            cache = caches[self.solver_name]
        cache.SetScene(scene)
        return {'FINISHED'}


__CLASSES__ = [
    HI_PHY_OT_SaveCache,
    HI_PHY_OT_LoadCache,
    HI_PHY_OT_ClearCache
]

def register():
    for class_ in __CLASSES__:
        bpy.utils.register_class(class_)


def unregister():
    for class_ in reversed(__CLASSES__):
        bpy.utils.unregister_class(class_)
