#!/usr/bin/env python
import argparse
import ConfigParser
import sys
import os
import logging
from pcbnew import *

"""drill.py
Adam Wolf, wayne@wayneandlayne.com
Wayne and Layne, LLC
May 5th, 2013

PRERELEASE

When completed, this script will use the Kicad scripting interface to generate 
plot/Gerber files.  If you do everything exactly like it expects, it will 
generate Gerber files.  Not all the options work.  Not much has been tested.

Based partially on printo.py from Lorenzo Marcantonio.
"""

#TODO
# add rest of inner layers
# test if the PCB edges layer ends up being PCB_Edges.outline
# test "not in this directory support" (BE CAREFUL THIS HAS CRASHED MY STUFF)

# show a special warning if pcbnew import fails
# add other outputters

logging.basicConfig(format='%(levelname)s:%(message)s')
logger = logging.getLogger()

plot_formats = ["gerber"]
    
layers = {
        "F.Cu": (LAYER_N_FRONT, "Front Copper"),
        "Inner1.Cu": (LAYER_N_2, "Inner Copper #1"), 
        "B.Cu": (LAYER_N_BACK, "Back Copper"),
        "F.Adhes": (ADHESIVE_N_FRONT, "Front Adhesive"),
        "B.Adhes": (ADHESIVE_N_BACK, "Back Adhesive"),
        "F.Paste": (SOLDERPASTE_N_FRONT, "Front Solderpaste"),
        "B.Paste": (SOLDERPASTE_N_BACK, "Back Solderpaste"),
        "F.SilkS": (SILKSCREEN_N_FRONT, "Front Silkscreen"),
        "B.SilkS": (SILKSCREEN_N_BACK, "Back Silkscreen"),
        "F.Mask": (SOLDERMASK_N_FRONT, "Front Soldermask"),
        "B.Mask": (SOLDERMASK_N_BACK, "Back Soldermask"),
        "Dwgs.User": (DRAW_N, "Drawings"),
        "Cmts.User": (COMMENT_N, "Comments"),
        "Eco1.User": (ECO1_N, "ECO 1"),
        "Eco2.User": (ECO2_N, "ECO 2"),
        "Edge.Cuts": (EDGE_N, "Edges"),
        }

def main():

    cli_layer_list = sorted(layers.keys())
    cli_layer_list.insert(0, "all")
    parser = argparse.ArgumentParser(description="Eventually, this will be a slick way to generate plot files for Kicad from the command line.  Currently, it's untested and a proof-of-concept only, but it generates Gerbers.  Do not use this, really, for anything.  Do not use with files that aren't backed up.")
    parser.add_argument("--format", choices=plot_formats, help="Selects the plot format.  Only a single format per run is supported.  Only gerber is currently supported.", default=plot_formats[0])
    parser.add_argument("--verbose", "-v", action="count", default=0, help="Increase verbosity. May be entered multiple times.")
    parser.add_argument("--exclude-edge-from-other-layers", action="store_true", help="Exclude PCB edge layer from other layers.")
    parser.add_argument("--plot-sheet-reference", help="Plot sheet reference on all layers.")
    parser.add_argument("pcbfile", metavar="FILE", help="Kicad board file (.kicad_pcb or .brd)")
    parser.add_argument("--plot-in-silk", choices=["pads", "module-value", "module-reference", "other-module-texts", "invisible-texts"], action='append', help="Plot pads on silkscreen.")
    #parser.add_argument("--output-dir", "-d", help="The output directory, relative to the directory the board file is in.  Defaults to the same directory the board file is in.", default="")
    parser.add_argument("--layers", choices=cli_layer_list, action='append', help="Select layers to plot.")

    #parser.add_argument("--do-not-tent-vias", action="store_true", help="Do not tent vias.")
    #line_width_group = parser.add_mutually_exclusive_group()
    #line_width_group.add_argument("--default-line-width-mils", help="Default line width in inches.  Defaults to Kicad's default (currently 6 IU)")
    #line_width_group.add_argument("--default-line-width-mm", help="Default line width in millimeters.")

    gerber_group = parser.add_argument_group('gerber options')
    gerber_group.add_argument("--use-auxiliary-axis-as-origin", action="store_true")
    gerber_group.add_argument("--subtract-soldermask-from-silk", action="store_true")

    args = parser.parse_args()
    
    if args.verbose == 0:
        logger.setLevel(logging.WARNING)
    elif args.verbose == 1:
        logger.setLevel(logging.INFO)
    elif args.verbose > 1:
        logger.setLevel(logging.DEBUG)
    #logger.info("sample info message")
    #logger.debug("sample debug message")
    logger.debug("Parsed args: %s" % args)

    if not args.plot_in_silk:
        args.plot_in_silk = []
    if not args.layers:
        args.layers = ["all"]

    if "all" in args.layers:
        args.layers = layers.keys()

    try:
        logger.debug("Loading board file %s" % args.pcbfile)
        pcb = LoadBoard(args.pcbfile)
        logger.debug("Successfully loaded board file.")
    except IOError:
        logger.error("Unable to load board file %s" % args.pcbfile)
        sys.exit(1)





    pctl = PLOT_CONTROLLER(pcb)

    popt = pctl.AccessPlotOpts()

    for format in args.format:
        if format == "gerber":
            popt.SetUseGerberExtensions(True)
            popt.SetSubtractMaskFromSilk(args.subtract_soldermask_from_silk)
            popt.SetUseAuxOrigin(args.use_auxiliary_axis_as_origin)

        popt.SetPlotPadsOnSilkLayer("pads" in args.plot_in_silk)
        popt.SetPlotValue("module-value" in args.plot_in_silk)
        popt.SetPlotReference("module-reference" in args.plot_in_silk)
        popt.SetPlotOtherText("other-module-texts" in args.plot_in_silk)
        popt.SetPlotInvisibleText("invisible-texts" in args.plot_in_silk)

        popt.SetExcludeEdgeLayer(args.exclude_edge_from_other_layers)
        popt.SetPlotFrameRef(args.plot_sheet_reference)
        #popt.SetOutputDirectory(args.output_dir) 

        # Anyway, remember that paper size it taken from the board and for all
        # plot purposes DXF and Gerber files have no paper size (so no
        # autoscaling for them). On the other hand DXF and Gerber *can* use the
        # auxiliary axis as origin.
        popt.SetLineWidth(FromMM(0.35))
        
        # PLEASE NOTE this is mostly equivalent to the default plot dialog loop!
        for layer_name in args.layers:
            layer_symbol, sheet_desc = layers[layer_name]
            if popt.GetUseGerberExtensions():
                pctl.OpenPlotfile(layer_name.replace(".", "_"),
                    PLOT_FORMAT_GERBER,
                    sheet_desc,
                    GetGerberExtension(layer_symbol))
            else:
                pctl.OpenPlotfile(layer_name.replace(".", "_"),
                    PLOT_FORMAT_GERBER,
                    sheet_desc)
            pctl.PlotLayer(layer_symbol)

if __name__ == "__main__":
    main()
