import { Console } from "console";
import { TextBuilder } from './TextBuilder.js';

console.log("Hello");
let someNumber: number;
let bigValue: bigint;
let someString: string = "fred";
let someBool: boolean = true;
let someValue: any;

someNumber = 5;
bigValue = 100n;
someValue = 4;
someValue = "tom";

const PI: number = 3.142;
console.log("Constant is " + PI);

type WindowStates = "open" | "closed" | "minimized";
let state: WindowStates = "open"; // Must be an allowed value
console.log("State is " + state);

function getLength(obj: string | string[]) {
    return obj.length;  // An array or a string
}

console.log("Length of string is " + getLength("Hello world"));
console.log("Length of array is " + getLength(["A", "B", "C"]));

type Fullname = string;

let customerName: Fullname = "Fred";
console.log("Fullname is " + customerName);

// Create an array
let numbers: string[] = [];
numbers[0] = "one";
numbers[1] = "two";
numbers[2] = "three";
for (let num of numbers) {
    console.log("Number in array is " + num);
}

// Create an array literal
let fruit: string[] = ["Apple", "Orange"];
console.log("The fruit in the array are " + fruit.join(", "));

// Create an anonymous object
let someObject = { x: 3, y: "Boo" }
// Can be used as a constant
const Fred = { name: "Fred", age: 23 }
// You can be specific about the required object contents
let myObject: { a: string, b: string };
myObject = { a: "hello", b: "hi" };
console.log(`myObject a=${myObject.a}, b=${myObject.b}`)
let myObject2: { a: string, b: string, c: string };
myObject2 = { a: "hello2", b: "hi2", c: "hmmm" };
myObject = myObject2;
console.log(`myObject a=${myObject.a}, b=${myObject.b}`)




// By default we can assign null to anything
let a: number | null = null;
console.log("The number is null? " + a);

// Typically, you encounter this with a function
const loggedInUsername: string = "Fred";

const users = [
    { name: "Oby", age: 12 },
    { name: "Heera", age: 32 },
];

// The find function can return undefined if object is not found
const loggedInUser = users.find((u) => u.name === loggedInUsername);
//console.log(loggedInUser.age);  // This gives a "possibly undefined" error

// Interface type
interface CoOrdinate {
    x: number;
    y: number;
}

let myCoord: CoOrdinate;
myCoord = {x:3, y:4};
console.log(`myCoord x=${myCoord.x}, y=${myCoord.y}`)

// Create two function
function DisplayNumber(num: number): void
{
        console.log("Value is "+num);
}

function AddNumbers(number1: number, number2: number): number
{
      return number1 + number2;
}

// Call it!!
let result: number = AddNumbers(2, 3);
DisplayNumber(result);

// What is the problem here
function PadLeftSpaces(text:string, spaces: number): string
{
    return " ".repeat(spaces) + text;
}

function PadLeftString(text: string, padding: string): string
{
    return padding + text;
}

// Add padding to front of text as either a number of white spaces
// or the padding provided.
// FIX THIS: also remove the useSpaces argument
// function PadLeft(text: string, padding: string|number, useSpaces: boolean): string
// {
//     if(useSpaces)
//         return PadLeftSpaces(text, padding);
//     else
//         return PadLeftString(text, padding);
// }

function PadLeft(text: string, padding: string|number): string
{
    if(typeof padding === "number")
        return PadLeftSpaces(text, padding);
    else
        return PadLeftString(text, padding);
}

console.log("Pad with spaces "+PadLeft("Hello", 10));
console.log("Pad with supplied string "+PadLeft("Hello","_____"));

// Generics
function Help<A>(arg: A): A
{
    return arg;
}

// Call it
let x: number = 5;
console.log("Number is "+<number>Help(x));

interface IMeasurable
{
    length: number
}

function DisplayLength <T extends IMeasurable>(measure: T): void
{
    console.log("Measurement length is "+measure.length);
}

let myNumbers = { numbers:[1,2,4], length: 3};
DisplayLength(myNumbers);

let tb: TextBuilder = new TextBuilder("How");

tb.AppendText(" Are You");
tb.AppendText(" Today");
console.log(tb.Result);
