﻿(() => {
	let output: string = "";

	// FUNCTIONS
	// Types can now be provided for arguments and returns (all are optional)
	function DisplayLine(text: string): void
	{
		output = output + text + "\n";
	}

	function DisplayNumber(num: number): void
	{
		DisplayLine("Number is " + num);
		if (num > 100)
		{
			DisplayLine("Number is very large");
		}
	}

	function AddNumbers(number1: number, number2: number): number
	{
		return number1 + number2;
	}

	let result: number = AddNumbers(2, 3);
	DisplayNumber(result);

	// Function Types
	// Variables can also contain functions
	let someFunction: (x: number, y: number) => number;   // Must use arrow to specify return type

	someFunction = AddNumbers;
	result = someFunction(2, 3);
	DisplayNumber(result);

	// Can do optional and default parameters
	//function DisplayNameOpt(firstName: string, lastName?: string) : string              // ? means optional
	//{
	//    return lastName ? firstName + " " + lastName : firstName;
	//}
	//DisplayLine(DisplayNameOpt("Fred"));    // Displays just "Fred"

	//function DisplayNameDef(firstName: string, lastName: string = "Smith"): string     // Default value
	//{
	//    return firstName + " " + lastName;
	//}
	//DisplayLine(DisplayNameDef("Fred"));    // Displays just "Fred Smith"

	// You can use the type "any" or just not provide the type.
	function GiveValueBack(someValue: any): any     // Or just "function GiveValueBack(someValue)"
	{
		return someValue;
	}

	let strResult: string = GiveValueBack("Hello");
	DisplayLine(strResult);
	let numResult: number = GiveValueBack(33);
	DisplayLine(numResult + "");


	// You can specify a function that takes any number of arguments
	// these are passed into the function as an array or through
	// an "arguments" variable associated with every function
	function BuildName(firstName: string, ...restOfName: string[]): string
	{
		let argCount: number = arguments.length;
		return "ArgCnt[" + argCount + "] " + "FirstArg["+ arguments[0] + "] " + firstName + " " + restOfName.join(" ");
	}

	DisplayLine(BuildName("Fred", "John", "Bloggs"));

	console.log(output); 
})();