# ##### BEGIN GPL LICENSE BLOCK #####
#
#  Copyright (C) 2022 VFX Grace - All Rights Reserved
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####

import bpy
import os
import sys
import platform
from ctypes import *


def init_module():
    lib_name = "hair_modifier"
    version = bpy.app.version
    if version[:2] == (3, 2):
        lib_name += "_320_py310"
    elif version[:2] == (3, 1):
        lib_name += "_310_py310"
    elif version[:2] == (3, 0):
        lib_name += "_300_py39"
    elif version[:2] == (2, 93):
        if bpy.app.version[2] < 4 or (bpy.app.version[2] == 4 and bpy.app.version_cycle != 'release'):
            lib_name += "_293_py39"
        else:
            lib_name += "_2934_py39"

    dirname = os.path.dirname(__file__)

    if sys.platform.startswith("linux"):
        ext = ".so"
    else:
        assert sys.platform.startswith("darwin")
        ext = ".dylib"
        if platform.machine() == 'arm64':
            dirname += "/darwin_arm64"

    dylib = cdll.LoadLibrary(f'{dirname}/{lib_name}{ext}')
    dylib.create_modifier.argtypes = (c_int,)
    dylib.create_modifier.restype = c_void_p

    dylib.apply_modifiers_wrap.argtypes = (c_void_p, c_int, c_void_p, c_void_p, c_int)

    dylib.reset_child_pathcache.argtypes = (c_void_p,)

    dylib.free_modifier.argtypes = (c_void_p,)

    dylib.set_scene_cddata_masks_to_mesh.argtypes = (c_void_p,)

    dylib.restore_scene_cddata_masks.argtypes = (c_void_p,)

    dylib.set_texture_evaluate_function.argtypes = (c_void_p,)

    dylib.set_mesh_calc_looptri_function.argtypes = (c_void_p,)

    dylib.get_clump_modifier_clump_point_count.argtypes = (c_void_p,)
    dylib.get_clump_modifier_clump_point_count.restype = c_int

    return dylib


py_clib = init_module()


def create_modifier(mod_type):
    return py_clib.create_modifier(mod_type)


def apply_modifiers(mods, obj, psys, flag):
    length = len(mods)
    if length == 0:
        ptrs = c_void_p(0)
    else:
        ptrs = (c_void_p * length)()
        for i in range(length):
            ptrs[i] = mods[i]

    return py_clib.apply_modifiers_wrap(ptrs, length, obj, psys, flag)


def reset_child_pathcache(psys):
    return py_clib.reset_child_pathcache(psys)


def free_modifier(modifier):
    return py_clib.free_modifier(modifier)


def set_scene_cddata_masks_to_mesh(scene):
    return py_clib.set_scene_cddata_masks_to_mesh(scene)


def restore_scene_cddata_masks(scene):
    return py_clib.restore_scene_cddata_masks(scene)


def set_texture_evaluate_function(func):
    return py_clib.set_texture_evaluate_function(func)


def set_mesh_calc_looptri_function(func):
    return py_clib.set_mesh_calc_looptri_function(func)


def get_clump_modifier_clump_point_count(mod):
    return py_clib.get_clump_modifier_clump_point_count(mod)
