/*
 * Test all connections of the board,
 * and update subnet variable of pads and tracks
 * TestForActiveLinksInRatsnest must be called after this function
 * to update active/inactive ratsnest items status
 */
void PCB_BASE_FRAME::TestConnections()
{
    // Clear the cluster identifier for all pads
    for( unsigned i = 0;  i< m_Pcb->GetPadCount();  ++i )
    {
        D_PAD* pad = m_Pcb->GetPad(i);

        pad->SetZoneSubNet( 0 );
        pad->SetSubNet( 0 );
    }

    m_Pcb->Test_Connections_To_Copper_Areas();

    // Test existing connections net by net
    // note some nets can have no tracks, and pads intersecting
    // so Build_CurrNet_SubNets_Connections must be called for each net
    CONNECTIONS connections( m_Pcb );

    int last_net_tested = 0;
    int current_net_code = 0;

    for( TRACK* track = m_Pcb->m_Track; track; )
    {
        // At this point, track is the first track of a given net
        current_net_code = track->GetNetCode();

        // Get last track of the current net
        TRACK* lastTrack = track->GetEndNetCode( current_net_code );

        if( current_net_code > 0 )  // do not spend time if net code = 0 ( dummy net )
        {
            // Test all previous nets having no tracks
            for( int net = last_net_tested+1; net < current_net_code; net++ )
                connections.Build_CurrNet_SubNets_Connections( NULL, NULL, net );

            connections.Build_CurrNet_SubNets_Connections( track, lastTrack, current_net_code );
            last_net_tested = current_net_code;
        }

        track = lastTrack->Next();    // this is now the first track of the next net
    }

    // Test last nets without tracks, if any
    int netsCount = m_Pcb->GetNetCount();
    for( int net = last_net_tested+1; net < netsCount; net++ )
        connections.Build_CurrNet_SubNets_Connections( NULL, NULL, net );

    Merge_SubNets_Connected_By_CopperAreas( m_Pcb );

    return;
}
void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
{
    wxString msg;

    if( aNetCode <= 0 ) // -1 = not existing net, 0 = dummy net
        return;

    if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
        Compile_Ratsnest( aDC, true );

    // Clear the cluster identifier (subnet) of pads for this net
    for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i )
    {
        D_PAD* pad = m_Pcb->GetPad(i);
        int    pad_net_code = pad->GetNetCode();

        if( pad_net_code < aNetCode )
            continue;

        if( pad_net_code > aNetCode )
            break;

        pad->SetSubNet( 0 );
    }

    m_Pcb->Test_Connections_To_Copper_Areas( aNetCode );

    // Search for the first and the last segment relative to the given net code
    if( m_Pcb->m_Track )
    {
        CONNECTIONS connections( m_Pcb );

        TRACK* firstTrack;
        TRACK* lastTrack = NULL;
        firstTrack = m_Pcb->m_Track.GetFirst()->GetStartNetCode( aNetCode );

        if( firstTrack )
            lastTrack = firstTrack->GetEndNetCode( aNetCode );

        if( firstTrack && lastTrack ) // i.e. if there are segments
        {
            connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, firstTrack->GetNetCode() );
        }
    }

    Merge_SubNets_Connected_By_CopperAreas( m_Pcb, aNetCode );

    // rebuild the active ratsnest for this net
    DrawGeneralRatsnest( aDC, aNetCode );
    TestForActiveLinksInRatsnest( aNetCode );
    DrawGeneralRatsnest( aDC, aNetCode );

    // Display results
    int net_notconnected_count = 0;
    NETINFO_ITEM* net = m_Pcb->FindNet( aNetCode );

    if( net )       // Should not occur, but ...
    {
        for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ )
        {
            if( m_Pcb->m_FullRatsnest[ii].IsActive() )
                net_notconnected_count++;
        }

        msg.Printf( wxT( "links %d nc %d  net:nc %d" ),
                    m_Pcb->GetRatsnestsCount(), m_Pcb->GetUnconnectedNetCount(),
                    net_notconnected_count );
    }
    else
        msg.Printf( wxT( "net not found: netcode %d" ),aNetCode );

    SetStatusText( msg );
    return;
}