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 s_straight(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,orient):
 grow_rules = [
   ['p',  
         lcat(['u'],lrepeat(repeat,['v',['tr','o','h']]))
   ],
   ['u',  
         ['q','u']
   ]
 ]
 terminal_rules = [
   ['u',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['q',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['v',[
          ['rF',2.0 * pi / repeat]
   ]],
   ['o',[
          ['rF',orient]
   ]],
   ['tr',[
          ['s',branch_scale,lenscale],['rS',-branch_angle]
   ]],
 ]
 axiom = ['a','p']
 return [axiom,grow_rules,terminal_rules]

def s_fork1(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,orient):
 grow_rules = [
   ['p',  
         lcat(lrepeat(repeat,['q',['tr','h']]),['p'])
   ]
 ]
 terminal_rules = [
   ['q',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['tr',[
          ['s',branch_scale,lenscale],['rF',pi * 0.5],['rS',branch_angle],['rF',orient]
   ]],
 ]
 axiom = ['a','p']
 return [axiom,grow_rules,terminal_rules]


def s_fork1_alt(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,orient):
 rep_half = repeat / 2
 rep_odd = repeat % 2
 if rep_odd:
   grow_rules = [
     ['p',  
           lcat(lrepeat(rep_half,['q',['tl','h'],'q',['tr','h']]),['q',['tl','h'],'p2'])
     ],
     ['p2',  
           lcat(lrepeat(rep_half,['q',['tr','h'],'q',['tl','h']]),['q',['tr','h'],'p'])
     ],
 ]
 else:
   grow_rules = [
     ['p',  
           lcat(lrepeat(rep_half,['q',['tl','h'],'q',['tr','h']]),['p'])
     ]
 ]
 terminal_rules = [
   ['q',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['tr',[
          ['s',branch_scale,lenscale],['rF',pi * 0.5],['rS',branch_angle],['rF',orient]
   ]],
   ['tl',[
          ['s',branch_scale,lenscale],['rF',-pi * 0.5],['rS',branch_angle],['rF',orient]
   ]],
 ]
 axiom = ['a','p']
 return [axiom,grow_rules,terminal_rules]


def s_fork2_alt(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,orient):
 rep_half = repeat / 2
 rep_odd = repeat % 2
 if rep_odd:
   grow_rules = [
     ['p',  
           lcat(lrepeat(rep_half,['q',['tl','h'],['tr','h'],'q',['v','tl','h'],['v','tr','h']]),['q',['tl','h'],['tr','h'],'p2'])
     ],
     ['p2',  
           lcat(lrepeat(rep_half,['q',['v','tl','h'],['v','tr','h'],'q',['tl','h'],['tr','h']]),['q',['v','tl','h'],['v','tr','h'],'p'])
     ],
 ]
 else:
   grow_rules = [
     ['p',  
           lcat(lrepeat(rep_half,['q',['tl','h'],['tr','h'],'q',['v','tl','h'],['v','tr','h']]),['p'])
     ],
 ]
 terminal_rules = [
   ['q',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['v',[
          ['rF',pi * 0.5]
   ]],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['tr',[
          ['s',branch_scale,lenscale],['rF',pi * 0.5],['rS',branch_angle],['rF',orient]
   ]],
   ['tl',[
          ['s',branch_scale,lenscale],['rF',-pi * 0.5],['rS',branch_angle],['rF',orient]
   ]],
 ]
 axiom = ['a','p']
 return [axiom,grow_rules,terminal_rules]

def s_fork3(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,orient):
 grow_rules = [
   ['p',  
         lcat(lrepeat(repeat,['q',['x','o','h'],['w','x','o','h'],['w','w','x','o','h']]),['p'])
   ]
 ]
 terminal_rules = [
   ['q',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['o',[
          ['rF',orient]
   ]],
   ['x',[
          ['s',branch_scale,lenscale],['rS',branch_angle]
   ]],
   ['w',[
          ['rF',0.66666 * pi]
   ]]
 ]
 axiom = ['a','p']
 return [axiom,grow_rules,terminal_rules]

def s_fork2(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,orient):
 grow_rules = [
   ['p',  
         lcat(lrepeat(repeat,['q',['tl','o','h'],['tr','o','h']]),['p'])
   ]
 ]
 terminal_rules = [
   ['q',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['o',[
          ['rF',orient]
   ]],
   ['tr',[
          ['s',branch_scale,lenscale],['rF',pi * 0.5],['rS',branch_angle]
   ]],
   ['tl',[
          ['s',branch_scale,lenscale],['rF',-pi * 0.5],['rS',branch_angle]
   ]]
 ]
 axiom = ['a','p']
 return [axiom,grow_rules,terminal_rules]

