/************************************************************************************************************
Methods:
1. Create()		create a directory
2. Delete()		delete a directory
3. List()		return listing of a directory
4. Rename()		rename a directory

Properties:
1. PutDot()			set whether to show "." or ".." directories in case of list method. valid values are
					FALSE or 0 (default) do not return "." and ".."directories
					TRUE or 1 return "." and ".."directories
2. GetErrorReason() reports any errors that occur during the request
3. PutFilter()		file extension filter to be applied to returned names, for example: *.asp. 
					only one mask filter can be applied at a time. if not specified then default value is *.*
4. GetIsError()		returns 1 if any error occur during the request otherwise 0
5. PutSort()		list of query columns to sort directory listing. valid values are
					Name_ASC (default)
					Name_DESC
					Size_ASC
					Size_DESC
					Type_ASC
					Type_DESC
					Attributes_ASC
					Attributes_DESC
					DateLastModified_ASC
					DateLastModified_DESC
					DateCreated_ASC
					DateCreated_DESC
************************************************************************************************************/

/***********************************/
/*include all required header files*/
/***********************************/
#include <stdio.h>
#include <conio.h>

/************************************************************************/
/*import AdvDirectory COM library here to get its methods and properties*/
/************************************************************************/
#import "C:\AdvDirectory.dll" no_namespace

/*************************/
/*prototype for functions*/
/*************************/
void Create();//Create function
void Delete();//Delete function
void List();//List function
void Rename();//Rename function

/**************/
/*main program*/
/**************/
void main(void)
{
	char Ch;
	do
	{
		printf("\r\nCreate	[C]");
		printf("\r\nDelete	[D]");
		printf("\r\nList	[L]");
		printf("\r\nRename	[R]");
		printf("\r\nQuit	[Q]");
		printf("\r\n\r\nEnter Choice = ");
		scanf("%c", &Ch);
		getchar();
		Ch = toupper(Ch);
		switch (Ch)
		{
			case 'C':Create();break;//call Create function
			case 'D':Delete();break;//call Delete function
			case 'L':List();break;//call List function
			case 'R':Rename();break;//call Rename function
			case 'Q':printf("\r\nGood Bye\r\n");break;
			default: printf("\r\nError: Please enter valid choice\r\n");
		}
	}
	while (Ch != 'Q');
}

/****************************************************************************************/
/*Create function: The function is used to create directory with the name given as input*/
/****************************************************************************************/
void Create()
{
	char m_Path[256];//define charecter buffer of 256 to read directory name
	printf("\r\nEnter Directory Name = ");
	gets(m_Path);//read directory name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IDirectoryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IDirectoryPtr("AdvDirectory.Directory");
		HRESULT hr = obj->Create(m_Path);//call Create method of COM library
		if (!SUCCEEDED(hr))//if COM call is not successfull then display error message and return
		{
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
			return;
		}
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
			printf("\r\nSuccessfully Created\r\n");//display successfull message
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}

/****************************************************************************************/
/*Delete function: The function is used to delete directory with the name given as input*/
/****************************************************************************************/
void Delete()
{
	char m_Path[256];//define charecter buffer of 256 to read directory name
	printf("\r\nEnter Directory Name = ");
	gets(m_Path);//read directory name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IDirectoryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IDirectoryPtr("AdvDirectory.Directory");
		HRESULT hr = obj->Delete(m_Path);//call Delete method of COM library
		if (!SUCCEEDED(hr))//if COM call is not successfull then display error message and return
		{
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
			return;
		}
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
			printf("\r\nSuccessfully Deleted\r\n");//display successfull message
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}

/*******************************************************************************************/
/*List function: The function is used to get directory listing with the name given as input*/
/*******************************************************************************************/
void List()
{
	char m_Path[256], m_Filter[256], m_Sort[256];//define charecter buffer of 256 to read directory name, filter and sorting criteria
	long l_Dot;//dot directory flag
	printf("\r\nEnter Directory Name = ");
	gets(m_Path);//read directory name
	printf("\r\nEnter Dot Directory Flag [0/1] = ");
	scanf("%d", &l_Dot);//read dot directory flag
	getchar();
	printf("\r\nEnter Filter = ");
	gets(m_Filter);//read filter
	printf("\r\nEnter Sorting Criteria = ");
	gets(m_Sort);//read sorting criteria
	try//for COM library call, try...catch is used to handle exceptions
	{
		IDirectoryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IDirectoryPtr("AdvDirectory.Directory");
		obj->PutFilter(m_Filter);//set filter property
		obj->PutSort(m_Sort);//set sort criteria property
		obj->PutDot(l_Dot);//set dot directory flag  property
		_variant_t pVal = obj->List(m_Path);//call Create method of COM library
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
		{
			printf("\r\nSuccessfully Listed\r\n");//display successfull message
			IDispatch* p = pVal.pdispVal;//IDispatch object is assigned VARIANT object
			IListPtr listobj;//take List interface object
			p->QueryInterface(IID_IDispatch,(void**)&listobj);//call query interface
			long count = listobj->GetCount();//get number of nodes
			for (int j = 1; j <= count; j++)//loop over each node
			{
				_variant_t retVal = listobj->GetItem(j);//get node item
				IDispatch* pp = retVal.pdispVal;//IDispatch object is assigned VARIANT object
				IListEntriesPtr listentriesobj;//take ListEntries interface object
				pp->QueryInterface(IID_IDispatch,(void**)&listentriesobj);//call query interface
				printf("\r\n%s | %d | %s | %s | %s | %s\r\n", (char*)listentriesobj->GetName(),
					listentriesobj->GetSize(), (char*)listentriesobj->GetType(),(char*)listentriesobj->GetAttributes(),
					(char*)listentriesobj->GetDateLastModified(), (char*)listentriesobj->GetDateCreated());//format data
			}
			printf("\r\n");
		}
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}

/*************************************************************************************************************/
/*Rename function: The function is used to rename existing directory with the old and new name given as input*/
/*************************************************************************************************************/
void Rename()
{
	char m_Old[256], m_New[256];//define charecter buffer of 256 to read old directory name and new directory name
	printf("\r\nEnter Old Directory Name = ");
	gets(m_Old);//read old directory name
	printf("\r\nEnter New Directory Name = ");
	gets(m_New);//read new directory name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IDirectoryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IDirectoryPtr("AdvDirectory.Directory");
		HRESULT hr = obj->Rename(m_Old, m_New);//call Rename method of COM library
		if (!SUCCEEDED(hr))//if COM call is not successfull then display error message and return
		{
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
			return;
		}
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
			printf("\r\nSuccessfully Renamed\r\n");//display successfull message
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}
