import substance_sampler as ssa 
import os
import sys
import time
import shutil
from random import randrange 
from pathlib import Path, PureWindowsPath

# <><><><><><> VALUES TO SET <><><><><><>

# this is your output directory where your assets will be exported to. Use double backslashes on windows
parent_dir = 'D:\\Trainz\\substance_processing_area\\staging\\'

# <><><><><><> CODE <><><><><><>

# Define my list of filters 
[normal_height_adjustment_filter] = ssa.get_filters("Normal/Height Adjustment") 

# Create a list of all filters, starting from bottom to top 
layer_stack_template = [normal_height_adjustment_filter]                         


# Function to export as SBSAR with default options 
def export_as_sbsar(asset_to_export, w_res, h_res, destination_path): 
    asset_to_export.export_material(w_resolution=w_res, 
                           h_resolution=h_res, 
                           path=destination_path) 
 
 
# Function to export as PNG with default options
def export_as_png_with_default_preset(asset_to_export, w_res, h_res, destination_path): 
    asset_to_export.export_material(w_resolution=w_res, 
                           h_resolution=h_res, 
                           path=destination_path, 
                           format=ssa.MaterialExportFormat.png)

# Function to export as PNG with Trainz preset
# note: you must install the Trainz preset manually first!
def export_as_png_with_trainz_preset(asset_to_export, w_res, h_res, destination_path):
    [trainz_export_preset] = ssa.get_export_presets("Trainz")  
    ssa.Asset.export_material(self=asset_to_export, 
                           w_resolution=w_res, 
                           h_resolution=h_res, 
                           path=destination_path, 
                           format=ssa.MaterialExportFormat.png,
                           preset=trainz_export_preset)                           
                           
def get_file_name(file_path, without_ext):
    file_path_components = file_path.split('\\')
    if without_ext:
        file_name_and_extension = file_path_components[-1].rsplit('.', 1)
        return file_name_and_extension[0]
    else:
       return file_path_components[-1]      
       
def implode_list(list, start_count = -1):
    ret = '';
    count = start_count
    for strTmp in list:
        if count >= 0:
            if not ret == '':
                ret = ret + ' ' + strTmp
            else:
                ret = strTmp
        count = count + 1       
    return ret
    
def get_dir_file_count(dir_path):
    count = 0
    for path in os.listdir(dir_path):
        # check if current path is a file
        if os.path.isfile(os.path.join(dir_path, path)):
            count += 1
    return count

def get_new_kuid(kuid, trainz_profile_id, trainz_asset_id, logs_dir, name):
    trainz_profile_id_str = "{}".format(int(trainz_profile_id))
    trainz_asset_id_str = "{}".format(int(trainz_asset_id))
    new_kuid = '<kuid:' + trainz_profile_id_str + ':' + trainz_asset_id_str + '>'
                
    # used to save in a google sheet to search assets (personal thing I do)
    f = open(logs_dir + '\\' + 'csv.txt', "a")
    f.write(trainz_asset_id_str + '\t' + 'groundtexture' + '\t' + name + '\n')
    f.close()
    
    return new_kuid
    
    

# make a child directory to export the files
if not os.path.exists(parent_dir):
    print('Parent directory is invalid: ' + parent_dir + ', aborting...')
    exit()

# check the Trainz preset is installed
preset_list = ssa.get_export_presets("Trainz")
if len(preset_list) <= 0:
    print('Trainz export preset is not installed, aborting...')
    exit()

# defines
parent_export_dir = parent_dir + 'export\\'
parent_extras_dir = parent_dir + 'extras\\'
logs_dir = parent_dir + 'logs\\'

# make a child directory to export the files
if not os.path.exists(parent_export_dir):
    os.mkdir(parent_export_dir)

# make a child directory to export the logs
if not os.path.exists(logs_dir):
    os.mkdir(logs_dir)
 
# flush logs
f = open(logs_dir + '\\' + 'csv.txt', "a")
f.close() 

# the size of the final texture output. if going above 1024 (for example 2048) you might want to avoid processing too many textures at once.
output_width = 2048
output_height = 2048

# this value determines how big your textures will be in meters to determine when they tile. This is a Trainz Asset value, not a substance parameter
trainz_texture_scale = 7

# kuid information
trainz_profile_id = 12345
# the next avaiable ID that isn't used
trainz_asset_id = 67890 
# if true this will increment the trainz_asset_id one successful generation of a trainz asset
increment_trainz_asset_id = True

# add additional filter layers on example. This adds a normal_height_adjustment_filter to help reduce the normal map sharpness to reduce artifacts in-game.
# If you plan on adding these filters manually then switch this to False
add_layers_on_export = True

# adds a snow texture to the trainz asset
add_snow_texture = True

# parse our settings file
file_path = os.path.join(parent_extras_dir, 'substance_settings.txt')
if os.path.isfile(file_path):
    # parse the substance_settings.txt file
    with open(file_path) as fileHandle:
        while True:
            line = fileHandle.readline()
            print('>> ' + line)
            if not line:
                print('if not line break')
                break
            print('if line continue')
            line_splits = line.strip().split()
            if len(line_splits) >= 1:                       
                line_splits = line.strip().split('=')
                asset_file_key = line_splits[0].lower().strip()
                print("asset_file_key: " + asset_file_key)
                if asset_file_key == '#':
                    print('line is comment')
                    break
                elif asset_file_key == 'trainz_profile_id':
                    print('trainz_profile_id')
                    trainz_profile_id = int(line_splits[-1])
                elif asset_file_key == 'trainz_asset_id':
                    print('trainz_asset_id')
                    trainz_asset_id = int(line_splits[-1])
                elif asset_file_key == 'trainz_texture_scale':
                    print('trainz_texture_scale')
                    trainz_texture_scale = int(line_splits[-1])
                elif asset_file_key == 'output_width':
                    print('output_width')
                    output_width = int(line_splits[-1])
                elif asset_file_key == 'output_height':
                    print('output_height')
                    output_height = int(line_splits[-1])
                elif asset_file_key == 'add_layers_on_export':
                    print('add_layers_on_export')
                    if int(line_splits[-1]) == 0:
                        add_layers_on_export = False
                elif asset_file_key == 'increment_trainz_asset_id':
                    print('increment_trainz_asset_id')
                    if int(line_splits[-1]) == 0:
                        increment_trainz_asset_id = False
                elif asset_file_key == 'add_snow_texture':
                    print('add_snow_texture')
                    if int(line_splits[-1]) == 0:
                        add_snow_texture = False

# create a new asset 
my_current_asset = ssa.get_selected_asset() 
 
kuid = ''
kind = 'groundtexture'
username = my_current_asset.name
texture_path = ''
albedo_filename = 'albedo.png'
normal_filename = 'normal.png'
parameters_filename = 'parameters.png'
thumbnail_filename = 'thumbnail.jpg'
found_thumbnail = False
thumbnail_width = '240'
thumbnail_height = '180'
category_class = 'GS'
category_era = '2020s'
category_region = 'AU'
description = ''
author = 'N3V Games'
license = ''
organisation = ''

# Get all layers 
my_asset_layers = my_current_asset.get_layers()     

# See if we have a normal height layer already as this will mean there is a good chance we shouldn't need to add our layer filters again 
normal_height_layer_found = False
for layer in my_asset_layers: 
    print("Layer:", layer.name) 
    # Filter all layers by the layer name 
    if layer.name == "Normal/Height Adjustment": 
        print("Layer FOUND:", layer.name) 
        normal_height_layer_found = True

if not normal_height_layer_found:
    # Insert all filters of my template on top of the layer stack 
    if add_layers_on_export:
        for filter_layer in layer_stack_template: 
            # Get the number of layers 
            number_of_layers = len(my_current_asset.get_layers()) 
            # insert a filter on top of the layer stack (position O is bottom, number of layers is top) 
            my_current_asset.insert_filter(filter_layer, number_of_layers)

    #time.sleep(5)

    # Get all layers 
    my_asset_layers = my_current_asset.get_layers()     

    # Update parameters 
    for layer in my_asset_layers: 
        print("Layer:", layer.name) 
        # Filter all layers by the layer name 
        if layer.name == "Normal/Height Adjustment": 
            print("Layer FOUND:", layer.name) 
     
            # Check the list of all parameters of the Tiling layer 
            for parameter in layer.parameters: 
                print("Parameter:", parameter.label) 
                # Filter the parameters list by the parameter name 
                if parameter.label.lower() == "normal - intensity": 
                    print("Before", parameter.value) 
                    parameter.value = -0.4 
                    print("After:", parameter.value)
                                 
del my_asset_layers
#del layer_stack_template

#time.sleep(5)                         
 
# export directory
asset_dir_name = "{}".format(int(trainz_asset_id)) + " " + my_current_asset.name
#export_dir = parent_export_dir + "\\" + subdir_splits[-1]
export_dir = os.path.join(parent_export_dir, asset_dir_name)
# make a child directory to export the files
if not os.path.exists(export_dir):
    os.mkdir(export_dir)

time.sleep(1)                        

# export files
print('export dir: ' + export_dir)
export_as_png_with_trainz_preset(my_current_asset, output_width, output_height, export_dir)
    
del my_current_asset

# copy thumbnail

thumbnail_dest = os.path.join(export_dir, thumbnail_filename)
thumbnail_path = os.path.join(parent_extras_dir, thumbnail_filename)
print('thumbnail path ' + thumbnail_path)
if os.path.isfile(thumbnail_path):
    print('thumbnail path ' + thumbnail_path + ' exists')
    shutil.copyfile(thumbnail_path, thumbnail_dest)
    print('thumbnail copy dest ' + thumbnail_dest)
        
# copy snow textures
if add_snow_texture:
    snow_albedo_filename = 'albedo_snow.png'
    snow_normal_filename = 'normal_snow.png'
    snow_parameters_filename = 'parameters_snow.png'
    snow_albedo_path = os.path.join(parent_extras_dir, snow_albedo_filename)
    snow_normal_path = os.path.join(parent_extras_dir, snow_normal_filename)
    snow_parameters_path = os.path.join(parent_extras_dir, snow_parameters_filename)
    snow_albedo_dest = os.path.join(export_dir, snow_albedo_filename)
    snow_normal_dest = os.path.join(export_dir, snow_normal_filename)
    snow_parameters_dest = os.path.join(export_dir, snow_parameters_filename)
    if os.path.isfile(snow_albedo_path):
        shutil.copyfile(snow_albedo_path, snow_albedo_dest)
    if os.path.isfile(snow_normal_path):
        shutil.copyfile(snow_normal_path, snow_normal_dest)
    if os.path.isfile(snow_parameters_path):
        shutil.copyfile(snow_parameters_path, snow_parameters_dest)

# copy texture.txt files
albedo_txt_filename = 'albedo.texture.txt'
normal_txt_filename = 'normal.texture.txt'
parameters_txt_filename = 'parameters.texture.txt'
albedo_txt_path = os.path.join(parent_extras_dir, albedo_txt_filename)
normal_txt_path = os.path.join(parent_extras_dir, normal_txt_filename)
parameters_txt_path = os.path.join(parent_extras_dir, parameters_txt_filename)
albedo_dest = os.path.join(export_dir, albedo_txt_filename)
normal_dest = os.path.join(export_dir, normal_txt_filename)
parameters_dest = os.path.join(export_dir, parameters_txt_filename)
if os.path.isfile(albedo_txt_path):
    shutil.copyfile(albedo_txt_path, albedo_dest)
if os.path.isfile(normal_txt_path):
    shutil.copyfile(normal_txt_path, normal_dest)
if os.path.isfile(parameters_txt_path):
    shutil.copyfile(parameters_txt_path, parameters_dest)
    
if add_snow_texture:
    snow_albedo_txt_filename = 'albedo_snow.texture.txt'
    snow_normal_txt_filename = 'normal_snow.texture.txt'
    snow_parameters_txt_filename = 'parameters_snow.texture.txt'
    snow_albedo_txt_path = os.path.join(parent_extras_dir, snow_albedo_txt_filename)
    snow_normal_txt_path = os.path.join(parent_extras_dir, snow_normal_txt_filename)
    snow_parameters_txt_path = os.path.join(parent_extras_dir, snow_parameters_txt_filename)
    snow_albedo_txt_dest = os.path.join(export_dir, snow_albedo_txt_filename)
    snow_normal_txt_dest = os.path.join(export_dir, snow_normal_txt_filename)
    snow_parameters_txt_dest = os.path.join(export_dir, snow_parameters_txt_filename)
    if os.path.isfile(snow_albedo_txt_path):
        shutil.copyfile(snow_albedo_txt_path, snow_albedo_txt_dest)
    if os.path.isfile(snow_normal_txt_path):
        shutil.copyfile(snow_normal_txt_path, snow_normal_txt_dest)
    if os.path.isfile(snow_parameters_txt_path):
        shutil.copyfile(snow_parameters_txt_path, snow_parameters_txt_dest)                            

trainz_texture_scale_str = "{}".format(int(trainz_texture_scale))

# kuid bump version
kuid = get_new_kuid(kuid, trainz_profile_id, trainz_asset_id, logs_dir, username)

if increment_trainz_asset_id:
    trainz_asset_id += 1
    
# create new config.txt
f = open(export_dir + '\\' + 'config.txt', "w")

f.write("kuid" + '\t' + kuid + '\n')
f.write("username" + '\t' + '"' + username + '"' + '\n')
f.write("kind" + '\t' + '"' + kind.replace('"','') + '"' + '\n')
f.write("trainz-build" + '\t' + '"5.3"' + '\n')

f.write('\n')

f.write("hd-primary-texture-size-meters" + '\t' + trainz_texture_scale_str + '\n')

f.write('\n')

f.write("texture-variants" + '\n')
f.write("{" + '\n')
f.write("\t" + '0' + '\n')
f.write("\t" + '{' + '\n')
f.write("\t" + "\t" + 'diffuse-texture' + '\t' + '"' + albedo_txt_filename.replace('.txt', '') + '"' + '\n')
f.write("\t" + "\t" + 'normal-texture' + '\t' + '"' + normal_txt_filename.replace('.txt', '') + '"' + '\n')
f.write("\t" + "\t" + 'parameters-texture' + '\t' + '"' + parameters_txt_filename.replace('.txt', '') + '"' + '\n')
f.write("\t" + '}' + '\n')

if add_snow_texture:
    f.write('\n')
    f.write("\t" + '2' + '\n')
    f.write("\t" + '{' + '\n')
    f.write("\t" + "\t" + 'diffuse-texture' + '\t' + '"' + snow_albedo_txt_filename.replace('.txt', '') + '"' + '\n')
    f.write("\t" + "\t" + 'normal-texture' + '\t' + '"' + snow_normal_txt_filename.replace('.txt', '') + '"' + '\n')
    f.write("\t" + "\t" + 'parameters-texture' + '\t' + '"' + snow_parameters_txt_filename.replace('.txt', '') + '"' + '\n')
    f.write("\t" + '}' + '\n')

f.write("}" + '\n')

f.write('\n')

if add_snow_texture:
    f.write("season-selector" + '\n')
    f.write("{" + '\n')
    f.write("\t" + 'above-snow-line' + '\t' + '1' + '\n')
    f.write('\n')
    f.write("\t" + 'branch-true' + '\n')
    f.write("\t" + '{' + '\n')
    f.write("\t" + "\t" + 'output-season' + '\t' + '2' + '\n')
    f.write("\t" + '}' + '\n')
    f.write('\n')
    f.write("\t" + 'branch-false' + '\n')
    f.write("\t" + '{' + '\n')
    f.write("\t" + "\t" + 'output-season' + '\t' + '0' + '\n')
    f.write("\t" + '}' + '\n')
    f.write("}" + '\n')
    f.write('\n')                        

f.write("category-class" + '\t' + '"' + category_class.replace('"','') + '"' + '\n')
f.write("category-era" + '\t' + '"' + category_era.replace('"','') + '"' + '\n')
f.write("category-region" + '\t' + '"' + category_region.replace('"','') + '"' + '\n')
f.write("description" + '\t' + '"' + description.replace('"','') + '"' + '\n')
f.write("author" + '\t' + '"' + author.replace('"','') + '"' + '\n')
f.write("organisation" + '\t' + '"' + organisation.replace('"','') + '"' + '\n')
f.write("license" + '\t' + '"' + license.replace('"','') + '"' + '\n')

f.write('\n')

f.write("thumbnails" + '\n')
f.write("{" + '\n')
f.write("\t" + '0' + '\n')
f.write("\t" + '{' + '\n')
f.write("\t" + "\t" + 'image' + '\t' + '"' + thumbnail_filename.replace('"','') + '"' + '\n')
f.write("\t" + "\t" + 'width' + '\t' + thumbnail_width + '\n')
f.write("\t" + "\t" + 'height' + '\t' + thumbnail_height + '\n')
f.write("\t" + '}' + '\n')
f.write("}" + '\n')

f.write('\n')

f.write("kuid-table" + '\n')
f.write("{" + '\n')
f.write("}" + '\n')


f.close()



# update the kuid number in the settings file automatically
if increment_trainz_asset_id:
    temp_settings_path = os.path.join(parent_extras_dir, 'substance_settings_tmp.txt')
    f = open(temp_settings_path, "w")
    file_path = os.path.join(parent_extras_dir, 'substance_settings.txt')
    if os.path.isfile(file_path):
        # parse the substance_settings.txt file
        with open(file_path) as fileHandle:
            while True:
                write_line_to_file = True
                line = fileHandle.readline()
                print('>> ' + line)
                if not line:
                    print('if not line break')
                    break
                print('if line continue')
                line_splits = line.strip().split()
                if len(line_splits) >= 1:                       
                    line_splits = line.strip().split('=')
                    asset_file_key = line_splits[0].lower().strip()
                    print("asset_file_key: " + asset_file_key)
                    if asset_file_key == 'trainz_asset_id':
                        print('write trainz_asset_id')
                        trainz_asset_id_next = "{}".format(int(trainz_asset_id))
                        f.write('trainz_asset_id=' + trainz_asset_id_next + '\n')
                        write_line_to_file = False
                if write_line_to_file:
                    f.write(line)
    f.close()

    # delete current settings file and rename new settings temp file to become the actual settings file
    if os.path.isfile(temp_settings_path):
        if os.path.isfile(file_path):
            os.remove(file_path)
            os.rename(temp_settings_path, file_path)
        
print("Script has finished execution")
