#usage "en: <qt><nobr>Command draw<p><u>Options</u>:<p>"
       "<b>+</b> distance/radius <br>"
       "<b>A</b>ngle start [A<b>n</b>gle step] [<b>E</b>nd angle] <br>"
       "[<b>L</b>ayer] <br>"
       "[<b>W</b>ire & width] <br>"
       "[<b>X</b>coordinate] [<b>Y</b>coordinate] **<br>"
       "[P<b>o</b>lygon] <br>"
       "[<b>P</b>ad || <b>S</b>md || <b>V</b>ia] <br>"
       "[W<b>i</b>dth Leng<b>t</b>h] SMD_dx SMD_dy <br>"
       "[<b>-</b>Name] signal/pad/smd <br>"
       "[<b>D</b>iameter] for Pad/Via, if used <br>"
       "[D<b>r</b>ill] for Pad/Via/Hole, if used <br>"
       "[<b>°</b>] define angle (in degrees) for step <br>"
       "[<b>/</b>] define number of steps within start and end angle <br>"
       "[<b>G</b>roup] rotate and paste <br>"
       "[rotate <b>m</b>atch] <br>"
       "[<b>MOVE</b>] elements on place by order <br>start with name (<i>only in Board</i>) <br>"
       "[<b>C</b>ircle] emulate/draw a cricle with wire or polygon <br>"
       "[full ellipse <b>0</b>] <br>"
       "[Ellipse <b>f</b>actor] height = radius * f <br>"
       "[1/<b>4</b> ellipse] 90 degree, 1st quadrant <br>"
       "<br>"
       "** If <b>MARK</b> is set in PAC/BRD/SCH editor, coordinates are relativ. <br>"
       "Parameters can be used in any order; not case sensitive."
       "<p>"
       "<author>Author: alf@cadsoft.de </author></nobr></qt>",

       "de: <qt><nobr>Command draw<p><u>Optionen</u>:<p>"
       "<b>+</b> Distance/Radius <br>"
       "St<b>a</b>rtwinkel [Wi<b>n</b>kelschritt oder A<b>n</b>zahl (# .)] [<b>E</b>ndwinkel] <br>"
       "[<b>L</b>ayer] <br>"
       "[<b>W</b>re width] setzt die Breite (width) und den Befehl WIRE. <br>"
       "<i>FÃ¼r Polygon muÃŸ <b>W</b> vor <b>O</b> angegeben werden.</i><br>"
       "[<b>X</b>-Koordinate] [<b>Y</b>-Koordinate] **<br>"
       "[P<b>o</b>lygon] <br>"
       "[<b>P</b>ad || <b>S</b>md || <b>V</b>ia] <br>"
       "[W<b>i</b>dth Leng<b>t</b>h] SMD_dx SMD_dy <br>"
       "[<b>-</b>Name] Signal/Pad/Smd <br>"
       "[<b>D</b>iameter] fÃ¼r Pad/Via, wenn benutzt <br>"
       "[D<b>r</b>ill] fÃ¼r Pad/Via/Hole, wenn benutzt <br>"
       "[<b>°</b>] Winkelschritt in Grad <br>"
       "[<b>/</b>] berechnet den Winkel (End - Start / Anzahl <br>"
       "[<b>G</b>roup] Rotate und Paste der vorher definierten Gruppe<br>"
       "[Rotate <b>m</b>atch] dreht die Bauteile/Pad/Smd im selben Winkel <br>in dem sie angeordnet werden<br>"
       "[<b>MOVE</b>] plaziert Elemente aufsteigend beginnend mit dem <br>angegebenen Namen (<i>nur im Board nutzbar</i> ) <br>"
       "[<b>C</b>ircle] zeichnet einen Kreis oder Ellipse als Wire oder Polygon <br>je nach Option (W/O) <br>"
       "[full ellipse <b>0</b>] zeichnet eine volle Ellipse <br>"
       "[Ellipse <b>f</b>aktor] der Wert mit dem die LÃ¤nge multipliziert wird <br>(Raduis * f) ergibt die LÃ¤nge in y <br>"
       "[1/<b>4</b> ellipse] zeichnet nur den ersten Qudranten <br>einer Ellipse oder Kreises <br>"
       "<br>"
       "** Ist <b>MARK</b> im benutzten PAC/BRD/SCH Editor gesezt, <br>werden die Koordinaten relativ zur Marke benutzt.<br>"
       "Die Parameter kÃ¶nnen in beliebiger Reihenfolge angegeben <br>und groÃŸ oder klein geschrieben werden."
       "<p>"
       "<author>Author: alf@cadsoft.de </author></nobr></qt>"

string Help = "<nobr>" +
       "RUN cmd-draw w0.4 -gnd x1.3 y2.56 +17.45 a115 n75 e180 # lTop <br>" +
       "RUN cmd-draw w0.4 -gnd x1.3 y2.56 +17.45 a115 n75 e180 . lTop <br>" +
       "RUN cmd-draw w0.4 -gnd x1.3 y2.56 +17.45 a115 ltop <br>" +
       "RUN cmd-draw a0 e150.0 x30 y4 w0.2 n9 # o +2.27 -gnd l1 <br>" +
       "RUN cmd-draw a0 e50.0 x30 y4 w0.2 n9 o 0 f1.7 +2.27 -gnd l1 <br>" +
       "RUN cmd-draw w0.4 +1.5 -gnd a2 y2.56 l16 <br>" +
       "RUN cmd-draw +2.0 e270.0 n9.0 w0.2 x-2.54 y5.08 <br>" +
       "RUN cmd-draw x1 y3.33 l1 w.2 +4.77 # n5 <br>" +
       "RUN cmd-draw s -1 +9 n7 # <br>" +
       "RUN cmd-draw r1.2 +19.9 n7 # <br>" +
       "RUN cmd-draw r1.2 +9.5 n7 . <br>" +
       "RUN cmd-draw +2.20 n9.0 w0.2 x-2.54 y-5.08 w.01 l1 O 0 f1.75 <br>" +
       "RUN cmd-draw +2.20 n9.0 w0.2 x-2.54 y-5.08 w.01 l1 O 4 f1.75 <br>" +
       "RUN cmd-draw s -1 +9 a22.5 m <br>" +
       "RUN cmd-draw s i1.55 t2.7 -A +2.20 n20.0 x-2.54 y-5.08 l1 f1.75 m <br>" +
       "RUN cmd-draw r.8 d1.4 v -A +4.20 n20.0 x-2.54 y-5.08 l1 f1.75 <br>" +
       "RUN cmd-draw g n33.333 # A0.0 e359.9 <br>" +
       "RUN cmd-draw G n33.333 . A0.0 e359.9 <br>" +
       "RUN cmd-draw +10 MOVE -R1 M a33 L16 N7 E322 .<br>"+
       "<p>" +
       "</nobr>";

// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED

#require 5.0000;

string help_move = "<qt>MOVE, PAD, SMD can be used clockwise, too. " +
                   "In this case <b>Angle step</b> has to be negative. Is <b>Angle start</b> less than " +
                   "<b>Angle end</b> for negative <b>Angle step</b>, 360° will be added to <b>Angle start</b>." +
                   "Thus you are allowed to arrange elements clockwise.</qt>";

string mark_info = "<nobr>If <font color=\"blue\"><b>MARK</b></font> is set coordinates are <b>relativ</b>.</nobr>";


if (language() == "de") {
  help_move = "MOVE, PAD, SMD kÃ¶nnen auch rechtsdrehend benutzt werden. " +
              "Dazu muÃŸ <b>Angle step</b> negativ sein.<br>" +
              "Ist <b>Angle start</b> bei <i>negativen</i> <b>Angle step</b> " +
              "kleiner als <b>Angle end</b> wird auf <b>Angle start</b> 360° aufaddiert.<br>" +
              "Damit ist es mÃ¶glich die Elemente rechtsdrehen anzuordnen.";

  mark_info = "<nobr>Ist <font color=\"blue\"><b>MARK</b></font> gesetzt, dann sind die Koordinaten relativ zu der Marke.</nobr>";
}

string label_move = " ";

int test = 1;

string Version = " Version 1.07 ";  // 2006-08-10 alf@cadsoft.de
                                    // 2008-04-10 changed GROUP ... (>x y); alf@cadsoft.de
                                    // 2008-05-06 SMD generierung mit Name berichtigt
                                    // 2010-06-09 Generierung des PAD-Namen berichtigt.
                                    // 2010-10-15 Startwinkel auf 720 erhÃ¶ht, um Bauteile
                                    //            im Uhrzeigersinn mit grÃ¶ÃŸerem Endwinkel
                                    //            als 0.0 zu platzieren.
                                    //            Beispiel Start 620.0° End 260.1°
                                    //            Hier muÃŸ der Startwinkel 260+360 = 620° sein.
                                    //            Neue Option: Winkeloffset


enum { DrawWIRE,             // ** do not change this list  **
       DrawPOLYGON,
       DrawMOVE,             // to place Elements in Board
       DrawGROUP,            // Group CUT paste, select all in group ** see also >> dlgGroup("Option") <<
       DrawHOLE,
       DrawPAD,
       DrawSMD
     };

int    drawtype = DrawWIRE;
string cmd_draw_info = "<img src=cmd-draw-move-match-none.bmp>";
string draw_info     = " ";
string Name_used;
string require = " <font color=\"red\">required</font> ";
string not_used = " <font color=\"darkgreen\">not used</font> ";
string can_used = " <font color=\"blue\">can be used</font> ";
if (library) Name_used  = not_used;
else         Name_used  = can_used;


string para    = "";
string signame = "";
string width   = "";
string layer   = "";
string Angle_step_used = not_used;
string Angle_end_used  = not_used;

real   x1, y1, x2;
real   startangle     = 0.0;         // start the rotated draw on degree
real   anglestep      = 0.0;         // angle step in degree to next element or steps at 90° for Ellipse
real   EangleOffset   = 0.0;         // the rotation off the element self + offset
real   endangle       = 360.0;       // end the rotated draw on degree
enum   { None, Degreestep, Calcstep };
int    anglesteptyp   = None;        // flag to calculate the anglestep from count (anglestep)
int    rotateMatch    = 0;           // rotate element with same angle with rotate

enum { NONE, CIRCLE, FULL_ELLIPSE, ELLIPSE_4 };
int    placeform      = NONE;
real   ellipsfactor   = 1.0;         // ratio x to y radius
real   m_ellipsfactor = 1.0;         // copy for menue

//int    polygon      = 0;           // draw ellipse as polygon
//int    smd          = 0;           // place a smd on endpoint
real   SMD_dx         = 0;           // SMD length
real   SMD_dy         = 0;           // SMD width
string PadVia         = "";          // draw Pad or Via as used in editor
string PAD_diameter   = "";          // pad diameter
string Shapes[];
int    ShapeSelect    = PAD_SHAPE_OFFSET+1;

string drill_hole     = "";          // drill diameter

int grid = 1;
string GridUnit[] = { "MIC", "MM", "MIL", "INCH" };
int    gridunit;
real   minx, maxx, miny, maxy;

string length_distance_radius = "&+ radius ";


int PressOk = 0;

string s;
string h;
string help_err = " ";

string name1st, nameext; // use as variable Label in Menu

// ### functions ###
void Set_MinMax_Unit(int Grid) {
  switch(Grid) {
    case GRID_UNIT_MIC  : {  // Micron
                            minx = u2mic(-8000000);
                            maxx = u2mic( 8000000);
                            miny = u2mic(-8000000);
                            maxy = u2mic( 8000000);
                            break;
                          }
    case GRID_UNIT_MM   : {  // Millimeter
                            minx = u2mm(-8000000);
                            maxx = u2mm( 8000000);
                            miny = u2mm(-8000000);
                            maxy = u2mm( 8000000);
                            break;
                          }
    case GRID_UNIT_MIL  : {  // Mil
                            minx = u2mil(-8000000);
                            maxx = u2mil( 8000000);
                            miny = u2mil(-8000000);
                            maxy = u2mil( 8000000);
                            break;
                          }
    case GRID_UNIT_INCH : {  // Inch
                            minx = u2inch(-8000000);
                            maxx = u2inch( 8000000);
                            miny = u2inch(-8000000);
                            maxy = u2inch( 8000000);
                            break;
                          }
  }
  return;
}


real u2u(int val) {
  switch (gridunit) {
    case GRID_UNIT_MIC  : return u2mic(val);
    case GRID_UNIT_MM   : return u2mm(val);
    case GRID_UNIT_MIL  : return u2mil(val);
    case GRID_UNIT_INCH : return u2inch(val);
  }
}


void info(void) {
  dlgDialog("cmd-draw HELP") {
    dlgHBoxLayout {
      dlgLabel(usage);
      dlgVBoxLayout {
        if (language() == "de")  dlgLabel("<u>Beispiele</u>:");
        else dlgLabel("<u>Examples</u>:");
        dlgLabel(Help);
        dlgStretch(1);
        dlgHBoxLayout {
          dlgStretch(1);
          dlgPushButton("+Ok") dlgAccept();
          dlgStretch(1);
        }
      }
    }
  };
  return;
}


// *** analysis User Error ***
int error(void) {
  int err = 0;
  if (strtod(width) >= x2)     { help_err = "Width > Radius";  err = -1; }
  if (!x2)                     { help_err = "Radius = 0";      err = -1; }
  if (drawtype == DrawSMD) {
    if (layer == "1" || layer == "16") ;
    else { err = -1; help_err = "Layer for SMD ?"; }
  }
  if (drawtype == DrawMOVE) {
    if (!signame) { help_err = "1.st Element name ?"; err = -1; }
  }
  if (drawtype == DrawGROUP)   {
    if (!anglestep || !endangle) { help_err = "Angle step or Angle end = 0"; err = -1; }
  }
  if (anglesteptyp && anglestep == 0) {
    err = -1; help_err = "Missing parameter: Angle step";
  }
  return err;
}



// *** set info for Menu *** Pictures and Texts ***
void set_draw_info(void) {
  label_move = " ";
  if (drawtype == DrawWIRE) {
    switch (anglesteptyp) {
      case None       :
                        Angle_step_used = not_used;
                        Angle_end_used  = not_used;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-wire-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-wire-none.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-wire-ellipse.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-wire-ellipse.bmp>";
                                              break;
                        }
                        break;

      case Degreestep :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-wire-degstep-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-wire-circle-degstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-wire-step-ellipse.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-wire-step-ellipse4.bmp>";
                                              break;
                        }
                        break;
      case Calcstep   :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-wire-calcstep-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-wire-circle-calcstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-wire-calc-ellipse.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-wire-clac-ellipse4.bmp>";
                                              break;
                        }
                        break;
    }
  }

  else if(drawtype == DrawPOLYGON) {
    Angle_step_used = require;
    Angle_end_used  = require;
    switch (anglesteptyp) {
      case None       : switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-polygon-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-polygon-none.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-polygon-ellipse-none.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-polygon-ellipse4-none.bmp>";
                                              break;
                        }
                        break;
      case Degreestep : switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-polygon-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-polygon-circle-degstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-polygon-ellipse-degstep.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-polygon-ellipse4-degstep.bmp>";
                                              break;
                        }
                        break;
      case Calcstep   : switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-polygon-none-calcstep.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-polygon-circle-calcstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-polygon-ellipse-calcstep.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-polygon-ellipse4-calcstep.bmp>";
                                              break;
                        }
                        break;
    }
  }

  else if(drawtype == DrawMOVE) {
    if (library || schematic) {
      dlgMessageBox("! MOVE\nYou can use this function ponly in a Board.", "OK");
    }
    else {
      label_move = help_move;
      switch (anglesteptyp) {
        case None       :
                          Angle_step_used = not_used;
                          Angle_end_used  = not_used;
                          switch (placeform) {
                            case NONE         : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-no_match-none.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-match-none.bmp>";
                                                break;
                            case CIRCLE       : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-no_match-none.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-match-none.bmp>";
                                                break;
                            case FULL_ELLIPSE : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-no_match-ellipse-none.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-match-ellipse-none.bmp>";
                                                break;
                            case ELLIPSE_4    : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-no_match-ellipse-none.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-match-ellipse-none.bmp>";
                                                break;
                          }
                          break;

        case Degreestep :
                          Angle_step_used = require;
                          Angle_end_used  = require;
                          switch (placeform) {
                            case NONE         : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-no_match-none.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-match-none.bmp>";
                                                break;
                            case CIRCLE       : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-circle-no_match-degstep.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-circle-match-degstep.bmp>";
                                                break;
                            case FULL_ELLIPSE : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-ellipse-no_match-degstep.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-ellipse-match-degstep.bmp>";
                                                break;
                            case ELLIPSE_4    : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-ellipse4-no_match-degstep.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-ellipse4-match-degstep.bmp>";
                                                break;
                          }
                          break;

        case Calcstep   :
                          Angle_step_used = require;
                          Angle_end_used  = require;
                          switch (placeform) {
                            case NONE         : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-no_match-none.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-match-none.bmp>";
                                                break;
                            case CIRCLE       : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-circle-no_match-calcstep.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-circle-match-calcstep.bmp>";
                                                break;
                            case FULL_ELLIPSE : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-ellipse-no_match-calcstep.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-ellipse-match-calcstep.bmp>";
                                                break;
                            case ELLIPSE_4    : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-move-ellipse4-no_match-calcstep.bmp>";
                                                else cmd_draw_info = "<img src=cmd-draw-move-ellipse4-match-calcstep.bmp>";
                                                break;
                          }
                          break;
      }
    }
  }

  else if(drawtype == DrawGROUP) {
    Angle_step_used = require;
    Angle_end_used  = require;
    cmd_draw_info = "<img src=cmd-draw-group.bmp>";
  }

  else if(drawtype == DrawPAD) {
    label_move = help_move;
    switch (anglesteptyp) {
      case None       :
                        Angle_step_used = not_used;
                        Angle_end_used  = not_used;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-pad-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-pad-none.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-pad-none.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-pad-none.bmp>";
                                              break;
                        }
                        break;

      case Degreestep :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-pad-none-degstep.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-pad-none-degstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-pad-ellipse-degstep.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-pad-ellipse4-degstep.bmp>";
                                              break;
                        }
                        break;

      case Calcstep   :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-pad-none-calcstep.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-pad-none-calcstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-pad-ellipse-calcstep.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-pad-ellipse4-calcstep.bmp>";
                                              break;
                        }
                        break;
    }
  }

  else if(drawtype == DrawSMD) {
    label_move = help_move;
    switch (anglesteptyp) {
      case None       :
                        Angle_step_used = not_used;
                        Angle_end_used  = not_used;
                        switch (placeform) {
                          case NONE         : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-no_match-none.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-match-none.bmp>";
                                              break;
                          case CIRCLE       : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-no_match-none.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-match-none.bmp>";
                                              break;
                          case FULL_ELLIPSE : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-no_match-none.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-match-none.bmp>";
                                              break;
                          case ELLIPSE_4    : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-no_match-none.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-match-none.bmp>";
                                              break;
                        }
                        break;

      case Degreestep :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-no_match-degsetp.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-match-degstep.bmp>";
                                              break;
                          case CIRCLE       : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-cricle-no_match-degstep.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-circle-match-degstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-ellipse-no_match-degstep.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-ellipse-match-degstap.bmp>";
                                              break;
                          case ELLIPSE_4    : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-ellipse4-no_match-degstep.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-ellipse4-match-degstep.bmp>";
                                              break;
                        }
                        break;

      case Calcstep   :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-no_match-none.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-match-none.bmp>";
                                              break;
                          case CIRCLE       : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-circle-no_match-calcstep.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-circle-match-calcstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-ellipse-no_match-calcstep.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-ellipse-match-calcstep.bmp>";
                                              break;
                          case ELLIPSE_4    : if (!rotateMatch) cmd_draw_info = "<img src=cmd-draw-smd-ellipse4-no_match-calcstep.bmp>";
                                              else cmd_draw_info = "<img src=cmd-draw-smd-ellipse4-match-calcstep.bmp>";
                                              break;
                        }
    }
  }

  else if(drawtype == DrawHOLE) {
    switch (anglesteptyp) {
      case None       :
                        Angle_step_used = not_used;
                        Angle_end_used  = not_used;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-hole-none.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-hole-none.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-hole-none.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-hole-none.bmp>";
                                              break;
                        }
                        break;

      case Degreestep :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-hole-none-degstep.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-hole-none-degstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-hole-ellipse-degstep.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-hole-ellipse4-degstep.bmp>";
                                              break;
                        }
                        break;

      case Calcstep   :
                        Angle_step_used = require;
                        Angle_end_used  = require;
                        switch (placeform) {
                          case NONE         : cmd_draw_info = "<img src=cmd-draw-hole-none-calcstep.bmp>";
                                              break;
                          case CIRCLE       : cmd_draw_info = "<img src=cmd-draw-hole-none-calcstep.bmp>";
                                              break;
                          case FULL_ELLIPSE : cmd_draw_info = "<img src=cmd-draw-hole-ellipse-calcstep.bmp>";
                                              break;
                          case ELLIPSE_4    : cmd_draw_info = "<img src=cmd-draw-hole-ellipse4-calcstep.bmp>";
                                              break;
                        }
                        break;
    }
  }

  if (drawtype == DrawGROUP) {
    Angle_step_used = require;
    Angle_end_used  = require;
    cmd_draw_info = "<img src=cmd-draw-group.bmp>";
    rotateMatch = 1;
  }
  else if (drawtype != DrawMOVE && PadVia == "VIA") {
    rotateMatch = 0;
  }
  return;
}



// ****** main menu ******
int menue(void) {
  int RESULT;
  if (placeform == NONE) length_distance_radius = "&+ radius ";
  else length_distance_radius = "&+ radius ";

  name1st = " ";
  nameext = " ";
  if (board && drawtype == DrawMOVE) {
    name1st = " &- 1st. Element ";
    nameext = " name";
  }
  if (board && drawtype == DrawWIRE) {
    name1st = " &- Signal ";
    nameext = " name";
  }
  if (board && drawtype == DrawPOLYGON) {
    name1st = " &- Signal ";
    nameext = " name";
  }
  if (library && drawtype == DrawPOLYGON) {
    name1st = " ";
    nameext = " ";
  }
  if (package && drawtype == DrawPAD) {
    name1st = " &- 1st. Pad ";
    nameext = " name";
  }
  if (board && drawtype == DrawPAD) {
    name1st = " &- Signal ";
    nameext = " name";
  }
  if (package && drawtype == DrawSMD) {
    name1st = " &- 1st. Smd ";
    nameext = " name";
  }
  if (package && drawtype == DrawMOVE || package && drawtype == DrawWIRE) {
    name1st = " ";
    nameext = " ";
  }
  if ( schematic) {
    name1st = " &- Net name ";
    nameext = " ";
  }

  RESULT = dlgDialog("Command Draw") {
      dlgVBoxLayout {
        dlgHBoxLayout {
          dlgSpacing (8);
          dlgLabel (draw_info, 1);
        }
        dlgHBoxLayout {
          dlgGroup("Option") {
            set_draw_info();
            dlgGridLayout {

              dlgCell(  1, 1) dlgHBoxLayout dlgSpacing(10);
              dlgCell(  1, 4) dlgHBoxLayout dlgSpacing(10);

              if (drawtype == DrawWIRE || drawtype == DrawPOLYGON) {
                dlgCell(  5, 2) dlgLabel( "&Width ");
                dlgCell(  5, 3) dlgStringEdit( width);
              }
              if (drawtype == DrawWIRE || drawtype == DrawPOLYGON || drawtype == DrawSMD || drawtype == DrawMOVE) {
                dlgCell(  5, 5) dlgLabel(" &Layer");
                dlgCell(  5, 6) dlgStringEdit(layer);
              }

              dlgCell(  5, 8) dlgLabel(name1st, 1);
              if ( name1st != " ") {
                dlgCell(  5, 9) dlgStringEdit(signame);     // Signal-, Element-, Net-Name
              }
              dlgCell(  5, 10) dlgLabel(nameext ,1);

              dlgCell(  7, 2) dlgLabel( "&X center coord. ");
              dlgCell(  7, 3) dlgRealEdit( x1, minx, maxx);
              dlgCell(  7, 5) dlgLabel( "&Y center coord. ");
              dlgCell(  7, 6) dlgRealEdit( y1, miny, maxy);
              dlgCell(  7, 8) dlgHBoxLayout { dlgLabel( length_distance_radius, 1); dlgStretch(1); }
              dlgCell(  7, 9) dlgHBoxLayout { dlgRealEdit( x2, 0, maxx); dlgStretch(1); }

              dlgCell(  8, 2) dlgLabel("Angle st&art ° ");
              dlgCell(  8, 3) dlgRealEdit( startangle, 0.0, 720.0); // 2010-10-15
              dlgCell(  8, 5) dlgLabel("A&ngle step ");
              dlgCell(  8, 6) dlgRealEdit( anglestep, -360.0, 360.0);
              dlgCell(  8, 7) dlgSpacing(12);
              dlgCell(  8, 8) dlgLabel(" Angle &end ° ");
              dlgCell(  8, 9) dlgRealEdit( endangle, 0.0, 720.0);
              dlgCell(  8,10) dlgSpacing(50);
              dlgCell(  9, 6) dlgLabel(Angle_step_used, 1);
              dlgCell(  9, 9) dlgLabel(Angle_end_used, 1);

              dlgCell(  9, 0) dlgVBoxLayout dlgSpacing(12);

              dlgCell(  5, 0) dlgRadioButton("Wire &1 ", drawtype) {
                draw_info = " ";
                if (library) Name_used  = not_used;
                else         Name_used  = " ";
                length_distance_radius = "&+ radius ";
                dlgReject();
                dlgAccept();
              }
              dlgCell(  6, 0) dlgRadioButton("P&olygon ", drawtype) {
                draw_info = " ";
                if (library) Name_used  = not_used;
                else         Name_used  = " ";
                length_distance_radius = "&+ radius ";
                dlgAccept();
              }
              dlgCell(  6, 9) dlgLabel(Name_used, 1);

              dlgCell(  7, 0) dlgRadioButton("&Move ", drawtype) {  // 2006.07.06 alf@cadsoft.de
                draw_info = "MOVE Elements by Name";
                Name_used  = require;
                length_distance_radius = "&+ radius ";
                dlgAccept();
              }

              dlgCell(  8, 0) dlgRadioButton("&Group *", drawtype) {
                draw_info = "GROUP CUT all elements displayed and GROUP MOVE (Rotate) and PASTE.";
                Name_used  = " ";
                length_distance_radius = "&+ distance ";
                rotateMatch = 1;
                dlgAccept();
              }

              if (board || package) {
                dlgCell( 12, 0) dlgRadioButton("&Hole ", drawtype) {
                  draw_info = " ";
                  Name_used  = " ";
                  length_distance_radius = "%+ distance ";
                  dlgAccept();
                }
                if (drawtype == DrawPAD || drawtype == DrawHOLE) {
                  if (drawtype == DrawHOLE) {
                    dlgCell( 12, 2) dlgLabel( " Hole d&rill ");
                  }
                  if (drawtype == DrawPAD) {
                    if (package) {
                      dlgCell( 12, 2) dlgLabel( " Pad d&rill ");
                    }
                    if (board) {
                      dlgCell( 12, 2) dlgLabel( " Via d&rill ");
                    }
                  }
                  dlgCell( 12, 3) dlgStringEdit( drill_hole);
                }
              }

              if (package) {
                PadVia = "PAD";
                Shapes[PAD_SHAPE_SQUARE]  = "Square";
                Shapes[PAD_SHAPE_ROUND]   = "Round";
                Shapes[PAD_SHAPE_OCTAGON] = "Octagon";
                Shapes[PAD_SHAPE_LONG]    = "Long";
                Shapes[PAD_SHAPE_OFFSET]  = "Offset";
                Shapes[PAD_SHAPE_OFFSET+1] = " ";  // last must be empty

                dlgCell( 13, 0) dlgRadioButton("&Pad ", drawtype) {
                  draw_info = " ";
                  Name_used  = " can be used";
                  length_distance_radius = "&+ distance ";
                  dlgAccept();
                }
                if (drawtype == DrawPAD) {
                  dlgCell( 13, 2) dlgLabel( " PAD &Diameter ");
                  dlgCell( 13, 3) dlgStringEdit( PAD_diameter);
                  dlgCell( 13, 5) dlgLabel( " Schape ");
                  dlgCell( 13, 6) dlgComboBox(Shapes, ShapeSelect);
                }
                dlgCell( 14, 0) dlgRadioButton("&Smd ", drawtype) {
                  draw_info = " ";
                  Name_used  = " ";
                  length_distance_radius = "&+ distance ";
                  dlgAccept();
                }
                if (drawtype == DrawSMD) {
                  dlgCell( 14, 2) dlgLabel( " &Wide dx ");
                  dlgCell( 14, 3) dlgRealEdit( SMD_dx);
                  dlgCell( 14, 5) dlgLabel( " Heigh&t dy ");
                  dlgCell( 14, 6) dlgRealEdit( SMD_dy);
                }
              }

              if (board) {
                PadVia = "VIA";
                Shapes[PAD_SHAPE_SQUARE]  = "Square";
                Shapes[PAD_SHAPE_ROUND]   = "Round";
                Shapes[PAD_SHAPE_OCTAGON] = "Octagon";
                Shapes[PAD_SHAPE_OCTAGON+1] = " ";
                ShapeSelect = PAD_SHAPE_OCTAGON+1;

                dlgCell( 13, 0) dlgRadioButton("&Via ", drawtype) {  // ** Via in Board / Pad in Package  **
                  draw_info = " ";
                  Name_used  = " can be used";
                  length_distance_radius = "&+ distance ";
                  rotateMatch = 0;
                  dlgAccept();
                }
                if (drawtype == DrawPAD) {
                  dlgCell( 13, 2) dlgLabel( " VIA &Diameter ");
                  dlgCell( 13, 3) dlgStringEdit( PAD_diameter);
                  dlgCell( 13, 5) dlgLabel( " Schape ");
                  dlgCell( 13, 6) dlgComboBox(Shapes, ShapeSelect);
                }
              }
            }
          }
          dlgStretch(1);
        }
        dlgSpacing(8);
        dlgHBoxLayout {
          dlgLabel(cmd_draw_info, 1);   // picture for info
          dlgGroup("Angle step type") {
            dlgRadioButton("Not used ", anglesteptyp)  set_draw_info();
            dlgRadioButton("&° degree step ", anglesteptyp)  set_draw_info();
            dlgRadioButton("&/ calc. steps ", anglesteptyp)  set_draw_info();
            dlgLabel(" ");
            if (drawtype == DrawMOVE || drawtype == DrawSMD ) {
              dlgCheckBox("Rotate &item to match ", rotateMatch) {
                set_draw_info();
              }
              dlgHBoxLayout {
                dlgLabel( " I&tem ");
                dlgRealEdit(EangleOffset, 0.0, 359.9);
                dlgLabel( " rotate offset");
              }
            }
          }
          dlgGroup("Form") {
            dlgHBoxLayout {
              //set_draw_info();
              dlgRadioButton("Not &Used", placeform) {
                set_draw_info();
                if (ellipsfactor != 1.0) {
                  m_ellipsfactor = ellipsfactor;
                  ellipsfactor = 1;
                }
              }
              dlgRadioButton("&Circle", placeform) {
                set_draw_info();
                if (ellipsfactor != 1.0) {
                  m_ellipsfactor = ellipsfactor;
                  ellipsfactor = 1;
                }
              }
              dlgRadioButton("Full ellipse &0", placeform) {
                set_draw_info();
                if (ellipsfactor != 1.0) {
                  m_ellipsfactor = ellipsfactor;
                }
                else ellipsfactor = m_ellipsfactor;
              }
              dlgRadioButton("1/&4 ellipse", placeform) {
                set_draw_info();
                if (ellipsfactor != 1.0) {
                  m_ellipsfactor = ellipsfactor;
                }
                else ellipsfactor = m_ellipsfactor;
              }
              dlgStretch(1);
            }
            dlgSpacing(8);
            dlgHBoxLayout {
              dlgLabel( " Ellipse &factor y = x*f ");
              dlgRealEdit( ellipsfactor, +0.01, +50.0);
            }
          }
          dlgStretch(1);
        }
      }

      dlgHBoxLayout {
        dlgLabel("<font color=\"blue\"><b>Grid " + GridUnit[grid] + "</b></font>");
        dlgSpacing(12);
        dlgLabel(mark_info);
        dlgStretch(1);
      }
      dlgLabel(label_move, 1);
      dlgHBoxLayout {
        dlgLabel("<nobr><font color=\"red\">" + help_err + "</font><nobr>", 1);
        dlgStretch(1);
      }
      dlgHBoxLayout {
        dlgPushButton("+OK") {
          dlgAccept();
          PressOk = 1;
        }
        dlgPushButton("-Cancel") { dlgReject(); exit(0); }
        dlgStretch(1);
        dlgLabel(Version);
        dlgPushButton("Help") info();
      }
  };
  return RESULT;
}


string getPrefix(string s) {
  int l = strlen(s);
  string prfx;
  for (int n = 0; n <= l; n++) {
    if (s[n] < '0' || s[n] > '9');
    else {
      prfx = strsub(s, 0, n);
      break;
    }
  }
  return prfx;
}


int getNumber(string s) {
  int l = strlen(s);
  for (int n = 0; n <= l; n++) {
    if (s[n] < '0' || s[n] > '9');
    else return strtol(strsub(s, n));
  }
  return 0;
}


// if Element in Project
int exist(string e) {
  board(B) {
    B.elements(E) {
      if (E.name == e) return 1;
    }
  }
  return 0;
}


// ** draw wire Ellipse **
string wireEllipse(void) {
  string e;
  real rad;
  string xystart;
  int    start = 1;
  for (real winkel = startangle; winkel <= endangle; winkel += anglestep) {
    rad = PI / 180 * winkel;
    sprintf(h, "(R%.4f %.4f)\n",
                    x1 + (cos(rad) * x2),
                    y1 + (sin(rad) * x2 * ellipsfactor) );
    e += h;
    if (start) {
      xystart = h;
      start = 0;
    }
  }
  if (drawtype == DrawPOLYGON && anglesteptyp != None) {
    e += xystart;
  }
  return e;
}


// *** generate Script to draw WIRE ***
void drawWire(void) {
  if (board && signame) signame = "'"+signame+"'";
  if (library) signame = "";

  real rad = PI / 180 * startangle;
  real a;

  if (anglesteptyp) {
    switch(placeform) {
      case NONE         :
                          for (a = startangle; a <= endangle; a += anglestep) {
                            rad = PI / 180 * a;
                            sprintf(h, "WIRE %s %s (R%.4f %.4f) (R%.4f %.4f);\n",
                                        width, signame,
                                        x1, y1,
                                        x1 + (cos(rad) * x2),
                                        y1 + (sin(rad) * x2 * ellipsfactor) );
                            s += h;
                          }
                          break;
      case CIRCLE       :
                          sprintf(h, "WIRE %s %s ", width, signame);
                          s += h;
                          for (a = startangle; a <= endangle; a += anglestep) {
                            rad = PI / 180 * a;
                            sprintf(h, " (R%.4f %.4f) ", x1 + (cos(rad) * x2), y1 + (sin(rad) * x2 * ellipsfactor) );
                            s += h;
                          }
                          s += ";\n";
                          break;
      case FULL_ELLIPSE :
                          sprintf(h, "WIRE %s %s ", width, signame);
                          s += h;
                          s += wireEllipse() + ";\n";
                          break;
      case ELLIPSE_4    :
                          sprintf(h, "WIRE %s %s ", width, signame);
                          s += h;
                          s += wireEllipse() + ";\n";
                          break;
    }
  }
  else {
    sprintf(h, "WIRE %s %s (R%.4f %.4f) (R%.4f %.4f);\n",
                     width, signame,
                     x1, y1,
                     x1 + (cos(rad) * x2),
                     y1 + (sin(rad) * x2 * ellipsfactor) );
    s += h;
  }
  return;
}


// ** draw Polygon ***
void drawPolygon(void) {
  if (board && signame) signame = "'"+signame+"'";
  if (library) signame = "";

  if((placeform == FULL_ELLIPSE || placeform == ELLIPSE_4) && ellipsfactor == 1.0) {
    dlgMessageBox("!Da fehlt der Ellipsfaktor", "OK");
    exit(-2);
  }
  string ecmd;

  if (anglesteptyp) {
    switch(placeform) {
      case NONE         :
                          sprintf(ecmd, "POLYGON %s %s ", width, signame );
                          s += ecmd;
                          s += wireEllipse();
                          break;
      case CIRCLE       :
                          sprintf(ecmd, "POLYG %s %s ", width, signame );
                          s += ecmd;
                          s += wireEllipse();
                          s += ";\n";
                          break;
      case FULL_ELLIPSE :
                          sprintf(ecmd, "Polygo %s %s ", width, signame );
                          s += ecmd;
                          s += wireEllipse();
                          s += ";\n";
                          break;
      case ELLIPSE_4    :
                          sprintf(ecmd, "Polygon %s %s ", width, signame );
                          s += ecmd;
                          s += wireEllipse();
                          s += ";\n";
                          break;
    }
  }
  else {
    switch(placeform) {
      case NONE         :
                          sprintf(ecmd, "POLy %s %s ", width, signame );
                          s += ecmd;
                          sprintf(ecmd, " (R%.4f %.4f)\n", x1, y1 );
                          s += ecmd;
                          s += wireEllipse();
                          s += ecmd +";\n";
                          break;
      case CIRCLE       :
                          sprintf(ecmd, "POLY %s %s ", width, signame );
                          s += ecmd;
                          sprintf(ecmd, " (R%.4f %.4f)\n", x1, y1 );
                          s += ecmd;
                          s += wireEllipse();
                          s += ecmd;
                          s += ";\n";
                          break;
      case FULL_ELLIPSE :
                          sprintf(ecmd, "POlY %s %s ", width, signame );
                          s += ecmd;
                          sprintf(ecmd, " (R%.4f %.4f)\n", x1, y1 );
                          s += ecmd;
                          s += wireEllipse();
                          s += ecmd;
                          s += ";\n";
                          break;
      case ELLIPSE_4    :
                          sprintf(ecmd, "pOLYGON %s %s ", width, signame );
                          s += ecmd;
                          sprintf(ecmd, " (R%.4f %.4f)\n", x1, y1 );
                          s += ecmd;
                          s += wireEllipse();
                          s += ecmd;
                          s += ";\n";
                          break;
    }
  }
  return ;
}


// *** generate Script to MOVE packages ***
void drawMove(void) {
  real rad = PI / 180 * startangle;
  string Prefix = getPrefix(signame);
  int    NameCount = getNumber(signame);
  string m = "";
  if (layer == "16") {
    m = "M";   // to mirror the Element
  }

  if (anglesteptyp) {
    if (anglestep < 0) {
      if (startangle < endangle) startangle+= 360;
      for (real a = startangle; a > endangle; a += anglestep) {
        string eName;
        sprintf(eName, "%s%d", Prefix, NameCount);
        if (exist(eName)) {
          rad = PI / 180 * a;
          sprintf(h, "MOVE '%s' (R%.4f %.4f);\n",
                      eName,
                      x1 + (cos(rad) * x2),
                      y1 + (sin(rad) * x2 * ellipsfactor)
                 );
          s += h;
          real ang = 0;
          if (rotateMatch) {
            if (m) ang = 180.0 - a;
            else ang = a;
          }
          sprintf(h, "ROTATE =%sR%.1f '%s';\n", m, ang+EangleOffset, eName);
          s += h;
          NameCount++;
        }
        else break;
      }
    }
    else {
      for (real a = startangle; a < endangle; a += anglestep) {
        string eName;
        sprintf(eName, "%s%d", Prefix, NameCount);
        if (exist(eName)) {
          rad = PI / 180 * a;
          sprintf(h, "MOVE '%s' (R%.4f %.4f);\n", eName,
                  x1 + (cos(rad) * x2),
                  y1 + (sin(rad) * x2 * ellipsfactor) );
          s += h;
          real ang = 0;
          if (rotateMatch) {
            if (m) ang = 180.0 - a;
            else ang = a;
          }
          sprintf(h, "ROTATE =%sR%.1f '%s';\n", m, ang, eName);
          s += h;
          NameCount++;
        }
        else break;
      }
    }
  }
  else {
    if (exist(signame)) {
      sprintf(h, "MOVE '%s' (R%.4f %.4f);\n", signame,
                  x1 + (cos(rad) * x2),
                  y1 + (sin(rad) * x2 * ellipsfactor) );
      s += h;
      real ang = startangle;
      if (rotateMatch) {
        if (m) ang = 180.0 - startangle;
        else ang = startangle;
      }
      else ang = 0;
      sprintf(h, "ROTATE =%sR%.1f '%s';\n", m, ang, signame);
      s += h;
    }
  }
  return;
}


// *** generate Script to place SMDs ***
void drawSmd(void) {
  if (signame) signame = "'"+signame+"'";
  if (SMD_dx && SMD_dy) {
    sprintf(h, "CHANGE SMD %.4f %.4f;\n", SMD_dx, SMD_dy);
    s += h;
  }
  real rad = PI / 180 * startangle;
  if (anglestep) {
    if (anglestep < 0) {
      if (startangle > endangle) startangle+= 360;
      for (real a = startangle; a > endangle; a += anglestep) {
        rad = PI / 180 * a;
        if (EAGLE_VERSION >= 4 && EAGLE_RELEASE >= 10 || EAGLE_VERSION >= 5) {
          string rm = "";
          if (rotateMatch) sprintf(rm, "R%.1f", a);
          sprintf(h, "SMD %s %s (R%.4f %.4f);\n",         // 2008-05-06
                     rm,
                     signame,
                     x1 + (cos(rad) * x2),
                     y1 + (sin(rad) * x2 * ellipsfactor)
                 );
          s += h;
        }
        else {
          sprintf(h, "SMD (R%.4f %.4f);\n",
                     x1 + (cos(rad) * x2),
                     y1 + (sin(rad) * x2 * ellipsfactor)
                 );
          s += h;
        }
        if (signame) signame = "";         // 2008-05-06
      }
    }
    else {
      for (real a = startangle; a < endangle; a += anglestep) {
        rad = PI / 180 * a;
        if (EAGLE_VERSION >= 4 && EAGLE_RELEASE >= 10 || EAGLE_VERSION >= 5) {
          string rm;
          if (rotateMatch) sprintf(rm, "R%.1f", a);
          sprintf(h, "SMD %s %s (R%.4f %.4f);\n",          // 2008-05-06
                     rm,
                     signame,
                     x1 + (cos(rad) * x2),
                     y1 + (sin(rad) * x2 * ellipsfactor)
                 );
          s += h;
          if (signame) signame = "";         // 2008-05-06
        }
        else {
          sprintf(h, "SMD (R%.4f %.4f);\n",
                     x1 + (cos(rad) * x2),
                     y1 + (sin(rad) * x2 * ellipsfactor)
                 );
          s += h;
        }
      }
    }
  }
  else {
    if (EAGLE_VERSION >= 4 && EAGLE_RELEASE >= 10 || EAGLE_VERSION >= 5) {
      string rm;
      if (rotateMatch) sprintf(rm, "R%.1f", startangle);

      sprintf(h, "SMD %s %s (R%.4f %.4f);\n",         // 2008-05-06
                  rm,
                  signame,
                  x1 + (cos(rad) * x2),
                  y1 + (sin(rad) * x2 * ellipsfactor)
             );
      s+= h;
      if (signame) signame = "";         // 2008-05-06
    }
    else {
      sprintf(h, "SMD (R%.4f %.4f);\n",
                  x1 + (cos(rad) * x2),
                  y1 + (sin(rad) * x2 * ellipsfactor)
             );
      s+= h;
    }
  }
  return ;
}


// *** generate Script to place PADs ***
void drawPad(void) {
  if (signame) signame = "'"+signame+"'";
  real rad = PI / 180 * startangle;
  if (drill_hole) {
    sprintf(h, "CHANGE DRILL %s;\n", drill_hole);
    s += h;
  }
  if (PAD_diameter) {
    sprintf(h, "CHANGE DIAMETER %s;\n", PAD_diameter);
    s += h;
  }

  if (PadVia == "PAD") {
    if (ShapeSelect < PAD_SHAPE_OFFSET+1)
    s += "CHANGE SHAPE " + Shapes[ShapeSelect] + ";\n";
  }
  string Rotate_option = "";
  if (anglestep) {
    string h;
    if (anglestep < 0) {
      if (startangle < endangle) startangle+= 360;
      for (real a = startangle; a > endangle; a += anglestep) {
        rad = PI / 180 * a;
        if (PadVia == "PAD") sprintf(Rotate_option, "R%.1f", a);
        if (EAGLE_VERSION >= 4 && EAGLE_RELEASE >= 10 || EAGLE_VERSION >= 5) {
          sprintf(h, "%s %s %s (R%.4f %.4f);\n", PadVia, Rotate_option, signame,  // 2010-06-09 alf
                    x1 + (cos(rad) * x2),
                    y1 + (sin(rad) * x2 * ellipsfactor) );
          }
        else {
          sprintf(h, "%s %s (R%.4f %.4f);\n", PadVia, signame,
                    x1 + (cos(rad) * x2),
                    y1 + (sin(rad) * x2 * ellipsfactor) );
          }
        s += h;
        signame = "";
      }
    }
    else {
      for (real a = startangle; a < endangle; a += anglestep) {
        rad = PI / 180 * a;
        if (PadVia == "PAD") sprintf(Rotate_option, "R%.1f", a);
        if (EAGLE_VERSION >= 4 && EAGLE_RELEASE >= 10 || EAGLE_VERSION >= 5) {
          sprintf(h, "%s %s %s (R%.4f %.4f);\n",  // 2010-06-09
                      PadVia,
                      Rotate_option,
                      signame,
                      x1 + (cos(rad) * x2),
                      y1 + (sin(rad) * x2 * ellipsfactor) );
          }
        else {
          sprintf(h, "%s '%s' (R%.4f %.4f);\n",
                      PadVia,
                      signame,
                      x1 + (cos(rad) * x2),
                      y1 + (sin(rad) * x2 * ellipsfactor) );
          }
        s += h;
        signame = "";
      }
    }
  }
  else {
    if (PadVia == "PAD") sprintf(Rotate_option, "R%.1f", startangle);
        if (EAGLE_VERSION >= 4 && EAGLE_RELEASE >= 10 || EAGLE_VERSION >= 5) {
      sprintf(h, "%s %s %s (R%.4f %.4f);\n",  // 2010-06-09
                  PadVia,
                  Rotate_option,
                  signame,
                  x1 + (cos(rad) * x2),
                  y1 + (sin(rad) * x2 * ellipsfactor) );
      s+= h;
    }
    else {
      sprintf(h, "%s '%s' (R%.4f %.4f);\n",
                  PadVia,
                  signame,
                  x1 + (cos(rad) * x2),
                  y1 + (sin(rad) * x2 * ellipsfactor) );
      s += h;
    }
  }
  return ;
}

// *** generate Script to place HOLEs ***
void drawHole(void) {
  real rad = PI / 180 * startangle;

  sprintf(h, "HOLE %s ", drill_hole);
  s += h;
  if (placeform == ELLIPSE_4) {
    s += wireEllipse() + ";\n";;
  }
  else if (anglestep) {
    if (anglestep < 0) {
      if (startangle < endangle) startangle+= 360;
      for (real a = startangle; a > endangle; a += anglestep) {
        rad = PI / 180 * a;
        sprintf(h, " (R%.4f %.4f);\n", x1 + (cos(rad) * x2), y1 + (sin(rad) * x2 * ellipsfactor) );
        s += h;
      }
    }
    else {
      for (real a = startangle; a < endangle; a += anglestep) {
        rad = PI / 180 * a;
        sprintf(h, " (R%.4f %.4f);\n", x1 + (cos(rad) * x2), y1 + (sin(rad) * x2 * ellipsfactor) );
        s += h;
      }
      s += ";\n";
    }
  }
  else {
    sprintf(h, "HOLE %s (R%.4f %.4f);\n", drill_hole,
                x1 + (cos(rad) * x2),
                y1 + (sin(rad) * x2 * ellipsfactor) );
    s += h;
  }
  return ;
}


void drawGroup(void) {
  real groupdistance, m;
  if (board) board(B) {
    gridunit = (B.grid.unit);
    m = abs(B.area.x2);
    if (groupdistance < m) groupdistance = m;
    m = abs(B.area.x1);
    if (groupdistance < m) groupdistance = m;
    m = abs(B.area.y2);
    if (groupdistance < m) groupdistance = m;
    m = abs(B.area.y1);
    if (groupdistance < m) groupdistance = m;
  }
  if (library) library(L) {
    gridunit = (L.grid.unit);
    if (package) package(P) {
      m = abs(P.area.x2);
      if (groupdistance < m) groupdistance = m;
      m = abs(P.area.x1);
      if (groupdistance < m) groupdistance = m;
      m = abs(P.area.y2);
      if (groupdistance < m) groupdistance = m;
      m = abs(P.area.y1);
      if (groupdistance < m) groupdistance = m;
    }
  }
  groupdistance = u2u(8000000);  // maximum
  string g;
  sprintf(g, "GROUP (%.4f %.4f) (%.4f %.4f) (%.4f %.4f) (%.4f %.4f) (>%.4f %.4f);\n",
              -groupdistance, -groupdistance,
               groupdistance, -groupdistance,
               groupdistance,  groupdistance,
              -groupdistance,  groupdistance,
              -groupdistance, -groupdistance
         );
  s = g;
  sprintf(h, "CUT (>R 0 0);\n");
  s += h;
  for (real a = startangle; a < endangle-anglestep; a += anglestep) {
    s += g;
    sprintf(h, "ROTATE =R%.1f (>R 0.0 0.0);\n", anglestep );
    s += h;
    s += "PASTE (R0 0);\n";
  }
  return;
}

void unknown(string m) {
  if (dlgMessageBox("unknown parameter\n" + m, "OK", "Cancel" ) != 0) exit(-1);
  return;
}


// ******* Main ***************************************************************
int n = 1;
if (argc > 1) {
  do {
    para = strupr(argv[n]);
    // *** Order of parameters can changed here ***
    // *** Eagle-Parser cut character ' from argument ***
    if      (para[0] == '+' )  { para[0] = ' ';  x2           = strtod(para); }
    else if (para[0] == 'A' )  { para[0] = ' ';  startangle   = strtod(para); }
    else if (para[0] == 'N' )  { para[0] = ' ';  anglestep    = strtod(para); }
    else if (para[0] == 'E' )  { para[0] = ' ';  endangle     = strtod(para); }
    else if (para[0] == 'L' )  { layer   = strsub(para, 1); }
    else if (para[0] == 'W' )  { para[0] = ' ';  width        = para; drawtype = DrawWIRE; }
    else if (para[0] == 'X' )  { para[0] = ' ';  x1           = strtod(para); }
    else if (para[0] == 'Y' )  { para[0] = ' ';  y1           = strtod(para); }
    else if (para[0] == 'O' )  {                 drawtype     = DrawPOLYGON;  }
    else if (para[0] == 'P' )  {                 PadVia       = "PAD"; drawtype = DrawPAD;  }
    else if (para[0] == 'V' )  {                 PadVia       = "VIA"; drawtype = DrawPAD;  }
    else if (para[0] == 'S' )  {                 drawtype     = DrawSMD;      }
    else if (para[0] == 'I' )  { para[0] = ' ';  SMD_dx       = strtod(para); }
    else if (para[0] == 'T' )  { para[0] = ' ';  SMD_dy       = strtod(para); }
    else if (para[0] == '-' )  { signame = strsub(para, 1); }
    else if (para[0] == 'D' )  { para[0] = ' ';  PAD_diameter = para;         }  // Pad/Via diameter
    else if (para[0] == 'R' )  { para[0] = ' ';  drill_hole   = para;  drawtype = DrawHOLE; }
    else if (para[0] == 0xb0)  {                 anglesteptyp = Degreestep;   }  // °
    else if (para[0] == '/' )  {                 anglesteptyp = Calcstep;     }
    else if (para[0] == 'G' )  {                 drawtype     = DrawGROUP;    }
    else if (strstr(para, "MOVE") == 0) {        drawtype     = DrawMOVE;     }  // ** do not change order with next line **
    else if (para[0] == 'M' )  {                 rotateMatch  = 1;            }  // ** do not change order with prior line **
    else if (para[0] == 'C' )  {                 placeform    = CIRCLE;       }
    else if (para[0] == '0' )  { para[0] = ' ';  placeform    = FULL_ELLIPSE; }
    else if (para[0] == 'F' )  { para[0] = ' ';  ellipsfactor = strtod(para); }
    else if (para[0] == '4' )  {                 placeform    = ELLIPSE_4;    }
    else unknown(para);
    n++;
  } while (argv[n]);
}
else {
  if (board) {
    board(B) grid = B.grid.unit;
  }
  if (schematic) { schematic(S) grid = S.grid.unit; }
  if (library)   {
    if (package || symbol) {
      library(L)   grid = L.grid.unit;
    }
    else {
      dlgMessageBox("!Start this ULP in a Package or Symbol Editor", "OK");
      exit(0);
    }
  }
  Set_MinMax_Unit(grid);

  int Result;
  do {
    Result = menue();
    if(PressOk) {
      if (error()) {
        dlgMessageBox(help_err, "OK");
        PressOk = 0;
      }
    }
  } while(!PressOk);
}

signame = strupr(signame);

sprintf(s, "SET Wire_Bend 2;\n");   // *** Script header ***
if (layer)        s += "CHANGE LAYER " + layer + ";\n";
if (PAD_diameter) s += "CHANGE DIAMETER " + PAD_diameter + ";\n";
if (drill_hole)   s += "CHANGE DRILL " + drill_hole + ";\n";
//if (signame &&  drawtype == DrawSMD || drawtype == DrawSMD) s += "SMD " + signame + ";\n"; // 2008.05.05

if (placeform == ELLIPSE_4) {
  if (endangle > 90.0) endangle = 90.0;
  if (startangle > endangle) startangle = 0.0;
}

switch(anglesteptyp) {
    case None         : if (drawtype != DrawPOLYGON) {
                         anglestep = 360;
                        }
                        break;
    case Degreestep   : if (!anglestep) anglesteptyp = None;
                        break;
    case Calcstep     : anglestep = (endangle - startangle) / anglestep;
                        break;
}

switch(drawtype) {
  case DrawWIRE    :  drawWire();
                      break;
  case DrawPOLYGON :  drawPolygon();
                      break;
  case DrawMOVE    :  drawMove();
                      break;
  case DrawGROUP   :  drawGroup();
                      break;
  case DrawHOLE    :  drawHole();
                      break;
  case DrawPAD     :  drawPad();
                      break;
  case DrawSMD     :  drawSmd();
                      break;
}


if (test) dlgDialog("Test") {
    dlgHBoxLayout dlgSpacing(500);
    dlgHBoxLayout {
      dlgVBoxLayout dlgSpacing(500);
      dlgTextView(s);
    }
    dlgHBoxLayout {
      dlgPushButton("OK") dlgAccept();
      dlgPushButton("ESC") { dlgReject(); exit(-1); }
      dlgStretch(1);
      dlgLabel(Version);
    }
  };

exit (s);


