#  ***** BEGIN GPL LICENSE BLOCK *****
#
#   Copyright (C) 2024 Ilia Kurochkin <brothermechanic@yandex.com>
#
#   Created by Ilia Kurochkin (brothermechanic)
#   contact:    brothermechanic@yandex.com
#
#   This 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 *****
#
# coding: utf-8
'''
DESCRIPTION.
Basic mesh processing for asset pipeline.
DEPRECATED
'''

__version__ = '0.1'

import bpy


def shell_remesher(lowpoly_obj, mod_name='shell_mod', tree_name='shell_tree'):
    ''' Conctruct geometry nodes modifier. '''

    modifier = lowpoly_obj.modifiers.new(mod_name, type='NODES')
    tree = bpy.data.node_groups.new(name=tree_name, type='GeometryNodeTree')
    modifier.node_group = tree

    group_input = tree.nodes.new(type='NodeGroupInput')

    collection_info = tree.nodes.new(type='GeometryNodeCollectionInfo')
    collection_info.location = (300, 0)
    collection_info.transform_space = 'RELATIVE'

    tree.interface.new_socket(name='Collection', in_out='INPUT',
                              socket_type='NodeSocketCollection')
    tree.links.new(group_input.outputs['Collection'],
                   collection_info.inputs['Collection'])

    realize_instances = tree.nodes.new(type='GeometryNodeRealizeInstances')
    realize_instances.location = (600, 0)

    tree.links.new(collection_info.outputs[0],
                   realize_instances.inputs['Geometry'])

    mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
    mesh_to_volume.location = (900, 0)
    mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
    mesh_to_volume.inputs['Density'].default_value = 10.0
    mesh_to_volume.inputs['Voxel Size'].default_value = 0.005
    #mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.005

    tree.links.new(realize_instances.outputs['Geometry'],
                   mesh_to_volume.inputs['Mesh'])

    volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
    volume_to_mesh.location = (1200, 0)

    tree.links.new(mesh_to_volume.outputs['Volume'],
                   volume_to_mesh.inputs['Volume'])

    extrude_mesh = tree.nodes.new(type='GeometryNodeExtrudeMesh')
    extrude_mesh.location = (1500, 0)
    extrude_mesh.inputs['Offset Scale'].default_value = 0.001
    extrude_mesh.inputs['Individual'].default_value = False

    tree.links.new(volume_to_mesh.outputs['Mesh'],
                   extrude_mesh.inputs['Mesh'])

    # 1 pass
    mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
    mesh_to_volume.location = (1800, 0)
    mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
    mesh_to_volume.inputs['Density'].default_value = 1.0
    mesh_to_volume.inputs['Voxel Size'].default_value = 0.003
    #mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.003

    tree.links.new(extrude_mesh.outputs['Mesh'],
                   mesh_to_volume.inputs['Mesh'])

    volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
    volume_to_mesh.location = (2100, 0)

    tree.links.new(mesh_to_volume.outputs['Volume'],
                   volume_to_mesh.inputs['Volume'])

    set_position_01 = tree.nodes.new(type='GeometryNodeSetPosition')
    set_position_01.location = (2400, -300)

    tree.links.new(volume_to_mesh.outputs['Mesh'],
                   set_position_01.inputs['Geometry'])

    # 2 pass
    mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
    mesh_to_volume.location = (2700, 0)
    mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
    mesh_to_volume.inputs['Density'].default_value = 1.0
    mesh_to_volume.inputs['Voxel Size'].default_value = 0.001
    #mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.001

    tree.links.new(set_position_01.outputs['Geometry'],
                   mesh_to_volume.inputs['Mesh'])

    volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
    volume_to_mesh.location = (3000, 0)

    tree.links.new(mesh_to_volume.outputs['Volume'],
                   volume_to_mesh.inputs['Volume'])

    set_position_02 = tree.nodes.new(type='GeometryNodeSetPosition')
    set_position_02.location = (3300, -300)

    tree.links.new(volume_to_mesh.outputs['Mesh'],
                   set_position_02.inputs['Geometry'])

    # 3 pass
    mesh_to_volume = tree.nodes.new(type='GeometryNodeMeshToVolume')
    mesh_to_volume.location = (3600, 0)
    mesh_to_volume.resolution_mode = 'VOXEL_SIZE'
    mesh_to_volume.inputs['Density'].default_value = 1.0
    mesh_to_volume.inputs['Voxel Size'].default_value = 0.0005
    #mesh_to_volume.inputs['Exterior Band Width'].default_value = 0.0001

    tree.links.new(set_position_02.outputs['Geometry'],
                   mesh_to_volume.inputs['Mesh'])

    volume_to_mesh = tree.nodes.new(type='GeometryNodeVolumeToMesh')
    volume_to_mesh.location = (3900, 0)

    tree.links.new(mesh_to_volume.outputs['Volume'],
                   volume_to_mesh.inputs['Volume'])

    set_position_03 = tree.nodes.new(type='GeometryNodeSetPosition')
    set_position_03.location = (4200, -300)

    tree.links.new(volume_to_mesh.outputs['Mesh'],
                   set_position_03.inputs['Geometry'])

    group_output = tree.nodes.new(type='NodeGroupOutput')
    group_output.location = (4500, 0)

    tree.interface.new_socket(name='Geometry', in_out='OUTPUT',
                              socket_type='NodeSocketGeometry')
    tree.links.new(set_position_03.outputs['Geometry'],
                   group_output.inputs['Geometry'])

    geometry_proximity = tree.nodes.new(type='GeometryNodeProximity')
    geometry_proximity.location = (1200, -1000)

    tree.links.new(realize_instances.outputs['Geometry'],
                   geometry_proximity.inputs['Target'])
    tree.links.new(geometry_proximity.outputs['Position'],
                   set_position_01.inputs['Position'])
    tree.links.new(geometry_proximity.outputs['Position'],
                   set_position_02.inputs['Position'])
    tree.links.new(geometry_proximity.outputs['Position'],
                   set_position_03.inputs['Position'])

    return modifier
