bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
{
    BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();

    const int layerCount = bds.GetCopperLayerCount();
    int currentLayer = m_router->GetCurrentLayer();

    PNS_SIZES_SETTINGS sizes = m_router->Sizes();

    // fixme: P&S supports more than one fixed layer pair. Update the dialog?
    sizes.ClearLayerPairs();
    sizes.AddLayerPair( m_frame->GetScreen()->m_Route_Layer_TOP,
                        m_frame->GetScreen()->m_Route_Layer_BOTTOM );

    if( !m_router->IsPlacingVia() )
    {
        // Cannot place microvias or blind vias if not allowed (obvious)
        if( ( aType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
            return false;

        if( ( aType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
            return false;

        //Can only place through vias on 2-layer boards
        if( ( aType != VIA_THROUGH ) && ( layerCount <= 2 ) )
            return false;

        //Can only place microvias if we're on an outer layer, or directly adjacent to one
        if( ( aType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount-2 ) )
            return false;

        //Cannot place blind vias with front/back as the layer pair, this doesn't make sense
        if( ( aType == VIA_BLIND_BURIED ) && ( sizes.GetLayerTop() == F_Cu ) && ( sizes.GetLayerBottom() == B_Cu ) )
            return false;
    }

    sizes.SetViaType( aType );
    if( VIA_MICROVIA == aType )
    {
        sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
        sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );
    }

    m_router->UpdateSizes( sizes );
    m_router->ToggleViaPlacement();

    m_router->Move( m_endSnapPoint, m_endItem );        // refresh

    return false;
}
bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType )
{
    BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();

    const int layerCount = bds.GetCopperLayerCount();
    int currentLayer = m_router->GetCurrentLayer();
    LAYER_ID pairTop = m_frame->GetScreen()->m_Route_Layer_TOP;
    LAYER_ID pairBottom = m_frame->GetScreen()->m_Route_Layer_BOTTOM;

    PNS_SIZES_SETTINGS sizes = m_router->Sizes();

    // fixme: P&S supports more than one fixed layer pair. Update the dialog?
    sizes.ClearLayerPairs();

    if( !m_router->IsPlacingVia() )
    {
        // Cannot place microvias or blind vias if not allowed (obvious)
        if( ( aType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
        {
            DisplayError( m_frame, _( "Blind/buried vias have to be enabled in the design settings." ) );
            return false;
        }

        if( ( aType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
        {
            DisplayError( m_frame, _( "Microvias have to be enabled in the design settings." ) );
            return false;
        }

        // Can only place through vias on 2-layer boards
        if( ( aType != VIA_THROUGH ) && ( layerCount <= 2 ) )
        {
            DisplayError( m_frame, _( "Only through vias are allowed on 2 layer boards." ) );
            return false;
        }

        // Can only place microvias if we're on an outer layer, or directly adjacent to one
        if( ( aType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) )
        {
            DisplayError( m_frame, _( "Microvias can be placed only between the outer layers " \
                                      "(F.Cu/B.Cu) and the ones directly adjacent to them." ) );
            return false;
        }
    }

    // Convert blind/buried via to a through hole one, if it goes through all layers
    if( aType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) )
                                    && ( ( pairTop == B_Cu && pairBottom == F_Cu )
                                      || ( pairTop == F_Cu && pairBottom == B_Cu ) ) )
    {
        aType = VIA_THROUGH;
    }

    switch( aType )
    {
    case VIA_THROUGH:
        sizes.SetViaDiameter( bds.GetCurrentViaSize() );
        sizes.SetViaDrill( bds.GetCurrentViaDrill() );
        sizes.AddLayerPair( pairTop, pairBottom );
        break;

    case VIA_MICROVIA:
        sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
        sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );

        if( currentLayer == F_Cu || currentLayer == In1_Cu )
            sizes.AddLayerPair( F_Cu, In1_Cu );
        else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
            sizes.AddLayerPair( B_Cu, layerCount - 2 );
        else
            wxASSERT( false );
        break;

    case VIA_BLIND_BURIED:
        sizes.SetViaDiameter( bds.GetCurrentViaSize() );
        sizes.SetViaDrill( bds.GetCurrentViaDrill() );

        if( currentLayer == pairTop || currentLayer == pairBottom )
            sizes.AddLayerPair( pairTop, pairBottom );
        else
            sizes.AddLayerPair( pairTop, currentLayer );
        break;

    default:
        wxASSERT( false );
        break;
    }

    sizes.SetViaType( aType );

    m_router->UpdateSizes( sizes );
    m_router->ToggleViaPlacement();

    updateEndItem( aEvent );

    m_router->Move( m_endSnapPoint, m_endItem );        // refresh

    return false;
}