import java.util.Vector;
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;



/**
 * This class is sort of a &quot;rendering engine&quot; for the scrolling
 * text.  It takes a <CODE>TextScroll</CODE> for an argument, and provides
 * one method, <CODE>performDirective</CODE>.  It is used to handle the
 * directives independant of the applet.
 *
 * @version 1.2, 15 Dec 1998
 * @author Kevin Swan, 013639s@dragon.acadiau.ca
 */
public class DirectiveManager {

  /**
   * The current version of this class.
   */
  public static final String VERSION = "1.2";

  /**
   * The set of supported directives.
   */
  public static final String[] directives = {
    "setLeftBackgroundColor",
    "setLeftForegroundColor",
    "setRightBackgroundColor",
    "setRightForegroundColor",
    "setBackgroundColor",
    "setForegroundColor",
    "setLeftText",
    "setSpeed",
    "pause",
    "setRightFontFace",
    "setLeftFontFace",
    "setFontFace",
    "setLeftFontSize",
    "setRightFontSize",
    "setFontSize",
    "setLeftCenter",
    "setRightCenter",
    "setCenter",
    "setLeftBold",
    "setRightBold",
    "setBold",
    "setLeftItalic",
    "setRightItalic",
    "setItalic",
    "setInset",
    "setURL"
  };


  /** The TextScroll to invoke methods on when handling directives. */
  private TextScroll applet;



  /**
   * Constructor.
   *
   * @param applet The <CODE>TextScroll</CODE> object to invoke the
   *               methods in when handling directives.
   */
  public DirectiveManager (TextScroll applet) {
    this.applet = applet;
  }



  /**
   * This method attempts to convert a <CODE>String</CODE> numeric
   * representation of a color into an actual <CODE>Color</CODE> object.
   * It expects the given <CODE>String</CODE> to be in the format
   * &quot;<CODE>red,green,blue</CODE>&quot;
   *
   * @param rgb A comma-separated RGB numeric representation of a
   *            color, passed as a <CODE>String</CODE>.
   *
   * @return A <CODE>Color</CODE> object represented by the given RGB value,
   *         if the values are legal.  If an error occurs, return
   *         <CODE>null</CODE>.
   */
  private static Color getColorFromString (String rgb) {

    int red, green, blue;

    red = green = blue = 0;

    if (rgb == null)
      return null;

    try{
      red   = Integer.parseInt ((rgb.substring (0, rgb.indexOf (","))).trim ());
      green = Integer.parseInt ((rgb.substring(rgb.indexOf (",") + 1, rgb.lastIndexOf (","))).trim ());
      blue  = Integer.parseInt ((rgb.substring(rgb.lastIndexOf (",") + 1)).trim ());
    } catch (NumberFormatException nfe) {
      return null;
    }

    try {
      return new Color(red, green, blue);
    } catch (IllegalArgumentException iae) {
      return null;
    }
  } /* getColorFromString () */



  /**
   * This method actually handles the directives.  It will not use
   * reflection, making this class Java 1.0 capable.  Note that it also
   * does not use any deprecated methods, so it manages to stay neutral.
   * This same class can be used with both the Java 1.0 and Java 1.1
   * versions.
   *
   * @param directive The actual directive to perform.  This is the string
   *                  read directly from the text data file, with or without
   *                  the two leading caret symbols.  This is simply a
   *                  method name, followed by 0 or more whitespace,
   *                  followed by a &quot;(&quot; character, then a string
   *                  argument, then a &quot;)&quot; character.
   *
   * @return <CODE>true</CODE> if the directive could successfully be
   *         handled, <CODE>false</CODE> if it could not.
   */
  public boolean performDirective (String directive) {

    if (directive.startsWith ("^^")) {
      /* Strip off the leading "^^" */
      directive = directive.substring (2, directive.length ());
    }

    if (directive.indexOf ('(') < 0) {
      System.err.println ("Error: not a directive: " + directive);
      return false;
    }
    if (directive.indexOf (')') < 0) {
      System.err.println ("Error: not a directive: " + directive);
      return false;
    }

    String methodName = directive.substring (0, directive.indexOf ('('));
    methodName = methodName.trim ();

    if (!supportedDirective (methodName))
      return false;

    String arg = directive.substring (directive.indexOf ('(') + 1,
                                      directive.indexOf(')'));

    if (methodName.equalsIgnoreCase ("setLeftBackgroundColor"))
      this.applet.setLeftBackgroundColor (arg);
    else if (methodName.equalsIgnoreCase ("setLeftForegroundColor"))
      this.applet.setLeftForegroundColor (arg);
    else if (methodName.equalsIgnoreCase ("setRightBackgroundColor"))
      this.applet.setRightBackgroundColor (arg);
    else if (methodName.equalsIgnoreCase ("setRightForegroundColor"))
      this.applet.setRightForegroundColor (arg);
    else if (methodName.equalsIgnoreCase ("setBackgroundColor"))
      this.applet.setBackgroundColor (arg);
    else if (methodName.equalsIgnoreCase ("setForegroundColor"))
      this.applet.setForegroundColor (arg);
    else if (methodName.equalsIgnoreCase ("setSpeed"))
      this.applet.setSpeed (arg);
    else if (methodName.equalsIgnoreCase ("setLeftText"))
      this.applet.setLeftText (arg);
    else if (methodName.equalsIgnoreCase ("pause"))
      if (arg.length () > 0)
        this.applet.pause (arg);
      else
        this.applet.pause ();
    else if (methodName.equalsIgnoreCase ("setLeftFontFace"))
      this.applet.setLeftFontFace (arg);
    else if (methodName.equalsIgnoreCase ("setRightFontFace"))
      this.applet.setRightFontFace (arg);
    else if (methodName.equalsIgnoreCase ("setFontFace"))
      this.applet.setFontFace (arg);
    else if (methodName.equalsIgnoreCase ("setLeftFontSize"))
      this.applet.setLeftFontSize (arg);
    else if (methodName.equalsIgnoreCase ("setRightFontSize"))
      this.applet.setRightFontSize (arg);
    else if (methodName.equalsIgnoreCase ("setFontSize"))
      this.applet.setFontSize (arg);
    else if (methodName.equalsIgnoreCase ("setLeftCenter"))
      this.applet.setLeftCenter (arg);
    else if (methodName.equalsIgnoreCase ("setRightCenter"))
      this.applet.setRightCenter (arg);
    else if (methodName.equalsIgnoreCase ("setCenter"))
      this.applet.setCenter (arg);
    else if (methodName.equalsIgnoreCase ("setLeftBold"))
      this.applet.setLeftBold (arg);
    else if (methodName.equalsIgnoreCase ("setRightBold"))
      this.applet.setRightBold (arg);
    else if (methodName.equalsIgnoreCase ("setBold"))
      this.applet.setBold (arg);
    else if (methodName.equalsIgnoreCase ("setLeftItalic"))
      this.applet.setLeftItalic (arg);
    else if (methodName.equalsIgnoreCase ("setRightItalic"))
      this.applet.setRightItalic (arg);
    else if (methodName.equalsIgnoreCase ("setItalic"))
      this.applet.setItalic (arg);
    else if (methodName.equalsIgnoreCase ("setInset"))
      this.applet.setInset (arg);
    else if (methodName.equalsIgnoreCase ("setURL"))
      this.applet.setURL (arg);
    else
      return false;

    return true;
  }



  /**
   * This method is used to determine whether or not a directive the
   * user is attempting to use is supported.  This is done for security
   * reasons, to protect the user from accidentally calling methods
   * they shouldn't be in Applet and its superclasses.
   *
   * @param methodName the name of the method the user is trying to use.
   *
   * @return true if the user is permitted to call the named method,
   *         false otherwise.
   */
  public static boolean supportedDirective (String methodName) {

    for (int i = 0 ; i < DirectiveManager.directives.length ; i++)
      if (DirectiveManager.directives[i].equalsIgnoreCase (methodName))
        return true;
    return false;
  }

}
