# coding: utf-8
#
# 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.
#


import apex
import time


def deleteEmptyParts(dict={}):
    apex.disableShowOutput()
    myModel = apex.currentModel()
    allParts = myModel.getParts(True)
    
    emptyParts = apex.entityCollection()
    for part in allParts:
        #physicalEnts = part.getPhysicalEntities()
        #if physicalEnts.len() > 0: continue
        
        #namedEnts = part.getNamedEntities()
        #if namedEnts.len() > 0: continue
        
        # see notes in main() regarding getPhysicalEntities, getNamedEntities and getEntities
        ents = part.getEntities()
        if ents.len() > 0: continue
        
        emptyParts.append(part)

    if emptyParts.len() > 0: apex.deleteEntities(emptyParts)



def deleteEmptyAssys(dict={}):
    apex.disableShowOutput()
    myModel = apex.currentModel()
    
    allAssys = myModel.getAssemblies(True)
    emptyAssys = apex.entityCollection()
    for assy in allAssys:
        aa = assy.getAssemblies(True)
        if aa.len() > 0: continue
        
        pp = assy.getParts(True)
        if pp.len() > 0: continue
        
        # not sure if this is needed or not.  need to think on it some more
        namedEnts = assy.getNamedEntities()
        if namedEnts.len() > 0: continue
        
        emptyAssys.append(assy)

    if emptyAssys.len() > 0: apex.deleteEntities(emptyAssys)



def collapseSinglePartSubAssys(dict = {}):
    apex.disableShowOutput()
    myModel = apex.currentModel()
    allAssys = myModel.getAssemblies(True)
    topAssys = myModel.getAssemblies()

    renamePart = False
    if dict["renamePart"].lower() == "true":   renamePart = True

    for assy in allAssys:
        print(assy.getName())
        aa = assy.getAssemblies()
        if aa.len() > 0: continue
        
        parts = assy.getParts()
        if parts.len() > 1: continue

        if parts.len() == 0:
            ents = apex.entityCollection()
            ents.append(assy)
            apex.deleteEntities(target = ents)
        else:
            parentAssy = assy.getParent()
            if parentAssy == None: continue

            apex.reparent(target = parts, parent = parentAssy)
            
            # not sure if this is needed or not.  need to think on it some more
            namedEnts = assy.getNamedEntities()
            if namedEnts.len() > 0: continue
            
            assyName = assy.getName()
            
            ents = apex.entityCollection()
            ents.append(assy)
            apex.deleteEntities(target = ents)

            parts[0].update(name = assyName)






def main(dict={}):
    apex.disableShowOutput()
    myModel = apex.currentModel()

    startTime = time.perf_counter()

    partQueryStart = startTime

    allParts = myModel.getParts(True)
    
    emptyParts = apex.entityCollection()
    for part in allParts:
        # removed this for performance reasons.  not sure if this is required
        #physicalEnts = part.getPhysicalEntities()
        #if physicalEnts.len() > 0: continue
        
        # removed this for performance reasons.  not sure if this is required
        #namedEnts = part.getNamedEntities()
        #if namedEnts.len() > 0: continue
        
        # I am not quite sure what is the difference between getPhyscialEntities, getNamedEntities, and getEntities
        # getPhysicalEntities and getNamedEntities seem very slow compared to getEntities
        ents = part.getEntities()
        if ents.len() > 0: continue
        
        emptyParts.append(part)

    partQueryEnd = time.perf_counter()
    print("Part Query Time: %0.4f" % (partQueryEnd - partQueryStart))

    assyQueryStart = partQueryEnd

    allAssys = myModel.getAssemblies(True)
    emptyAssys = apex.entityCollection()
    singlePartSubAssys = apex.entityCollection()
    for assy in allAssys:
        aa = assy.getAssemblies(True)
        if aa.len() > 0: continue
        pp = assy.getParts(True)
        if pp.len() == 1: singlePartSubAssys.append(assy)
        if pp.len() > 0: continue
        
        emptyAssys.append(assy)

    assyQueryEnd = time.perf_counter()
    print("Assy Query Time: %0.4f" % (assyQueryEnd - assyQueryStart))

    ret_dict = {}
    ret_dict["allParts"]        = str(allParts.len())
    ret_dict["emptyParts"]      = str(emptyParts.len())
    ret_dict["allAssemblies"]   = str(allAssys.len())
    ret_dict["emptyAssemblies"] = str(emptyAssys.len())
    ret_dict["singlePartSubAssemblies"] = str(singlePartSubAssys.len())

    return ret_dict


