/**
   * Constructor.
   *
   * @param lib the library to be inherited.
   * @param l the list of layers.
   * @param x the x coordinate of the control point of the macro.
   * @param y the y coordinate of the control point of the macro.
   * @param key_t the key to be used to uniquely identify the macro (it will be converted to
   *     lowercase).
   * @param na the name to be shown.
   * @param xa the x coordinate of the name of the macro.
   * @param ya the y coordinate of the name of the macro.
   * @param va the value to be shown.
   * @param xv the x coordinate of the value of the macro.
   * @param yv the y coordinate of the value of the macro.
   * @param macroF the font to be used for the name and the value of the macro.
   * @param macroS the size of the font.
   * @param oo the macro orientation.
   * @param mm the macro mirroring.
   * @throws IOException if an unrecognized macro is found.
   */
  public PrimitiveMacro(
      Map<String, MacroDesc> lib,
      Vector<LayerDesc> l,
      int x,
      int y,
      String key_t,
      String na,
      int xa,
      int ya,
      String va,
      int xv,
      int yv,
      String macroF,
      int macroS,
      int oo,
      boolean mm)
      throws IOException {
    super();
    initPrimitive(-1, macroF, macroS);
    library = lib;
    layers = l;
    String key = key_t.toLowerCase(new Locale("en"));
    macro = new DrawingModel();
    macroCoord = new MapCoordinates();
    changed = true;
    setMacroFontSize(macroS);
    o = oo;
    m = mm;

    // Store the points of the macro and the text describing it.
    virtualPoint[0].x = x;
    virtualPoint[0].y = y;
    virtualPoint[1].x = xa;
    virtualPoint[1].y = ya;
    virtualPoint[2].x = xv;
    virtualPoint[2].y = yv;

    name = na;
    value = va;

    MacroDesc macro = (MacroDesc) library.get(key);

    // Check if the macro description is contained in the database
    // containing all the libraries.
    if (macro == null) {
      IOException G = new IOException("Unrecognized macro " + key);
      throw G;
    }
    macroDesc = macro.description;
    macroName = key;
    macroFont = macroF;

    macroStore(layers);
  }
  /**
   * Parse a token array and store the graphic data for a given primitive Obviously, that routine
   * should be called *after* having recognized that the called primitive is correct. That routine
   * also sets the current layer.
   *
   * @param tokens the tokens to be processed. tokens[0] should be the command of the actual
   *     primitive.
   * @param N the number of tokens present in the array
   * @throws IOException if the arguments are incorrect or the primitive is invalid.
   */
  public void parseTokens(String[] tokens, int N) throws IOException {
    // assert it is the correct primitive
    changed = true;
    if (tokens[0].equals("MC")) { // Line
      if (N < 6) {
        IOException E = new IOException("bad arguments on MC");
        throw E;
      }
      // Load the points in the virtual points associated to the
      // current primitive.

      virtualPoint[0].x = Integer.parseInt(tokens[1]);
      virtualPoint[0].y = Integer.parseInt(tokens[2]);
      virtualPoint[1].x = virtualPoint[0].x + 10;
      virtualPoint[1].y = virtualPoint[0].y + 10;
      virtualPoint[2].x = virtualPoint[0].x + 10;
      virtualPoint[2].y = virtualPoint[0].y + 5;
      o = Integer.parseInt(tokens[3]); // orientation
      m = Integer.parseInt(tokens[4]) == 1; // mirror
      macroName = tokens[5];

      // This is useful when a filename contains spaces. However, it does
      // not work when there are two or more consecutive spaces.

      for (int i = 6; i < N; ++i) macroName += " " + tokens[i];

      // The macro key recognition is made case insensitive by converting
      // internally all keys to lower case.

      macroName = macroName.toLowerCase(new Locale("en"));

      // Let's see if the macro is recognized and store it.
      MacroDesc macro = (MacroDesc) library.get(macroName);

      if (macro == null) {

        IOException G = new IOException("Unrecognized macro '" + macroName + "'");
        throw G;
      }
      macroDesc = macro.description;
      macroStore(layers);

    } else {
      IOException E = new IOException("MC: Invalid primitive:" + tokens[0] + " programming error?");
      throw E;
    }
  }