using uCalcSoftware;

var uc = new uCalc();
// Rosetta Stone
// Pseudocode translation to C++, C#, or VB

// This shows only in C#

//This shows in C# and VB, not C++

//This shows in C++ and C#, not Vb
//The c tag is the same as the NotVB tag
// Tags (c, cpp, cs, vb, NotCpp, NotCs, NotVb, etc.,) are not case-sensitive

Console.Write("w() prints text without ");
Console.Write("a new line at the end.");
Console.WriteLine(); // Moves to a new line
Console.WriteLine("wl() prints a line, ending with a newline.");
Console.WriteLine("Line 2");
Console.WriteLine("Line 3");
Console.WriteLine($"{123} multiple args for wl()");
Console.Write("multiple "); Console.Write("args "); Console.Write("for w() too");
Console.WriteLine("");

var t = uc.NewTransformer();
// Property setter syntax: @ followed by property name and value in parenthesis
t.Description = "Some description goes here";

// Property getter sytanx: @ followed by property name, and empty parenthesis
Console.WriteLine(t.Description);

// Each property has an alternative getter and setter function syntax
// with the Get or Set prefix like this:
t.SetDescription("A new description");
Console.WriteLine(t.GetDescription());

// Using the alternative function syntax for a property can be useful when chaining calls
// I use the c tag for the sake of VB that wants everything on the same line.
t.SetText("Some Text").SetDescription("Some description")
.FromTo("Text", "String").SetCaseSensitive(true).SetMinimum(1).SetMaximum(5)
.GetParentTransformer().Transform();
Console.WriteLine(t.Text);

// For compatibility across C++, C#, and VB, use the Verbatim tag for multi-line
// strings.  Do not use escapes or specialized double-quote syntax in a string.
var MyString = """
Here is some "quoted" text on one line
And some random text on another line
""";
Console.WriteLine(MyString);

// Use this syntax to define a variable with a uCalc-related type
// Either with or without an initial value
uCalc.String MyStringA;
uCalc.String MyStringB = "This is some text.";
MyStringA = MyStringB.Text + " Some more text";
Console.WriteLine(MyStringA.Text);

// For simple types not belonging to uCalc, use this C#-like notation instead:

var OtherString = "Some other string ";
var MyNumber = 12345;
Console.WriteLine($"{OtherString}{MyNumber}");

// Another way to define a new variable (with a uCalc type) is with the more
// flexible New.  Use this especially if you need to use arguments:

var MyVar = new uCalc.Item("Variable: x = 123");
var MyFunc = new uCalc.Item(uc, "Function: f(x) = x^2");
Console.WriteLine(uCalc.DefaultInstance.Eval("x"));
Console.WriteLine(uc.Eval("f(5)"));

// To define a uCalc object that gets released when the object goes out of scope, do:
using (var tr = new uCalc.Transformer()) {
   tr.FromTo("This", "That");
   Console.WriteLine(tr.Transform("This car").Text);
   // To accomodate other languages besides C#, you must explicitely end the using block
}

// Use the C++ style to_string to convert a value to a string
Console.WriteLine("Value: " + (100 + 25).ToString());

// Always use the C++ double colon, ::, for scope resolution
// (it gets translated to a dot, ., in C# and VB
var MyTokens = t.Tokens;
Console.WriteLine(uc.DataTypeOf(BuiltInType.Float_Double).Name);

// Other supported constructs
for (double x = 1; x <= 10; x++) {
   Console.WriteLine(x);
}

for (double x = 1; x <= 10; x = x + 2) {
   Console.WriteLine(x);
}

foreach(var dType in uc.DataTypes) {
   Console.WriteLine(dType.Name);
}

var count = 0;

while (count <= 5) {
   Console.WriteLine(count);
   count += 1;
}

do {
   Console.WriteLine(count);
   count = count + 1;
} while (count <= 10);

if (count < 100) {
   Console.WriteLine("count is less than 100");
}

if (count < 5) {
   // Some lines of code
   Console.WriteLine("count is less than 5");
} else if (count <= 50) {
   // . . .
   Console.WriteLine("count is less than or equal to 50");
} else {
   // More lines of code
   Console.WriteLine("count is greater than 50");
}

// Declare and initialize a string array
string[] items = {"Apple", "Banana", "Cherry"};

// Get the size of the array
count = items.Length;
Console.WriteLine($"Total items: {count}");

// Access and modify elements
Console.WriteLine($"First item: {items[0]}");
items[1] = "Blueberry";

// Iterate through the array
var i = 0;
do {
   Console.WriteLine(items[i]);
   i = i + 1;
} while (i < items.Length);

// For proper translation into the 3 supported languages, wrap Boolean values with
// bool.  When pseudocode contains the bool function, a helper function named tf is
// inserted towards to the top of the code

Console.WriteLine($"{uc.EvalStr("'Cos is a function? '")}{uc.ItemOf("Cos").IsProperty(ItemIs.Function)}");
Console.WriteLine($"{uc.EvalStr("'Cos is a variable? '")}{uc.ItemOf("Cos").IsProperty(ItemIs.Variable)}");