#!/usr/bin/env python

import sys
import string
import xml.etree.ElementTree as ET


def usage(argv):
	print
	print 'USAGE: ' + argv[0] + ' <model.feb> <modify_model.cfg> <modified_model_filename.feb>'
	print


def main(argv):

	# Check for appropriate usage
	if len(argv) != 4:
		usage(argv)
		sys.exit(1)

	model_filename = argv[1]
	cfg_filename = argv[2]
	# set output filename
	output_filename = argv[3]


	# import options from config file
	cfg_content = parse_file(cfg_filename, '*', '**')

	#print cfg_content

	# import the XML tree data structure
	model_tree = ET.parse(model_filename)
	model_root = model_tree.getroot()

	is_model_changed = False

	# Attempts to modify contents of each keyword in the config file
	for keyword in cfg_content.keys():

		#print keyword

		# Try to find the element associated with the keyword in the config file
		# assumes only one element for a specified keyword
		keyword_element = model_root.find(keyword)

		# Modify model element parameters if a valid keyword was found
		if ET.iselement(keyword_element):

			#ET.dump(keyword_element)

			# ONLY SETUP TO MODIFY THE LOAD !!!
			if keyword=='Loads':

				# Overwrite all nodal loads
				# WARNING: scalar value will overwrite loads in all dimensions previously defined
				for node in keyword_element.iter('node'):

					#print node.attrib, node.text

					node.text = cfg_content[keyword][0]

				if not is_model_changed:
					is_model_changed = True


	# Output modified FEBio model if it has been changed
	if is_model_changed:

		# set encoding
		encoding = "ISO-8859-1"

		# write modified FEBio model
		model_tree.write(output_filename, encoding=encoding)

	'''
	for child in model_root:
		print child.tag, child.attrib

		if cfg_content.has_key(child.tag):
			print child.tag
			is_changed = True
	'''

# END OF main()


# Function from:
# j2c/private/prj/mdlTS/Framework/scripts/macro_fiber.py
def parse_file(fname, skyw, scmt): # file name, keyword string, comment string

       fid = open(fname, 'r')
       # remove trailing white space and load file content
       flines = map(string.rstrip, fid.readlines()) # each line is a string in a list
       fid.close()
             
       #remove spaces
       tmp = []
       dmys = flines[:]
       for line in dmys:
             dmy = line.replace(" ","")
             tmp.append(dmy)
       del flines
       flines = tmp # same list with white spaces removed
       del dmys
             
       # remove comments and empty lines
       dmys = flines[:]
       for dmy in dmys:
             if (scmt in dmy) or (dmy == ''):
                  flines.remove(dmy) # list with all comment lines and empty lines removed
       del dmys
       
       # find all keywords
       findx = [];
       i = 0;
       for fline in flines:
             if skyw in fline:
                  findx.append(i) # list of the line #s that contain keywords
             i = i + 1
       
       # save contents to a dictionary
       fcontent = {}
       nfind = len(findx) # get number of keywords
       for i in range(nfind):
             indst = findx[i]+1 # line number just after keyword
             if i < nfind-1:
                  indsp = findx[i+1]; # line number of next keyword
             else:
                  indsp = len(flines)

             fcontent[flines[indst-1].strip(skyw)] = flines[indst:indsp] # remove * from keyword, use as key in dictionary, following list (up to next keyword) is the value
       
       return fcontent

# END OF parse_file()


if __name__ == "__main__":
    main(sys.argv)
