#usage "<b>Export IPC-D-356 data format</b>\n"
       "<p>"
       "Generates a netlist in IPC-D-356 format from the current board."
       "<p>"
       "Please take care of net names. IPC-D-356 does not allow more than 14 characters! "
       "Written for EAGLE 4.1. "
       "<p>"
        "IPC-D-356 syntax generated according to the specifications of<br>"
        "<table><tr><td>"
        "<i>IPC-D-356 Simplified</i><br>"
        "Written by Rich Nedbal<br>"
        "DownStream Technologies, LLC<br>"
        "</td></tr></table>"
       "<p>"
       "<author>Author: support@cadsoft.de</author>"

#require 4.1602

// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
//
// Release 1.0 -- November 2003
// Release 1.0.1  -- May 2006,  Added source of specification (ric)
// Release 2.0.0  -- 2012-02-29, values calculated with u2inch (alf)
// Release 2.0.1  -- 2012-03-13, corrected calulation of diameter (alf)
//                   now generate the same data as the original ulp up to V5.
// Release 2.0.2  -- corrected line 82, multiplicator 1000 -> 10000

string Version = "2.0.2";

string fileName, RefDes, Access, Xpolarity, Ypolarity, RestOfLine, NoDiameter;
int n, TypeNumber, Diameter, Xcoord, Ycoord, RectDataX, RectDataY, Angle ;


void Header(UL_BOARD B) {
  printf("C  IPC-D-356 generated by %s\n", EAGLE_SIGNATURE);
  printf("C  Database %s -- Exported at %s\n", B.name, t2string(time()));
  //printf("C  ULP-Version %s : Values = Inch/1000\n", Version); // 2012-03-13
  printf("C  \n");
  printf("P  JOB EAGLE %d.%d NETLIST, DATE: %s\n", EAGLE_VERSION, EAGLE_RELEASE , t2string(time()));
  printf("P  UNITS CUST 0\n");
  printf("P  DIM N\n");
}


void TestRecord(UL_BOARD B) {
  B.signals(S) {
      S.vias(V) {
        TypeNumber = 317 ;
        RefDes = "VIA";
        Diameter = round(u2inch(V.drill)*1000);
        if (V.start == 1 && V.end == 16)  Access = "A00";  ///gibts auch andere?
        Xcoord = round(u2inch(V.x)*10000);
        Ycoord = round(u2inch(V.y)*10000);
         if (Xcoord >= 0) Xpolarity = "X ";
         if (Xcoord <  0) Xpolarity = "X-";
         if (Ycoord >= 0) Ypolarity = "Y ";
         if (Ycoord <  0) Ypolarity = "Y-";
        RectDataX = RectDataY = round(u2inch(V.diameter[V.start])*10000);
        RestOfLine = "             " ; // 13 blanks to fill up 80 characters

        printf("%3d%-14s   %-12sD%4dP%-3s%2s%6d%2s%6dX%4dY%4d%-13s\n",
         TypeNumber, S.name, RefDes, Diameter, Access, Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord),
         RectDataX, RectDataY, RestOfLine);
      }
  }
  B.elements(E) {
    E.package.contacts(C) {
      if (C.pad) {
         TypeNumber = 317 ;
         RefDes = E.name;
         Diameter = round(u2inch(C.pad.drill)*1000);
         Access = "A00";
         Xcoord = round(u2inch(C.pad.x)*10000);
         Ycoord = round(u2inch(C.pad.y)*10000);
          if (Xcoord >= 0) Xpolarity = "X ";
          if (Xcoord <  0) Xpolarity = "X-";
          if (Ycoord >= 0) Ypolarity = "Y ";
          if (Ycoord <  0) Ypolarity = "Y-";
         if (C.pad.elongation == 0)
           RectDataX = RectDataY = round(u2inch(C.pad.diameter[LAYER_TOP])*10000);
         else { // if (C.pad.elongation != 0)
           RectDataX = round(u2inch(C.pad.diameter[LAYER_TOP])*10000);
           RectDataY = round((u2inch(C.pad.diameter[LAYER_TOP])*10000) * (C.pad.elongation / 100) + u2inch(C.pad.diameter[LAYER_TOP])*10000);
         }
         Angle = round(C.pad.angle);
         RestOfLine = "         ";

         printf("%3d%-14s   %-6s-%-4s D%4dP%-3s%2s%6d%2s%6dX%4dY%4dR%3d%-9s\n",
          TypeNumber, C.pad.signal, RefDes, C.pad.name, Diameter, Access,
          Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, Angle, RestOfLine);
      }
      if (C.smd) {
         TypeNumber = 327 ;
         RefDes = E.name;
         NoDiameter = "      ";  // No drill ==> coloum 33-38 empty
         if (C.smd.layer == 1)  Access = "A01";
         if (C.smd.layer == 16)  Access = "A16";
         Xcoord = round(u2inch(C.smd.x)*10000);
         Ycoord = round(u2inch(C.smd.y)*10000);
          if (Xcoord >= 0) Xpolarity = "X ";
          if (Xcoord <  0) Xpolarity = "X-";
          if (Ycoord >= 0) Ypolarity = "Y ";
          if (Ycoord <  0) Ypolarity = "Y-";
         RectDataX = round(u2inch(C.smd.dx) * 10000) ;
         RectDataY = round(u2inch(C.smd.dy) * 10000) ;
         Angle = round(C.smd.angle);
         RestOfLine = "         ";

         printf("%3d%-14s   %-6s-%-4s %-6s%-3s%2s%6d%2s%6dX%4dY%4dR%3d%-9s\n",
          TypeNumber, C.smd.signal, RefDes, C.smd.name, NoDiameter, Access,
          Xpolarity, abs(Xcoord), Ypolarity, abs(Ycoord), RectDataX, RectDataY, Angle, RestOfLine);
      }
    }
        //   B.holes(H) TypeNumber = 347 ;    printf("%d", TypeNumber);
        //   E.package.holes(H) TypeNumber = 347 ;   printf("%d", TypeNumber);
  }
}


void EndOfFile(void) {
  printf("999\n");
}

//==========main===========


if (board) {
 board(B) {
  fileName = dlgFileSave("Save IPC-D-356 File", filesetext(B.name, ".ipc"), "*.ipc");
  if (fileName == "") exit(0);

  output(fileName) {
     Header(B);
     TestRecord(B);
     EndOfFile();
  }
 }
}

else {
   dlgMessageBox("!Start this ULP in a Board.");
   exit (0);
}
