/*****************************************************************/
/* Routines de tracage des pistes ( Toutes, 1 piste, 1 segment ) */
/*****************************************************************/

#include "fctsys.h"
#include "gr_basic.h"

#include "common.h"
#include "pcbnew.h"
#include "trigo.h"

#include "protos.h"

/* variables locales : */

/*********************************************************************************/
void Trace_Pistes( WinEDA_DrawPanel* panel, BOARD* Pcb, wxDC* DC, int drawmode )
/********************************************************************************/

/* Draw all tracks and zones.  As long as dark colors are used for the tracks,
 * Then the OR draw mode should show tracks underneath other tracks.  But a white
 * track will cover any other color since it has more bits to OR in.
 */
{
    for( TRACK* track = Pcb->m_Track;  track;   track = track->Next() )
    {
        track->Draw( panel, DC, drawmode );
    }

    for( SEGZONE* zone = Pcb->m_Zone;  zone;   zone = zone->Next() )
    {
        zone->Draw( panel, DC, drawmode );
    }
}


/************************************************************************/
void Trace_Une_Piste( WinEDA_DrawPanel* panel, wxDC* DC, TRACK* Track,
                      int nbsegment, int draw_mode )
/************************************************************************/

/* routine de trace de n segments consecutifs en memoire.
 *  Utile pour monter une piste en cours de trace car les segments de cette
 *  piste sont alors contigus en memoire
 *  Parametres :
 *  pt_start_piste = adresse de depart de la liste des segments
 *  nbsegment = nombre de segments a tracer
 *  draw_mode = mode ( GR_XOR, GR_OR..)
 *  ATTENTION:
 *  le point de depart d'une piste suivante DOIT exister: peut etre
 *  donc mis a 0 avant appel a la routine si la piste a tracer est la derniere
 */
{
    for(  ;   nbsegment > 0  && Track;   nbsegment--, Track = Track->Next() )
    {
        Track->Draw( panel, DC, draw_mode );
    }
}


/*************************************************************/
void Trace_DrawSegmentPcb( WinEDA_DrawPanel* panel, wxDC* DC,
                           DRAWSEGMENT* PtDrawSegment, int draw_mode )
/*************************************************************/

/* Affichage d'un segment type drawing PCB:
 *  draw_mode = mode de trace ( GR_OR, GR_XOR, GrAND)
 *      Les contours sont de differents type:
 *      segment
 *      cercle
 *      arc
 */
{
    int ux0, uy0, dx, dy;
    int l_piste;
    int color, mode;
    int zoom;
    int rayon;

    color = g_DesignSettings.m_LayerColor[PtDrawSegment->GetLayer()];
    if( color & ITEM_NOT_SHOW )
        return;

    if( panel )
        zoom = panel->GetZoom();
    else
        zoom = ActiveScreen->GetZoom();

    GRSetDrawMode( DC, draw_mode );
    l_piste = PtDrawSegment->m_Width >> 1;  /* l_piste = demi largeur piste */

    /* coord de depart */
    ux0 = PtDrawSegment->m_Start.x;
    uy0 = PtDrawSegment->m_Start.y;
    
    /* coord d'arrivee */
    dx = PtDrawSegment->m_End.x;
    dy = PtDrawSegment->m_End.y;

    mode = DisplayOpt.DisplayDrawItems;
    if( PtDrawSegment->m_Flags & FORCE_SKETCH )
        mode = SKETCH;
    if( l_piste < (L_MIN_DESSIN * zoom) )
        mode = FILAIRE;

    switch( PtDrawSegment->m_Shape )
    {
    case S_CIRCLE:
        rayon = (int) hypot( (double) (dx - ux0), (double) (dy - uy0) );
        if( mode == FILAIRE )
        {
            GRCircle( &panel->m_ClipBox, DC, ux0, uy0, rayon, color );
        }
        else if( mode == SKETCH )
        {
            GRCircle( &panel->m_ClipBox, DC, ux0, uy0, rayon - l_piste, color );
            GRCircle( &panel->m_ClipBox, DC, ux0, uy0, rayon + l_piste, color );
        }
        else
        {
            GRCircle( &panel->m_ClipBox, DC, ux0, uy0, rayon, PtDrawSegment->m_Width, color );
        }
        break;

    case S_ARC:
    {
        int StAngle, EndAngle;
        rayon    = (int) hypot( (double) (dx - ux0), (double) (dy - uy0) );
        StAngle  = (int) ArcTangente( dy - uy0, dx - ux0 );
        EndAngle = StAngle + PtDrawSegment->m_Angle;
        if( StAngle > EndAngle )
            EXCHG( StAngle, EndAngle );
        if( mode == FILAIRE )
            GRArc( &panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon, color );
        else if( mode == SKETCH )
        {
            GRArc( &panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
                   rayon - l_piste, color );
            GRArc( &panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
                   rayon + l_piste, color );
        }
        else
        {
            GRArc( &panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
                   rayon, PtDrawSegment->m_Width, color );
        }
    }
        break;

    default:
        if( mode == FILAIRE )
            GRLine( &panel->m_ClipBox, DC, ux0, uy0, dx, dy, 0, color );
        else if( mode == SKETCH )
        {
            GRCSegm( &panel->m_ClipBox, DC, ux0, uy0, dx, dy,
                     PtDrawSegment->m_Width, color );
        }
        else
        {
            GRFillCSegm( &panel->m_ClipBox, DC, ux0, uy0, dx, dy,
                         PtDrawSegment->m_Width, color );
        }
        break;
    }
}