Subversion Repositories svn1-original

Rev

Rev 46 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*************************************************************************
*           Copyright (C) 1995 Embedded Solutions
*                       All rights reserved
*
* file:     src\legtime.c
*
* purpose:  Leg time calculations
*
* functions
*   set_legs                    - Menu: Setup leg times
*   tm_lgs                      - Set up the leg start times for leg
*   leg_start                   - Set up the leg start times
*   tm_fixedstart               - Set the start time for a specific leg
*   tm_staggered                - Set a staggered start time for a specific leg
*   tm_clearleg                 - Clear start times on a specific leg
*   leg_ini                     - Initialize all stored times
*   tm_init                     - Initialize all team data
*   tm_gen                      - Generate dummy team names
*   legs_start_report           - Generate starters report
*   ls_timer                    - print the current leg entry
*   ls_team                     - print next ( numeric ) leg entry
*   sort_legs                   - Qsort callback function
*
* programmer: David Purdie
*
* revision  date        by      reason
*           11-Oct-89   DDP     leg-3 starttime. Now has an option to generate
*                               a printed report of teams and times
*
*           21-May-90   MV      now able to set start time and generate
*                               a printed report for any leg
*   00.0    27/01/95    DDP     Tidies up the program and formatted the file
*
**************************************************************************/

#include    "consts.h"
#include    "structs.h"
#include    "proto.h"

#if defined(HI_TECH_C) || defined(__TURBOC__)
#include    <alloc.h>
#endif

menu_table  leg_menu[] = {
    { '1', "Set start time from category", leg_start },
    { '2', "Clear all leg times", leg_ini },
    { '3', "Reset team information", tm_init },
    { '4', "Generate dummy team names", tm_gen },
    { '5', "Set calculated leg start", tm_lgs },
    { '6', "Set ordered incremental leg start", tm_lgs1 },
    { '7', "Set staggered start time", tm_staggered },
    { '8', "Set fixed start time", tm_fixedstart },
    { '9', "Clear single leg start times", tm_clearleg },
    { 'q', "Return to main menu", 0 },
    { '\0' }
};

/*========================================================================
 *
 *  Menu: Setup leg times
 *
 *  Purpose:
 *      This function is called to produce the menu that will
 *      setup leg times
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void set_legs(void)
{
    do_menu( "Leg time setup", "Select option", leg_menu );
}

/*========================================================================
 *
 *  Set up the leg start times for leg
 *
 *  Purpose:
 *      This function is called to Set up the leg start times for leg
 *      The start time is based on category information
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_lgs1(void)
{
    time_t      delta;                           /* The time delta */
    time_t      starttime;
    int         report_it = FALSE;               /* Report the operation */
    int         clear_it = FALSE;

    t_legs     *data;                            /* Address of table */
    t_legs     *dptr;                            /* Moving pointer */
    int         num_records;                     /* Number of records in array */
    int         i;

    cur( 0, 5 );
    while( TRUE )
    {
        leg = 0;
        d_field( 0, 5, "Enter leg to set start time :", D_NUMBER, 1,
                 ( char * ) &leg, TRUE, M_UPDATE );
        if( leg == 0 )
            return;                              /* Null leg - just exit */
        if( leg <= config.num_legs )             /* Valid leg number - Exit loop */
            break;
        beep();                                  /* Make a noise and wait for valid number */
    }

    cur( 0, 5 );
    printf ( "Setting start times for all valid teams from %-d to %-d for leg %d\n",
                config.min_team, config.max_team, leg );

    starttime = 0;
    do
    {
        d_time( 0, 6, "Enter the start time : ", &starttime, TRUE );
        if( abort_flag )
            return;

        if( starttime < 0 )
            beep();

    } while( starttime < 0 );

    delta = 0;
    do
    {
        d_time( 0, 7, "Enter the delta time : ", &delta, TRUE );
        if( abort_flag )
            return;

        if( delta < 0 )
            beep();

    } while( delta < 0 );


    report_it = getyes( "\nGenerate leg start report" );
    if( abort_flag )
        return;

    clear_it = getyes("Invalidate the leg start times" );
    if( abort_flag )
        return;

    /*
    **  Read existing data into memory
    */
    data = ( t_legs * ) calloc( ( unsigned ) ( config.max_team - config.min_team + 2 ), sizeof( t_legs ) ); /* Fetch memory */
    if( !data )
    {
        printf( "\nNo memory for report\n" );
        return;
    }

    /*
     * Extract the required data from the data base
     * Only save that information required for the operation
     *      - The end time of the previous leg
     */
    dptr = data;
    num_records = 0;
    for( i = config.min_team; i <= config.max_team; i++ )
    {
        if( valid_field( i ) && g_record( i, &team_buf ) )
        {
            dptr->numb = team_buf.numb;
            dptr->start = team_buf.leg[leg-1].end;
            dptr->flags = team_buf.flags;
            dptr++;
            num_records++;
        }
    }

    /*
     * Sort the data into some logical order 
     */
    qsort( ( char * ) data, num_records, sizeof( t_legs ), sort_legs );

    /*
    **  Update the team information based on the start order
    **  Ignore validity flags as the data will have been sorted with
    **  these in mind.
    */
    for( dptr = data, i = 0; i < num_records; i++, dptr++ )
    {
        if( valid_field( dptr->numb ) )
        {
            g_record( dptr->numb, &team_buf );
            team_buf.leg[leg].start = starttime;
            starttime += delta;
            team_buf.leg[leg].manual = TRUE;

            set_times( &team_buf );
            test_times( &team_buf, 0 );
            put_team_record( dptr->numb, &team_buf );
        }

        if( i % 10 == 0 )
        {
            cur( 0, 8 );
            printf( "Upto entry %d", i );
            flush_out();
        }
    }

    /*
    **  Release the data
    */
    free( data );

    if( report_it )
        legs_start_report(9);

    if ( clear_it )
        tm_clearleg_specified( leg, TRUE, 10 );
}

/*========================================================================
 *
 *  Set up the leg start times for leg
 *
 *  Purpose:
 *      This function is called to Set up the leg start times for leg
 *      The start time is based on current placing with:
 *          A constant offset added ( ie: lunch)
 *          A fixed increment
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_lgs(void)
{
    time_t      delta;                           /* The time delta */
    int         report_it = FALSE;               /* Report the operation */
    int         clear_it = FALSE;
    int         line = 5;                        /* Current line */

    cur( 0, line );
    while( TRUE )
    {
        leg = 0;
        d_field( 0, line, "Enter leg to set start time :", D_NUMBER, 1,
                 ( char * ) &leg, TRUE, M_UPDATE );
        if( leg == 0 )
            return;                              /* Null leg - just exit */
        if( leg <= config.num_legs )             /* Valid leg number - Exit loop */
            break;
        beep();                                  /* Make a noise and wait for valid number */
    }


    cur( 0, ++line );
    printf ( "Setting start times for all valid teams from %-d to %-d for leg %d\n",
                config.min_team, config.max_team, leg );
    delta = 0;
    line++;
    do
    {
        d_time( 0, line, "Enter the time difference : ", &delta, TRUE );

        if( abort_flag )
            return;

        if( delta < 0 )
            beep();

    } while( delta < 0 );

    line++;
    report_it = getyes( "\nGenerate leg start report" );
    if( abort_flag )
        return;

    line++;
    clear_it = getyes("Invalidate the leg start times" );
    if( abort_flag )
        return;

    line++;
    team = config.min_team;                      /* Team we are working with */
    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            g_record( team, &team_buf );
            if( team_buf.flags.valid && team_buf.leg[leg - 1].end > 0 )
            {
                team_buf.leg[leg].start = team_buf.leg[leg - 1].end + delta;
                team_buf.leg[leg].manual = TRUE;
            }
            else
                team_buf.leg[leg].start = ( time_t ) - 1;

            set_times( &team_buf );
            test_times( &team_buf, 0 );
            put_team_record( team, &team_buf );
        }

        if( team % 10 == 0 )
        {
            cur( 0, line );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }

    if( report_it )
        legs_start_report(++line);

    if ( clear_it )
        tm_clearleg_specified( leg, TRUE, ++line );
}

/*========================================================================
 *
 *  Set up the leg start times
 *
 *  Purpose:
 *      This function is called to Set up the leg start times
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void leg_start(void)
{

    team = config.min_team;                      /* Team we are working with */
    cur( 0, 5 );
    printf( "Setting start times for all valid teams from %-d to %-d \n",
            config.min_team, config.max_team );
    if( !getyes( "Continue operation" ) )
        return;

    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            ( void ) g_record( team, &team_buf );
            if( team_buf.class > 0 && team_buf.class <= config.num_class )
                team_buf.leg[0].start =
                    config.team_class[team_buf.class - 1].start;
            else
                team_buf.leg[0].start = ( time_t ) - 1;
            team_buf.leg[1].manual = 0;
            team_buf.leg[1].start = team_buf.leg[0].start;
            team_buf.leg[0].l_place = 0;
            team_buf.leg[0].le_place = 0;
            team_buf.leg[0].lec_place = 0;
            team_buf.leg[0].lc_place = 0;
            team_buf.leg[0].manual = FALSE;
            set_times( &team_buf );
            test_times( &team_buf, 0 );
            put_team_record( team, &team_buf );
        }
        if( team % 10 == 0 )
        {
            cur( 0, 8 );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
}

/*========================================================================
 *
 *  Set the start time for a specific leg
 *
 *  Purpose:
 *      This function is called to set the start time for a specific
 *      leg to a specified and fixed time
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_fixedstart(void)
{
    time_t      starttime;                       /* The start time */
    int         report_it = FALSE;               /* Report the operation */
    int         clear_it = FALSE;
    int         line = 5;                        /* Current line */
    
    cur( 0, 5 );
    while( TRUE )
    {
        leg = 0;
        d_field( 0, line, "Enter leg to set start time :", D_NUMBER, 1,
                 ( char * ) &leg, TRUE, M_UPDATE );
        if( leg == 0 )
            return;                              /* Null leg - just exit */
        if( leg <= config.num_legs )             /* Valid leg number - Exit loop */
            break;
        beep();                                  /* Make a noise and wait for valid number */
    }
    line++;


    team = config.min_team;                      /* Team we are working with */
    cur( 0, line++ );
    printf
        ( "Setting start times for all valid teams from %-d to %-d for leg %d\n",
          config.min_team, config.max_team, leg );

    starttime = 0;
    do
    {
        d_time( 0, line, "Enter the start time : ", &starttime, TRUE );
        if( abort_flag )
            return;

        if( starttime < 0 )
            beep();

    } while( starttime < 0 );
    
    line++;
    report_it = getyes( "\nGenerate leg start report" );
    if( abort_flag )
        return;

    line++;
    clear_it = getyes("Invalidate the leg start times" );
    if( abort_flag )
        return;
    
    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            g_record( team, &team_buf );
            if( team_buf.flags.valid )
            {
                team_buf.leg[leg].start = starttime;
                team_buf.leg[leg].manual = TRUE;
            }
            else
                team_buf.leg[leg].start = ( time_t ) - 1;

            set_times( &team_buf );
            test_times( &team_buf, 0 );
            put_team_record( team, &team_buf );
        }

        if( team % 10 == 0 )
        {
            cur( 0, 8 );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
    
    if( report_it )
        legs_start_report(++line);

    if ( clear_it )
        tm_clearleg_specified( leg, TRUE, ++line );
}

/*========================================================================
 *
 *  Set a staggered start time for a specific leg
 *
 *  Purpose:
 *      This function is called to set the start time for a specific
 *      leg to a specified and a staggered time
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_staggered(void)
{
    time_t      starttime;                       /* The start time */
    time_t      delta;                           /* The stagger */
    int         report_it = FALSE;               /* Report the operation */
    int         clear_it = FALSE;
    int         line = 5;                        /* Current line */
    
    cur( 0, line );
    while( TRUE )
    {
        leg = 0;
        d_field( 0, 5, "Enter leg to set start time :", D_NUMBER, 1,
                 ( char * ) &leg, TRUE, M_UPDATE );
        if( leg == 0 )
            return;                              /* Null leg - just exit */
        if( leg <= config.num_legs )             /* Valid leg number - Exit loop */
            break;
        beep();                                  /* Make a noise and wait for valid number */
    }
    line++;


    team = config.min_team;                      /* Team we are working with */
    cur( 0, line++ );
    printf
        ( "Setting staggered start times for all valid teams from %-d to %-d for leg %d\n",
          config.min_team, config.max_team, leg );

    starttime = 0;
    do
    {
        d_time( 0, line, "Enter the start time : ", &starttime, TRUE );
        if( abort_flag )
            return;

        if( starttime < 0 )
            beep();

    } while( starttime < 0 );
    line++;

    delta = 0;
    do
    {
        d_time( 0, line, "Enter the stagger time : ", &delta, TRUE );
        if( abort_flag )
            return;

        if( delta < 0 )
            beep();

    } while( delta < 0 );

    line++;
    report_it = getyes( "\nGenerate leg start report" );
    if( abort_flag )
        return;

    line++;
    clear_it = getyes("Invalidate the leg start times" );
    if( abort_flag )
        return;

    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            g_record( team, &team_buf );
            if( team_buf.flags.valid )
            {
                team_buf.leg[leg].start = starttime;
                starttime += delta;
                team_buf.leg[leg].manual = TRUE;
            }
            else
                team_buf.leg[leg].start = ( time_t ) - 1;

            set_times( &team_buf );
            test_times( &team_buf, 0 );
            put_team_record( team, &team_buf );
        }

        if( team % 10 == 0 )
        {
            cur( 0, 9 );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
    
    if( report_it )
        legs_start_report(++line);

    if ( clear_it )
        tm_clearleg_specified( leg, TRUE,  ++line );
}

/*========================================================================
 *
 *  Clear start times on a specific leg
 *
 *  Purpose:
 *      This function is called to clear start times on a specifc leg
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_clearleg(void)
{

    cur( 0, 5 );
    while( TRUE )
    {
        leg = 0;
        d_field( 0, 5, "Enter leg to clear start time :", D_NUMBER, 1,
                 ( char * ) &leg, TRUE, M_UPDATE );
        if( leg == 0 )
            return;                              /* Null leg - just exit */
        if( leg <= config.num_legs )             /* Valid leg number - Exit loop */
            break;
        beep();                                /* Make a noise and wait for valid number */
    }


    cur( 0, 5 );
    printf
        ( "Setting start times for all valid teams from %-d to %-d for leg %d\n",
          config.min_team, config.max_team, leg );
    if( !getyes( "Continue operation" ) )
        return;

    tm_clearleg_specified( leg, FALSE, 6 );
}

/*========================================================================
 *
 *  Clear start times on a specific leg
 *
 *  Purpose:
 *      This function is called to clear start times on a specifc leg
 *
 *  Parameters:
 *      cleg                - Leg to clear
 *      manual              - Force manual, else leave alone
 *      line                - Current display line number
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_clearleg_specified(int cleg, bool manual, int line)
{

    /*
    **  Validate the users argument
    */
    if( cleg == 0 )
        return;                              /* Null leg - just exit */
    if( cleg > config.num_legs )             /* Valid leg number - Exit loop */
        return;
    leg = cleg;

    team = config.min_team;                 /* Team we are working with */
    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            g_record( team, &team_buf );
            team_buf.leg[leg].manual = manual;
            team_buf.leg[leg].start = ( time_t ) -1;
            
            set_times( &team_buf );
            test_times( &team_buf, 0 );
            put_team_record( team, &team_buf );
        }
        if( team % 10 == 0 )
        {
            cur( 0, line );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
}


/*========================================================================
 *
 *  Initialize all stored times
 *
 *  Purpose:
 *      This function is called to Initialize all stored times
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void leg_ini(void)
{
    int         i;


    team = config.min_team;                      /* Team we are working with */
    cur( 0, 5 );
    printf( "\nInitializing ALL times for all valid teams from %-d to %-d\n",
            config.min_team, config.max_team );
    if( !getyes( "Continue operation" ) )
        return;

    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            ( void ) g_record( team, &team_buf );
            for( i = 0; i <= MAX_LEGS; i++ )
            {
                team_buf.leg[i].start = team_buf.leg[i].end =
                    team_buf.leg[i].elapsed = ( time_t ) - 1;
                team_buf.leg[i].l_place = 0;
                team_buf.leg[i].le_place = 0;
                team_buf.leg[i].lec_place = 0;
                team_buf.leg[i].lc_place = 0;
                team_buf.leg[i].manual = FALSE;
            }
            if( team_buf.class > 0 && team_buf.class <= config.num_class )
                team_buf.leg[0].start =
                    config.team_class[team_buf.class - 1].start;
            else
                team_buf.leg[0].start = ( time_t ) - 1;

            team_buf.leg[1].start = team_buf.leg[0].start;
            team_buf.flags.disqualified = FALSE;
            team_buf.flags.non_equestrian = FALSE;
            put_team_record( team, &team_buf );
        }
        if( team % 10 == 0 )
        {
            cur( 0, 8 );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
}

/*========================================================================
 *
 *  Initialize all team data
 *
 *  Purpose:
 *      This function is called to Initialize all team data
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/
void tm_init(void)
{

    team = config.min_team;                      /* Team we are working with */
    cur( 0, 5 );
    printf
        ( "\nDelete ALL team information for all valid teams from %-d to %-d\n",
          config.min_team, config.max_team );
    if( !getyes( "Continue operation" ) )
        return;

    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            clr_team( team, &team_buf );
            put_team_record( team, &team_buf );
        }
        if( team % 10 == 0 )
        {
            cur( 0, 8 );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
}

/*========================================================================
 *
 *  Generate dummy team names
 *
 *  Purpose:
 *      This function is called to Generate dummy team names
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void tm_gen(void)
{

    team = config.min_team;                      /* Team we are working with */
    cur( 0, 5 );
    printf( "Generate DUMMY team names for all valid teams from %-d to %-d\n",
            config.min_team, config.max_team );
    if( !getyes( "Continue operation" ) )
        return;

    while( team <= config.max_team )
    {
        if( valid_field( team ) )
        {
            ( void ) g_record( team, &team_buf );
            team_buf.flags.valid = TRUE;
            sprintf( team_buf.name, "Team - %4.4d", team );
            team_buf.class = 1;                  /* Set default class */
            put_team_record( team, &team_buf );
        }
        if( team % 10 == 0 )
        {
            cur( 0, 8 );
            printf( "Upto team %d", team );
            flush_out();
        }
        team++;
    }
}


/*========================================================================
 *
 *  Generate starters report
 *
 *  Purpose:
 *      This routine is used to generate a list of leg start times
 *      This system can cope with a break at the start of leg
 *
 *  Parameters:
 *      None
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void legs_start_report(int line)
{
    int         i;
    t_legs     *data;                            /* Address of table */
    t_legs     *dptr;                            /* Moving pointer */
    int         last_team;
    int         num_records = 0;                 /* Number of records in array */
    char        l_s[40];                         /* Name of start time file */

    cur( 0, line );
    printf( "Generating Starters report for Leg-%d", leg );

    data = ( t_legs * ) calloc( ( unsigned ) ( config.max_team - config.min_team + 2 ), sizeof( t_legs ) ); /* Fetch memory */

    if( !data )
    {
        printf( "\nNo memory for report\n" );
        return;
    }

    /*
     * Extract the required data from the data base
     * Only save that information required for the operation
     */

    dptr = data;
    for( i = config.min_team; i <= config.max_team; i++ )   /* Print team order data */
    {
        if( valid_field( i ) && g_record( i, &team_buf ) )
        {
            dptr->numb = team_buf.numb;
            dptr->start = team_buf.leg[leg].start;
            dptr->flags = team_buf.flags;
            dptr++;
            num_records++;
        }
    }


    /*
     * Sort the data into some logical order 
     */
    qsort( ( char * ) data, num_records, sizeof( t_legs ), sort_legs );

    /*
    **  Now print the data on the printer
    **      - Generte the name of the printer file
    **      - Open the printer
    */

    sprintf( l_s, "l_%d", leg );
    if( !open_printer( "", l_s, 80, FALSE, "Starters Report" ) )
        return;

    /*
     * Print out the header for the file 
     */
    print( "\nStarters report for leg:%d %-*s\n", leg, 18, config.leg_name[leg - 1] );
    print( "Team order listing\n\n" );

    print_underline (TRUE);
    print( "%-8s   %-5s   %-8s   |   %-5s   %-8s", "Time", "Team", "DeltaT", "Team", "Time" );
    print_underline (FALSE);
    print( "\n" );

    last_team = 0;
    for( dptr = data, i = 0; i < num_records; i++ )
    {
        ls_timer( dptr++, i );
        print( "   |   " );
        ls_team( &last_team, data );
        print( "\n" );
    }

    print( "\nTeams without marked times will be started when ALL marked teams\n" );
    print( "have been started.\n" );

    /*
    **  Release the resources
    **      - Printer
    **      - Memory
    */
    close_printer();
    free( data );
}

/*========================================================================
 *
 *  print the current leg entry
 *
 *  Purpose:
 *      This function is a helper routine to print the current leg entry
 *      in time : Team number order
 *
 *  Parameters:
 *      ptr     Pointer to entry
 *      num     Entry index
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void ls_timer( t_legs * ptr, int num )
{
    time_t      time;
    time_t      delta;

    if( num == 0 )
        delta = ( time_t ) - 1;
    else
        delta = ptr[0].start - ptr[-1].start;

    time = ptr->start;
    if( ptr->flags.disqualified )
        time = ( time_t ) - 1;

    print( "%-8s   %-5d", time_fa( time, ptr->flags.disqualified ),
           ptr->numb );
    print( "   %-8s", time_fa( delta, TRUE ) );
}


/*========================================================================
 *
 *  print next ( numeric ) leg entry
 *
 *  Purpose:
 *      This helper function is called to print next ( numeric ) leg entry
 *      in Team # time order
 *
 *  Parameters:
 *      last        Last one found
 *                  Used to relocate my self
 *      data        Start of data
 *
 *  Returns:
 *      Nothing
 *
 *========================================================================*/

void ls_team( int *last, t_legs * data )
{
    t_legs     *min;
    time_t      time;

    for( min = 0; data->numb; data++ )
    {
        if( data->numb > *last && ( min == 0 || data->numb < min->numb ) )
            min = data;
    }
    *last = min->numb;                           /* Save current team as done */

    time = min->start;
    if( min->flags.disqualified )
        time = ( time_t ) - 1;
    print( "%-5d   %-8s", min->numb,
           time_fa( time, min->flags.disqualified ) );
}

/*========================================================================
 *
 *  Qsort callback function
 *
 *  Purpose:
 *      This function is provided to Qsort() to sort the teams
 *
 *  Parameters:
 *      a           - Leg entry to compare
 *      b           - Leg entry to compare
 *
 *
 *  Returns:
 *      -1      a < b
 *       0      a = b
 *       1      a > b
 *
 *========================================================================*/

int sort_legs( const void * aa, const void * bb )
{

    const t_legs * a = aa;
    const t_legs * b = bb;

    int         a_bad;
    int         b_bad;

    a_bad = a->flags.disqualified || a->start <= 0;
    b_bad = b->flags.disqualified || b->start <= 0;

    if( a_bad || b_bad )                         /* Valid data has precedence */
    {
        if( a_bad && b_bad )
            return ( a->numb - b->numb );
        else
            return ( a_bad ? 1 : -1 );
    }

    if( a->start == b->start )
        return ( a->numb - b->numb );
    else
    {
        if( ( a->start > 0 ) && ( b->start > 0 ) )
            return ( ( int ) ( a->start - b->start ) );
        else
            return ( ( a->start > 0 ) ? -1 : 1 );
    }
}

/********************************* EOF ***********************************/