package tcra.exercises;

import java.io.*;
import javax.swing.*;
import tcra.logger.LogWriter;
import tcra.math.*;

/**
 * Supplies general exercise utility functions.
 * Cannot be instantiated.
 */
public class ExerciseUtilities
{
   private ExerciseUtilities() {}

   /**
    * Opens a FileChooser to allow the user to select the exercise
    * to be opened. Using reflection, this method loads the exercise
    * and returns it to the caller.
    *
    * @return TCRAExercise chosen by the user.
    */
   @SuppressWarnings("unchecked")
   public static TCRAExercise loadFile() throws Throwable
   {
      JFileChooser fc_open = new JFileChooser();
      int choice = fc_open.showOpenDialog(null);
      if(choice == JFileChooser.APPROVE_OPTION)
      {
         File file = fc_open.getSelectedFile();
         if(file.exists() && file.getName().endsWith(".class"))
         {
           // Reflection Code
           try
           {
              // need to know package name
              // solved by forcing exercises to be in the exercises
              // folder, declaring themselves to be in the
              // tcra.exercises package
              String name = file.getName();
              name        = name.substring(0, name.length()-6);
              Class exercise = Class.forName(
                 "tcra.exercises." + name);
              
              LogWriter.getInstance().logFileOpened(file.getName());
              
              return (TCRAExercise)exercise.newInstance();
            } // end try
            catch(ClassNotFoundException cnf)
            {
              throw cnf;
            } // end catch(ClassNotFoundException)
            // chosen file is inside 'exercises' but is not
            // an implementation of TCRAExercise
            catch(ClassCastException cce)
            {
              throw cce;
            } // end catch(ClassNotFoundException)
            catch(Throwable e) { throw e; }
         } // end if
         return null;
      } // end if
      return null;
   } // end loadFile()
} // end class
