//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// To jest główny plik projektu dla projektu aplikacji VC++, 
// wygenerowany przy użyciu Application Wizarda.

#include "stdafx.h"

#using <mscorlib.dll>
#include <tchar.h>
#include "unmanaged.h"

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Text;

int _tmain(void)
{
	int retInt = AddInteger(1, 2);
	Console::WriteLine(S"Wynik AddInteger: {0}", __box(retInt));

	String *str = S"To jest test";
	IntPtr sPtr = Marshal::StringToHGlobalAnsi(str);
	int retLength = StringLength((char*)sPtr.ToPointer());
	Console::WriteLine(S"Długość ciągu: {0}", __box(retLength));
	Marshal::FreeHGlobal(sPtr);

	sPtr = Marshal::StringToHGlobalUni(str);
	retLength = UnicodeStringLength((wchar_t*)sPtr.ToPointer());
	Console::WriteLine(S"Długość ciągu Unicode: {0}", __box(retLength));
	Marshal::FreeHGlobal(sPtr);

	unsigned char byteRet = ByteFunc(10);
	short shortRet = ShortFunc(10);
	unsigned short ushortRet = WordFunc(10);
	unsigned int uintRet = UintFunc(10);
	int intRet = IntFunc(10);
	long longRet = LongFunc(10);
	unsigned long ulongRet = UnsignedLongFunc(10);
	char charRet = CharFunc(10);
	float floatRet = FloatFunc(10);
	double doubleRet = DoubleFunc(10);

	ByteOutOutFunc(20,&byteRet);
	ShortOutFunc(20, &shortRet);
	WordOutFunc(20, &ushortRet);
	IntOutFunc(20, &intRet);
	UintOutFunc(20, &uintRet);
	LongOutFunc(20, &longRet);
	UnsignedLongOutFunc(20, &ulongRet);
	CharOutFunc(20, &charRet);
	FloatOutFunc(20, &floatRet);
	DoubleOutFunc(20, &doubleRet);

	String *a = S"To jest ";
	String *b = S"test";
	IntPtr aPtr = Marshal::StringToHGlobalAnsi(a);
	IntPtr bPtr = Marshal::StringToHGlobalAnsi(b);
	String *result = ConcatString((char*)aPtr.ToPointer(),
		                          (char*)bPtr.ToPointer());
	Console::WriteLine(S"Wynik połączenia ciągów: {0}", result);
	Marshal::FreeHGlobal(aPtr);
	Marshal::FreeHGlobal(bPtr);

	aPtr = Marshal::StringToHGlobalUni(a);
	bPtr = Marshal::StringToHGlobalUni(b);
	result = ConcatUnicodeString((wchar_t*)aPtr.ToPointer(),
		                         (wchar_t*)bPtr.ToPointer());
	Console::WriteLine(S"Wynik połączenia ciągów Unicode: {0}", result);
	Marshal::FreeHGlobal(aPtr);
	Marshal::FreeHGlobal(bPtr);

	aPtr = Marshal::StringToHGlobalAnsi(a);
	bPtr = Marshal::StringToHGlobalAnsi(b);
	StringBuilder *sb = new StringBuilder(128);
	IntPtr rPtr = Marshal::StringToHGlobalAnsi(sb->ToString());
	ConcatOutString((char*)aPtr.ToPointer(),
		            (char*)bPtr.ToPointer(),
					(char*)rPtr.ToPointer());
	Console::WriteLine(S"Po usunięciu ciągu: {0}", Marshal::PtrToStringAnsi(rPtr));
	Marshal::FreeHGlobal(aPtr);
	Marshal::FreeHGlobal(bPtr);

	int *ia = new int [4];
	ia[0] = 1;
	ia[1] = 2;
	ia[2] = 3;
	ia[3] = 4;
	Console::WriteLine("Tablica liczb całkowitych: {0}", __box(4));
	retInt = IntArrayFunction(ia, 4);
	Console::WriteLine("Największa liczba całkowita: {0}", __box(retInt));

	complex ac;
	ac.re = 1.0;
	ac.im = 2.0;
	complex bc;
	bc.re = 3.0;
	bc.im = 4.0;
	complex cc = ComplexAdd(ac, bc);

    return 0;
}