# ~ Matt 2016-07-01, revised 2017-05-06
# Pick up for IQbuds MAX.  No change to the model structure, but trying to
# get it to work with the current FreeCAD. ~ 2020-07-11

# Not sure where to get FreeCAD's sin/cos functions, so use Python's.
import math

def vectorOfPoint(p):
	return FreeCAD.Vector(p.X, p.Y, p.Z)

def objByLabel(l):
	return App.ActiveDocument.getObjectsByLabel(l)[0]

def deg2rad(x): return x * math.pi / 180

# This helper is very specific to the way the model currently does things.  I'll generalize it if a use case arises.
def axisForDirection(angle_deg):
	angle_rad = deg2rad(angle_deg)
	return FreeCAD.Vector(-math.sin(angle_rad), math.cos(angle_rad), 0)

# FreeCAD API is underdocumented... *grumble*
params_live = objByLabel('params_live')
params_staging = objByLabel('params_staging')
# params_staging may have additional intermediate properties that params_live doesn't need.
userProperties = [p for p in params_live.PropertiesList if params_live.getCellFromAlias(p) is not None]  # Bleh; proper API?
for p in userProperties:
	# Plain "get" gives us a Base.Quantity, which we can't set into another spreadsheet.
	# But "getContents" gives us the formula, which we don't want.  Instead use "str" on the Base.Quantity.
	#params_live.set(p, params_staging.getContents(params_staging.getCellFromAlias(p)))
	#print "Setting %s" % p
	x = params_staging.get(p)
	params_live.set(p, str(x))

for l in 'nozzle', 'comply_hole':
	objByLabel(l).Placement.Rotation.Axis = axisForDirection(params_staging.nozzle_dir)

# freecad-0.16-1.fc23 seems to have a bug when the components of an axis are defined by formulas:
# the formula evaluator sets the components one at a time and fights with the code that normalizes
# the vector, giving a wrong answer.  Instead, set the whole axis at once here.
for l in 'outer', 'inner':
	# Careful, do not read params_live, it has not been updated yet!
	objByLabel('nozzle_bend_start_' + l).Placement.Rotation.Axis = axisForDirection(params_staging.nozzle_bend_start_direction)
	objByLabel('nozzle_bend_end_' + l).Placement.Rotation.Axis = axisForDirection(params_staging.nozzle_dir)

objByLabel('nozzle_bend_path').Points = [
	vectorOfPoint(objByLabel(pl))
	for pl in ['nozzle_bend_start_center_staging', 'nozzle_bend_start_control_staging', 'nozzle_bend_end_control_staging', 'nozzle_bend_end_center_staging']]

# Apparently this is not implicit.
App.ActiveDocument.recompute()
