#
# Copyright 2011, Blender Foundation.
#
# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

# <pep8 compliant>

import bpy
CURRENT_VERSION='16.3.1'

def check_compatibility():        
    file_version = get_current_version()
    check_compatibility_octane_world(file_version)
    check_compatibility_camera_imagers(file_version)    
    check_compatibility_octane_node_tree_15_2_5(file_version)
    check_compatibility_octane_node_tree_15_2_7(file_version)
    check_compatibility_octane_node_tree_16_3(file_version)
    update_current_version()

def get_current_version():
    if bpy.context.scene.octane:
        return getattr(bpy.context.scene.octane, 'octane_blender_version', '')
    return ''

def check_update(current_version, update_version):
    try:
        current_version_list = [int(s) for s in current_version.split('.')]
    except:
        current_version_list = []
    try:
        update_version_list = [int(s) for s in update_version.split('.')]  
    except:
        update_version_list = []
    max_len = max(len(current_version_list), len(update_version_list))
    if len(current_version_list) < max_len:
        current_version_list.extend([0] * (max_len - len(current_version_list)))
    if len(update_version_list) < max_len:
        update_version_list.extend([0] * (max_len - len(update_version_list)))
    current_version_number = 0
    update_version_number = 0
    for idx in range(max_len):
        current_version_number += current_version_list[idx] * ((10 ** 3) ** (max_len - idx - 1))
        #print('current_version_number', current_version_list[idx] * ((10 ** 3) ** (max_len - idx - 1)))
        update_version_number += update_version_list[idx] * ((10 ** 3) ** (max_len - idx - 1))
        #print('update_version_number', update_version_list[idx] * ((10 ** 3) ** (max_len - idx - 1)))
    #print(current_version_number, update_version_number)
    return current_version_number < update_version_number

def update_current_version():
    if bpy.context.scene.octane and hasattr(bpy.context.scene.octane, 'octane_blender_version'):
        setattr(bpy.context.scene.octane, 'octane_blender_version', CURRENT_VERSION)    

def _check_compatibility_octane_specular_material_node_15_2_5(node_tree, node):
    try:
        links = node_tree.links
        src_input = node.inputs['Transmission']
        target_input = node.inputs['Transmission Color']
        for src_link in src_input.links:
            links.new(src_link.from_socket, target_input)
    except Exception as e:
        pass

def _check_compatibility_octane_mix_material_node_16_3(node_tree, node):
    try:
        links = node_tree.links
        input_1 = node.inputs['Material1']
        input_2 = node.inputs['Material2']
        if len(input_1.links) and len(input_2.links):
            from_socket_1 = input_1.links[0].from_socket
            from_socket_2 = input_2.links[0].from_socket
            links.remove(input_1.links[0])
            links.remove(input_2.links[0])
            links.new(from_socket_1, input_2)
            links.new(from_socket_2, input_1)
        elif len(input_1.links):
            from_socket_1 = input_1.links[0].from_socket
            links.remove(input_1.links[0])
            links.new(from_socket_1, input_2)
        elif len(input_2.links):
            from_socket_2 = input_2.links[0].from_socket
            links.remove(input_2.links[0])
            links.new(from_socket_2, input_1)
        else:
            pass
    except Exception as e:
        pass

def _check_compatibility_octane_displacement_node_15_2_7(node_tree, node):
    try:        
        links = node_tree.links
        src_input = node.inputs['Offset']
        target_input = node.inputs['Mid level']
        target_input.default_value = src_input.default_value
        for src_link in src_input.links:
            links.new(src_link.from_socket, target_input)
    except Exception as e:
        pass

def check_compatibility_octane_node_tree_15_2_5(file_version):
    UPDATE_VERSION = '15.2.5'
    if not check_update(file_version, UPDATE_VERSION):
        return   
    for mat in bpy.data.materials:
        if not getattr(mat, 'node_tree', None):
            continue
        for node in mat.node_tree.nodes:
            if node.type == 'OCT_SPECULAR_MAT':
                _check_compatibility_octane_specular_material_node_15_2_5(mat.node_tree, node)
            if node.type == 'OCT_DISPLACEMENT_TEX':
                _check_compatibility_octane_displacement_node_15_2_7(mat.node_tree, node)

def check_compatibility_octane_node_tree_15_2_7(file_version):
    UPDATE_VERSION = '15.2.7'
    if not check_update(file_version, UPDATE_VERSION):
        return   
    for mat in bpy.data.materials:
        if not getattr(mat, 'node_tree', None):
            continue
        for node in mat.node_tree.nodes:
            if node.type == 'OCT_DISPLACEMENT_TEX':
                _check_compatibility_octane_displacement_node_15_2_7(mat.node_tree, node)

def check_compatibility_octane_node_tree_16_3(file_version):
    UPDATE_VERSION = '16.3'
    if not check_update(file_version, UPDATE_VERSION):
        return   
    for mat in bpy.data.materials:
        if not getattr(mat, 'node_tree', None):
            continue
        for node in mat.node_tree.nodes:
            if node.type == 'OCT_MIX_MAT':
                _check_compatibility_octane_mix_material_node_16_3(mat.node_tree, node)

def check_compatibility_camera_imagers(file_version):
    UPDATE_VERSION = '15.2.4'
    if not check_update(file_version, UPDATE_VERSION):
        return    
    print('[OctaneBlender] check compatibility for camera imagers...')
    if bpy.context.scene.octane:
        bpy.context.scene.octane.hdr_tonemap_render_enable = getattr(bpy.context.scene.octane, 'hdr_tonemap_enable', False)
        bpy.context.scene.octane.hdr_tonemap_preview_enable = getattr(bpy.context.scene.octane, 'hdr_tonemap_enable', False)

def check_compatibility_env_textures(octane_world, file_version):
    UPDATE_VERSION = '15.2.4'
    if not check_update(file_version, UPDATE_VERSION):
        return
    print('[OctaneBlender] check compatibility for env textures...')
    TEXTURE_LIST = ['env_texture', 'env_medium', 'env_vis_texture', 'env_vis_medium']
    for name in TEXTURE_LIST:
        tex_name = getattr(octane_world, name, '')
        # print(name, tex_name, getattr(octane_world, name + '_ptr', None))
        if tex_name and getattr(octane_world, name + '_ptr', None) is None:
            for texture in bpy.data.textures:
                if tex_name == texture.name:
                    setattr(octane_world, name + '_ptr', texture)
                    break
        setattr(octane_world, name, '')

def check_compatibility_octane_world(file_version):
    for world in bpy.data.worlds:
        if getattr(world, 'octane', None):
            check_compatibility_env_textures(world.octane, file_version)

