/**
   * Creates a new effect, with parameters passed as InteractionContent.
   *
   * @param content parameters for the effect, including its class.
   * @return the new effect, created and initialized, ready to be triggered!
   */
  public Effect createEffect(InteractionContent content) {
    try {
      Class effectClass = registeredEffects.get(content.function);
      Constructor effectConstructor =
          effectClass.getConstructor(new Class[] {InteractionContent.class});
      Effect ef = (Effect) effectConstructor.newInstance(new Object[] {content});

      if (content.object1.equalsIgnoreCase("TIME") || content.object2[0].equalsIgnoreCase("TIME"))
        return new TimeEffect(content, ef);

      return ef;

    } catch (NoSuchMethodException e) {
      e.printStackTrace();
      System.out.println(
          "Error creating effect "
              + content.function
              + " between "
              + content.object1
              + " and "
              + content.object2);
    } catch (Exception e) {
      e.printStackTrace();
      System.out.println(
          "Error creating effect "
              + content.function
              + " between "
              + content.object1
              + " and "
              + content.object2);
    }

    return null;
  }
  /**
   * Creates a game, receiving a GameContent object
   *
   * @param content potential parameters for the class.
   * @return The game just created.
   */
  public Game createGame(GameContent content) {
    try {
      Class gameClass = registeredGames.get(content.referenceClass);
      Constructor gameConstructor = gameClass.getConstructor(new Class[] {GameContent.class});
      return (Game) gameConstructor.newInstance(new Object[] {content});

    } catch (NoSuchMethodException e) {
      e.printStackTrace();
      System.out.println("Error creating game of class " + content.referenceClass);
    } catch (Exception e) {
      e.printStackTrace();
      System.out.println("Error creating game of class " + content.referenceClass);
    }

    return null;
  }
  /**
   * Creates a new termination, with parameters passed as TerminationContent.
   *
   * @param content parameters for the termination condition, including its class.
   * @return the new termination, created and initialized, ready to be checked!
   */
  public Termination createTermination(TerminationContent content) {
    try {
      Class terminationClass = registeredTerminations.get(content.identifier);
      Constructor terminationConstructor =
          terminationClass.getConstructor(new Class[] {TerminationContent.class});
      Termination ter = (Termination) terminationConstructor.newInstance(new Object[] {content});
      return ter;

    } catch (NoSuchMethodException e) {
      e.printStackTrace();
      System.out.println("Error creating termination condition " + content.identifier);
    } catch (Exception e) {
      e.printStackTrace();
      System.out.println("Error creating termination condition " + content.identifier);
    }

    return null;
  }
  /**
   * Creates a new sprite with a given dimension in a certain position. Parameters are passed as
   * SpriteContent.
   *
   * @param content parameters for the sprite, including its class.
   * @param position position of the object.
   * @param dim dimensions of the sprite on the world.
   * @return the new sprite, created and initialized, ready for play!
   */
  public VGDLSprite createSprite(SpriteContent content, Vector2d position, Dimension dim) {
    try {
      Class spriteClass = registeredSprites.get(content.referenceClass);
      Constructor spriteConstructor =
          spriteClass.getConstructor(
              new Class[] {Vector2d.class, Dimension.class, SpriteContent.class});
      return (VGDLSprite) spriteConstructor.newInstance(new Object[] {position, dim, content});

    } catch (NoSuchMethodException e) {
      e.printStackTrace();
      System.out.println(
          "Error creating sprite " + content.identifier + " of class " + content.referenceClass);
    } catch (Exception e) {
      e.printStackTrace();
      System.out.println(
          "Error creating sprite " + content.identifier + " of class " + content.referenceClass);
    }

    return null;
  }