// This "sample" really tests some basic properties if IGLU's smart pointer classes

#include <stdio.h>

// All headers are automatically included from "iglu.h"
#include "iglu.h"

// IGLU classes and constants are all inside the iglu namespace.
using namespace iglu;

// Create a dumb class that prints stuff out in the ctor and dtor, plus a Test() method
class Tester {
public:
	Tester(const char *name)  { m_name = strdup(name); printf("   - %s created!\n", m_name); }
	~Tester()                 { printf("   - %s destroyed!\n", m_name);  free(m_name); }
	void Test( void )         { printf("   - %s tested!\n", m_name); }

	typedef IGLUPtr<Tester,void*,char*> Ptr;
private:
	char *m_name;
};

// Create a couple fancy smart pointers to some Tester classes.
Tester::Ptr myTest1 = 0;
Tester::Ptr myTest3;


int main(int argc, char** argv)
{
	// Do both a NULL initializer and an "=0" initializer give a null pointer?
	printf( "Tester 1: %s NULL!\n", myTest1.IsNull() ? "is" : "is not" );
	printf( "Tester 3: %s NULL!\n\n", myTest3.IsNull() ? "is" : "is not" );

	// Create a test object
	printf("Allocaing initial tester, Tester1...\n");
	myTest1 = new Tester( "Tester1" );
	myTest1->Test();

	// See what happens when we copy a pointer to this test object...
	printf("Starting new code block (new variable scope scope)...\n");
	{
		// Create an IGLUPtr<> class that will get deleted at the end of this scope
		printf("\nCopying Tester1 into a new local variable (in local scope)...\n");
		Tester::Ptr myTest2 = myTest1;
		myTest2->Test();

		// Allocate an object in a local scope that we'll use outside this local scope.
		printf("Creating new tester, Tester3 by allocating it the global scope...\n");
		myTest3 = new Tester( "Tester3" );
		myTest3->Test();

		// Create an object that will go away at the end of this block
		printf("Creating completly local scope Tester4 on the stack...\n");
		Tester::Ptr myTest4 = new Tester( "Tester4" );
		myTest4->Test();

		// When we leave this scope, we will delete myTest2, but myTest1 should still be valid.
		//    myTest4 should be deleted in its entirety, with the Tester object destroyed.
		printf("Leaving new, local scope...\n");
	}

	// Make sure all the test objects that should be valid globally are still valid.
	printf("\nTesting scope of two valid global testers...\n");
	myTest1->Test();
	myTest3->Test();

	// Check that the global-scope testers are freed upon exit from main!
	printf("\nDone with program.  Returning from main()...\n");
	return 0;
}

