// This is the program which will load the plugins and test them.
// Compile with the following command line:
//  csc PlugInTester.cs /r:MyPlugIn.dll
using System;
using System.Reflection;
using System.IO;

class PlugInTester
{
  public static void Main()
  {
    //Get a list of all the files in the current directory
    // who's names match the plugin mask.
    string[] plugInFileNames = Directory.GetFiles(
      Environment.CurrentDirectory,
      PlugInForm.FileNameMask);
    //Iterate through them all.
    foreach(string fileName in plugInFileNames)
    {
      //Split off the file name and display it.
      Console.WriteLine("Loading DLL '{0}'",
        Path.GetFileName(fileName));
      
      //Load the assembly so that we can manipulate it and 
      // instantiate the concrete class contained within it.
      Assembly assCurrent = Assembly.LoadFrom(fileName);
      
      //Get a list of all types contained within the object
      Type[] typPlugInTypes = assCurrent.GetTypes();
      
      //Iterate through all the types in the assembly
      foreach(Type typCurrent in typPlugInTypes)
      {
        //If the type is one we know how to handle
        if (typCurrent.IsSubclassOf(typeof(PlugInForm)))
        {
          //Create an instance of the type
          object objCurrent = Activator.CreateInstance(
                                typCurrent);
          
          //Get a handle to the method we know it has
          MethodInfo miCurrent = typCurrent.GetMethod(
                                   "WhatIsPI");
          
          //Write out the type of the object
          Console.Write("    {0} says:    ",
            typCurrent.ToString());
          
          // followed by the output from the method we know.
          miCurrent.Invoke(objCurrent,null);
        }
        else
        {
          //Otherwise, spit out a message saying the name of 
          // the type.
          Console.WriteLine("    {0} is not derived from "+
            "PlugInForm",typCurrent.ToString());
          
          //For a more advanced look at what you can do with an 
          // unknown type, uncomment the following code and run with
          // the MPIPhilosopher plugin:
          //  MethodInfo[] miAll = typCurrent.GetMethods();
          //  foreach(MethodInfo miThisOne in miAll)
          //  {
          //    ParameterInfo[] piThisOne = miThisOne.GetParameters();
          //    if (piThisOne.Length == 0)
          //    {
          //      Console.WriteLine("        {0} has no parameters "+
          //        "so I will run it.",miThisOne.ToString());
          //      
          //      //Create an instance of the type
          //      object objThisOne = Activator.CreateInstance(
          //                            typCurrent);
          //      
          //      if(miThisOne.ReturnType == typeof(void))
          //      {
          //        //Run the method
          //        Console.Write("            ");
          //        miThisOne.Invoke(objThisOne,null);
          //      }
          //      else
          //      {
          //        //Run the method and print the output
          //        Console.WriteLine("            {0}",
          //          miThisOne.Invoke(objThisOne,null));
          //      }
          //    } 
          //    else
          //    {
          //      //If the method had parameters then you would go 
          //      // on and find out what type they
          //      // were and pass in appropriate values.
          //      Console.WriteLine("        {0} has parameters so "+
          //        "I will NOT run it.",miThisOne.ToString());
          //    }
          //  }
        }
      }
    }
  }
}