/**
 * In a contiguous list of wires, remove wires that backtrack over the previous
 * wire. Example:
 *
 * Wire is added:
 * ---------------------------------------->
 *
 * A second wire backtracks over it:
 * -------------------<====================>
 *
 * RemoveBacktracks is called:
 * ------------------->
 */
static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires )
{
    SCH_LINE* last_line = NULL;

    EDA_ITEM* first = aWires.GetFirst();
    for( EDA_ITEM* p = first; p; )
    {
        SCH_LINE *line = dynamic_cast<SCH_LINE*>( p );
        if( !line )
        {
            wxFAIL_MSG( "RemoveBacktracks() requires SCH_LINE items" );
            break;
        }
        p = line->Next();

        if( last_line )
        {
            wxASSERT_MSG( last_line->GetEndPoint() == line->GetStartPoint(),
                    "RemoveBacktracks() requires contiguous lines" );
            if( IsPointOnSegment( last_line->GetStartPoint(), line->GetStartPoint(),
                        line->GetEndPoint() ) )
            {
                last_line->SetEndPoint( line->GetEndPoint() );
                delete s_wires.Remove( line );
            }
            else
                last_line = line;
        }
        else
            last_line = line;
    }
}
bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint )
{
    SCH_LINE* segment;
    SCH_LINE* newSegment;
    bool brokenSegments = false;

    for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
    {
        if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) )
            continue;

        segment = (SCH_LINE*) item;

        if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) )
            continue;

        // Break the segment at aPoint and create a new segment.
        newSegment = new SCH_LINE( *segment );
        newSegment->SetStartPoint( aPoint );
        segment->SetEndPoint( aPoint );
        m_drawList.Insert( newSegment, segment->Next() );
        item = newSegment;
        brokenSegments = true;
    }

    return brokenSegments;
}
/**
 * Mouse capture callback for drawing line segments.
 */
static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
                         bool aErase )
{
    SCH_LINE* segment;

    if( s_wires.GetCount() == 0 )
        return;

    segment = (SCH_LINE*) s_wires.begin();
    EDA_COLOR_T color = GetLayerColor( segment->GetLayer() );
    ColorChangeHighlightFlag( &color, !(color & HIGHLIGHT_FLAG) );

    if( aErase )
    {
        while( segment )
        {
            if( !segment->IsNull() )  // Redraw if segment length != 0
                segment->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, color );

            segment = segment->Next();
        }
    }

    SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) aPanel->GetParent();

    wxPoint endpos = frame->GetCrossHairPosition();

    if( frame->GetForceHVLines() ) /* Coerce the line to vertical or horizontal one: */
        ComputeBreakPoint( (SCH_LINE*) s_wires.GetLast()->Back(), endpos );
    else
        ( (SCH_LINE*) s_wires.GetLast() )->SetEndPoint( endpos );

    segment = (SCH_LINE*) s_wires.begin();

    while( segment )
    {
        if( !segment->IsNull() )  // Redraw if segment length != 0
            segment->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, color );

        segment = segment->Next();
    }
}
/**
 * In a contiguous list of wires, remove wires that backtrack over the previous
 * wire. Example:
 *
 * Wire is added:
 * ---------------------------------------->
 *
 * A second wire backtracks over it:
 * -------------------<====================>
 *
 * RemoveBacktracks is called:
 * ------------------->
 */
static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires )
{
    EDA_ITEM* first = aWires.GetFirst();
    std::vector<SCH_LINE*> last_lines;

    for( EDA_ITEM* p = first; p; )
    {
        SCH_LINE *line = static_cast<SCH_LINE*>( p );
        p = line->Next();

        if( !last_lines.empty() )
        {
            SCH_LINE* last_line = last_lines[last_lines.size() - 1];
            bool contiguous = ( last_line->GetEndPoint() == line->GetStartPoint() );
            bool backtracks = IsPointOnSegment( last_line->GetStartPoint(),
                    last_line->GetEndPoint(), line->GetEndPoint() );
            bool total_backtrack = ( last_line->GetStartPoint() == line->GetEndPoint() );

            if( contiguous && backtracks )
            {
                if( total_backtrack )
                {
                    delete s_wires.Remove( last_line );
                    delete s_wires.Remove( line );
                    last_lines.pop_back();
                }
                else
                {
                    last_line->SetEndPoint( line->GetEndPoint() );
                    delete s_wires.Remove( line );
                }
            }
            else
            {
                last_lines.push_back( line );
            }
        }
        else
        {
            last_lines.push_back( line );
        }
    }
}