# 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 #####


import bpy
from .. import preferences
from ..Shared import ops, material, modifiers, particles


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

"""


def set_domain(context, domain):
    pref = preferences.get_preferences()

    domain.modifiers["Fluid"].fluid_type = 'DOMAIN'

    modifier_settings = domain.modifiers["Fluid"].domain_settings

    modifier_settings.domain_type = 'LIQUID'
    modifier_settings.use_mesh = True
    modifier_settings.flip_ratio = 1
    modifier_settings.cache_frame_end = 250
    modifier_settings.resolution_max = pref.liquid_resolution
    modifier_settings.time_scale = pref.liquid_sim_speed
    modifier_settings.cache_resumable = True

    material.add_material(context.active_object, "MantaPro Liquid")

    context.scene.MantaPro.active_domain = domain
    context.active_object.MantaPro.particle_size = 1

    particles.add_particles(context)

    ops.set_domain_index(context, domain)

    if bpy.data.filepath:
        domain.MantaPro.moved_cache = True


def set_flow(context, obj):
    ops.set_flow_index(context, obj)


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


class MantaProDomain(bpy.types.Operator):
    bl_idname = "mantapro_liquid.make_domain"
    bl_label = "make selected domain"
    bl_description = "make selected object an domain"

    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return ops.add_poll(context)

    def execute(self, context):
        scene_set = context.scene.MantaPro
        # get current area
        area = context.area.ui_type
        context.area.ui_type = "VIEW_3D"
        bpy.ops.object.modifier_add(type='FLUID')

        set_domain(context, context.active_object)

        context.area.ui_type = area

        if preferences.get_preferences().auto_ops:
            context.scene.MantaPro.auto_ops = True
        return {'FINISHED'}


class MantaProAddDomain(bpy.types.Operator):
    bl_idname = "mantapro_liquid.add_domain"
    bl_label = "add domain object"
    bl_description = "add domain object to scene"

    bl_options = {'REGISTER', 'UNDO'}

    @ classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        # add domain object
        cursor = context.scene.cursor.location
        bpy.ops.mesh.primitive_cube_add(
            size=2, enter_editmode=False, location=cursor)
        domain = bpy.context.active_object
        domain.name = "domain"
        bpy.ops.object.editmode_toggle()
        bpy.ops.transform.translate(value=(0, 0, 1))
        bpy.ops.object.editmode_toggle()

        domain.scale = (5, 5, 5)
        bpy.ops.object.modifier_add(type='FLUID')
        bpy.ops.object.shade_smooth()
        set_domain(context, domain)

        if preferences.get_preferences().auto_ops:
            context.scene.MantaPro.auto_ops = True
        return {'FINISHED'}


class MantaProFlow(bpy.types.Operator):
    bl_idname = "mantapro_liquid.make_flow"
    bl_label = "make selected flow"
    bl_description = "make selected object an flow"

    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return ops.add_poll(context)

    def execute(self, context):
        # get current area
        area = context.area.ui_type
        context.area.ui_type = "VIEW_3D"

        obj = context.object

        bpy.ops.object.modifier_add(type='FLUID')
        context.object.modifiers["Fluid"].fluid_type = 'FLOW'
        modifier_settings = context.object.modifiers["Fluid"].flow_settings
        modifier_settings.flow_type = "LIQUID"
        modifier_settings.flow_behavior = "INFLOW"
        set_flow(context, obj)
        ops.move_to_collection(obj, "FLOW", context)

        context.area.ui_type = area

        if preferences.get_preferences().auto_ops:
            context.scene.MantaPro.auto_ops = True
        return {'FINISHED'}


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


class MantaProLinkParticels(bpy.types.Operator):
    bl_idname = "mantapro_liquid.link_particles"
    bl_label = "Link Particle"
    bl_description = "Set particles to default for MantaPro"

    @classmethod
    def poll(cls, context):
        if context.scene.MantaPro.active_domain:
            return True
        else:
            return False

    def execute(self, context):
        # get settings
        domain = context.scene.MantaPro.active_domain
        modifier_settings = modifiers.get_modifier_domain(domain=domain)
        modifier_settings.sndparticle_combined_export = "OFF"
        particles.sync_particles(context, domain)
        return {'FINISHED'}


class MantaProQuickToggleparticles(bpy.types.Operator):
    bl_idname = "mantapro_liquid.quick_toggle_particles"
    bl_label = "Quick Toggle"
    bl_description = "Switch all display to Point or Object"

    @classmethod
    def poll(cls, context):
        if context.scene.MantaPro.active_domain:
            return True
        else:
            return False

    def execute(self, context):
        # get settings
        domain = context.scene.MantaPro.active_domain
        sys = particles.get_sys(domain)
        if sys:
            first = sys[0].display_method
            if first == "DOT":
                switch = "RENDER"
            else:
                switch = "DOT"
            for i in sys:
                i.display_method = switch
        return {'FINISHED'}


class MantaProToggleParticles(bpy.types.Operator):
    bl_idname = "mantapro_liquid.toggle_liquid_particles"
    bl_label = "Reveal Particles"
    bl_description = "toggle particles objects visibility in the viewport"

    def execute(self, context):
        domain = context.scene.MantaPro.active_domain
        collection = domain.MantaPro.particle_collection
        if not collection:
            return {'CANCELLED'}
        if collection.hide_viewport:
            collection.hide_viewport = False
        else:
            collection.hide_viewport = True
        return {'FINISHED'}


class MantaProFluidRestoreGravity(bpy.types.Operator):
    bl_idname = "mantapro_liquid.restore_gravity"
    bl_label = "Restore Gravity"
    bl_description = "Restore gravity to default values"

    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        if context.scene.use_gravity:
            context.scene.gravity = (0, 0, -9.81)
        else:
            modifier_settings = modifiers.get_modifier_domain(
                domain=context.scene.MantaPro.active_domain)
            modifier_settings.gravity = (0, 0, -9.81)
        return {'FINISHED'}


class MantaProSetupEevee(bpy.types.Operator):
    bl_idname = "mantapro_liquid.setup_eevee"
    bl_label = "Setup Eevee"
    bl_description = "make smoke multi color"

    @ classmethod
    def poll(cls, context):
        domain = context.scene.MantaPro.active_domain
        if domain and context.engine == "BLENDER_EEVEE":
            return True
        else:
            return False

    def execute(self, context):
        context.scene.eevee.use_ssr = True
        context.scene.eevee.use_ssr_refraction = True
        return {'FINISHED'}


class MantaProIORRefrance(bpy.types.Operator):
    bl_idname = "mantapro_liquid.ior_refrance"
    bl_label = "IOR Refrance"
    bl_description = "Opens IOR Refrance website"

    @ classmethod
    def poll(cls, context):
        domain = context.scene.MantaPro.active_domain
        if domain:
            return True
        else:
            return False

    def execute(self, context):
        bpy.ops.wm.url_open(url="https://pixelandpoly.com/ior.html#ior-w")
        return {'FINISHED'}


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

classes = (MantaProDomain,
           MantaProFlow, MantaProAddDomain,
           MantaProToggleParticles,
           MantaProLinkParticels, MantaProQuickToggleparticles,
           MantaProFluidRestoreGravity, MantaProSetupEevee,
           MantaProIORRefrance,)

keymaps = []


def register():
    for i in classes:
        bpy.utils.register_class(i)


def unregister():
    for i in classes:
        bpy.utils.unregister_class(i)
