#
# 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.
#
# Created 21. April 2020 by Lars Oelgeschlaeger MSC Software

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


# setting pre-defined properties of tool_propertyContainer
def getUIContent():
    my_toolProperty = apex_sdk.ToolPropertyContainer()
    my_toolProperty.ToolPropertyContent = getCustomToolPropertyContent()

    # Provide an icon and a name for the tool property panel
    icon_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), r"node_updatecoordinates.png")
    my_toolProperty.TitleImageUriString = icon_path
    my_toolProperty.TitleText = "Node Update Coordinates"

    # handle apply button (green) click event
    my_toolProperty.AppliedCommand = apex_sdk.ActionCommand(System.Action(HandleApplyButton))
    # handle exit button (red) click event
    my_toolProperty.ExitCommand = apex_sdk.ActionCommand(System.Action(HandleExitButton))

    # define pickFilterTools
    my_toolProperty.ShowPickChoice = True
    my_toolProperty.PickFilterList = setPickFilterTools()

    # workflow instructions
    my_toolProperty.WorkFlowInstructions = """<HTML><BODY><P STYLE=\"font-size:10;\"><SPAN>Select one or more nodes 
    and and click the 'get Node IDs' button.</SPAN></P> <P STYLE=\"font-size:10;\"><SPAN>The node IDs will be 
    shown.</SPAN></P> <P><SPAN> </SPAN></P> <P STYLE=\"font-size:10;\"><SPAN>Type the new coordinates in the fields 
    x,y, and z.</SPAN></P> <P STYLE=\"font-size:10;\"><SPAN>If only one or two coordinates should be updated leave 
    the other fields empty.</SPAN></P> <P STYLE=\"font-size:10;\"><SPAN>Click the 'Apply' button.</SPAN></P> <P 
    STYLE=\"font-size:10;\"><SPAN>The coordinates of the selected nodes will be updated accordingly.</SPAN></P> 
    <P><SPAN> </SPAN></P> <P STYLE=\"font-size:10;\"><SPAN>Created 21. April 2020 by Lars Oelgeschlaeger MSC 
    Software</SPAN></P></BODY></HTML> """

    # return my_toolProperty
    return my_toolProperty


# get tool property content
def getCustomToolPropertyContent():
    # Create a Grid
    my_Grid = WPFControls.Grid()

    # Add 11 Rows and Two Columns
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())
    my_Grid.RowDefinitions.Add(WPFControls.RowDefinition())

    my_Grid.ColumnDefinitions.Add(WPFControls.ColumnDefinition())
    my_Grid.ColumnDefinitions.Add(WPFControls.ColumnDefinition())
    my_Grid.ColumnDefinitions.Add(WPFControls.ColumnDefinition())

    box_width = 2
    box_width1 = 3

    # Row 0
    # Create a Label (TextBlock)
    # Set it's Text value
    # Assign it to Row 0, Column 0
    NodeIDTextBlock = WPFControls.TextBlock()
    NodeIDTextBlock.Text = "Node IDs:"
    WPFControls.Grid.SetRow(NodeIDTextBlock, 0)
    WPFControls.Grid.SetColumn(NodeIDTextBlock, 0)

    # Create a button to get node IDs, assign it to Row 0, Column 1
    NodeIdBtn = WPFControls.Button()
    NodeIdBtn.Content = "get Node IDs"
    WPFControls.Grid.SetColumnSpan(NodeIdBtn, box_width)
    WPFControls.Grid.SetRow(NodeIdBtn, 0)
    WPFControls.Grid.SetColumn(NodeIdBtn, 1)
    NodeIdBtn.Click += GetNodeIdButton

    # Add the Row 0 controls to the Grid
    my_Grid.Children.Add(NodeIDTextBlock)
    my_Grid.Children.Add(NodeIdBtn)

    # Row1
    # Create an empty input TextBox assign it to Row 0, Column 1
    global NodeIDTextBox
    NodeIDTextBox = WPFControls.TextBox()
    WPFControls.Grid.SetColumnSpan(NodeIDTextBox, box_width1)
    WPFControls.Grid.SetRow(NodeIDTextBox, 1)
    WPFControls.Grid.SetColumn(NodeIDTextBox, 0)

    # Add the Row 1 controls to the Grid
    my_Grid.Children.Add(NodeIDTextBox)

    # Row 2
    # Create a Label (TextBlock)
    # Set it's Text value
    # Assign it to Row 2, Column 0
    CoordinatesTextBlock = WPFControls.TextBlock()
    CoordinatesTextBlock.Text = "Coordinates:"
    WPFControls.Grid.SetRow(CoordinatesTextBlock, 2)
    WPFControls.Grid.SetColumn(CoordinatesTextBlock, 0)

    # Add the Row 2 controls to the Grid
    my_Grid.Children.Add(CoordinatesTextBlock)

    # Row 3
    # Create a Label (TextBlock)
    # Set it's Text value
    # Assign it to Row 3, Column 0
    XTextBlock = WPFControls.TextBlock()
    XTextBlock.Text = "x:"
    WPFControls.Grid.SetRow(XTextBlock, 3)
    WPFControls.Grid.SetColumn(XTextBlock, 0)

    # Create an empty input TextBox assign it to Row 3, Column 1
    global XTextBox
    XTextBox = WPFControls.TextBox()
    WPFControls.Grid.SetColumnSpan(XTextBox, box_width)
    WPFControls.Grid.SetRow(XTextBox, 3)
    WPFControls.Grid.SetColumn(XTextBox, 1)

    # Add the Row 3 controls to the Grid
    my_Grid.Children.Add(XTextBlock)
    my_Grid.Children.Add(XTextBox)

    # Row 4
    # Create a Label (TextBlock)
    # Set it's Text value
    # Assign it to Row 4, Column 0
    YTextBlock = WPFControls.TextBlock()
    YTextBlock.Text = "y:"
    WPFControls.Grid.SetRow(YTextBlock, 4)
    WPFControls.Grid.SetColumn(YTextBlock, 0)

    # Create an empty input TextBox assign it to Row 4, Column 1
    global YTextBox
    YTextBox = WPFControls.TextBox()
    WPFControls.Grid.SetColumnSpan(YTextBox, box_width)
    WPFControls.Grid.SetRow(YTextBox, 4)
    WPFControls.Grid.SetColumn(YTextBox, 1)

    # Add the Row 4 controls to the Grid
    my_Grid.Children.Add(YTextBlock)
    my_Grid.Children.Add(YTextBox)

    # Row 5
    # Create a Label (TextBlock)
    # Set it's Text value
    # Assign it to Row 5, Column 0
    ZTextBlock = WPFControls.TextBlock()
    ZTextBlock.Text = "z:"
    WPFControls.Grid.SetRow(ZTextBlock, 5)
    WPFControls.Grid.SetColumn(ZTextBlock, 0)

    # Create an empty input TextBox assign it to Row 5, Column 1
    global ZTextBox
    ZTextBox = WPFControls.TextBox()
    WPFControls.Grid.SetColumnSpan(ZTextBox, box_width)
    WPFControls.Grid.SetRow(ZTextBox, 5)
    WPFControls.Grid.SetColumn(ZTextBox, 1)

    # Add the Row 5 controls to the Grid
    my_Grid.Children.Add(ZTextBlock)
    my_Grid.Children.Add(ZTextBox)

    # return the Grid
    return my_Grid


# set pickFilters
def setPickFilterTools():
    # 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)

    # LBCs
    pickChoices.Add(apex_sdk.PickFilterTypes.Node)

    return pickChoices


# apply button (green) from tool header
@apex_sdk.errorhandler
def HandleApplyButton():
    dictionary = {"xvalue": XTextBox.Text, "yvalue": YTextBox.Text, "zvalue": ZTextBox.Text}

    file_path = os.path.dirname(os.path.realpath(__file__))
    script_path = os.path.join(file_path, 'node_updatecoordinates_api.py')
    apex_sdk.runScriptFunction(script_path, "nodeupdate", dictionary)

    return HandleApplyButton


# getNodeId Button
@apex_sdk.errorhandler
def GetNodeIdButton(sender, args):
    file_path = os.path.dirname(os.path.realpath(__file__))
    script_path = os.path.join(file_path, 'node_updatecoordinates_api.py')
    apex_sdk.runScriptFunction(script_path, "nodeid", callback=UpdateNodeProperties)

    return GetNodeIdButton


# exit button (red) from tool header
@apex_sdk.errorhandler
def HandleExitButton():
    print("HandleExitButton")


# adding data to fields
@apex_sdk.errorhandler
def UpdateNodeProperties():
    name_dict = apex_sdk.getScriptFunctionReturnData()
    NodeIDTextBox.Text = str(name_dict["nodeid"])
