#
# Copyright © 2020 MSC.Software Corporation
#  
# Permission to use Scripts
#  
# Permission is granted to MSC.Software customers with valid licenses of the MSC Apex™ software 
# to use script files posted on this page (collectively “Scripts”) solely for customers’ own authorized 
# internal use in conjunction with licensed use of the MSC Apex software.  
# No other use is permitted.  No license to MSC Apex or other software is granted under this Permission.
#  
# SCRIPTS ARE PROVIDED ON AN "AS-IS" BASIS, WITH NO WARRANTIES OF ANY KIND.  USE OF THE SCRIPTS IS AT CUSTOMER'S SOLE RISK.
#  
# IN NO EVENT SHALL MSC.SOFTWARE CORPORATION, ITS AFFILIATES, SUBSIDIARIES, SUPPLIERS, AGENTS, REPRESENTATIVES OR EMPLOYEES BE LIABLE FOR ANY 
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, 
# STRICT LIABILITY, OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION USE OF THE SCRIPTS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
#  
# Customer shall indemnify, defend and hold MSC.Software Corporation, its affiliates, subsidiaries, suppliers, agents, 
# employees or representatives (collectively, “Indemnified Parties”) harmless from and against any third-party claims 
# brought against Indemnified Parties rising out of or in connection with Customer’s use of the Scripts.
#
# MSC Apex - User Defined Tools using Python Scripts
# Check Box UI Example
# 
import sys
import os
import apex_sdk
import clr

# .NET references
import System
import System.Windows.Controls as WPFControls
from System.Windows.Automation import AutomationProperties
from Microsoft.Win32 import OpenFileDialog

#color picker namespace
import Xceed.Wpf.Toolkit

# Define current file path of example
current_file_path = os.path.dirname(os.path.realpath(__file__))

# Global variable to keep track of how many objects are currently selected
global selected_entity_count
selected_entity_count = 0

# Global variable to keep track of pick modifiers (Ctrl, Shift)
global selection_modifier_is_active
selection_modifier_is_active = False

auto_execute = False

# Set pre-defined properties of ToolPropertyContainer
def getUIContent():

    # Make the tool property panel global
    # We need to read the state of the Auto-execute button from other functions
    global my_toolProperty
    my_toolProperty = apex_sdk.ToolPropertyContainer()
    # Automation Id is needed for internal testing ONLY
    my_toolProperty.SetValue(AutomationProperties.AutomationIdProperty, "AID_USER_TOOL_PROPERTY_MODE");
    #   my_toolProperty.applyMMB = True;

    # Provide an icon and a name for the tool property panel
    my_toolProperty.TitleImageUriString = os.path.join(os.path.dirname(current_file_path), r"res\Robot_48.png")
    my_toolProperty.TitleText = "Color picker"

    # Define UI
    my_toolProperty.ToolPropertyContent = getCustomToolPropertyContent()

    # Define PickFilterList
    my_toolProperty.ShowPickChoice = True
    my_toolProperty.PickFilterList = setPickFilterList()


    # Enable auto execute (Lightning bolt) behavior
    # This causes the lightning bolt button to be displayed at the top left of the
    # Tool property pane
    my_toolProperty.IsAutoAppliedVisible = True

    # Initialize the Tool with Auto-execute active (default)
    # Set this value to False if you want the tool to be displayed initially in manual execution mode
    my_toolProperty.IsAutoApplied = True

    # Handle apply button (green) click event
    my_toolProperty.AppliedCommand = apex_sdk.ActionCommand(System.Action(HandleApplyButton))

    apex_sdk.registerGestureHandler( HandleGesture )

    return my_toolProperty


# Set PickFilters
def setPickFilterList():
    # Create an empty List of strings
    pickChoices = System.Collections.Generic.List[System.String]()

    # Exclusive picking and visibility picking
    pickChoices.Add(apex_sdk.PickFilterTypes.ExclusivePicking)
    pickChoices.Add(apex_sdk.PickFilterTypes.VisibilityPicking)

    # Add Types

    pickChoices.Add(apex_sdk.PickFilterTypes.Assembly)
    pickChoices.Add(apex_sdk.PickFilterTypes.Part)
    pickChoices.Add(apex_sdk.PickFilterTypes.Solid)
    pickChoices.Add(apex_sdk.PickFilterTypes.Surface)
    pickChoices.Add(apex_sdk.PickFilterTypes.Curve)
    pickChoices.Add(apex_sdk.PickFilterTypes.Point)
    pickChoices.Add(apex_sdk.PickFilterTypes.SolidMesh)
    pickChoices.Add(apex_sdk.PickFilterTypes.SurfaceMesh)
    pickChoices.Add(apex_sdk.PickFilterTypes.CurveMesh)

    # Return the pick filter list
    return pickChoices

# HandleGesture is called whenever a gesture event occurs
# You can name this method whatever you want and register it with the gesture
# handler above
# But it MUST support the two arguments shown below
@apex_sdk.errorhandler
def HandleGesture( ToolGestureEventData, args ):
    global selection_modifier_is_active
    global selected_entity_count

    # ignore the Mouse and Continue Gestures...
    if "Mouse" in ToolGestureEventData.ges.gestureName:
        return

    if "Continue" in ToolGestureEventData.ges.gestureName:
        return

    # The KeyPress event is fired if any keyboard key is pressed
    # Check if Ctrl or Shift keys are pressed and cache state in
    # the global variable "selection_modifier_is_active"
    # We'll use this state elsewhere to avoid automatically executing the tool while these keys are pressed
    if "KeyPress" in ToolGestureEventData.ges.gestureName:
        if ToolGestureEventData.ges.modifiers in [2, 4]:
            selection_modifier_is_active = True
        return

    # Check if any modifier keys are released
    # Reset the cached value of "selection_modifier_is_active"
    # Execute the ApplyButton if there are any selected entities AND auto-execute is active
    if "KeyRelease" in ToolGestureEventData.ges.gestureName:
        if ToolGestureEventData.ges.modifiers in [0]:
            selection_modifier_is_active = False
            if selected_entity_count > 0 and my_toolProperty.IsAutoApplied == True :
                HandleApplyButton()
        return

    # The SingleSelection event is fired when a single LMB pick happens
    # Update the value of "selected_entity_count"
    # If,
    #   1 or more entities are currently selected, AND
    #   2) Auto-execute mode is active, AND
    #   3) No pick modifiers (Ctrl, Shift) are currently pressed
    # Then
    #   execute the Apply Button function
    if "SingleSelection" in ToolGestureEventData.ges.gestureName:
        selected_entity_count = ToolGestureEventData.ges.currentSelectionList.count()
        if selected_entity_count > 0 and my_toolProperty.IsAutoApplied == True and not selection_modifier_is_active:
            HandleApplyButton()
        return

    # Apex fires the "RectangleSelect" event whenever a box pick happens
    # Update the value of "selected_entity_count"
    # This event uses pretty much the same logic as the SingleSelection event handler to determine
    # whether the Apply function should be called
    if "RectangleSelect" in ToolGestureEventData.ges.gestureName:
        selected_entity_count = ToolGestureEventData.ges.currentSelectionList.count()
        if selected_entity_count > 0 and my_toolProperty.IsAutoApplied == True and not selection_modifier_is_active:
            HandleApplyButton()
        return

    # Apex fires the "SelectionExtended" event whenever the current selection is extended
    # Basically, if picking is hppening while the Ctrl or Shift keys are pressed
    # Updates the value of "selected_entity_count"
    # This event uses pretty much the same logic as the SingleSelection event handler to determine
    # whether the Apply function should be called
    if "SelectionExtended" in ToolGestureEventData.ges.gestureName:
        selected_entity_count = ToolGestureEventData.ges.currentSelectionList.count()
        if selected_entity_count > 0 and my_toolProperty.IsAutoApplied == True and not selection_modifier_is_active:
            HandleApplyButton()
        return

    # Apex fires the "SelectionEmpty" or "SelectionCleared" events whenever the current selection is cleared
    # Update the value of "selected_entity_count to 0
    if ToolGestureEventData.ges.gestureName in ["SelectionEmpty", "SelectionCleared"]:
        selected_entity_count = 0
        return


# Define Layout and Components
def getCustomToolPropertyContent():

    # Create a Grid
    my_Grid = WPFControls.Grid()

    # Add 1 Row and One Column
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())
    my_Grid.ColumnDefinitions.Add(WPFControls.ColumnDefinition())

    #create color picker and set the default color to Yellow (8 bit rgb = 255,255,0)
    global colorPicker
    colorPicker = Xceed.Wpf.Toolkit.ColorPicker()
    colorPicker.SelectedColor = System.Windows.Media.Color.FromRgb(255, 255, 0)

    # Position the ColorPicker in the first row, column of the Grid
    WPFControls.Grid.SetRow(colorPicker, 0)
    WPFControls.Grid.SetColumn(colorPicker, 0)

    # Add the ColorPicker to the Grid
    my_Grid.Children.Add(colorPicker)

    # Return the Grid
    return my_Grid


# Apply button handler (Green check mark)
# This function is called each time the Apply button is clicked
@apex_sdk.errorhandler
def HandleApplyButton():

    print("Handling Apply")

    # Create a Dictionary to store the user defined tool data
    dictionary = {}

    # Get the selected color from the color picker and send it to the tool function
    # NOTE : the color is an 8 digit aRGB hex color AARRGGBB
    # Note that this is somewhat safe since only one radio button can be checked
    dictionary["color"] = colorPicker.SelectedColor


    # Call the Apex API script using apex_sdk.runScriptFunction()
    # argument 1 = the fully qualified path name of your API script
    # argument 2 = the name of the function in your API script that will receive the Dictionary
    # argument 3 = the Dictionary containing the UI data
    apex_sdk.runScriptFunction(os.path.join(current_file_path, r"color_picker.py"), "set_selected_entities_color", dictionary)
