# 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
from apex.construct import Point3D, Point2D

import os
import sys
import importlib

apex.setScriptUnitSystem(unitSystemName = r'''mm-kg-s-N-K''')

pathDir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

if not pathDir in sys.path:
	sys.path.insert(0, pathDir)
	print('inserted ' + pathDir + ' into sys.path')	


from aux_functions_v106e import *
importlib.reload(sys.modules['aux_functions_v106e'])
from aux_functions_v106e import *


def importMaterialFromBdf(bdf_file,TempMatDir):

	#Read material

	model_1 = apex.currentModel()
	
	global MxPxD

	MxPxD=read_mat_and_props(bdf_file)
	CLexApex.setMxPxD(MxPxD)
	for card in MxPxD:
		#print(card,MxPxD[card])
		print(card)
		for key in MxPxD[card].keys():
			print("%8d" % (key),MxPxD[card][key])
		print("========")
		
	#get Mat
	# get MAT1's and assiciated MATX and TABX cards
	
	for mat1_id in MxPxD['MAT1'].keys():
		m1=material(MxPxD['MAT1'][mat1_id][0])
		try:
			#try using SXNAME 
			print("MxPxD['MAT1'][mat1_id]")
			print(MxPxD['MAT1'][mat1_id])
			try:
				mat_name=MxPxD['MAT1'][mat1_id][2]
				print(mat_name)
				m1.name=mat_name
			except:
				mat_name='MAT1'
		except:
			print("***Fail*** No name found")
			
			
		m1.writeMatToTempFile(TempMatDir)
		
	for mat1_id in MxPxD['MAT2'].keys():
		m2=material(MxPxD['MAT2'][mat1_id][0])
		m2.writeMatToTempFile(TempMatDir)	
		
		
	for mat1_id in MxPxD['MAT8'].keys():
		m8=material(MxPxD['MAT8'][mat1_id][0])
		#m1.writeMatToTempFile(r"C:\Users\e7390\Documents\MSC_Apex Workspace\JaguarUtils\TmpMaterials")
		#m1.writeMatToTempFile(r"D:\Software\Apex\MaterialMethods\TmpMaterials")
		m8.writeMatToTempFile(TempMatDir)	
		
	
	return 
	

apex.enableUndoRedo()
apex.enableRecoveryFileRecording()
apex.enableShowOutput()

import os

# get new material and class objects from aux_functions
				
class Panel:
	def __init__(self,surf,panelName="Panel_"):
		self.surf=surf
		self.apexPanel = apex.attribute.createLayeredPanel(	target = self.surf )
		self.apexPanel.update(name = panelName )
		
		CLexApex.addPanel(self)
		
	def addPly(self,globalPly):
	
		#_coverageRegion = apex.EntityCollection()
		idL=[]
		#_coverageRegion=apex.EntityCollection()
		for subPanel in globalPly.subPanels:
			print("Global Ply contains of: ", subPanel.name, "Id", subPanel.id )
			print(subPanel.name)
			#_coverageRegion.append(subPanel.face)
			idL.append(subPanel.id)
			
		#Get the face associated with the subpanel

		_coverageRegion2 = self.surf.getFaces( ids = ','.join(idL) ) 

		ply_1 = self.apexPanel.createAddPlyUsingProjectedVector(
			material = globalPly.material.apexMat,
			thickness = globalPly.thickness,
			angle = globalPly.orientation,
			coverageRegion = _coverageRegion2,
		)
	
class globalPly:
	def __init__(self,id):
	
		self.id=id
		#self.materialHSName=PcompgD[id][5]
		self.orientation=float(PcompgD[id][4])
		# get material from Hypersizer Name
		
		print("PcompgD[id][3]:   ", PcompgD[id][3])
		
		self.material=CLexApex.getmaterialFromHyperSizerName( PcompgD[id][3])
		print("I am in here")
		self.material.createApexOrtotropic()

		self.thickness=float(PcompgD[id][0])
		
		tmp_vect=PcompgD[id][6][0]
		print("tmp_vect: ",tmp_vect)
		if len(tmp_vect) != len(GroupsL):
			print("warning...mismatching lengths...something is wrong")
			print(tmp_vect)
			print(GroupsL)
			print("===")
		else:
			
			self.subPanelNames=[ GroupsL[i]  for i in range(len(tmp_vect)) if tmp_vect[i].strip() !="" ] 
			# get subpanels by their names
			
			#self.subPanels=[ CLexApex.getSubPanelFromApexName(name) for name in self.subPanelNames ]
			self.subPanels=[ CLexApex.getSubPanelFromHyperSizerName(name) for name in self.subPanelNames ]
			#self.subPanels getSubPanelFromHyperSizerName
		
			
	def printInfo(self):
		print("=================")
		print("Global Ply id  : ", self.id)
		print("Orientation    : ", self.orientation)
		print("Material     : ",self.material.name," with id ",self.material.id )
		print("SubpanelNames      : ", self.subPanelNames)	
		
class subPanel:
	def __init__(self,face):
		print("I am in subPanel, face id:",face.getId())
		self.face = face
		self.id = face.getId()
		self.surf=face.getBody()
		# add to master
		CLexApex.addSubPanel(self)

		try:
			tmp_attributes=face.getUserAttributes(['SectionName'])
			self.name=tmp_attributes[0].getStringValue()  #SectName
		except:
			self.name = ""
			print("***failed*** obtaining SectionName")
	
		print("self.name",self.name)
		# check if PCOMPG
		if self.name in PcompD.keys():
			print("I am in check PCOMPG")
			self.GroupId=PcompD[self.name]
			self.stack=GroupD[self.GroupId]
			self.panelType="PCOMPG"
		else:
			print("I am in check MAT2")			#MAT2 panel
			for pshell_id in PShellD:
				if PShellD[pshell_id][0] == self.name:
					self.GroupId="C" + str(pshell_id)
					self.stack=[pshell_id]
					self.panelType="MAT2"
					
					# get material for panel of type MAT2
					_mat1Id=int(PShellD[pshell_id][1][16:24])
					_mat2Id= int(PShellD[pshell_id][1][32:40])
					_mat4Id=int(PShellD[pshell_id][1][98:114])
					self.material=CLexApex.getmaterialFromId(_mat1Id)
					self.mat2=CLexApex.getmaterialFromId(_mat2Id)
					self.mat4=CLexApex.getmaterialFromId(_mat4Id)
					
					self.assignMaterialToFace()
					
					self.writeMat2Tobdf()
					
					break
					
	def writeMat2Tobdf(self):
		# add material to MaterialTempFolder:
		mat_dir=r"C:\Users\e7390\Documents\MSC_Apex Workspace\JaguarUtils\TmpMaterials"
		if not os.path.isdir(mat_dir):
			os.mkdir(mat_dir)
		tmp_mat_file=mat_dir + '\\' + self.material.name + '.bdf'
		
		file_h=open(tmp_mat_file,'w' )
		# first write dummy MAT1-
		file_h.write("%-8s%8d%8.1f%8s%8.3f%8.3e\n" % ("MAT1",self.material.id,self.material.E,"",self.material.POI,self.material.RHO) )
		# write  MAT2 Mid1 Mid2 and Mid4...Mid3 appears to be blank
		file_h.write(self.material.bdf_str)
		file_h.write(self.mat2.bdf_str)
		file_h.write(self.mat4.bdf_str)
		# write PSHELL
		file_h.write(PShellD[self.stack[0]][1])
		file_h.close()
		
		print("written material info to " + tmp_mat_file )


	
			
	def printInfo(self):
		print("=====Sub Panel==============")
		print("Panel Type: ", self.panelType )
		if self.panelType=="MAT2":
			print("Material Id:", self.material.id)
		print("Section Name:", self.name )
		print("FaceId:",self.id)	
		print("Parent Surface:",self.surf.getName() )
		print("Group Id:",self.GroupId)
		print("Stack:",self.stack)
		
	def updateSection(self):
		# create Section from MAT2 and PSHELL data from Mat2D
		# 
		# createSection(MAT2,thick, offs)
		section_1 = apex.catalog.createShellSection( name = "Section 1", description = "", thickness = 0, offset = 0 )
		
		
	
		#section_1.update( name = "Section 1_from_MAT2"
		#section_1.update(	thickness = 0.14 )
		#section_1.update(	offset = 0.0,	)
		
		
		# assignSection
		pass
		
	


	def assignMaterialToFace(self):
		# get material -
		_target = apex.EntityCollection()
		_target.append( self.face )
		apex.attribute.assignMaterial(material = self.material.apexMat, target = _target )
	
def getStackInfoFromFaceId():
	pass

def read_stack(csv_file):
	csv_h=open(csv_file,'r')
	csv_lines=csv_h.readlines()
	csv_h.close()
	
	header_line=csv_lines[8]
	#raw_groups=header_line.split(',')[8:]
	groups=[i.strip() for i in header_line.split(',')[8:] ]
	print(header_line,"====================")
	print(groups)
	PcompgD={}
	n=9
	while n < len(csv_lines):
		tmp=csv_lines[n].split(',')
		# indx 6 is the vector of groups vs mat
		PcompgD[int(tmp[0])]=[float(tmp[1]),tmp[2],int(tmp[3]),tmp[4],float(tmp[5]),tmp[4],[tmp[8:]]]
		n+=1
	# Now, iterate through the lines again, Group, by Group to extract the stack info
	
	GroupD={}
	i=0
	for group in groups:
		GroupD[group]=[]
		n=9
		while n < len(csv_lines):
			if csv_lines[n].split(',')[8 +i].strip() != "":
				GroupD[group].append(int(csv_lines[n].split(',')[0]))
			n+=1
		i+=1
	return GroupD,PcompgD,groups

def read_bdf(bdf_file):
	
	bdf_h=open(bdf_file,'r')
	bdf_lines=bdf_h.readlines()
	bdf_h.close()
	
	#Get all PCOMPS:
	# Find PCOMP- Then-> identify Section Name from Comments
	PcompD={} 	# use Sect ID as lookup
	Mat8D={}
	Mat2D={}
	PShellD={}
	
	n=0
	N=len(bdf_lines)
	while n < N:
		if bdf_lines[n].find("PCOMP*") ==0:
			pcomp_sect=bdf_lines[n-2].split(':')[1].strip()
			print(pcomp_sect)
			PcompId=bdf_lines[n][8:24].strip()
			HyperSizerGroupName="C" + PcompId
			PcompD[pcomp_sect]=HyperSizerGroupName
			
		elif bdf_lines[n].find("MAT8*") ==0:
			mat8Id=int(bdf_lines[n][8:24])
			mat8_lines=bdf_lines[n]
			while bdf_lines[n+1].find("*") ==0:
				mat8_lines+=bdf_lines[n+1]
				n+=1
			Mat8D[mat8Id]=mat8_lines
		
		elif bdf_lines[n].find("PSHELL") ==0:
			# read all PSHELLs
			pshell_sect=bdf_lines[n-2].split(':')[1].strip()
			pshellId=int(bdf_lines[n][8:16])
			pshell_lines=bdf_lines[n]
			while bdf_lines[n+1].find("+") ==0:
				pshell_lines+=bdf_lines[n+1]
				n+=1
			PShellD[pshellId]=[pshell_sect,pshell_lines]
			

		elif bdf_lines[n].find("MAT2*") ==0:
			#MAT2 will be manage as other unsupported materials i.e:
			#Import to Apex as MAT1 and- At export convert to MAT2 using name as link and script trigger or export Utils
			mat2Id=int(bdf_lines[n][8:24])
			mat2_lines=bdf_lines[n]
			while bdf_lines[n+1].find("*") ==0:
				mat2_lines+=bdf_lines[n+1]
				n+=1
			Mat2D[mat2Id]=mat2_lines
			# 
			
			
		n+=1

	
	return PcompD, Mat8D, PShellD, Mat2D
		

def main(dict={}):

	model_1 = apex.currentModel()
	bdf_file=dict["bdf_file"] 
	csv_file=dict["csv_file"] 
	Scenario="MAT8"
	try:
		if os.path.isfile(csv_file):
			pass
		else:
			print("csv file not selected")
			Scenario="MAT2"
	except:
		print("Something is wrong the csv file: " + csv_file + " doesn't seem to exist or is not readable")
		return
	
	try:
		if os.path.isfile(bdf_file):
			pass
		else:
			print("Bdf file not selected")
			return
	except:
		print("Something is wrong the bdf file: " + bdf_file + " doesn't seem to exist or is not readable")
		return
		
	global GroupD, PcompgD, PcompD, Mat8D, GroupsL, PShellD
	
	
	if Scenario=="MAT8":	
		#GroupD,PcompgD, GroupsL=read_stack(r"D:\Software\Hypersizer\Scripts\GlobalPlies.csv")

		GroupD,PcompgD, GroupsL=read_stack(csv_file)
		#PcompD, Mat8D =read_bdf(r"D:\Software\Hypersizer\Scripts\Static_Scenario_Part.bdf")
		PcompD, Mat8D, PShellD, Mat2D =read_bdf(bdf_file)
		
		CLexApex.setPcompD(PcompD)
		print("===PcompD===")
		print(PcompD)

		parts=model_1.getParts(True)
		subPanelL=[]
		for part in parts:
			surfs=part.getSurfaces()
			for surf in surfs:
				faces=surf.getFaces()
				for face in faces:
					# add only if there is a custom attribute
					tmp_attributes=face.getUserAttributes(['SectionName'])
					if len(tmp_attributes)==1:
						tmp_face= subPanel(face)
						subPanelL.append(tmp_face)
						tmp_face.printInfo()

		# currently one Panel per surf
		surf=subPanelL[0].surf
		
		print("===Surf===",surf.getName() )
		Panel_1=Panel(surf,"Panel")

		for item in Mat8D.keys():
			print("===Creating MAT8===",Mat8D[item])
			m1=material(Mat8D[item],PcompgD)

			
			m1.printInfo()
		
		# create all plies... keys in PcompgD...
		for key in sorted(PcompgD.keys()):
			tmp_ply=globalPly(key)
			print("Global Ply Id: ",key)
			tmp_ply.printInfo()
			# add ply
			Panel_1.addPly(tmp_ply)
	
	elif Scenario=="MAT2":
		#PcompD, Mat8D, PShellD, Mat2D=read_bdf(r"D:\Software\Hypersizer\LargerWing_bdf_200609_0916\Static_Scenario_Part.bdf")
		PcompD, Mat8D, PShellD, Mat2D=read_bdf(bdf_file)
		#for id in Mat2D:
		#	print(id,Mat2D[id])
		

		for id in Mat2D:
			m1=material(Mat2D[id])	
	
		for id in PShellD:
			print(id,PShellD[id])
			

		parts=model_1.getParts(True)
		subPanelL=[]
		for part in parts:
			surfs=part.getSurfaces()
			for surf in surfs:
				faces=surf.getFaces()
				for face in faces:
					# add only if there is a custom attribute
					tmp_attributes=face.getUserAttributes(['SectionName'])
					if len(tmp_attributes)==1:
						tmp_face= subPanel(face)
						subPanelL.append(tmp_face)
						tmp_face.printInfo()

if __name__ == "__main__":
	main(dict={})
		

##main()


