void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
                                            bool aGenDrill, bool aGenMap,
                                            REPORTER * aReporter )
{
    wxFileName  fn;
    wxString    msg;

    std::vector<LAYER_PAIR> hole_sets = getUniqueLayerPairs();

    // append a pair representing the NPTH set of holes, for separate drill files.
    if( !m_merge_PTH_NPTH )
        hole_sets.push_back( LAYER_PAIR( F_Cu, B_Cu ) );

    for( std::vector<LAYER_PAIR>::const_iterator it = hole_sets.begin();
            it != hole_sets.end();  ++it )
    {
        LAYER_PAIR  pair = *it;
        // For separate drill files, the last layer pair is the NPTH dril file.
        bool doing_npth = m_merge_PTH_NPTH ? false : ( it == hole_sets.end() - 1 );

        BuildHolesList( pair, doing_npth );

        // The file is created if it has holes, or if it is the non plated drill file
        // to be sure the NPTH file is up to date in separate files mode.
        if( GetHolesCount() > 0 || doing_npth )
        {
            fn = drillFileName( pair, doing_npth );
            fn.SetPath( aPlotDirectory );

            if( aGenDrill )
            {
                wxString fullFilename = fn.GetFullPath();

                FILE* file = wxFopen( fullFilename, wxT( "w" ) );

                if( file == NULL )
                {
                    if( aReporter )
                    {
                        msg.Printf(  _( "** Unable to create %s **\n" ),
                                          GetChars( fullFilename ) );
                        aReporter->Report( msg );
                    }
                    break;
                }
                else
                {
                    if( aReporter )
                    {
                        msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
                        aReporter->Report( msg );
                    }
                }

                CreateDrillFile( file );
            }

            if( aGenMap )
            {
                fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
                wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
                fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt );

                bool success = GenDrillMapFile( fullfilename, m_mapFileFmt );

                if( ! success )
                {
                    if( aReporter )
                    {
                        msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) );
                        aReporter->Report( msg );
                    }

                    return;
                }
                else
                {
                    if( aReporter )
                    {
                        msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) );
                        aReporter->Report( msg );
                    }
                }
            }
        }
    }
}
void EXCELLON_WRITER::CreateDrillandMapFilesSet(  const wxString& aPlotDirectory,
                                            bool aGenDrill, bool aGenMap,
                                            REPORTER * aReporter )
{
    wxFileName fn;
    wxString msg;

    wxString    layername_extend;   // added to the board filefame to create a full filename
                                    //(board fileName + layer pair names)

    // If some buried/blind vias are found, drill files are created
    // layer pair by layer pair for buried vias
    bool hasBuriedVias = false;

    for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
    {
        if( track->Type() == PCB_VIA_T )
        {
            const VIA *via = static_cast<const VIA*>( track );

            if( via->GetViaType() == VIA_MICROVIA ||
                via->GetViaType() == VIA_BLIND_BURIED )
            {
                hasBuriedVias = true;
                break;
            }
        }
    }


    int        layer1 = F_Cu;
    int        layer2 = B_Cu;
    bool       gen_through_holes = true;
    bool       gen_NPTH_holes    = false;

    for( ; ; )
    {
        BuildHolesList( layer1, layer2, gen_through_holes ? false : true,
                                       gen_NPTH_holes, m_merge_PTH_NPTH );

        if( GetHolesCount() > 0 ) // has holes?
        {
            fn = m_pcb->GetFileName();
            layername_extend.Empty();

            if( gen_NPTH_holes )
            {
                layername_extend << wxT( "-NPTH" );
            }
            else if( !gen_through_holes )
            {
                if( layer1 == F_Cu )
                    layername_extend << wxT( "-front" );
                else
                    layername_extend << wxT( "-inner" ) << layer1;

                if( layer2 == B_Cu )
                    layername_extend << wxT( "-back" );
                else
                    layername_extend << wxT( "-inner" ) << layer2;
            }

            fn.SetName( fn.GetName() + layername_extend );

            fn.SetPath( aPlotDirectory );

            if( aGenDrill )
            {
                fn.SetExt( DrillFileExtension );
                wxString fullFilename = fn.GetFullPath();

                FILE* file = wxFopen( fullFilename, wxT( "w" ) );

                if( file == NULL )
                {
                    if( aReporter )
                    {
                        msg.Printf(  _( "** Unable to create %s **\n" ),
                                          GetChars( fullFilename ) );
                        aReporter->Report( msg );
                    }
                    break;
                }
                else
                {
                    if( aReporter )
                    {
                        msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
                        aReporter->Report( msg );
                    }
                }

                CreateDrillFile( file );
            }

            if( aGenMap )
            {
                fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
                wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
                fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt );

                bool success = GenDrillMapFile( fullfilename, m_mapFileFmt );

                if( ! success )
                {
                    if( aReporter )
                    {
                        msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) );
                        aReporter->Report( msg );
                    }

                    return;
                }
                else
                {
                    if( aReporter )
                    {
                        msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) );
                        aReporter->Report( msg );
                    }
                }
            }
        }

        if( gen_NPTH_holes )    // The last drill file was created
            break;

        if( !hasBuriedVias )
            gen_NPTH_holes = true;
        else
        {
            if( gen_through_holes )
                layer2 = layer1 + 1;    // done with through-board holes, prepare generation of first layer pair
            else
            {
                if( layer2 >= B_Cu )    // no more layer pair to consider
                {
                    layer1 = F_Cu;
                    layer2 = B_Cu;
                    gen_NPTH_holes = true;
                    continue;
                }

                layer1++;
                layer2++;                      // use next layer pair

                if( layer2 == m_pcb->GetCopperLayerCount() - 1 )
                    layer2 = B_Cu;      // the last layer is always the back layer
            }

            gen_through_holes = false;
        }
    }
}