#
# 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.
#
''' Module to add simple ply stack to top of existing plies
panel must already exist
only one material and one thickness can be specified
ply angles specified with / between angles '''

# coding: utf-8
# V1.0
import ctypes
import apex

# from apex.construct import Point3D, Point2D

# from operator import itemgetter


def main(dict={}):
    apex.disableShowOutput()
    ''' main function called from ui module.
    dict contains all inputs '''
    model = apex.currentModel()
    parts = model.getParts()
    try:
        thickness = float(dict.get("Thickness"))
    except:
        message_box("Add Ply Stack", "Thickness not a number", 48, 0)
        print("Thickness not a number!")
        return 100

    angle_string = dict.get("Angles")
    angles = angle_string.split('/')
    for _angle in angles:
        try:
            angle = float(_angle)
        except:
            message_box("Add Ply Stack", "Angle input format incorrect!", 48, 0)
            print("Angle input format incorrect!")
            return 100

    material = apex.catalog.getMaterial(name=dict.get("Material"))

# get selected coverage region
    if dict.get("Test"):
        myModel = apex.currentModel()
        Parts = myModel.getParts(True)
        _selected = apex.entityCollection()
        for part in Parts:
            _selected += part.getSurfaces()
    else:
        _selected = apex.selection.getCurrentSelection()
#    print("_selected: " + str(_selected))
    print("No Selected: " + str(len(_selected)))

    faces = []
    surfaces = []
    zones = []
    _geoms = apex.EntityCollection()
    panels = apex.EntityCollection()
    panels = apex.attribute.getLayeredPanels([{}])
    # check if there are no panels
    if len(panels) == 0:
        message_box("Add Ply Stack", "No Panels in model!  Create panel before using", 16, 0)
        return 200

    for sel in _selected:

#        selected_type = type(sel)
        selected_type = sel.getEntityType()
#        print(f"Type: {selected_type}")
#        print ('Zone type = ', apex.EntityType.Zone)
        if selected_type == apex.EntityType.Face:
            faces.append(sel)
            # print("Geoms: "+str(_geoms))
            _geoms.append(sel)
        elif selected_type == apex.EntityType.Surface:
            surfaces.append(sel)
            _geoms.extend(sel.getFaces(ids=""))
        elif selected_type == apex.EntityType.Zone:
            zones.append(sel)
    print(str(len(surfaces)) + " Surfaces selected")
    print(str(len(faces)) + " Faces selected")
#    print(str(len(zones)) + " Zones selected")
    print("Geoms number: "+str(len(_geoms)))

    # selectedName = _selected.getName()
    # print(selectedName)
#    layeredpanel_1 = panels[0]

#    materials = apex.catalog.getMaterialDictionary()
#    print (angles)
    # section from macro for coverage
    _coverage_region = apex.EntityCollection()
    _coverage_region.extend(_geoms)
    # print ("Coverage Number : " + str(len(coverage_region)))
    for _angle in angles:
        angle = float(_angle)
        for panel in panels:
            # print ("panel: "+ panel.getName())
            try:
                myply = panel.createAddPlyUsingProjectedVector(material=material,
                                                               thickness=float(dict.get("Thickness")),
                                                               angle=angle,
                                                               coverageRegion=_coverage_region,)
                if -22.5 <= angle < 22.5:
                    myply.update(color=[254, 0, 0])
                else:
                    if 67.5 <= angle < 112.5:
                        myply.update(color=[0, 254, 0])
                    else:
                        myply.update(color=[0, 0, 127])
            except:
                print("Error creating ply.  Contact MSC")

        thickness = dict.get("Thickness")
        print(f"Ply Mat: {material.name} Thick: {thickness} Angle {_angle}")


def get_materials(self):
    '''get all materials used in model and return as a dictionary
    of material objects'''
    apex.disableShowOutput()
    my_model = apex.currentModel()
    matls = apex.catalog.getMaterials([{"path": my_model.getName()+"/Materials"}])
#    print(f"matls: {matls}")
    matl_names = []
    for matl in matls:
        matl_names.append(matl.getName())

    if len(matl_names) == 0:
        matl_names.append("None")

    ret_dict = {}
    ret_dict["matlList"] = matl_names

    return ret_dict


def message_box(title, text, icon, style):
    # Force to top
    if style < 4095:
        style += 4096
    messageBox = ctypes.windll.user32.MessageBoxW
    returnValue = messageBox(None, text, title, icon | style)
    return returnValue

# Icon
# 16 Stop-sign icon
# 32 Question-mark icon
# 48 Exclamation-point icon
# 64 Information-sign icon consisting of an 'i' in a circle
#  Styles:
#  0 : OK
#  1 : OK | Cancel
#  2 : Abort | Retry | Ignore
#  3 : Yes | No | Cancel
#  4 : Yes | No
#  5 : Retry | No
#  6 : Cancel | Try Again | Continue
