// Lindenmayer (c) CSE, 2006
			var canvas, ctx;
			
            function apply_rules( str, rles ) {
               new_str = '';
               for (var i=0; i<str.length; i++) {
                   var c=str.charAt(i);
                   if (rles[c] != undefined)
                     new_str += rles[c];
                   else
                     new_str += c;
               }
               return new_str;
            }
 
            function drawBackground()
            {
                  hor_h = document.linden.ver_i.value*1;
                  grd = ctx.createLinearGradient(0, 0, 0, hor_h-50);
                  grd.addColorStop(0,"#00A0E0");
                  grd.addColorStop(1,"#A0E0E0");
                  ctx.fillStyle = grd;
                  ctx.beginPath();
                  ctx.moveTo(0, 0);
                  ctx.lineTo(0, hor_h-50);
                  ctx.lineTo(canvas.width, hor_h-50);
                  ctx.lineTo(canvas.width, 0);
                  ctx.closePath();
                  ctx.fill();
//                  ctx.fillRect(0, 0, canvas.width, hor_h-50);
                  grd = ctx.createLinearGradient(0, hor_h-51, 0, canvas.height);
                  grd.addColorStop(0,"#80EE60");
                  grd.addColorStop(1,"#20A000");
                  ctx.fillStyle = grd;
                  ctx.beginPath();
                  ctx.moveTo(0, hor_h-51);
                  ctx.lineTo(0, canvas.height);
                  ctx.lineTo(canvas.width, canvas.height);
                  ctx.lineTo(canvas.width, hor_h-51);
                  ctx.closePath();
                  ctx.fill();
//                  ctx.fillRect(0, hor_h-51, canvas.width, canvas.height-hor_h+51);
                  // Berg
                    ctx.beginPath();
                  hgt = Math.floor(Math.random()*60);
                  ctx.moveTo(0, hor_h-50-hgt);
                  var nb_mnt = Math.floor(Math.random()*10);
                  mx_h = hgt;
                  for (var i=0; i<nb_mnt; i++) {
                        hgt = Math.floor(Math.random()*60);
                        if (hgt > mx_h) mx_h = hgt;
                        ctx.lineTo(canvas.width/nb_mnt*(i+1),hor_h-50-hgt);
                  }
                  ctx.lineTo(canvas.width,hor_h-51);
                  ctx.lineTo(0,hor_h-51);
                  grd = ctx.createLinearGradient(0, hor_h-50, 0, hor_h-50-mx_h);
                  grd.addColorStop(0,"#EEEEEE");
                  grd.addColorStop(1,"#AAAAAA");
                  ctx.fillStyle = grd;
                  ctx.closePath();
                  ctx.fill();
               		ctx.stroke();
                  ctx.beginPath();
                  hgt = Math.floor(Math.random()*50);
                  ctx.moveTo(0, hor_h-50-hgt );
                  var nb_mnt = Math.floor(Math.random()*10);
                  mx_h = hgt;
                  for (var i=0; i<nb_mnt; i++) {
                        hgt = Math.floor(Math.random()*50);
                        if (hgt > mx_h) mx_h = hgt;
                        ctx.lineTo(canvas.width/nb_mnt*(i+1),hor_h-50-hgt);
                  }
                  ctx.lineTo(canvas.width,hor_h-51);
                  ctx.lineTo(0,hor_h-51);
                  grd = ctx.createLinearGradient(0, hor_h-50, 0, hor_h-50-mx_h);
                  grd.addColorStop(0,"#AAAAAA");
                  grd.addColorStop(1,"#888888");
                  ctx.fillStyle = grd;
                  ctx.closePath();
                  ctx.fill();
               		ctx.stroke();
                  ctx.beginPath();
                  hgt = Math.floor(Math.random()*20);
                  ctx.moveTo(0, hor_h-50-hgt);
                  mx_h = hgt;
                  var nb_mnt = Math.floor(Math.random()*15);
                  for (var i=0; i<nb_mnt; i++) {
                        hgt = Math.floor(Math.random()*20);
                        if (hgt > mx_h) mx_h = hgt;
                        ctx.lineTo(canvas.width/nb_mnt*(i+1),hor_h-50-hgt);
                  }
                  ctx.lineTo(canvas.width,hor_h-51);
                  ctx.lineTo(0,hor_h-51);
                  grd = ctx.createLinearGradient(0, hor_h-50, 0, hor_h-50-mx_h);
                  grd.addColorStop(0,"#888888");
                  grd.addColorStop(1,"#00AA00");
                  ctx.fillStyle = grd;
                  ctx.closePath();
                  ctx.fill();
               ctx.stroke();
 
 
            }
           
            function iterate( str, rles, iter ) {
               while (iter > 0) {
                   str=apply_rules(str, rles);
                   iter--;
               }
               return str;
            }
           
           
            function lne() {
               ctx.moveTo(0,0);
               ctx.lineTo(0,-move_step);
               ctx.stroke();
               ctx.translate(0,-move_step);
            }
           
            function mve() {
               ctx.moveTo(0,-move_step);
               ctx.stroke();
               ctx.translate(0,-move_step);
            }
           
            function rot( deg ) {
               ctx.rotate( deg*Math.PI*2.0/360.0 );
            }
            
            function setCharAt(str, index, ch) {
   				return str.substr(0, index - 1) + ch + str.substr(index);
			}
            
            function drawStr(stri, move_step, ang, cur_width) {
            
                  var w_tbl = new Array();
                  var lvl =0;
                  
                  var str = stri;
                  
               ctx.beginPath();
               for (var i=0; i<str.length; i++) {
                   c=str.charAt(i);
                   // i = ignore;
                   if (c == 'F') lne();
                   if (c == 'f') mve();
                   if (c == '+') rot(+ang);
                   if (c == '-') rot(-ang);
                   if (c == 'B') cur_width=cur_width*2; ctx.lineWidth = cur_width;
                   if (c == 'T')
                   {
                        cur_width=cur_width*0.8;
                        if (cur_width<1) cur_width=1;
                        ctx.lineWidth=cur_width;
                   }
                   if (c == '[')
                   {
                        ctx.save();
                        w_tbl[lvl] = cur_width;
                        lvl = lvl + 1;
                   }
                   if (c == ']')
                   {
                        ctx.restore();
                        lvl = lvl-1;
                        cur_width = w_tbl[lvl];
                        ctx.lineWidth = cur_width;
                   }
                   if (c == 'L')
                   {
                     	ctx.strokeStyle = document.linden.lf_col.value;
                        ctx.lineWidth = 5;
                     	ctx.moveTo(0,0);
                     	ctx.lineTo(0,-5);
                     	ctx.stroke();
                     	ctx.strokeStyle = document.linden.tr_col.value;
                        ctx.lineWidth = cur_width;
                   }
                   if (c == 'l')
                   {
                     	ctx.strokeStyle = document.linden.lf_col.value;
                        ctx.lineWidth = 2;
                     	ctx.moveTo(0,0);
                     	ctx.lineTo(0,-2);
                     	ctx.stroke();
                     	ctx.strokeStyle = document.linden.tr_col.value;
                        ctx.lineWidth = cur_width;
                   }
                   if (c == 'P')
                   {
                     ctx.strokeStyle = document.linden.ft_col.value;
                        ctx.lineWidth = 5;
                     	ctx.moveTo(0,0);
                     	ctx.lineTo(0,-5);
                     	ctx.stroke();
                     	ctx.strokeStyle = document.linden.tr_col.value;
                        ctx.lineWidth = cur_width;
                   }
                  if (c == 'R')
                   {
                        if (Math.random()>0.5)
                        {
                             // replace everything until comma
                             j = i+1;
                             while (str.charAt(j) != ',')
                             {
                                   str = setCharAt(str, j+1, 'i');
                                   j = j + 1;
                             }
                        	//alert("main " + str);
                        } else {
                             // replace everything after comma until ")"
                             j = i+1;
                             while (str.charAt(j) != ',')
                             {
                                   j = j + 1;
                             }
                             while (str.charAt(j) != ')')
                             {
                                   str = setCharAt(str, j+1, 'i');
                                   j = j + 1;
                             }
                        	//alert("alt " + str);
                        }
                   }
 
               }
           
               ctx.closePath();
            }
           
            function testdraw2() {
           
           
               move_step = document.linden.step.value*1;
               ang = document.linden.angle.value*1;
               iter = document.linden.iter.value*1;
               var str = document.linden.ini_str.value;
               var rles = {'F':document.linden.rleF.value,'f':document.linden.rleN.value, 'X':document.linden.rleX.value, 'Y':document.linden.rleY.value, 'Z':document.linden.rleZ.value};
           
               canvas = document.getElementById("cv");
               ctx = canvas.getContext("2d");
 
               ctx.clearRect(0,0,canvas.width,canvas.height);
 
               if (document.linden.backgd.checked) drawBackground();
 
               ctx.lineWidth = document.linden.ln_wd.value*1;
               ctx.strokeStyle = document.linden.tr_col.value;
               ctx.moveTo(0,0);
               ctx.save();
               ctx.translate(document.linden.hor_i.value,document.linden.ver_i.value);
               cur_width = document.linden.ln_wd.value*1;
              
               //alert(str);
               if (iter > 0) str = iterate(str, rles, iter);
               //alert(str);
               
           	   drawStr(str, move_step, ang, cur_width);
               
               ctx.restore();
               
               //window.location.href='#cvns'
            }
           
            function addIteration() {
                  cur_it = document.linden.iter.value*1;
                  if (cur_it < 99) cur_it = cur_it + 1;
                  document.linden.iter.value = cur_it;
                  proposeStep();
            }
           
            function removeIteration() {
                  cur_it = document.linden.iter.value*1;
                  if (cur_it > 0) cur_it = cur_it - 1;
                  document.linden.iter.value = cur_it;
                  proposeStep();
            }
           
            function count_F(str) {
                  var cnt = 0;
                  var count = 0;
                  for (var i=0; i<str.length; i++) {
                        if (str.charAt(i) == '[') count++;
                        if ((str.charAt(i) == 'F') & (count == 0)) cnt++;
                        if (str.charAt(i) == ']') count--;
                  }
                  return cnt;
            }
           
            function proposeStep() {
                  if (document.linden.adapt.checked) {
                        cur_it = document.linden.iter.value*1;
                        ini_str = document.linden.ini_str.value;
                        var rles = {'F':document.linden.rleF.value,'f':document.linden.rleN.value, 'X':document.linden.rleX.value, 'Y':document.linden.rleY.value, 'Z':document.linden.rleZ.value};
                        var factor = document.linden.factor.value*1;
                        if (factor == 0) {
                             factor = count_F(ini_str);
                              factor = count_F(apply_rules(ini_str, rles))/factor;
                        }
//                      alert(cur_it);
                        cur_step = document.linden.base_step.value*1;
                        //alert(factor);
                        for (var i = 0; i< cur_it; i++) {
                             cur_step = cur_step / factor;
                        }
//                      alert(cur_step);
                        document.linden.step.value = cur_step;
                        if (cur_step < 1) {
                             input_box= confirm("Details are smaller than one pixel. Iterating further is probably not very useful! But I can do it anywaay! (it will be slow and you probably won't see anything!). Shall I proceed?");
                        } else {
                             input_box = true;
                        }
                        if (input_box == true) {
                             testdraw2();
                        } else {
                             removeIteration();
                        }
                  }
            }
           
            function fillValues() {
                  switch (document.linden.cool.value*1) {
                        case 1: //example
                             document.linden.ini_str.value = 'F';
                             document.linden.step.value = 5;
                             document.linden.angle.value = 33;
                             document.linden.iter.value = 4;
                             document.linden.rleF.value = 'F[+FL]FX[-FZ]F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'Y';
                             document.linden.rleY.value = 'PX';
                             document.linden.rleZ.value = 'X';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '500';
                             document.linden.factor.value = '3';
                             document.linden.base_step.value = 400;
                             document.linden.backgd.checked = true;
                             break;
                        case 2:
                             document.linden.ini_str.value = 'F-F-F-F-F-F';
                             document.linden.step.value = 200;
                             document.linden.angle.value = 60;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F+F--F+F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '475';
                             document.linden.ver_i.value = '400';
                             document.linden.factor.value = '3';
                             document.linden.base_step.value = 200;
                             document.linden.backgd.checked = false;
                             break;
                        case 3:
                             document.linden.ini_str.value = 'F+F+F';
                             document.linden.step.value = 300;
                             document.linden.angle.value = 240;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F-F+F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '350';
                             document.linden.factor.value = '1.85';
                             document.linden.base_step.value = 300;
                             document.linden.backgd.checked = false;
                             break;
                        case 4:
                              document.linden.ini_str.value = 'F+F+F+F';
                             document.linden.step.value = 300;
                             document.linden.angle.value = 90;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F+F-F+F+F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '230';
                             document.linden.ver_i.value = '400';
                             document.linden.factor.value = '2.5';
                             document.linden.base_step.value = 300;
                             document.linden.backgd.checked = false;
                             break;
                        case 5:
                             document.linden.ini_str.value = 'F+F+F+F';
                             document.linden.step.value = 300;
                             document.linden.angle.value = 90;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F+f+F-FF+f+F-F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '180';
                             document.linden.ver_i.value = '401';
                             document.linden.factor.value = '3.5';
                             document.linden.base_step.value = 300;
                             document.linden.backgd.checked = false;
                             break;
                        case 6:
                             document.linden.ini_str.value = 'YF';
                             document.linden.step.value = 280;
                             document.linden.angle.value = 60;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'YF+XF+Y';
                             document.linden.rleY.value = 'XF-YF-X';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '400';
                             document.linden.factor.value = '2';
                             document.linden.base_step.value = 280;
                             document.linden.backgd.checked = false;
                             break;
                        case 7:
                             document.linden.ini_str.value = 'Y';
                             document.linden.step.value = 200;
                             document.linden.angle.value = 60;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'XF+F+XF-F-F-XF-F+F+F-F+F+F-X';
                             document.linden.rleY.value = 'XF+F+XF+F+XF+F';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '100';
                             document.linden.ver_i.value = '550';
                             document.linden.factor.value = '2.2';
                             document.linden.base_step.value = 280;
                             document.linden.backgd.checked = false;
                             break;
                        case 8:
                             document.linden.ini_str.value = 'FX';
                             document.linden.step.value = 100;
                             document.linden.angle.value = 90;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X+YF+';
                             document.linden.rleY.value = '-FX-Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '300';
                             document.linden.factor.value = '1.45';
                             document.linden.base_step.value = 280;
                             document.linden.backgd.checked = false;
                             break;
                        case 9:
                             document.linden.ini_str.value = 'F+XF+F+XF';
                             document.linden.step.value = 50;
                             document.linden.angle.value = 90;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'XF-F+F-XF+F+XF-F+F-X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '50';
                             document.linden.ver_i.value = '300';
                             document.linden.factor.value = '2.3';
                             document.linden.base_step.value = 280;
                             document.linden.backgd.checked = false;
                             break;
                        case 10:
                             document.linden.ini_str.value = 'BF';
                             document.linden.step.value = 200;
                             document.linden.angle.value = 20;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'F[+TTTFL]F[-TTTTFl]F';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '550';
                             document.linden.factor.value = '2.5';
                             document.linden.base_step.value = 200;
                             document.linden.backgd.checked = true;
                             break;
                        case 11:
                             document.linden.ini_str.value = 'BX';
                             document.linden.step.value = 400;
                             document.linden.angle.value = 20;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'FF';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'F[+TXP]F[-TXL]+TX';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '550';
                             document.linden.factor.value = '2.2';
                             document.linden.base_step.value = 400;
                             document.linden.backgd.checked = true;
                             break;
                        case 12:
                             document.linden.ini_str.value = 'BBF';
                             document.linden.step.value = 20;
                             document.linden.angle.value = 20;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'FF+T[+Fl-Fl-FL]-[-FL+FP+Fl]';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '550';
                             document.linden.factor.value = '2.3';
                             document.linden.base_step.value = 200;
                             document.linden.backgd.checked = true;
                             break;
                        case 13:
                             document.linden.ini_str.value = 'BY';
                             document.linden.step.value = 350;
                             document.linden.angle.value = 25;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'FF';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'X[-TFFF][+TFFF]FTX';
                             document.linden.rleY.value = 'YFX[+TY][-TY]';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '550';
                             document.linden.factor.value = '2.5';
                             document.linden.base_step.value = 350;
                             document.linden.backgd.checked = true;
                             break;
                        case 14: // Tree Cool
                             document.linden.ini_str.value = 'BBX';
                             document.linden.step.value = 200;
                             document.linden.angle.value = 22.5;
                             document.linden.iter.value = 0;
                             document.linden.rleF.value = 'FF';
                             document.linden.rleN.value = 'f';
                             document.linden.rleX.value = 'F-[[TXL]+X]+F[+TFXL]-X';
                             document.linden.rleY.value = 'Y';
                             document.linden.rleZ.value = 'Z';
                             document.linden.hor_i.value = '300';
                             document.linden.ver_i.value = '550';
                             document.linden.factor.value = '2';
                             document.linden.base_step.value = 200;
                             document.linden.backgd.checked = true;
                             break;
                            
                  }
            }
           
            function menuToCustom() {
                  document.linden.cool.value = 0;
                  document.linden.factor.value = 0;
                  document.linden.base_step.value = document.linden.step.value;
            }
