using uCalcSoftware;

var uc = new uCalc();

static void MoveTurtle(uCalc.Callback cb) {
   var dist = cb.Arg(1);
   var uc_inst = cb.uCalc;
   var x = uc_inst.ItemOf("x").Value();
   var y = uc_inst.ItemOf("y").Value();
   var angle = uc_inst.ItemOf("angle").Value();
   var pen_down = uc_inst.ItemOf("pen_down").ValueBool();
   int new_x = Convert.ToInt32(x + dist * uc_inst.Eval("CosD(" + (angle).ToString() + ")"));
   int new_y = Convert.ToInt32(y + dist * uc_inst.Eval("SinD(" + (angle).ToString() + ")"));
   if (pen_down) {
      Console.WriteLine($"Drawing line to ({new_x},{new_y})");
   } else {
      Console.WriteLine($"Moving to ({new_x},{new_y})");
   }
   uc_inst.ItemOf("x").Value(new_x);
   uc_inst.ItemOf("y").Value(new_y);
}


// --- Setup ---
uc.DefineVariable("x = 0.0");
uc.DefineVariable("y = 0.0");
uc.DefineVariable("angle = 90.0");
uc.DefineVariable("pen_down = false");
uc.DefineConstant("PI = 3.1415926535");
uc.DefineFunction("CosD(a) = Cos(a * PI / 180)");
uc.DefineFunction("SinD(a) = Sin(a * PI / 180)");
uc.DefineFunction("Move(dist)", MoveTurtle);

var t = uc.ExpressionTransformer;
t.FromTo("FD {@Number:dist}", "Move({dist})");
t.FromTo("RT {@Number:deg}", "angle = angle - {deg}");
t.FromTo("PD", "pen_down = true");

// --- Script ---
var script = """

PD
FD 100
RT 90
FD 50

""";

uc.EvalStr(script);

Console.WriteLine($"Final Position: ({uc.Eval("x")}, {uc.Eval("y")})");