#include "stdafx.h"

#include "FindType.h"

#include "App.h"


void App::Main(String* args[])
{
    FindType* ft = new FindType();
    SetOptions(args, ft);
    ft->Search();
}

void App::PrintUsage()
{
    Console::WriteLine();
    Console::WriteLine(S"FindType [SystemOptions] [MatchOptions] [ShowOptions] [MiscOptions] Name");
    Console::WriteLine();
    Console::WriteLine(S"  where SystemOptions");
    Console::WriteLine(S"    d:[Directory] - Additional directory to search");
    Console::WriteLine(S"  where MatchOptions");
    Console::WriteLine(S"    x - Name = Exact Type Name (including namespace)");
    Console::WriteLine(S"    n - Name = Namespace ");
    Console::WriteLine(S"    w - Match the name anywhere in the namespace");
    Console::WriteLine(S"  where ShowOptions");
    Console::WriteLine(S"    i - Show Interfaces");
    Console::WriteLine(S"    f - Show Fields");
    Console::WriteLine(S"    p - Show Properties");
    Console::WriteLine(S"    e - Show Events");
    Console::WriteLine(S"    m - Show Methods");
    Console::WriteLine(S"    a - Show All Info");
    Console::WriteLine(S"    l - Show Module Information");
    Console::WriteLine(S"  where MiscOptions");
    Console::WriteLine(S"    v = Verbose");
    Console::WriteLine(S"    r = For every type find display base type information");
    Console::WriteLine(S"    ? = Prints Usage information");
    Console::WriteLine();
    Console::WriteLine(S"Examples");
    Console::WriteLine();
    Console::WriteLine(S" FindType String");
    Console::WriteLine(S"   Finds all types that have \'String\' as part of their type name\r\n");
    Console::WriteLine(S" FindType -r String");
    Console::WriteLine(S"   Finds all types that have \'String\' as part of their name");
    Console::WriteLine(S"   and prints out all base classes\r\n");
    Console::WriteLine(S" FindType -n System.Reflection");
    Console::WriteLine(S"   Displays all types in the \'System.Reflection\' namespace\r\n");
    Console::WriteLine(S" FindType -xipm System.String");
    Console::WriteLine(S"   Displays the interfaces, properties and methods on the \'System.String\' type\r\n");
    Console::WriteLine(S" FindType -d:C:\\ -d:\"C:\\Program Files\\Microsoft.NET\\FrameworkSDK\\Lib\" String");
    Console::WriteLine(S"   Searches DLLs C:\\ and C:\\Program Files\\Microsoft.NET\\FrameworkSDK\\Lib");
    Console::WriteLine(S"   as well as in the current directory \r\n");
    Console::WriteLine();
}

void App::SetOptions(String* args[], FindType* ft)
{
    if (args->Length == 0)
    {
        PrintUsage();
    }
    else
    {
        ft->VerbosePrint = false;
        int _Vb_t_i4_0 = args->Length - 1;
        for (int i = 0; i <= _Vb_t_i4_0; i++)
        {
            String* curArg = args[i];
            String* backslash = S"\\";
            if ((curArg->ToCharArray()[0] == '-' | curArg->ToCharArray()[0] == '/') == 0)
            {
                ft->ClassAdd(curArg);
            }
            else if (Char::ToUpper(curArg->ToCharArray()[1]) != 'D')
            {
                int _Vb_t_i4_1 = curArg->ToCharArray()->Length - 1;
                for (int j = 1; j <= _Vb_t_i4_1; j++)
                {
                    switch (Char::ToUpper(curArg->ToCharArray()[j]))
                    {
                    case 'X':
                        ft->ExactMatchOnly = true;
                        break;

                    case 'R':
                        ft->RecurseTypes = true;
                        break;

                    case 'V':
                        ft->VerbosePrint = true;
                        break;

                    case 'N':
                        ft->MatchOnlyNamespace = true;
                        break;

                    case 'W':
                        ft->WideSearch = true;
                        break;

                    case 'I':
                        ft->ShowInterfaces = true;
                        break;

                    case 'M':
                        ft->ShowMethods = true;
                        break;

                    case 'F':
                        ft->ShowFields = true;
                        break;

                    case 'P':
                        ft->ShowProperties = true;
                        break;

                    case 'E':
                        ft->ShowEvents = true;
                        break;

                    case 'L':
                        ft->ShowModuleInfo = true;
                        break;

                    case 'A':
                        ft->ShowAll();
                        break;

                    case '?':
                        PrintUsage();
                        break;

                    case 'D':
                        Console::WriteLine(S"Directory not specified");
                        break;

                    default:
                        Console::WriteLine(S"Invald Option[{0}]", __box(curArg->ToCharArray()[j]));
                        break;
                    }
                }
            }
            else if ((curArg->ToCharArray()->Length > 2 & curArg->ToCharArray()[2] == ':') != 0)
            {
                String* dir = curArg->Substring(3)->TrimEnd(backslash->ToCharArray())->ToUpper();
                if (StringType::StrCmp(dir, S"", false) != 0)
                {
                    ft->DirAdd(dir);
                }
                else
                {
                    Console::WriteLine(S"Directory not specified");
                }
            }
            else
            {
                Console::WriteLine(S"Directory not specified");
            }
        }
    }
}


