public PcbPad(string number, PcbUnits coordinateUnits, double x, double y,
               PcbLayer layer, PcbPadStyle style, string flags = null)
 {
     Number          = number;
     CoordinateUnits = coordinateUnits;
     X     = x;
     Y     = y;
     Layer = layer;
     Style = style;
     Flags = flags;
 }
        private static PcbPadStyle DeterminePadStyle(PadStack.StackLine line,PcbUnits coordinateUnits)
        {
            PcbPadStyle style;
            bool        drilled = line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Present;

            switch (line.CurrentShape)
            {
            case PadStack.Shape.Round:     //"Round" pads with drill argument are used for drilled pads (not annular pads!)
                style = new PcbPadStyle(drilled ? PcbPadShape.CircularTH : PcbPadShape.CircularSMT,
                                        coordinateUnits,line.Size,0,
                                        drilled ? (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value : 0);
                break;

            case PadStack.Shape.Square:
                style = new PcbPadStyle(drilled ? PcbPadShape.RectangularTH : PcbPadShape.RectangularSMT,
                                        coordinateUnits,line.Size,line.Size,
                                        drilled ? (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value : 0);
                break;

            case PadStack.Shape.Annular:
                style = new PcbPadStyle(drilled ? PcbPadShape.CircularTH : PcbPadShape.CircularSMT,
                                        coordinateUnits,line.Size,
                                        (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.InternalDiameter].Value,
                                        drilled ? (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value : 0);
                break;

            case PadStack.Shape.RectangularFinger:
                style = new PcbPadStyle(PcbPadShape.RectangularSMT,coordinateUnits,line.Size,
                                        (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.FingerLength].Value);
                WarningListener.Add(new NotImplementedException("Only Length argument is supported for RectangularFinger pad style!"));
                break;

            default:
                throw new NotImplementedException(string.Format(
                                                      "Pad shape {0} ignored.",Enum.GetName(typeof(PadStack.Shape),line.CurrentShape)));
            }
            return(style);
        }
        private static void ProcessDecalPads(PcbDesign res,PcbUnits coordinateUnits,Partdecal decal)
        {
            //Terminals + padstacks = pads
            PadStack defaultStack = decal.PadStacks.FirstOrDefault(x => x.PinDesignator == PadStack.AllTerminalsDesignator);

            res.Pads.Capacity += decal.Terminals.Count;
            foreach (var item in decal.Terminals)
            {
                var padstack = FindSuitablePadstack(decal,item,defaultStack);
                if (padstack == null)
                {
                    WarningListener.Add(new ArgumentException(),"Can't find a suitable padstack for the terminal #" + item.PinDesignator);
                    continue;
                }
                var drillLine = padstack.StackLines.FirstOrDefault(x => x.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Present);
                if (drillLine != null)
                {
                    //Detect drill-only holes
                    double d = (double)drillLine.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value;
                    if (d >= drillLine.Size)
                    {
                        res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,PcbLayer.Drill,
                                                new PcbPadStyle(PcbPadShape.CircularTH,coordinateUnits,d,0,d)));
                        continue;
                    }
                }
                List <PadStack.StackLine> usefulLines =
                    padstack.StackLines.Where(x => (x.Size != 0 || x.Arguments.Any(y => y.Present))).ToList();
                if (usefulLines.Count == 3)   //Recognize layer "ALL"
                {
                    //PADS requires minimum of 3 layers specified, 0x0 size indicates that the pad is not actually present
                    //If some stacklines have 0 size and no useful arguments (shape does not count), then we effectively have less stacklines
                    if (usefulLines.Select(x => x.Layer).Union(PadStack.AllLayerPattern).Count() == 3)
                    {
                        //Find layer that contains the most arguments (drill for example appears only for component-side layer)
                        int maxArgs = 0;
                        for (int i = 1; i < usefulLines.Count; i++)
                        {
                            if (usefulLines[maxArgs].Arguments.Count(x => x.Present) <
                                usefulLines[i].Arguments.Count(x => x.Present))
                            {
                                maxArgs = i;
                            }
                        }
                        res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,PcbLayer.All,
                                                DeterminePadStyle(usefulLines[maxArgs],coordinateUnits)));
                        continue;
                    }
                }
                //If this is not a special case, parse stacklines one-by-one
                foreach (var line in usefulLines)
                {
                    PcbPadStyle style = DeterminePadStyle(line,coordinateUnits);
                    PcbLayer    layer = DeterminePcbLayer(line);
                    res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,layer,style));
                    //-1 stands for both "Internal layers", but we can return only a single layer, so fix it afterwards
                    if (layer == PcbLayer.InternalBottom)
                    {
                        res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,
                                                PcbLayer.InternalTop,style));
                    }
                }
            }
        }