import bpy

currentSettings = None
k_lightmapNodeGroupName = "NEEDLE_lightmap"

def getLightmapNodeGroupName():
    return k_lightmapNodeGroupName

class LightmapBakeContext():
    lightmap: bpy.types.Image
    width: int

    # experimental options
    selection_only: bool = False
    view_only: bool = False

    def __init__(self, width: int, height: int):
        global currentSettings
        currentSettings = self
        print("Lightmap size: " + str(width) + "x" + str(height) + "px")
        self.lightmap = getLightmapImage(width, height)
        self.width = width

    def cleanup(self):
        global currentSettings
        currentSettings = None


class RenderSettings():
    def __init__(self):
        # https://github.com/blender/blender/blob/e6e57cebecd13c2f30cee3a8262eda3c3191acbd/intern/cycles/hydra/render_delegate.h#L19
        self.scene = bpy.context.scene
        self.cycles = bpy.context.scene.cycles
        self.use_denoising = self.cycles.use_denoising
        self.denoising_prefilter = self.cycles.denoising_prefilter
        self.denoising_input_passes = self.cycles.denoising_input_passes
        # max samples:
        self.samples = self.cycles.samples
        # min samples:
        self.sample_offset = self.cycles.sample_offset
        self.time_limit = self.cycles.time_limit
        # noise threshold:
        self.adaptive_threshold = self.cycles.adaptive_threshold

        self.bake_settings = self.scene.render.bake
        self.bake_target = self.bake_settings.target

    def apply(self, quality_mode:str, use_denoising:bool):
        print("Using Lightmap Quality Mode: " + str(quality_mode))
        cycles = self.cycles

        if quality_mode != "CUSTOM":
            self.bake_settings.target = "IMAGE_TEXTURES"

        if quality_mode == "PREVIEW":
            cycles.use_denoising = use_denoising
            cycles.denoising_prefilter = 'FAST'
            cycles.denoising_input_passes = 'RGB_ALBEDO'
            cycles.samples = 1024
            cycles.sample_offset = 0
            cycles.use_adaptive_sampling = True
            cycles.time_limit = 0.05
            cycles.adaptive_threshold = .01
            cycles.noise_threshold = .2
            cycles.use_fast_gi = True
            cycles.use_camera_cull = True
            cycles.tile_size = 512
            cycles.max_bounces = 1
            cycles.transparent_max_bounces = 1
            cycles.transmission_bounces = 1
            cycles.glossy_bounces = 1
        elif quality_mode == "HIGH":
            cycles.use_denoising = use_denoising
            cycles.denoising_prefilter = 'ACCURATE'
            cycles.denoising_input_passes = 'RGB_ALBEDO_NORMAL'
            cycles.samples = 4096
            cycles.sample_offset = 0
            cycles.use_adaptive_sampling = True
            cycles.time_limit = .2
            cycles.adaptive_threshold = .0005
            cycles.noise_threshold = .1
            cycles.use_fast_gi = True
            cycles.use_camera_cull = True
            cycles.tile_size = 512
            cycles.max_bounces = 2
            cycles.transparent_max_bounces = 2
            cycles.transmission_bounces = 2
            cycles.glossy_bounces = 2

        elif quality_mode == "CUSTOM":
            pass

    def reset(self):
        bake_settings = self.bake_settings
        bake_settings.target = self.bake_target

        cycles = self.cycles
        cycles.use_denoising = self.use_denoising
        cycles.denoising_prefilter = self.denoising_prefilter
        cycles.denoising_input_passes = self.denoising_input_passes
        cycles.samples = self.samples
        cycles.sample_offset = self.sample_offset
        cycles.time_limit = self.time_limit
        cycles.adaptive_threshold = self.adaptive_threshold
        pass



k_needleLightmapImageName = "NEEDLE_lightmap_image"
def getLightmapImage(x = 1024, y = 1024):
    # check if we have a lightmap image
    lightmapImage = bpy.data.images.get(k_needleLightmapImageName)
    # make sure it has alpha
    # if lightmapImage:
        # bpy.data.images.remove(lightmapImage)
        # lightmapImage = None

    # check size
    if lightmapImage and (lightmapImage.size[0] != x or lightmapImage.size[1] != y):
        bpy.data.images.remove(lightmapImage)
        lightmapImage = None

    if not lightmapImage:
        print("Creating new lightmap image")
        # create a new lightmap image
        lightmapImage = bpy.data.images.new(k_needleLightmapImageName, x, y, float_buffer=True, alpha=True)
    
    lightmapImage.alpha_mode = 'CHANNEL_PACKED'
    lightmapImage.generated_type = 'BLANK'
    # set colorspace to linear
    if bpy.app.version < (4, 0, 0):
        lightmapImage.colorspace_settings.name = 'Linear'
    else:
        lightmapImage.colorspace_settings.name = 'Linear Rec.2020'
    
    # make it 32 bit
    lightmapImage.use_half_precision = False

    return lightmapImage
