import bpy
import mathutils

class SaveMusclesPosOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.save_muscles_operator"
    bl_label = "Save muscles positions"
    filepath = bpy.props.StringProperty(subtype="FILE_PATH")

    @classmethod
    def poll(cls, context):
        return context.active_object is not None and context.active_object.type == 'MESH'

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

    def execute(self, context):
        print("Filename: %s" % self.filepath)
        muscles = [obj for obj in bpy.data.objects if obj.type == 'MUSCLE']
        obj = context.active_object
        vs = context.active_object.data.vertices
        f = open(self.filepath, 'w')
        f.write("%d\n" % len(muscles))
        for muscle in sorted(muscles, key=lambda x: 0 if x.parent is None else 1):
            loc = muscle.location.copy()
            if muscle.parent is not None:
                loc += muscle.parent.location
            mdist = -1
            mv = None
            mid = None
            for id in range(0, len(vs)):
                v = vs[id]
                dist = (obj.matrix_world*v.co - loc).magnitude
                #print("Dist is %f" % dist)
                if (mdist == -1) or (dist < mdist):
                    mv = v
                    mdist = dist
                    mid = id
            disp = loc - obj.matrix_world*mv.co
            f.write("%s\n" % muscle.name)
            f.write("%s\n" % muscle.data.type)
            f.write("%s\n" % (muscle.parent.name if muscle.parent is not None else ""))
            md = muscle.data
            f.write("%d %f %f %f %f %f %f %f %f %f %d %f %f\n" % (mid, disp[0], disp[1], disp[2], md.omega, md.height, md.fs, md.ff, md.k, md.wrinkle_h, md.wrinkle_n, md.r, md.h))
            print("Muscle %s closest vertex is %d on %f, %f, %f with displacement %f, %f, %f" % (muscle.name, mid, mv.co[0], mv.co[1], mv.co[2], disp[0], disp[1], disp[2]))
        f.close()
        #print(bpy.data.muscles)
        #context.mesh
        return {'FINISHED'}


class LoadMusclesOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.load_muscles_operator"
    bl_label = "Load muscles from file"
    filepath = bpy.props.StringProperty(subtype="FILE_PATH")

    @classmethod
    def poll(cls, context):
        return context.active_object is not None and context.active_object.type == 'MESH'

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

    def execute(self, context):
        obj = context.active_object
        vs = context.active_object.data.vertices
        f = open(self.filepath, 'r')
        n = int(f.readline().strip())
        created = {}
        for i in range(0, n):
            name = f.readline().strip()
            type = f.readline().strip()
            parent_name = f.readline().strip()
            data = f.readline().strip()
            vid, dx, dy, dz, omega, height, fs, ff, k, wrinkle_h, wrinkle_n, r, h = data.split(" ")
            loc = obj.matrix_world*obj.data.vertices[int(vid)].co
            loc = loc + mathutils.Vector((float(dx), float(dy), float(dz)))
            md = bpy.data.muscles.new(name + '_data')
            md.omega = float(omega)
            md.height = float(height)
            md.fs = float(fs)
            md.ff = float(ff)
            md.k = float(k)
            md.wrinkle_h = float(wrinkle_h)
            md.wrinkle_n = int(wrinkle_n)
            md.r = float(r)
            md.h = float(h)
            md.type = type
            musc_ob = bpy.data.objects.new(name, md)
            context.scene.objects.link(musc_ob)
            if parent_name != "":
                musc_ob.parent = created[parent_name]
                loc -= created[parent_name].location
            musc_ob.location = loc
            created[name] = musc_ob
        f.close()
        #print(bpy.data.muscles)
        #context.mesh
        return {'FINISHED'}
