# Copyright (C) <2021>  <Reston Stanton>

# ##### BEGIN GPL LICENSE BLOCK #####
#
# 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
# MERCHANTIBILITY 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 <http://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####


from bpy import path
import bpy
from . import modifiers, particles, forces, material, uiCore


def unbaked_guides(domain):
    return (
        domain.use_guide and not domain.has_cache_baked_guide and
        ((domain.guide_source == 'EFFECTOR') or
            (domain.guide_source == 'DOMAIN' and not domain.guide_parent))
    )


def get_baking(settings, kind: str):
    """returns the False if selected cache type has been baked.
    usefull for self.enable()

    settings: any - the domain settings for fluid simulation
    kind: str - determans the cache that is checked. KEYS=("DATA", "MESH", "PARTICLE", "NOISE", "GUIDES", "ANY")

    """
    baking = settings.is_cache_baking_any
    type_baked = None
    if kind == "DATA":
        type_baked = settings.has_cache_baked_data
    if kind == "MESH":
        type_baked = settings.has_cache_baked_mesh
    if kind == "PARTICLE":
        type_baked = settings.has_cache_baked_particles
    if kind == "NOISE":
        type_baked = settings.has_cache_baked_noise
    if kind == "GUIDES":
        type_baked = settings.has_cache_baked_guide
    if kind == "ANY":
        type_baked = settings.has_cache_baked_any
    return not baking and not type_baked


def bake_guides(self: uiCore.Core, modifier_settings, kind):
    if modifier_settings.guide_source == "EFFECTOR" and modifier_settings.use_guide:
        self.set_layout("row", align=True, reset=True)
        self.enabled()
        bake_incomplete = (
            modifier_settings.cache_frame_pause_guide < modifier_settings.cache_frame_end)

        if modifier_settings.cache_resumable and modifier_settings.has_cache_baked_guide and not modifier_settings.is_cache_baking_guide and bake_incomplete:
            self.operator(
                "mantapro.bake", text="Resume", settings=[["op", "GUIDES_B"], ["domain_type", kind]])
            self.operator(
                "mantapro.bake", text="Free Guides", settings=[["op", "GUIDES_F"], ["domain_type", kind]])

        elif modifier_settings.is_cache_baking_guide and not modifier_settings.has_cache_baked_guide:
            self.operator("fluid.pause_bake",
                          text="Baking Guides - ESC to pause")
        elif not modifier_settings.has_cache_baked_guide and not modifier_settings.is_cache_baking_guide:
            self.operator(
                "mantapro.bake", text="Bake Guides", settings=[["op", "GUIDES_B"], ["domain_type", kind]])

        else:
            self.operator(
                "mantapro.bake", text="Free Guides", settings=[["op", "GUIDES_F"], ["domain_type", kind]])


def bake_data(self: uiCore.Core, modifier_settings, kind):
    if modifier_settings.cache_type == 'MODULAR':
        self.set_layout("col", reset=True)
        if unbaked_guides(modifier_settings):
            self.enabled(False)
            if modifier_settings.guide_source == "DOMAIN":
                self.label(text="No Guide Set")
            else:
                self.label(text="Unbaked Guides")
        # bake data
        bake_incomplete = (
            modifier_settings.cache_frame_pause_data < modifier_settings.cache_frame_end)

        if modifier_settings.cache_resumable and modifier_settings.has_cache_baked_data and not modifier_settings.is_cache_baking_data and bake_incomplete:
            self.operator("mantapro.bake", text="Resume", settings=[
                ["op", "DATA_B"], ["domain_type", kind]])
            self.operator("mantapro.bake", text="Free Data", settings=[
                ["op", "DATA_F"], ["domain_type", kind]])

        elif modifier_settings.is_cache_baking_data and not modifier_settings.has_cache_baked_data:
            self.operator("fluid.pause_bake",
                          text="Baking Data - ESC to pause")

        elif not modifier_settings.has_cache_baked_data and not modifier_settings.is_cache_baking_data:
            self.operator("mantapro.bake", text="Bake Data", settings=[
                ["op", "DATA_B"], ["domain_type", kind]])

        else:
            self.operator("mantapro.bake", text="Free Data", settings=[
                ["op", "DATA_F"], ["domain_type", kind]])


def bake_mesh(self: uiCore.Core, modifier_settings, kind):
    if modifier_settings.cache_type == 'MODULAR':
        self.set_layout("col", reset=True)
        if not modifier_settings.has_cache_baked_data:
            self.enabled(False)
            self.label(text="Unbaked Data: Bake Data first", icon="INFO")
        # bake mesh
        bake_incomplete = (
            modifier_settings.cache_frame_pause_mesh < modifier_settings.cache_frame_end)

        if modifier_settings.cache_resumable and modifier_settings.has_cache_baked_mesh and not modifier_settings.is_cache_baking_mesh and bake_incomplete:
            self.operator(
                "mantapro.bake", text="Resume", settings=[["op", "MESH_B"], ["domain_type", kind]])
            self.operator("mantapro.bake", text="Free Mesh", settings=[
                ["op", "MESH_F"], ["domain_type", kind]])
        elif modifier_settings.is_cache_baking_mesh and not modifier_settings.has_cache_baked_mesh:
            self.operator("fluid.pause_bake",
                          text="Baking Mesh - ESC to pause")
        elif not modifier_settings.has_cache_baked_mesh and not modifier_settings.is_cache_baking_mesh:
            self.operator(
                "mantapro.bake", text="Bake Mesh", settings=[["op", "MESH_B"], ["domain_type", kind]])
        else:
            self.operator("mantapro.bake", text="Free Mesh", settings=[
                ["op", "MESH_F"], ["domain_type", kind]])


def bake_particles(self, modifier_settings, kind):
    # bake particle
    if modifier_settings.cache_type == 'MODULAR':
        if modifier_settings.use_foam_particles or modifier_settings.use_spray_particles or modifier_settings.use_bubble_particles:
            self.set_layout("col", reset=True)
            if not modifier_settings.has_cache_baked_data:
                self.enabled(False)
                self.label(text="Unbaked Data: Bake Data first", icon="INFO")

            bake_incomplete = (
                modifier_settings.cache_frame_pause_particles < modifier_settings.cache_frame_end)
            if modifier_settings.cache_resumable and modifier_settings.has_cache_baked_particles and not modifier_settings.is_cache_baking_particles and bake_incomplete:
                self.operator(
                    "mantapro.bake", text="Resume", settings=[["op", "PARTICLE_B"], ["domain_type", kind]])
                self.operator(
                    "mantapro.bake", text="Free Particles", settings=[["op", "PARTICLE_F"], ["domain_type", kind]])
            elif modifier_settings.is_cache_baking_particles and not modifier_settings.has_cache_baked_particles:
                self.operator("fluid.pause_bake",
                              text="Baking Particles - ESC to pause")
            elif not modifier_settings.has_cache_baked_particles and not modifier_settings.is_cache_baking_particles:
                self.operator(
                    "mantapro.bake", text="Bake Particles", settings=[["op", "PARTICLE_B"], ["domain_type", kind]])
            else:
                self.operator(
                    "mantapro.bake", text="Free Particles", settings=[["op", "PARTICLE_F"], ["domain_type", kind]])


def bake_noise(self, modifier_settings, kind):
    if modifier_settings.use_noise and modifier_settings.cache_type == 'MODULAR':
        self.ui_reset()
        if not modifier_settings.has_cache_baked_data:
            self.enabled(False)
            self.label(text="Unbaked Data: Bake Data first", icon="INFO")
        bake_incomplete = (
            modifier_settings.cache_frame_pause_noise < modifier_settings.cache_frame_end)
        if modifier_settings.cache_resumable and modifier_settings.has_cache_baked_noise and not modifier_settings.is_cache_baking_noise and bake_incomplete:
            self.operator("mantapro.bake", text="Resume", settings=[
                ["op", "NOISE_B"], ["domain_type", kind]])
            self.operator("mantapro.bake", text="Free Noise", settings=[
                ["op", "NOISE_F"], ["domain_type", kind]])

        elif modifier_settings.is_cache_baking_noise and not modifier_settings.has_cache_baked_noise:
            self.operator("fluid.pause_bake",
                          text="Baking Noise - ESC to pause")
        elif not modifier_settings.has_cache_baked_noise and not modifier_settings.is_cache_baking_noise:
            self.operator(
                "mantapro.bake", text="Bake Noise", settings=[["op", "NOISE_B"], ["domain_type", kind]])
        else:
            self.operator("mantapro.bake", text="Free Noise", settings=[
                ["op", "NOISE_F"], ["domain_type", kind]])


def bake_all(self, modifier_settings, kind):
    if modifier_settings.cache_type == "ALL":
        self.set_layout("row", align=True, reset=True)
        bake_incomplete = (
            modifier_settings.cache_frame_pause_data < modifier_settings.cache_frame_end)
        if modifier_settings.cache_resumable and modifier_settings.has_cache_baked_any and not modifier_settings.is_cache_baking_data and bake_incomplete:
            self.operator("mantapro.bake", text="Resume", settings=[
                ["op", "ALL_B"], ["domain_type", kind]])
            self.operator("mantapro.bake", text="Free", settings=[
                ["op", "ALL_F"], ["domain_type", kind]])

        elif modifier_settings.is_cache_baking_data and not modifier_settings.has_cache_baked_data:
            self.operator("fluid.pause_bake",
                          text="Baking All - ESC to pause")
        elif not modifier_settings.has_cache_baked_data and not modifier_settings.is_cache_baking_data:
            self.operator("mantapro.bake", text="Bake All", settings=[
                ["op", "ALL_B"], ["domain_type", kind]])
        else:
            self.operator("mantapro.bake", text="Free Bake", settings=[
                ["op", "ALL_F"], ["domain_type", kind]])


def cache_worning(self, modifier_settings):
    if bpy.data.filepath and not modifier_settings.id_data.MantaPro.moved_cache:
        self.set_layout("col", align=True, reset=True)
        self.alert()
        self.ui_layout.scale_y = 0.7
        self.label(text="The default cache might be in a temporary directory")
        self.ui_refresh()
        self.ui_layout.emboss = "PULLDOWN_MENU"
        self.operator("mantapro.move_cache",
                      text="Move Cache (Recommended)", icon="ERROR")
        self.operator("mantapro.move_cache_ignore",
                      text="Ignore", icon="ERROR",)
        self.alert(False)
        self.separator(1)


def cache(self: uiCore.Core, modifier_settings, kind):
    self.set_layout("row", align=True, reset=True)

    cache_worning(self, modifier_settings)

    if modifier_settings.cache_type == "MODULAR":
        self.set_layout("col", align=True)

        bake_data(self, modifier_settings, kind)

        # NOISE

        if kind == "GAS":
            bake_mesh(self, modifier_settings, kind)

            bake_guides(self, modifier_settings, kind)
            return

        bake_mesh(self, modifier_settings, kind)

        # bake particle
        bake_particles(self, modifier_settings, kind)

        bake_guides(self, modifier_settings, kind)

    if modifier_settings.cache_type == "REPLAY":
        self.set_layout("col", reset=True)
        self.operator("mantapro.replay_clear",
                      text="Clear Cache", icon="LOOP_BACK")

    bake_all(self, modifier_settings, kind)


def effector(self: uiCore.Core, context):

    self.set_layout("col")

    if modifiers.check_type_liquid(context.scene.MantaPro.active_effector, "EFFECTOR"):

        modifier_settings = modifiers.find_modifier(
            context.scene.MantaPro.active_effector).effector_settings

        self.set_layout("col")
        self.label_prop(modifier_settings, "effector_type",
                        text="Effector Type")

        self.icon_prop(modifier_settings, "use_effector")

        self.prop(modifier_settings, "subframes")

        self.separator(factor=0.25)
        self.icon_prop(modifier_settings, "use_plane_init")
        self.separator(factor=0.25)

        self.prop(modifier_settings, "surface_distance",
                  text="surface thickness")

        if modifier_settings.effector_type == "GUIDE":
            self.separator(2)

            self.prop(modifier_settings, "velocity_factor",
                      text="Velocity Factor")
            self.prop(modifier_settings, "guide_mode")


def guides(self: uiCore.Core, modifier_settings):
    if modifier_settings.use_guide:
        self.set_layout("col")
        self.prop(modifier_settings, "guide_alpha")
        self.prop(modifier_settings, "guide_beta")
        self.prop(modifier_settings, "guide_vel_factor")
        self.label_prop(modifier_settings, "guide_source")

        if modifier_settings.guide_source == "DOMAIN":
            self.prop(modifier_settings, "guide_parent")
        else:
            pass
    else:
        self.label(text="Guides are disabled")


def simple_guides(self: uiCore.Core, modifier_settings):
    if modifier_settings.use_guide:
        self.set_layout("col")
        self.prop(modifier_settings, "guide_alpha", text="Lag?")
        #self.prop(modifier_settings, "guide_beta")
        #self.prop(modifier_settings, "guide_vel_factor")
        self.label_prop(modifier_settings, "guide_source")

        if modifier_settings.guide_source == "DOMAIN":
            self.prop(modifier_settings, "guide_parent")
    else:
        self.label(text="Guides are disabled")


def collections(self: uiCore.Core, modifier_settings):
    self.set_layout("col")
    self.label_prop(modifier_settings, "fluid_group", text="Flow")
    self.label_prop(modifier_settings, "effector_group", text="Effector")
    self.label_prop(modifier_settings.effector_weights,
                    "collection", text="Force Field")


def border_collisions(self: uiCore.Core, modifier_settings):
    self.set_layout("row")
    self.prop(modifier_settings, "use_collision_border_front")
    self.prop(modifier_settings, "use_collision_border_back")
    self.prop(modifier_settings, "use_collision_border_right")

    self.ui_refresh()
    self.prop(modifier_settings, "use_collision_border_left")
    self.prop(modifier_settings, "use_collision_border_top")
    self.prop(modifier_settings, "use_collision_border_bottom")


def field_weights(self: uiCore.Core, modifier_settings):
    self.set_layout("col")
    self.prop(modifier_settings.effector_weights, "gravity", slider=True)
    self.prop(modifier_settings.effector_weights, "all", slider=True)
    self.prop(modifier_settings.effector_weights, "force", slider=True)
    self.prop(modifier_settings.effector_weights, "vortex", slider=True)
    self.prop(modifier_settings.effector_weights, "magnetic", slider=True)
    self.prop(modifier_settings.effector_weights, "harmonic", slider=True)
    self.prop(modifier_settings.effector_weights, "charge", slider=True)

    self.prop(modifier_settings.effector_weights,
              "lennardjones", slider=True)

    self.prop(modifier_settings.effector_weights, "wind", slider=True)

    self.prop(modifier_settings.effector_weights,
              "curve_guide", slider=True)

    self.prop(modifier_settings.effector_weights, "texture", slider=True)
    self.prop(modifier_settings.effector_weights, "smokeflow", slider=True)
    self.prop(modifier_settings.effector_weights, "turbulence", slider=True)
    self.prop(modifier_settings.effector_weights, "drag", slider=True)
    self.prop(modifier_settings.effector_weights, "boid", slider=True)


def flow(self: uiCore.Core, modifier_settings):
    self.set_layout("col")
    self.label_prop(modifier_settings, "flow_behavior", text="Flow Behavior")

    if not modifier_settings.flow_behavior == "GEOMETRY":
        self.icon_prop(modifier_settings, "use_inflow")

    self.prop(modifier_settings, "subframes", text="Sampling Substeps")


def flow_source(self: uiCore.Core, modifier_settings, context=None):
    self.set_layout("col")
    is_gas = modifier_settings.flow_type != "LIQUID"
    if is_gas:
        self.label_prop(modifier_settings, "flow_source", text="Source")

    if modifier_settings.flow_source == "PARTICLES":
        self.prop_search(modifier_settings, "particle_system",
                         context.scene.MantaPro.active_flow, "particle_systems", text="Particle System")

        self.ui_refresh()
        self.set_layout("col", align=True)

        self.icon_prop(modifier_settings, "use_particle_size")

        if modifier_settings.use_particle_size:
            self.prop(modifier_settings, "particle_size")

        return

    self.icon_prop(modifier_settings, "use_plane_init")

    self.set_layout("col", align=True)
    self.prop(modifier_settings, "surface_distance",
              text="Emission Distance")
    if is_gas:
        self.prop(modifier_settings, "volume_density",
                  text="Volume Distance")


def initial_velocity(self: uiCore.Core, modifier_settings):
    self.set_layout("col")
    if modifier_settings.use_initial_velocity:
        self.prop(modifier_settings, "velocity_factor")
        self.prop(modifier_settings, "velocity_normal")
        self.prop(modifier_settings, "velocity_coord")
    else:
        self.label(text="Initial Velocity is disabled")


def gravity(self: uiCore.Core, modifier_settings, context):
    self.set_layout("col")
    self.label(text="Warning: Global Gravity effects ALL of blender")
    self.prop(context.scene, "use_gravity", text="Use Global Gravity")

    if context.scene.use_gravity:
        self.prop(context.scene, "gravity")
    else:
        self.ui_refresh()
        self.enabled(get_baking(modifier_settings, "DATA"))
        self.prop(modifier_settings, "gravity")
        self.label(text="Warning: animating this gravity is bugged")


def display(self: uiCore.Core, obj):
    self.set_layout("col")
    self.label_prop(obj, "display_type")
    self.prop(obj, "hide_render")
    settings = self.operator("mantapro.transparent_material", icon="CUBE")
    settings.obj = obj.name


def display_flow(self: uiCore.Core, obj):
    self.set_layout("col")
    self.label_prop(obj, "display_type")
    ember_system = particles.find_ember_system(obj)
    if ember_system:
        self.icon_prop(obj, "show_instancer_for_render", text="Disable in Renders (Emitter)",
                       icon_on="RESTRICT_RENDER_OFF", icon_off="RESTRICT_RENDER_ON", invert=True)
    else:
        self.prop(obj, "hide_render")
    settings = self.operator("mantapro.transparent_material", icon="CUBE")
    settings.obj = obj.name


"""
                          █████
                         ░░███
  ██████  █████████████   ░███████   ██████  ████████
 ███░░███░░███░░███░░███  ░███░░███ ███░░███░░███░░███
░███████  ░███ ░███ ░███  ░███ ░███░███████  ░███ ░░░
░███░░░   ░███ ░███ ░███  ░███ ░███░███░░░   ░███
░░██████  █████░███ █████ ████████ ░░██████  █████
 ░░░░░░  ░░░░░ ░░░ ░░░░░ ░░░░░░░░   ░░░░░░  ░░░░░



"""


def ember(self: uiCore.Core, context: bpy.types.Context):
    flow = context.scene.MantaPro.active_flow
    self.set_layout("col")
    system = particles.find_ember_system(flow)

    if system:
        settings = system.settings
        force = flow.MantaPro.ember_force_object
        if not force or not force.users_collection:
            self.set_layout("col")
            self.alert()
            self.label(text="Unable to find the force object")
            self.label(text="Try removing the ember system")
            self.label(text="Then add a new one")
            return
        force_settings = force.field
        cache = system.point_cache

        self.set_layout("col")
        if context.scene.render.engine == "CYCLES":
            self.icon_prop(context.scene.render,
                           "use_motion_blur", text="Motion Blur (Scene)")
        elif context.scene.render.engine == "BLENDER_EEVEE":
            self.icon_prop(context.scene.eevee, "use_motion_blur",
                           text="Motion Blur (Scene)")

        self.enabled(not cache.is_baked)

        self.set_layout("col", align=True)
        self.prop(settings, "count", text="Particle Count")
        self.prop(settings, "particle_size", text="Particle Size")
        self.prop(settings, "lifetime", text="Particle Lifetime")
        self.separator(factor=2)
        self.prop(settings, "brownian_factor", text="Random Movement")
        self.prop(settings, "normal_factor", text="Normal Velocity")
        self.prop(settings, "factor_random", text="Random Velocity")

        self.set_layout("row", align=True)
        self.enabled()
        if flow.MantaPro.ember_domain != force_settings.source_object:
            self.set_layout("row", align=True)
            self.alert()
            self.label("Force Domain Object is out of sync")
            self.operator("mantapro.ember_doamin_sync",
                          icon="FILE_REFRESH", text="")

        self.set_layout("col", align=True)
        self.prop(force_settings, "strength", text="Force Strength")
        self.separator()
        self.label_prop(flow.MantaPro, "ember_domain",
                        text="Force Domain Object")


def ember_particle(self: uiCore.Core, context: bpy.types.Context):
    flow = context.scene.MantaPro.active_flow
    system = particles.find_ember_system(flow)
    settings = system.settings
    cache = system.point_cache

    self.set_layout("col", align=True)
    self.enabled(not cache.is_baked)
    self.prop(system, "seed")
    self.separator()

    self.set_layout("col", align=True)
    self.prop(settings, "size_random", text="  Size Randomness")
    self.prop(settings, "lifetime_random", text="  Lifetime Randomness")
    self.separator()

    self.set_layout("col")
    self.prop(settings.effector_weights, "gravity",
              slider=True, text="  Gravity")

    self.separator()

    self.set_layout("row", align=True)
    self.icon_prop(flow.MantaPro, "ember_use_sub_force", text="Use Sub Force")
    self.set_layout("col", align=True)
    if settings.force_field_1.type == "FORCE":
        self.prop(settings, "effector_amount", text="Sub Force Count")
        self.prop(settings.force_field_1, "strength",
                  text="Sub Force Strength")
        self.prop(settings.force_field_1, "noise", text="Sub Force Noise")
        self.prop(settings.force_field_1, "distance_max",
                  text="Sub Force Distance")
    self.separator()

    self.set_layout("col", align=True)
    self.enabled(True)
    self.operator("mantapro.toggle_ember_particles", icon="VIS_SEL_10")
    self.separator()
    self.operator("mantapro.quick_toggle_ember_particles", icon="PIVOT_ACTIVE")


def ember_force(self: uiCore.Core, context: bpy.types.Context):
    flow = context.scene.MantaPro.active_flow
    force = flow.MantaPro.ember_force_object
    if not force or not force.users_collection:
        self.set_layout("col")
        self.alert()
        self.label(text="Unable to find the force object")
        self.label(text="Try removing the ember system")
        self.label(text="Then add a new one")
        return
    force_settings = force.field

    self.set_layout("col", align=True)
    self.label_prop(force_settings, "shape", text="Shape")
    self.separator()
    self.prop(force_settings, "flow")
    self.separator()
    self.icon_prop(force_settings, "use_smoke_density")


def ember_force_falloff(self: uiCore.Core, context: bpy.types.Context):
    flow = context.scene.MantaPro.active_flow
    force = flow.MantaPro.ember_force_object
    if not force or not force.users_collection:
        self.set_layout("col")
        self.alert()
        self.label(text="Unable to find the force object")
        self.label(text="Try removing the ember system")
        self.label(text="Then add a new one")
        return
    force_settings = force.field
    forces.draw_falloff(self, force_settings)


def ember_material(self: uiCore.Core, context):
    flow = context.scene.MantaPro.active_flow
    ember = flow.MantaPro.ember_particle_object
    emission, color_ramp, math, eevee_emission, eevee_mix = material.get_ember_nodes(
        ember)

    if emission and color_ramp and math and eevee_emission and eevee_mix:
        if context.scene.render.engine == "CYCLES":
            self.set_layout("col", align=True)
            self.material_prop(emission.inputs["Strength"])
            self.material_prop(math.inputs[1], "Color Fade Strength")

            self.set_layout("col", align=True)
            self.label_prop(
                color_ramp.color_ramp.elements[0], "color", "Ember Colors")
            self.prop(color_ramp.color_ramp.elements[1], "color", "")
        elif context.scene.render.engine == "BLENDER_EEVEE":
            self.set_layout("col")
            self.alert()
            self.label(text="The ember material is cycles only")
            self.label(text="An approximation is being used")

            self.set_layout("col", align=True)
            self.material_prop(
                eevee_emission.inputs["Strength"], text="Emission Strength")
            self.material_prop(eevee_mix.inputs[0], "  Transparency")

            self.set_layout("col", align=True)
            self.label_material_prop(
                eevee_emission.inputs["Color"], text="Color")
    else:
        self.set_layout("col")
        self.label(text="Material is not found or incorrect")
        self.operator("mantapro.fix_material", icon="TOOL_SETTINGS",
                      settings=[["kind", "EMBER"]])


def ember_cache(self: uiCore.Core, context):
    flow = context.scene.MantaPro.active_flow
    system = particles.find_ember_system(flow)
    settings = system.settings
    cache = system.point_cache
    if cache.is_outdated:
        self.set_layout("col")
        self.alert()
        self.label(text="     The Cache is Outdated")

    self.set_layout("col", align=True)
    self.enabled(not cache.is_baked)
    self.prop(settings, "frame_start")
    self.prop(settings, "frame_end")
    self.separator(factor=1)
    self.set_layout("col", align=True)
    self.enabled()

    self.operator("mantapro.bake_ember", text="Calculate to Frame",
                  settings=[["op", "TO_FRAME_B"]])
    self.separator()

    if cache.is_baked:
        self.operator("mantapro.bake_ember", text="Delete Bake",
                      settings=[["op", "CACHE_F"]])
    else:
        self.operator("mantapro.bake_ember", text="Bake",
                      settings=[["op", "CACHE_B"]])
    self.operator("mantapro.bake_ember", text="Current Cache to Bake",
                  settings=[["op", "CURRENT_TO_B"]])


def ember_custom_particles(self: uiCore.Core, context):
    flow = context.scene.MantaPro.active_flow
    system = particles.find_ember_system(flow)
    settings = system.settings

    self.set_layout("col", align=True)

    self.separator()
    self.label_prop(settings, "render_type", text="Render As")
    instance_type = settings.render_type

    if instance_type == "OBJECT" or instance_type == "COLLECTION":
        self.separator()
        self.label_prop(settings, "instance_" + instance_type.lower(),
                        text="Instance " + instance_type.capitalize())

    self.separator()
    self.label_prop(settings, "display_method", text="Display As")
    self.prop(settings, "display_percentage", text="View amount")


def MantaPro_tools(self: uiCore.Core, context):
    domain = context.scene.MantaPro.active_domain
    modifier_settings = modifiers.get_modifier_domain(domain=domain)

    self.set_layout("col", align=True)
    self.operator("mantapro.switch_type",
                  icon="ARROW_LEFTRIGHT", settings=[["kind", "DOMAIN"]])

    self.set_layout("col", align=True)
    self.operator(
        "mantapro.toggle_bounds", icon="PIVOT_BOUNDBOX", settings=[["kind", "FLUID"]])

    self.operator(
        "mantapro.display_bounds", icon="SHADING_BBOX", settings=[["kind", "FLUID"]])

    self.operator("mantapro.toggle_voxles_view", icon="MESH_GRID", text="Toggle Voxles")
