/*
 *  This EAGLE User Language Program 
 *  generates a script for add a drill chart 
 *  in the current board. The first time,
 *  you must move manually the drill chart to
 *  the location of your choice. But the next
 *  time, the drill chart will be automatically 
 *  replaced at his last location in the board.
 *  At each time you run this ulp do'nt forget:
 *  1) Update and sort the >Options>Setting>Drill 
 *  in ascending order as the drill chart.
 *  2) Re-run the DRILLCFG.ULP for the CamProcessor.
 *  
 ****************************************************
 * DRILTABH (Horizontal) Version 1.01 (24/08/99)    *
 * By Christian BOHRER (PCB Designer)               *
 * email:cao.azelectronic@wanadoo.fr                *
 * http://www.azelectronic.fr/                      *
 ****************************************************
 */
/**** GENERATION OF THE DRILL CHART PACKAGE ****/

int W = 650;
int X = -75;
int Y = 400;
int Z = 350;
string plated[] = { "YES", "MIX", "NO"};
int FactorRound = pow(10, 3);
real Alldrills[];
int amax = 0;
real list[];
int cnt = 0;
real Hole[];
int hmax = 0;
int h;
real Metal[];
int mmax = 0;
int m;

/* TABLE OF 18 DRILL SYMBOLS */

string ds[] ={ "Wire  4 (500 740) (500 660);\n\
Wire  4 (460 700) (540 700);\n",

"Wire  4 (760 740) (840 660);\n\
Wire  4 (840 740) (760 660);\n",

"Wire  4 (1100 700) (1100 740) (1140 740) (1140 660) (1060 660) (1060 740) (1100 740);\n",

"Wire  4 (1400 700) (1400 740) (1440 700) (1400 660) (1360 700) (1400 740);\n",

"Wire  4 (1660 740) (1740 740) (1660 660) (1740 660) (1660 740);\n",

"Wire  4 (1960 740) (2040 660) (2040 740) (1960 660) (1960 740);\n",

"Wire  4 (2260 700) (2340 700) (2300 740) (2300 660) (2260 700);\n",

"Wire  4 (2600 740) (2600 660) (2640 700) (2560 700) (2600 740);\n",

"Wire  4 (2860 740) (2940 660);\n\
Wire  4 (2940 740) (2860 660);\n\
Wire  4 (2900 740) (2900 660);\n",

"Wire  4 (3160 740) (3240 660);\n\
Wire  4 (3240 740) (3160 660);\n\
Wire  4 (3160 700) (3240 700);\n",

"Wire  4 (3460 740) (3540 740) (3500 700) (3460 740);\n\
Wire  4 (3500 700) (3500 660);\n",

"Wire  4 (3800 740) (3800 700) (3840 660) (3760 660) (3800 700);\n",

"Wire  4 (4035 700) (4075 700) (4115 740) (4115 660) (4075 700);\n",

"Wire  4 (4440 700) (4400 700) (4360 740) (4360 660) (4400 700);\n",

"Wire  4 (4700 740) (4700 660);\n\
Wire  4 (4660 700) (4740 700);\n\
Circle 4 (4700 700) (4739.05 700);\n",

"Circle 4 (5000 700) (5039.05 700);\n\
Circle 4 (5000 700) (5020 700);\n\
Wire  4 (5000 740) (5000 660);\n\
Wire  4 (4960 700) (5040 700);\n",

"Wire  4 (5260 740) (5300 740) (5340 740) (5340 700) \
      (5340 660) (5300 660) (5260 660) (5260 700) \
      (5260 740);\n\
Wire  4 (5300 740) (5300 660);\n\
Wire  4 (5260 700) (5340 700);\n",

"Wire  4 (5560 740) (5560 700) (5560 660) (5600 660) \
      (5640 660) (5640 700) (5640 740) (5600 740) \
      (5560 740);\n\
Wire  4 (5580 720) (5580 680) (5620 680) (5620 720) (5580 720);\n\
Wire  4 (5600 740) (5600 660);\n\
Wire  4 (5560 700) (5640 700);\n"};

void AddAlldrills(int Size)
{
  real x;
  x = round(u2inch(Size) * FactorRound) / FactorRound;
list[cnt++] = x;
  for (int i = amax; --i >= 0; )
      if (Alldrills[i] == x)
         return;
  Alldrills[amax++] = x;
}

void AddHole(int Dri)
{
  real y;
  y = round(u2inch(Dri) * FactorRound) / FactorRound;
  for (int u = hmax; --u >= 0; )
      if (Hole[u] == y)
         return;
      Hole[hmax++] = y;
}

void CmpHole(real Comp)
{
 h = 0;
  for (int u = 0; u < hmax; ++u)
      if (Hole[u] == Comp)
            h = 1;
}

void AddMetal(int Met)
{
  real z;
  z = round(u2inch(Met) * FactorRound) / FactorRound;
  for (int a = mmax; --a >= 0; )
      if (Metal[a] == z)
         return;
      Metal[mmax++] = z;
}

void CmpMetal(real Cmp)
{
 m = 1;
  for (int o = 0; o < mmax; ++o)
      if (Metal[o] == Cmp)
            m = 0;
}


board(B) {
  B.holes(H) AddAlldrills(H.drill), AddHole(H.drill);
  B.signals(S) S.vias(V) AddAlldrills(V.drill), AddMetal(V.drill);
  B.elements(E)  {
    E.package.contacts(C) {
      if (C.pad)
         AddAlldrills(C.pad.drill), AddMetal(C.pad.drill);
      }
    E.package.holes(H) AddAlldrills(H.drill), AddHole(H.drill);
    }

   sort(mmax, Metal);
   sort(hmax, Hole);
   sort(amax, Alldrills);
   sort(cnt, list);
       int tool = 0, qty[];
	for (int e = 1; e <= cnt; ++e)
	   if (list[e] != list[e-1])
	   qty[tool++]++;
             else
	      qty[tool]++;

  output(filesetext(B.name, ".SCR")) {
	string dfile = filedir(B.name);
        printf("open %s\drilltab.lbr\n",dfile);
        int ttime = time();
        string ftime;
	sprintf(ftime,"%d",ttime);
	string tfile = strsub(ftime, 1, 7);
        printf("Edit @%s.pac\n",tfile);
	printf("Display none;\n");
	printf("Display 44;\n");
        printf("Set Wire_Style 2;\n");
        printf("Grid mil 25 1 mil;\n");
        printf("layer 44;\n");
        printf("Change Size 70;\n");
        printf("Change Ratio 8;\n");
        printf("Text 'SYMB' R0 (50 662);\n");
	printf("Text 'TOOL' R0 (50 525);\n");
	printf("Text 'MILS' R0 (50 400);\n");
	printf("Text 'MM' R0 (100 275);\n");
	printf("Text 'QTY' R0 (75 150);\n");
	printf("Text 'METAL' R0 (25 25);\n");
	printf("Wire  5 (0 775) (0 0);\n");
	printf("Wire  5 (350 775) (350 0);\n");
	printf("Wire  5 (350 775) (0 775);\n");
	printf("Wire  5 (350 0) (0 0);\n");
	printf("Wire  5 (350 125) (0 125);\n");
	printf("Wire  5 (350 250) (0 250);\n");
	printf("Wire  5 (350 375) (0 375);\n");
	printf("Wire  5 (350 500) (0 500);\n");
	printf("Wire  5 (350 625) (0 625);\n");

    {
     for (int i = 0; i < amax; ++i, Y=Y+300, W=W+300, X=X+300, Z=Z+300)
        CmpHole(Alldrills[i]),
        CmpMetal(Alldrills[i]),
        printf("Text 'T%02d' R0 (%d 525);\n", i + 1, Y),                /* TOOL  */
        printf("Text '%-3.0f' R0 (%d 400);\n", Alldrills[i]*1000, Y),  /* MILS  */
        printf("Text '%-1.2f' R0 (%d 275);\n", Alldrills[i]*25.4, Y), /* MM    */
        printf("Text '%d' R0 (%d 150);\n", qty[i], Y),               /* QTY   */
        printf("Text '%s' R0 (%d 25);\n", plated[m+h], Y),          /* METAL */
        printf("Wire  5 (%d 775) (%d 0);\n",W, W),
        printf("Wire  5 (%d 0) (%d 0);\n",W, Z),
        printf("Wire  5 (%d 125) (%d 125);\n",W, Z),
        printf("Wire  5 (%d 250) (%d 250);\n",W, Z),
        printf("Wire  5 (%d 375) (%d 375);\n",W, Z),
        printf("Wire  5 (%d 500) (%d 500);\n",W, Z),
        printf("Wire  5 (%d 625) (%d 625);\n",W, Z),
        printf("Wire  5 (%d 775) (%d 775);\n",W, Z),
        printf("%s \n",ds[i]);                             /* SYMB  */

    }
        printf("write;\n");
        printf("close;\n");
        printf("DISPLAY 23 44 45;\n");
        printf("Grid mil 25 1 mil;\n");
        printf("USE %s\DRILLTAB;\n",dfile);

/*ADD OR REPLACE IF EXIST A ELEMENT OF DRILLTAB.LBR*/

string packlib[];
int x[], y[];
int count = 0;
string libr = "drilltab";
int pos = -1;
int locx;
int locy;
int replace = -1;


       B.elements(E) {
       packlib[count] = E.package.library;
       x[count] = u2mil(E.x);
       y[count] = u2mil(E.y);
       pos = strrstr(packlib[count], libr);
       if (pos == 0){
       replace = pos,
       locx = x[count],
       locy = y[count];
      }
       else
       count++;
       }

      if (replace == -1)
        printf("ADD @%s R0 (0 -2000);\n",tfile);
        else
        printf("REPLACE @%s (%d %d);\n",tfile, locx, locy),
        printf("DISPLAY -23;\n");
        printf("Grid last;\n");
     }

    }
   