pi = 3.1415926

def lrepeat(num,l):
	res = []
	for i in range(num):
		res.extend(l)
	return res
def lcat(la,lb):
	la.extend(lb)
	return la
def AddEndPoint(branchLeafRotRad, addEndPoint):
	arr = None
	if not addEndPoint:
		arr = ['lf', [] ]
	else:
		arr = ['lf', [['rF', -pi*0.5],['rF', branchLeafRotRad],['rS', -pi*0.5],['el', 1.0]]]
	return arr

def l_endpoint(repeat,rotF,curve,length,branch_scale,resolutionV, branchLeafRotRad):
 grow_rules = [
	 ['e', 
				 ['g']
	 ],
 ]
 terminal_rules = [
	 ['e',
					lrepeat(repeat,[['a',(length / repeat)],['rS',curve],['rF',rotF]])
	 ],
	 ['lf', [
					['rF', branchLeafRotRad],
					['rS', -pi*0.5],
					['el', 1.0]
				 ]
	 ],
	 ['h', []
	 ],
	 ['h2', []
	 ],
	 ['h3', []
	 ],
 ]
 axiom = []
 return [axiom,grow_rules,terminal_rules]

def l_activepoint(repeat,rotF,curve,length,branch_scale,resolutionV,branchLeafRotRad):
 grow_rules = [
	 ['e', 
				 ['g']
	 ],
 ]
 terminal_rules = [
	 ['e',
					lrepeat(repeat,[['a',(length / repeat)],['rS',curve],['rF',rotF]])
	 ],
	 ['h', [
					['rF', branchLeafRotRad],
					['rS', -pi*0.5],
					['el', 1.0]
				 ]
	 ],
	 ['h2', [
					['rF', branchLeafRotRad],
					['rS', -pi*0.5],
					['el', 1.0]
				 ]
	 ],
	 ['h3', [
					['rF', branchLeafRotRad],
					['rS', -pi*0.5],
					['el', 1.0]
				 ]
	 ],
	 ['lf', []
	 ],
 ]
 axiom = []
 return [axiom,grow_rules,terminal_rules]

def l_fork1_alt_prp(repeat, rotF, curve, length, branch_scale, resolutionV, branchLeafRotRad, addEndPoint):
 grow_rules = [
	 ['e', 
				 ['f']
	 ],
	 ['f', 
				 ['g']
	 ]
 ]
 terminal_rules = [
	 ['f',
#			 lcat(lrepeat(repeat,[['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF',(pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ],['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF',(-pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ] ]),[])
					lcat(lrepeat(repeat,[['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF', branchLeafRotRad],['l1',1.0],['rF',(pi * 0.5)],['l',1.0] ] ],['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF', branchLeafRotRad],['l1',1.0],['rF',(-pi * 0.5)],['l',1.0] ] ] ]),[])
	 ],
	 ['e',
#			 lcat(lrepeat(repeat,[['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF',(pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ],['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF',(-pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ] ]),[]) 
					lcat(lrepeat(repeat,[['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF', branchLeafRotRad],['rF',(pi * 0.5)],['l',1.0] ] ],['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],['b',[ ['rF', branchLeafRotRad],['rF',(-pi * 0.5)],['l',1.0] ] ] ]),[])	
	 ],
	 AddEndPoint(branchLeafRotRad, addEndPoint),
	 ['h', []
	 ],
	 ['h2', []
	 ],
	 ['h3', []
	 ],
 ]
 axiom = []
 return [axiom,grow_rules,terminal_rules]

def l_fork2_prp(repeat,rotF,curve,length,branch_scale,resolutionV, branchLeafRotRad, addEndPoint):
 grow_rules = [
	 ['e', 
				 ['f']
	 ],
	 ['f', 
				 ['g']
	 ]
 ]
 terminal_rules = [
	 ['f',
#				lcat(lrepeat(repeat,[['a',(length / (repeat))],['rS',curve],['rF',rotF],['b',[ ['rF',(pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ],['b',[ ['rF',(-pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ] ]),[]) 
					lcat(lrepeat(repeat,[['a',(length / (repeat))],['rS',curve],['rF',rotF],['b',[ ['rF', branchLeafRotRad],['rF',(pi*0.5)],['l',1.0] ] ],['b',[ ['rF', branchLeafRotRad],['rF',(-pi*0.5)],['l',1.0] ] ] ]),[]) 
	 ],
	 ['e',
#				lcat(lrepeat(repeat,[['a',(length / (repeat))],['rS',curve],['rF',rotF],['b',[ ['rF',(pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ],['b',[ ['rF',(-pi * 0.5)],['rS',branch_angle],['rF',bank],['l',1.0] ] ] ]),[]) 
					lcat(lrepeat(repeat,[['a',(length / (repeat))],['rS',curve],['rF',rotF],['b',[ ['rF', branchLeafRotRad],['rF',(pi*0.5)],['l',1.0] ] ],['b',[ ['rF', branchLeafRotRad],['rF',(-pi*0.5)],['l',1.0] ] ] ]),[]) 
	 ],
	 AddEndPoint(branchLeafRotRad, addEndPoint),
	 ['h', []
	 ],
	 ['h2', []
	 ],
	 ['h3', []
	 ],
 ]
 axiom = []
 return [axiom,grow_rules,terminal_rules]

def l_fork2_alt_prp(repeat,rotF,curve,length,branch_scale,resolutionV, branchLeafRotRad, addEndPoint):
 grow_rules = [
	 ['e', 
				 ['f']
	 ],
	 ['f', 
				 ['g']
	 ]
 ]
 terminal_rules = [
	 ['f',
					lrepeat(repeat,
						[['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],
						['b',[['rF', branchLeafRotRad],['rF',(0.0)],['l',1.0] ] ],
						['b',[['rF', branchLeafRotRad],['rF',(pi)],['l',1.0] ] ] ,
						['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],
						['b',[['rF', branchLeafRotRad],['rF',(pi * 0.5)],['l',1.0] ] ],
						['b',[['rF', branchLeafRotRad],['rF',(-pi * 0.5)],['l',1.0] ] ] ]
					)
	 ],
	 ['e',
					lrepeat(repeat,
						[['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],
						['b',[['rF', branchLeafRotRad],['rF',(0.0)],['l',1.0] ] ],
						['b',[['rF', branchLeafRotRad],['rF',(pi)],['l',1.0] ] ] ,
						['a',(length / (2.0 * repeat))],['rS',curve],['rF',rotF],
						['b',[['rF', branchLeafRotRad],['rF',(pi * 0.5)],['l',1.0] ] ],
						['b',[['rF', branchLeafRotRad],['rF',(-pi * 0.5)],['l',1.0] ] ] ]
					)
	 ],
	 AddEndPoint(branchLeafRotRad, addEndPoint),
	 ['h', []
	 ],
	 ['h2', []
	 ],
	 ['h3', []
	 ],
 ]
 axiom = []
 return [axiom,grow_rules,terminal_rules]

def l_fork3_prp(repeat,rotF,curve,length,branch_scale,resolutionV, branchLeafRotRad, addEndPoint):
	grow_rules = [
		['e', 
			['f']
		],
		['f', 
			['g']
		]
	]
	# experimental - fully implemented in l_max
	rnge = 3.0
	arr = []
	arr.append(['a',(length / (repeat))])
	arr.append(['rS',curve])
	arr.append(['rF',rotF])
	for i in range(0,rnge):
		arr.append(['b',[['rF', branchLeafRotRad],['rF',pi*((2/rnge)*i)],['l',1.0] ] ])
	terminal_rules = [
		['f',
					lrepeat(repeat, arr)
		],
		['e',
					lrepeat(repeat, arr)
		],
		AddEndPoint(branchLeafRotRad, addEndPoint),
		['h', []
		],
		['h2', []
		],
		['h3', []
		],
	]
	axiom = []
	return [axiom,grow_rules,terminal_rules]

# experimental leaf rule
def l_advanced(repeat,rotF,curve,length,branch_scale,resolutionV, branchLeafRotRad, addEndPoint, leavesAroundPoint, leavesRepeatAlongSegment):
	grow_rules = [
		['e', 
			['f']
		],
		['f', 
			['g']
		]
	]
	
	# v1.5.8:
	arr = []
	# altsRange specifies the number of rads to calculate the rotation over. odd number of leaves over 2, even over 1
	altsRange = (leavesAroundPoint % 2.0) + 1.0
	for i_alt in range(0, leavesRepeatAlongSegment):
		# loop outside this for repeating to add alternating positions
		arr.append(['a',(length / (leavesRepeatAlongSegment*repeat))])
		arr.append(['rS',curve])
		arr.append(['rF',rotF])
		# loop this for repeating leaves around point
		for i in range(0,leavesAroundPoint):
			arr.append(['b',[['rF',pi*((altsRange/leavesRepeatAlongSegment)*i_alt)],['rF', branchLeafRotRad],['rF',pi*((2.0/leavesAroundPoint)*i)],['l',1.0] ] ])
		
	# create the terminal rules 
	terminal_rules = [
		['f',
					lrepeat(repeat, arr)
		],
		['e',
					lrepeat(repeat, arr)
		],
		AddEndPoint(branchLeafRotRad, addEndPoint),
		['h', []
		],
		['h2', []
		],
		['h3', []
		],
	]
	axiom = []
	return [axiom,grow_rules,terminal_rules]