/*
 *
 * http://mathworld.wolfram.com/SierpinskiCurve.html
 *
 *
 *
 */


// http://arxiv.org/abs/0806.4787
// http://mathworld.wolfram.com/SierpinskiCurve.html

const g_params = {
  depth: 2, width: 30, type: "sierpinski1", start_x: 15, start_y: 0, start_direction: 0
//  depth: 2, width: 30, type: "sierpinski2", start_x: 15, start_y: 0, start_direction: 0
//  depth: 2, width: 30, type: "sierpinski3", start_x: 15, start_y: 0, start_direction: 0
//  depth: 4, width: 30, type: "moore", start_x: 0, start_y: 15, start_direction: 0
//  depth: 5, width: 30, type: "hilbert", start_x: 0, start_y: 0, start_direction: 0
};

var g_group;
var g_months = [31,29,31,30,31,30,31,31,30,31,30,31];


//===================================================================================
// L-System
var g_systems =
  {"hilbert":
   {
     rules: {"L":"+RF-LFL-FR+", "R":"-LF+RFR+FL-"},
     axiom: "L",
     closed: false
   },
   "moore":
   {
     rules: {"L":"-RF+LFL+FR-","R":"+LF-RFR-FL+"},
     axiom: "LFL+F+LFL",
     closed: false
   },
   "sierpinski1":
   {
     rules: {"A":"A+A-B+A", "B":"B+A-B+A"},
     axiom: "A+A+A+A",
     closed: true,
     terminals: {"A":"F+FF-FF", "B":"+F-FFF-FF"}
   },
   "sierpinski2":
   {
     rules: {"A":"A+A-B+A", "B":"B+A-B+A"},
     axiom: "A+A+A+A",
     closed: true,
     terminals: {"A":"F+FF-FF", "B":"F+F-F-F+F-F"}
   },
   "sierpinski3":
   {
     rules: {"A":"A+A-B+A", "B":"B+A-B+A"},
     axiom: "A+A+A+A",
     closed: true,
     terminals: {"A":"F+F-F+F-F", "B":"F+F-F-F+F-F"}
   }
  };

//===================================================================================

function rewrite(s,system)
{
  var s2=[];
  var matching_rule;
  for (var i=0;i<s.length;i++)
  {
    matching_rule=system.rules[s[i]];
    s2.push(matching_rule ? matching_rule : s[i]);
  }
//  alert("rewrote "+s+" to "+s2.join(''));
  return s2.join('');
}

//===================================================================================

function run(system,iterations)
{
  var s=system.axiom;
  for (var i=0;i<iterations;i++)
  {
    s=rewrite(s,system);
  }
  s=s.replace(/[LR]/g,"");

  for (var terminal in system.terminals)
  {
    s=s.replace(new RegExp(terminal,"g"),system.terminals[terminal]);
  }
  return s;
}

//==================================================================================

function draw()
{
  g_group = document.getElementById('calendar');
  var s=run(g_systems[g_params.type],g_params.depth);
  var colour;
  var x=g_params.start_x, y=g_params.start_y, direction=g_params.start_direction, count=0;
  var day=0, month=0, year=2008;
  var pathData=[];

  if (!g_systems[g_params.type].closed)
  {
    drawCell(g_params.start_x*g_params.width, g_params.start_y*g_params.width,30,"1/1");
    pathData.push(g_params.start_x*g_params.width+","+g_params.start_y*g_params.width);
    day=1;
  }

  for (var i=0; i<s.length; i++)
  {
    switch(s[i])
    {
      case "+": direction = (direction+270) % 360; break;
      case "-": direction = (direction+90) % 360; break;
      case "F":
        switch (direction)
        {
          case 0: x++; break;
          case 90: y--; break;
          case 180: x--; break;
          case 270: y++; break;
        }
        pathData.push(x*g_params.width+','+y*g_params.width);
        count++;

        if (++day > g_months[month]) {
          if (++month > 11) {
            g_months[1] = (++year % 4 == 0) ? 29 : 28;
            month=0;
          }
          day=1;
        }
        switch(month%4)
        {
          case 0: colour=30; break;
          case 1: colour=60; break;
          case 2: colour=90; break;
          case 3: colour=120; break;
        }
        drawCell(x*g_params.width,y*g_params.width,colour,day+"/"+(1+month));
      break;
    }
  }
  var path=document.getElementById('polyline');
  path.setAttribute("points",pathData.join(' '));
  path.setAttribute("stroke-width",g_params.width-5);
}

function drawCell(x,y,colour,text)
{
  var rect=document.createElement("rect");
  var w=g_params.width-1;
  rect.setAttribute("x",x-w/2);
  rect.setAttribute("y",y-w/2);
  rect.setAttribute("width",w);
  rect.setAttribute("height",w);
  rect.setAttribute("stroke","none");
  rect.setAttribute("fill","rgb("+colour+","+colour+","+colour+")");
  g_group.appendChild(rect);

  var textEl=document.createElement("text");
  textEl.setAttribute("x",x-w/2+5);
  textEl.setAttribute("y",y+w/2-5);
  textEl.setAttribute("fill","white");
  textEl.setAttribute("font-size",5);
  textEl.appendChild(document.createTextNode(text));
  g_group.appendChild(textEl);
}

