# Copyright (c) VOLVICON.
#
# This file is provided solely for educational purposes in connection with
# the Volvicon software and related documentation.
#
# You may use and modify this file for personal or internal purposes when
# working with Volvicon products. Any reproduction, distribution, or use
# of this file outside the Volvicon ecosystem is strictly prohibited
# without prior written authorization from VOLVICON.

"""
Application Preferences Operations Tutorial.

This tutorial demonstrates how to read and update application preferences
through the scripting API.

Topics covered:
- Reading the current preference values
- Updating preferences from multiple tabs
- Modifying CAD import defaults as a grouped options object
- Restoring the original preference values after the example completes

Prerequisites:
- Volvicon application must be running
- A valid license must be active
"""

import ScriptingApi as api

# Create Application instance and get preferences operations
app = api.Application()
preferences_operations = app.get_preferences_operations()

# Capture the original settings so this tutorial leaves the application unchanged.
original_user_interface : api.UserInterfaceOptions = preferences_operations.get_user_interface_options()
original_general : api.GeneralOptions = preferences_operations.get_general_options()
original_rendering : api.RenderingOptions = preferences_operations.get_rendering_options()
original_view_3d : api.View3dOptions = preferences_operations.get_view_3d_options()
original_view_2d : api.View2dOptions = preferences_operations.get_view_2d_options()
original_import : api.ImportOptions = preferences_operations.get_import_options()


def restore_preferences():
    preferences_operations.set_save_application_size_and_position_on_exit(
        original_user_interface.save_application_size_and_position_on_exit
    )
    preferences_operations.set_show_splash_screen(original_user_interface.show_splash_screen)
    preferences_operations.set_border_in_fullscreen(original_user_interface.border_in_fullscreen)
    preferences_operations.set_enable_high_dpi_scaling(original_user_interface.enable_high_dpi_scaling)
    preferences_operations.set_high_dpi_scale_factor_rounding_mode(
        original_user_interface.high_dpi_scale_factor_rounding_mode
    )
    preferences_operations.set_application_font_size(original_user_interface.application_font_size)

    preferences_operations.set_default_working_directory(original_general.default_working_directory)
    preferences_operations.set_maximum_undos(original_general.maximum_undos)
    preferences_operations.set_maximum_camera_undos(original_general.maximum_camera_undos)
    preferences_operations.set_undo_storage_location(original_general.undo_storage_location)
    preferences_operations.set_maximum_recent_files(original_general.maximum_recent_files)
    preferences_operations.set_maximum_number_of_threads(original_general.maximum_number_of_threads)
    preferences_operations.set_auto_save_frequency_minutes(original_general.auto_save_frequency_minutes)
    preferences_operations.set_project_file_compression_level(original_general.project_file_compression_level)
    preferences_operations.set_help_improve_user_experience(original_general.help_improve_user_experience)

    preferences_operations.set_zoom_to_cursor_position(original_rendering.zoom_to_cursor_position)
    preferences_operations.set_reset_camera_when_object_is_added(original_rendering.reset_camera_when_object_is_added)

    preferences_operations.set_keep_only_whole_cells_when_clipping(original_view_3d.keep_only_whole_cells_when_clipping)
    preferences_operations.set_3d_clipping_outline_color(original_view_3d.clipping_outline_color)
    preferences_operations.set_3d_clipping_handle_color(original_view_3d.clipping_handle_color)
    preferences_operations.set_automatically_regenerate_3d_preview_if_any_visible_mask_is_modified(
        original_view_3d.automatically_regenerate_3d_preview_if_any_visible_mask_is_modified
    )
    preferences_operations.set_use_accurate_surface_detection_for_each_label_in_the_multilabel_mask(
        original_view_3d.use_accurate_surface_detection_for_each_label_in_the_multilabel_mask
    )
    preferences_operations.set_surface_extraction_algorithm_for_each_label_in_the_multilabel_mask(
        original_view_3d.surface_extraction_algorithm_for_each_label_in_the_multilabel_mask
    )

    preferences_operations.set_enable_mask_outline_cache(original_view_2d.enable_mask_outline_cache)

    preferences_operations.set_spacing_comparison_decimal_places(original_import.spacing_comparison_decimal_places)
    preferences_operations.set_origin_comparison_decimal_places(original_import.origin_comparison_decimal_places)
    preferences_operations.set_allow_import_of_images_with_mismatched_geometry(
        original_import.allow_import_of_images_with_mismatched_geometry
    )
    preferences_operations.set_resample_mismatched_images_to_match_the_projects_active_volume(
        original_import.resample_mismatched_images_to_match_the_projects_active_volume
    )
    preferences_operations.set_volume_interpolation_method_for_mismatched_images(
        original_import.volume_interpolation_method_for_mismatched_images
    )
    preferences_operations.set_mask_interpolation_method_for_mismatched_images(
        original_import.mask_interpolation_method_for_mismatched_images
    )
    preferences_operations.set_import_multi_part_files_as_single_surface_object(
        original_import.import_multi_part_files_as_single_surface_object
    )
    preferences_operations.set_cad_file_import_options(original_import.cad_file_import_options)


try:
    print("Current application preferences:")
    print(f"  Show splash screen: {original_user_interface.show_splash_screen}")
    print(f"  Maximum undos: {original_general.maximum_undos}")
    print(f"  Zoom to cursor position: {original_rendering.zoom_to_cursor_position}")
    print(f"  Enable mask outline cache: {original_view_2d.enable_mask_outline_cache}")
    print(f"  Spacing comparison precision: {original_import.spacing_comparison_decimal_places}")

    # =============================================================================
    # User Interface and General Preferences
    # =============================================================================
    # Set UI and general preferences to new values.
    preferences_operations.set_show_splash_screen(False)
    preferences_operations.set_application_font_size(api.ApplicationFontSize.Medium)
    preferences_operations.set_maximum_undos(25)
    preferences_operations.set_undo_storage_location(api.UndoStorageLocation.Disk)
    preferences_operations.set_project_file_compression_level(api.ProjectFileCompressionLevel.Balanced)

    # =============================================================================
    # Rendering and View Preferences
    # =============================================================================
    # Set rendering and view preferences to new values.
    preferences_operations.set_zoom_to_cursor_position(True)
    # Keep the current camera when new objects are added instead of reframing the scene each time.
    preferences_operations.set_reset_camera_when_object_is_added(False)
    preferences_operations.set_keep_only_whole_cells_when_clipping(True)
    preferences_operations.set_3d_clipping_outline_color([0.10, 0.45, 0.80])
    preferences_operations.set_enable_mask_outline_cache(False)

    # Choose how each label's surface is extracted when building a multilabel mask 3D preview.
    # This setting applies only when accurate surface detection is turned off:
    # - SmoothClosedLabels creates complete smooth boundaries for every label.
    # - VoxelizedConforming keeps unsmoothed neighboring boundaries aligned where possible.
    # - SmoothSharedInterfaces keeps one internal interface copy; separated labels may be open.
    preferences_operations.set_use_accurate_surface_detection_for_each_label_in_the_multilabel_mask(False)
    preferences_operations.set_surface_extraction_algorithm_for_each_label_in_the_multilabel_mask(
        api.SurfaceExtractionAlgorithm.SmoothClosedLabels
    )

    # =============================================================================
    # Import Preferences
    # =============================================================================
    # Set import preferences to new values.
    preferences_operations.set_spacing_comparison_decimal_places(4)
    preferences_operations.set_origin_comparison_decimal_places(6)
    preferences_operations.set_allow_import_of_images_with_mismatched_geometry(True)
    preferences_operations.set_resample_mismatched_images_to_match_the_projects_active_volume(True)
    preferences_operations.set_volume_interpolation_method_for_mismatched_images(api.ImageInterpolationMethod.Cubic)
    preferences_operations.set_mask_interpolation_method_for_mismatched_images(api.ImageInterpolationMethod.Nearest)
    preferences_operations.set_import_multi_part_files_as_single_surface_object(True)

    cad_import_options : api.CadFileImportOptions = preferences_operations.get_cad_file_import_options()
    cad_import_options.auto_deflections = False
    cad_import_options.linear_deflection = 0.01
    cad_import_options.angular_deflection = 0.4
    cad_import_options.build_solid = True
    preferences_operations.set_cad_file_import_options(cad_import_options)

    updated_user_interface : api.UserInterfaceOptions = preferences_operations.get_user_interface_options()
    updated_general : api.GeneralOptions = preferences_operations.get_general_options()
    updated_rendering : api.RenderingOptions = preferences_operations.get_rendering_options()
    updated_import : api.ImportOptions = preferences_operations.get_import_options()

    print("Updated application preferences:")
    print(f"  Show splash screen: {updated_user_interface.show_splash_screen}")
    print(f"  Application font size: {updated_user_interface.application_font_size}")
    print(f"  Maximum undos: {updated_general.maximum_undos}")
    print(f"  Undo storage: {updated_general.undo_storage_location}")
    print(f"  Zoom to cursor position: {updated_rendering.zoom_to_cursor_position}")
    print(f"  Reset camera when a new object is added: {updated_rendering.reset_camera_when_object_is_added}")
    print(f"  Import multipart files as a single object: {updated_import.import_multi_part_files_as_single_surface_object}")

finally:
    restore_preferences()
    print("Original application preferences restored.")

