/* 

has sm09_e38.gsz as a basis.

Changes: 
- Internode, petiole and blade get an additional parameter lnfb 
  (leaf number from base).
- Growth parameters are set by constants and can thus be found
  better in the head section of the programme.

*/

// internode with small start size:
module Internode(int age, int lnfb) extends F(0.01, 0.0005)
{{ setShader(GREEN); }};

// meristem as seed for growth:
module Meristem(int age, int lnfb) extends Sphere(0.0005)
{{ setShader(RED); }};

// the petiole:
module Petiole(int age, int lnfb) extends F(0.001, 0.0001)
{{ setShader(GREEN); }}

// the leaf:
module Blade(int age, int lnfb) extends Parallelogram(1.0, 1.0/1.3);

const Shader leafmat = shader("Leaf1");

public int time;               // time unit = one hour

const int PLASTOCHRON = 48;    // number of time units between the
                               // emergence of two leaves
const int MAX_GROWTHTIME_INTERNODE = 30;
const int MAX_GROWTHTIME_PETIOLE = 30;
const int MAX_GROWTHTIME_LEAF = 96;

const float GROWTH_RATE_INTERNODE_LENGTH = 0.001;
const float GROWTH_RATE_INTERNODE_DIAMETER = 0.000004;
const float GROWTH_RATE_PETIOLE_LENGTH = 0.00117;
const float GROWTH_RATE_PETIOLE_DIAMETER = 0.000031;
const float GROWTH_RATE_LEAF_SCALE = 0.0016;


protected void init()
{
   time = 0;
   [
   Axiom ==> Meristem(0, 0);
   ]
}

public void run()
{
   time++;
   println("Hour:" + time);
   [   
   // first rule: The meristem ages
   m:Meristem ::> m[age]++;	

   // for a meristem: formation of the internode
   m:Meristem, (m[age] == PLASTOCHRON || m[lnfb] == 0) ==> 
      Internode(0, m[lnfb]+1) [ RL(45) Petiole(0, m[lnfb]+1) 
      RH(5) RL(30) 
      [ Blade(0, m[lnfb]+1).(setShader(leafmat), setScale(0.001)) ]
      ] RH(140) RU(random(-5,5)) Meristem(0, m[lnfb]+1);
   ]

   [  
   // block for internode extension:
   i:Internode ::> 
      {
      if(i[age] <  MAX_GROWTHTIME_INTERNODE) 
         { 
         i[length] += GROWTH_RATE_INTERNODE_LENGTH; 
         }  // length growth for the first days
      i[diameter] += GROWTH_RATE_INTERNODE_DIAMETER; 
                  // diameter growth always
      i[age]++; // age increment
      }
   ]

   [
   // block for the extension of the petiole during the first days:
   p:Petiole, (p[age] <  MAX_GROWTHTIME_PETIOLE) ::> 
      {
      p[length] += GROWTH_RATE_PETIOLE_LENGTH;     // length growth
      p[diameter] += GROWTH_RATE_PETIOLE_DIAMETER; // diameter growth
      p[age]++; // age increment
      }
   ]

   [ 
   // block for leaf growth:
   s:Blade, (s[age] <  MAX_GROWTHTIME_LEAF) ::> 
      {
      s.setScale(s[scale] + GROWTH_RATE_LEAF_SCALE);
      s[age]++;	
      }
   ]
}

