Subversion Repositories svn1-original

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 root 1
/*************************************************************************
2
*           Copyright (C) 1995 Embedded Solutions
3
*                       All rights reserved
4
*
5
* file:     src\report.c
6
*
7
* purpose:  PREFIX -
8
*
9
* functions
10
*       report                  - Report menu
11
*       pri_team                - Print in team order
12
*       pri_leg                 - Print in given leg finishing time
13
*       p_place                 - Print place information
14
*       p_team                  - Print team information
15
*       pri_eleg                - Print on elapsed times for given leg
16
*       pe_place                - Print place and elapsed time information
17
*       pe_team                 - Print team and elapsed time information
18
*       pri_final               - Print final results
19
*       pri_interim             - Print interim results
20
*       print_class_header      - Print a class header
21
*       print_class_stats       - Generate the class stats
22
*       print_legend            - Print the legend
23
*       pi_place                - Return place data
24
*       pr_place                - Return place data
25
*       ck_data                 - Check data for bad times
26
*       srt_place               - Update placing information
27
*       do_big_sort             - Main sort routine for final data
28
*       sort                    - Sort in memory buffer
29
*       sort_comp               - qsort comparison function
30
*       load                    - load report data into memory
31
*       gen_stats               - Generate all the stats
32
*
33
* programmer: David Purdie
34
*
35
* revision  date        by      reason
36
*    e388   11-Oct-88           Option in the final printout to only
37
*                               produce the main result sheet. The leg
38
*                               placing printout is not produced.
39
*
40
*                               Changes to the display format of unknown
41
*                               times of disqualified teams. Only affects
42
*                               the leg-printouts.
43
*                               Disqualified teams show as -- -- --
44
*                               Otherwise they show as     ** ** **
45
*                               or a valid time.
46
*
47
*   e339    31-Oct-88   DDP     Added the "Interim Report" facility
48
*   00.0    27/01/95    DDP     Tidies up the program and formatted the file
49
*   00.1    06-sep-02   DDP     Added support for HTML report generation
50
*
51
**************************************************************************/
52
 
53
#include    <stdio.h>
54
#if defined(HI_TECH_C) || defined(__TURBOC__)
55
#include    <alloc.h>
56
#endif
57
#include    "consts.h"
58
#include    "structs.h"
59
#include    "proto.h"
60
 
61
void pri_awards(void);
62
void pri_master_index(void);
63
char *placing ( int place );
18 david 64
void pri_name_index(void);
65
void pri_name_index_body( void );
29 - 66
void pri_all_reports (void );
67
void pri_leg_body(int leg);
68
void pri_eleg_body(int leg);
1 root 69
 
70
 
71
menu_table  rpt_menu[] = {
72
    { '1', "Print team order", pri_team },
73
    { '2', "Print end leg times", pri_leg },
74
    { '3', "Print elapsed leg times", pri_eleg },
75
    { '4', "Print final results", pri_final },
76
    { '5', "Print final results(All-HTML)", pri_final_html },
77
    { '6', "Print Interim results", pri_interim },
78
    { '7', "Update event and class placings", srt_place },
79
    { '8', "Display summary information", display_summary },
13 david 80
    { '9', "Print summary information", pri_summary },
1 root 81
    { 'a', "Print Awards only", pri_awards },
82
    { 'b', "Print Master Index only", pri_master_index },
18 david 83
    { 'c', "Print Name Index only", pri_name_index },
29 - 84
    { 'z', "Print all reports", pri_all_reports },
85
 
1 root 86
#if defined(HI_TECH_C) || defined(__TURBOC__)
87
    { 'S', "MS-DOS system", ms_system },
88
#endif
89
    { 'q', "Return to main menu", 0 },
90
    { '\0' }
91
};
92
 
93
#define MAX_PLACE 11
94
char * place_text[] =
95
{
96
    "Zero'th",
97
    "First",
98
    "Second",
99
    "Third",
100
    "Fourth",
101
    "Fifth",
102
    "Sixth",
103
    "Seventh",
104
    "Eighth",
105
    "Ninth",
106
    "Tenth",
107
    "Eleventh"
108
};
109
 
110
int         sort_leg;
111
int         sort_mode;
112
bool        report_html = FALSE;
29 - 113
bool        report_all = FALSE;
1 root 114
 
115
/* Parameters used by the sort routine to govern its actions */
116
 
117
#define S_L     1                                /* Elasped times */
118
#define S_LE    2                                /* Leg end time */
119
#define S_LC    3                                /* Elapsed times per class */
120
#define S_LEC   4                                /* Leg end time per class */
121
#define S_FIN   5                                /* Sort on finish time at given leg */
122
#define S_TEAM  6                                /* Sort on team order */
123
#define S_CLASS 7                                /* Sort on class/team order */
124
 
125
/*
126
**  Various checking modes
127
*/
128
#define C_ELAPSED   1                            /* Check elapsed times */
129
#define C_END       2                            /* Check end times */
130
#define C_DISQUAL   3                            /* Check disqualified teams */
131
 
132
/*
133
**  Data
134
*/
135
ty_s_data  *sort_data = 0;                       /* pointer to memory */
136
ty_s_aux   *sort_aux = 0;                        /* pointer to aux sort info */
18 david 137
ty_s_namedata *sort_name_data = 0;                /* pointer to name info */
1 root 138
unsigned    sort_num;                            /* Number in the array */
18 david 139
unsigned    sort_num_data;                       /* Number in the array */
1 root 140
 
141
/*
142
**  A structure to hold statistical information
143
*/
144
typedef struct
145
{
146
    int         team[MAX_LEGS + 1][MAX_CLASS + 1];
147
    struct
148
    {
149
        int     team[MAX_LEGS + 1][MAX_CLASS + 1];
150
        time_t  time[MAX_LEGS + 1][MAX_CLASS + 1];
151
    } fast;
152
    time_t      average[MAX_LEGS + 1][MAX_CLASS + 1];
153
} ty_stats;
154
 
155
ty_stats        stats;                           /* Holds statistics */
156
 
157
/*========================================================================
158
 *
159
 *  Report menu
160
 *
161
 *  Purpose:
162
 *      This function is called to produce the "Report Menu"
163
 *
164
 *  Parameters:
165
 *      None
166
 *
167
 *  Returns:
168
 *      Nothing
169
 *
170
 *========================================================================*/
171
 
172
void report(void)
173
{
174
    report_html = FALSE;
175
    if( load_report_data() )
176
        do_menu( "Report generation", "Select option", rpt_menu );
177
 
178
    if( sort_data )
179
        free( ( char * ) sort_data );
180
    if( sort_aux )
181
        free( ( char * ) sort_aux );
18 david 182
    if ( sort_name_data )
183
        free( ( char * ) sort_name_data );
1 root 184
    sort_data = ( ty_s_data * ) 0;
185
    sort_aux = ( ty_s_aux * ) 0;
18 david 186
    sort_name_data = ( ty_s_namedata * ) 0;
1 root 187
}
188
 
189
/*========================================================================
190
 *
191
 *  Print in team order
192
 *
193
 *  Purpose:
194
 *      This function is called to Print in team order
195
 *      This function may also be used to create an HTML suite of files
196
 *      within the result set
197
 *
198
 *  Parameters:
199
 *      None
200
 *
201
 *  Returns:
202
 *      Nothing
203
 *
204
 *========================================================================*/
205
 
206
void pri_team(void)
207
{
208
    int         i, k;
209
 
210
    cur( 0, 5 );
211
    printf( "Team information - in team order\n" );
212
    printf( "\nPrinting team names\n" );
213
    flush_out();
214
 
215
    if( !open_printer( "", "name", 132, report_html, "Team Names" ) )
216
        return;
217
 
218
    /*
219
     * Print out the data 
220
     * Print out the header
221
     */
222
 
223
    print( "\n" );
224
 
225
    print_underline( TRUE );
226
    print( "%-*s %-*s %-*s", MAX_TM_NAME + 5, "Entry number and name",
227
               LEN_CLASS_NAME, "Category",
228
               config.num_countries == 0 ? 1 : LEN_CNTRY_NAME,
229
               config.num_countries == 0 ? "" : "Country" );
230
    for( k = 0; k < MAX_MEMB; k++ )
231
    {
232
        print( " %-*s", MAX_PERSON_NAME, config.leg_name[k] ? config.leg_name[k] : "Competitor"  );
233
    }
234
    print_underline( FALSE ) ;
235
    print( "\n" );
236
 
237
    for( i = config.min_team; i <= config.max_team; i++ )
238
    {
239
        if( valid_field( i ) && g_record( i, &team_buf ) )
240
        {
241
            /*
242
            **  If printing an HTML report then we need to mark
243
            **  the entry with a reference so that we can link to it
244
            */
245
            if ( report_html )
246
            {
247
                print( "<A NAME=\"Team_%04d\">",team_buf.numb );
248
                print( "</A>" );
249
            }
250
 
251
            /*
252
            **  Basic information
253
            **      - Team number - with Xref back to full result
254
            **      - Full team name
255
            **      - Full categoray name - with Xref to category results
256
            **      - Country name
257
            */
258
            if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "finish" ,"html"), team_buf.numb );
259
            print( "%4d",       team_buf.numb );
260
            if ( report_html ) print( "</A>" );
261
 
262
            print( " %-*s ",     MAX_TM_NAME, team_buf.name );
263
 
264
            if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">",p_filename(filebase, config.team_class[team_buf.class - 1].abr ,"html"), team_buf.numb );
265
            print( "%-*s",     LEN_CLASS_NAME, team_buf.class == 0 ? "" : config.team_class[team_buf.class - 1].full_name );
266
            if ( report_html ) print( "</A>" );
267
 
268
            print( " %-*s",     config.num_countries == 0 ? 1 : LEN_CNTRY_NAME,
269
                                config.num_countries == 0
270
                                || team_buf.country ==
271
 
272
 
273
            for( k = 0; k < MAX_MEMB; k++ )
274
                print( " %-*s", MAX_PERSON_NAME, team_buf.members[k].name );
275
 
276
            print( "\n" );
277
        }
278
    }
279
    close_printer();
280
}
281
 
18 david 282
/*========================================================================
283
 *
284
 *  Print in name order
285
 *
286
 *  Purpose:
287
 *      This function is called to print a list of all known competitors
288
 *      This function may also be used to create an HTML suite of files
289
 *      within the result set
290
 *
291
 *  Parameters:
292
 *      None
293
 *
294
 *  Returns:
295
 *      Nothing
296
 *
297
 *========================================================================*/
298
void pri_name_index( void )
299
{
300
    cur( 0, 5 );
301
    printf( "Team Member information - in name order\n" );
302
    printf( "\nPrinting competitor names\n" );
303
    flush_out();
304
    pri_name_index_body();
305
    printf( "Found %d names\n", sort_num_data );
306
    printf( "\nAny key to continue" );
307
    getinp();
308
}
1 root 309
 
310
/*========================================================================
311
 *
18 david 312
 *  Print in name order
313
 *
314
 *  Purpose:
315
 *      This function is called to print a list of all known competitors
316
 *      This function may also be used to create an HTML suite of files
317
 *      within the result set
318
 *
319
 *  Parameters:
320
 *      None
321
 *
322
 *  Returns:
323
 *      Nothing
324
 *
325
 *========================================================================*/
326
void pri_name_index_body( void )
327
{
328
    ty_s_namedata *ptr;
329
    unsigned    num;
330
    int i,k;
331
    int num_names;
332
 
333
    /*
334
    **  Determine the number of names to allow for
335
    *   Based on the total number of teams
336
    */
337
    num = config.max_team - config.min_team + 1 ;
338
    num *= MAX_MEMB;
339
 
340
    sort_name_data = ( ty_s_namedata * ) calloc ( num , sizeof( ty_s_namedata ) );
341
 
342
    if( sort_name_data == 0 )
343
    {
344
        printf( "\n\nError in allocating memory\n" );
345
        sleep( 5 );
346
        return;
347
    }
348
 
349
    /*
350
    **  Read all teams an extract name information
351
    */
352
    ptr = sort_name_data;
353
    for( i = config.min_team; i <= config.max_team; i++ )
354
    {
355
        if( valid_field( i ) && g_record( i, &team_buf ) )
356
        {
357
            num_names = 0;
358
            for( k = 0; k < MAX_MEMB; k++ )
359
            {
360
                if ( team_buf.members[k].name[0] )
361
                {
362
                    ptr->team = i;
363
                    ptr->leg = k;
364
                    ptr->class = team_buf.class;
365
                    strncpy( ptr->name,team_buf.members[k].name, sizeof(team_buf.members[k].name));
366
                    ptr++;
367
                    num_names++;
368
                }
369
            }
370
 
371
            if ( num_names == 0 )
372
            {
373
                ptr->team = i;
374
                ptr->leg = 0;
375
                ptr->class = team_buf.class;
376
                strncpy( ptr->name,team_buf.name, sizeof(team_buf.members[k].name));
377
                ptr++;
378
            }
379
 
380
        }
381
    }
382
    sort_num_data = ptr - sort_name_data;
383
 
384
    /*
385
    **  Now stort the entries by name:team:leg
386
    */
387
    qsort( ( char * ) sort_name_data, sort_num_data, sizeof( ty_s_namedata ), sort_comp_cname );
388
 
389
    /*
390
    **  Now generate the report
391
    */
392
 
393
    if( !open_printer( "", "competitor", 80, report_html, "Competitor Names" ) )
394
        return;
395
 
396
    /*
397
     * Print out the data 
398
     * Print out the header
399
     */
400
    print( "\n" );
401
 
402
    print_underline( TRUE );
403
    print( "%-*s %-*s %-*s %-*s", MAX_TM_NAME + 5, "Competitor name",
404
               6, "Leg",
405
               5, "Team",
406
               LEN_CLASS_NAME, "Category"
407
               );
408
    print_underline( FALSE ) ;
409
    print( "\n" );
410
 
411
    ptr = sort_name_data;
412
    for( k = 1; k <= sort_num_data; k++, ptr++ )
413
    {
414
        print( "%-*s", MAX_TM_NAME + 5, ptr->name );
415
        print( " " );
416
 
417
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "finish" ,"html"), ptr->team );
418
        print( "%-*d", 6, ptr->leg + 1 );
419
        if ( report_html ) print( "</A>" );
420
        print( " " );
421
 
422
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "name" ,"html"), ptr->team );
423
        print( "%-*d", 5, ptr->team );
424
        if ( report_html ) print( "</A>" );
425
        print( " " );
426
 
427
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">",p_filename(filebase, config.team_class[ptr->class - 1].abr ,"html"), ptr->team );
428
        print( "%-*s", LEN_CLASS_NAME, ptr->class == 0 ? "" : config.team_class[ptr->class - 1].abr );
429
        if ( report_html ) print( "</A>" );
430
        print( " " );
431
 
432
        if ( ptr->multi ) print( "* ");
433
        print( "\n" );
434
    }
435
 
436
    print_legend( -1, 0 );
437
    close_printer();
438
 
439
}
440
 
441
/*========================================================================
442
 *
1 root 443
 *  Print in given leg finishing time
444
 *
445
 *  Purpose:
446
 *      This function is called to Print in given leg finishing time
447
 *
448
 *  Parameters:
449
 *      None
450
 *
451
 *  Returns:
452
 *      Nothing
453
 *
454
 *========================================================================*/
455
 
456
void pri_leg(void)
457
{
458
    int         leg = 0;
459
 
29 - 460
 
1 root 461
    /*
462
     * This function is used to provide interum print-outs
463
     * The team data is sorted by time at leg-end and the times printed are
464
     * real times at leg end.
465
     * This operation is designed to be quick - it doesn't update the disk file
466
     * and is not available in an HTML version - yet
467
     */
468
 
469
    cur( 0, 5 );
470
    printf( "Leg finishing time report\n" );
471
    while( TRUE )
472
    {
473
        d_field( 0, 7, "Enter leg to print :", D_NUMBER, 1, ( char * ) &leg,
474
                 TRUE, M_UPDATE );
475
        if( abort_flag )
476
            return;
477
        if( leg <= config.num_legs )
478
            break;
479
        beep();
480
    }
29 - 481
 
482
    pri_leg_body ( leg );
483
}
1 root 484
 
29 - 485
void pri_leg_body(int leg)    
486
{
487
    ty_s_data  *ptr;
488
    int         i, k;
1 root 489
    /*
490
     * Sort the data in finishing order 
491
     */
492
 
493
    printf( "\nSorting the data\n" );
494
    flush_out();
495
    if( ck_data( leg, C_END ) )
496
        return;                                  /* Check data for this leg */
497
    sort_team_data( leg, S_FIN );                /* Sort the data */
498
 
499
 
500
    /*
501
     * Now print the data on the printer 
502
     */
503
    if( !open_printer( "",
504
                        tprintf("lg%1.1d", leg ),
505
                        80,
506
                        report_html,
507
                        leg ? tprintf ("Finish order for Leg %d.", leg)
508
                            : "Final team finish order"
509
                     ) )
510
    {
511
        return;
512
    }
513
 
514
    /*
515
     * Print out the data 
516
     */
517
    print( "PRELIMINARY RESULTS ONLY\n\n" );
518
 
519
    print_underline( TRUE );
520
    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
521
    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
522
    print( "|" );
523
    print( "%4s %4s %-8s  ", "Team", "Plce", "Time" );
524
    print( "%4s %4s %-8s\n", "Team", "Plce", "Time" );
525
    print_underline( FALSE );
526
 
527
    for( ptr = sort_data, k = 0, i = config.min_team; i <= config.max_team; )
528
    {
529
        p_place( ptr++, leg, k++ );
530
        p_place( ptr++, leg, k++ );
531
        print( "|" );
532
        while( i <= config.max_team && !valid_field( i ) )
533
            i++;
534
        p_team( i++, leg );
535
        while( i <= config.max_team && !valid_field( i ) )
536
            i++;
537
        p_team( i++, leg );
538
        print( "\n" );
539
    }
540
 
32 - 541
    printf( "\n\n" );
542
    print_underline( TRUE );
543
    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
544
//    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
545
    print( "|" );
546
//    print( "%4s %4s %-8s  ", "Team", "Plce", "Time" );
547
    print( "%4s %4s %-8s\n", "Team", "Plce", "Time" );
548
    print_underline( FALSE );
549
 
550
    for( ptr = sort_data, k = 0, i = config.min_team; i <= config.max_team; )
551
    {
552
        p_place( ptr++, leg, k++ );
553
//        p_place( ptr++, leg, k++ );
554
        print( "|" );
555
        while( i <= config.max_team && !valid_field( i ) )
556
            i++;
557
        p_team( i++, leg );
558
//        while( i <= config.max_team && !valid_field( i ) )
559
//            i++;
560
//        p_team( i++, leg );
561
        print( "\n" );
562
    }
563
 
564
 
1 root 565
    /*
566
     * Insert the leg statistics 
567
     */
568
 
569
    gen_stats();                               /* Generate all stats */
570
    print( "\nLeg statistics\n" );
571
    print( "Fastest team: %4d time : %s.",
572
           stats.fast.team[leg][0], time_a( stats.fast.time[leg][0] ) );
573
    print( " Average time: %s\n", time_a( stats.average[leg][0] ) );
574
 
575
    close_printer();
576
}
577
 
578
/*========================================================================
579
 *
580
 *  Print place information
581
 *
582
 *  Purpose:
583
 *      This helper function is called to Print place information
584
 *      in a 20-character field
585
 *
586
 *  Parameters:
587
 *      ptr         Address of the place data
588
 *      leg         Leg to print
589
 *      k           Current index into sorted array. Simply
590
 *                  used to determine if the entry is valid
591
 *                  or if it should be space-filled
592
 *
593
 *  Returns:
594
 *      Nothing
595
 *
596
 *========================================================================*/
597
 
598
void p_place( ty_s_data * ptr, int leg, unsigned k )
599
{
600
    if( k < sort_num )
601
    {
602
        print( "%4.4s %4d %8s  ",
603
               pr_place( ptr->place, ptr->flags.bad_times ),
604
               ptr->team, time_fa( ptr->leg[leg], ptr->flags.disqualified ) );
605
    }
606
    else
607
    {
608
        print( "%20s", "" );
609
    }
610
}
611
 
612
/*========================================================================
613
 *
614
 *  Print team information
615
 *
616
 *  Purpose:
617
 *      This helper function is called to Print team information
618
 *      in a 20-character field
619
 *
620
 *  Parameters:
621
 *      i           team to print
622
 *      leg         Leg to print
623
 *
624
 *  Returns:
625
 *      Nothing
626
 *
627
 *========================================================================*/
628
 
629
void p_team( int i, int leg )
630
{
631
    ty_s_data  *ptra;                            /* Pointer to sort data */
632
    int         found = FALSE;
633
    unsigned    j;
634
 
635
    if( valid_field( i ) )
636
    {
637
        ptra = sort_data;
638
        for( j = 1; j <= sort_num; j++, ptra++ )
639
            if( i == ptra->team )
640
            {
641
                found = TRUE;
642
                break;
643
            }
644
    }
645
    if( found )
646
    {
647
        print( "%4d %4.4s %8s  ",
648
               ptra->team,
649
               pr_place( ptra->place, ptra->flags.bad_times ),
650
               time_fa( ptra->leg[leg], ptra->flags.disqualified ) );
651
    }
652
    else
653
    {
654
        print( "%20s", "" );
655
    }
656
}
657
 
658
/*========================================================================
659
 *
660
 *  Print on elapsed times for given leg
661
 *
662
 *  Purpose:
663
 *      This function is called to Print on elapsed times for given leg
664
 *
665
 *  Parameters:
666
 *      None
667
 *
668
 *  Returns:
669
 *      Nothing
670
 *
671
 *========================================================================*/
672
 
673
void pri_eleg(void)
674
{
675
    int         leg = 0;
676
 
29 - 677
 
1 root 678
    /*
679
     * This function is used to provide interum print-outs
680
     * The team data is sorted by time at leg-elapsed and the times printed are
681
     * real times at leg end.
682
     * This operation is designed to be quick - it doesn't update the disk file
683
     * and is not available in an HTML version - yet
684
     */
685
 
686
    cur( 0, 5 );
687
    printf( "Leg elapsed time report\n" );
688
    while( TRUE )
689
    {
690
        d_field( 0, 7, "Enter leg to print :", D_NUMBER, 1, ( char * ) &leg,
691
                 TRUE, M_UPDATE );
692
        if( abort_flag )
693
            return;
694
        if( leg <= config.num_legs )
695
            break;
696
        beep();
697
    }
29 - 698
    pri_eleg_body(leg);
699
}
1 root 700
 
29 - 701
 
702
void pri_eleg_body( int leg)
703
{
704
    ty_s_data  *ptr;
705
    int         i, k;
32 - 706
 
1 root 707
    /*
708
     * Sort the data in finishing order 
709
     */
710
 
711
    printf( "\nSorting the data\n" );
712
    flush_out();
713
    if( ck_data( leg, C_ELAPSED ) )
714
        return;                                  /* Check data for this leg */
715
    sort_team_data( leg, S_L );                  /* Sort the data on elapsed time */
716
 
717
 
718
    /*
719
     * Now print the data on the printer 
720
     */
721
    if( !open_printer( "", tprintf( "le%1.1d", leg ),
722
                       80,
723
                       report_html,
724
                       leg ? tprintf( "Elapsed time order for Leg %d.", leg )
725
                           : tprintf( "Final elapsed team finishing order." )
726
                     ) )
727
    {
728
        return;
729
    }
730
 
731
    /*
732
     * Print out the data 
733
     */
734
    print( "PRELIMINARY RESULTS ONLY\n\n" );
735
 
736
    print_underline( TRUE );
737
    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
738
    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
739
    print( "|" );
740
    print( "%4s %4s %-8s  ", "Team", "Plce", "Time" );
741
    print( "%4s %4s %-8s\n", "Team", "Plce", "Time" );
742
    print_underline( FALSE );
32 - 743
 
1 root 744
 
745
    for( ptr = sort_data, k = 0, i = config.min_team; i <= config.max_team; )
746
    {
747
        pe_place( ptr++, leg, k++ );
748
        pe_place( ptr++, leg, k++ );
749
        print( "|" );
750
        while( i <= config.max_team && !valid_field( i ) )
751
            i++;
752
        pe_team( i++, leg );
753
        while( i <= config.max_team && !valid_field( i ) )
754
            i++;
755
        pe_team( i++, leg );
756
        print( "\n" );
757
    }
758
 
32 - 759
    print( "\n\n" );
760
    print_underline( TRUE );
761
    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
762
//    print( "%4s %4s %-8s  ", "Plce", "Team", "Time" );
763
    print( "|" );
764
//    print( "%4s %4s %-8s  ", "Team", "Plce", "Time" );
765
    print( "%4s %4s %-8s\n", "Team", "Plce", "Time" );
766
    print_underline( FALSE );
767
 
768
 
769
    for( ptr = sort_data, k = 0, i = config.min_team; i <= config.max_team; )
770
    {
771
        pe_place( ptr++, leg, k++ );
772
//        pe_place( ptr++, leg, k++ );
773
        print( "|" );
774
        while( i <= config.max_team && !valid_field( i ) )
775
            i++;
776
        pe_team( i++, leg );
777
//        while( i <= config.max_team && !valid_field( i ) )
778
//            i++;
779
//        pe_team( i++, leg );
780
        print( "\n" );
781
    }
782
 
783
 
1 root 784
    /*
785
     * Insert the leg statistics 
786
     */
787
 
788
    gen_stats();                               /* Generate all stats */
789
    print( "\nLeg statistics\n" );
790
    print( "Fastest team: %4d time : %s.",
791
           stats.fast.team[leg][0], time_a( stats.fast.time[leg][0] ) );
792
    print( " Average time: %s\n", time_a( stats.average[leg][0] ) );
793
 
794
    close_printer();
795
}
796
 
797
/*========================================================================
798
 *
799
 *  Print place information
800
 *
801
 *  Purpose:
802
 *      This helper function is called to Print place and elapsed information
803
 *      in a 20-character field
804
 *
805
 *  Parameters:
806
 *      ptr         Address of the place data
807
 *      leg         Leg to print
808
 *      k           Current index into sorted array. Simply
809
 *                  used to determine if the entry is valid
810
 *                  or if it should be space-filled
811
 *
812
 *  Returns:
813
 *      Nothing
814
 *
815
 *========================================================================*/
816
 
817
void pe_place( ty_s_data * ptr, int leg, unsigned k )
818
{
819
    if( k < sort_num )
820
    {
821
        print( "%4.4s %4d %8s  ",
822
               pr_place( ptr->place, ptr->flags.bad_times ),
823
               ptr->team,
824
               time_fa( ptr->lege[leg], ptr->flags.disqualified ) );
825
    }
826
    else
827
    {
828
        print( "%20s", "" );
829
    }
830
}
831
 
832
/*========================================================================
833
 *
834
 *  Print team information
835
 *
836
 *  Purpose:
837
 *      This helper function is called to Print team and elapsed time
838
 *      information
839
 *      in a 20-character field
840
 *
841
 *  Parameters:
842
 *      i           Team to print
843
 *      leg         Leg to print
844
 *
845
 *  Returns:
846
 *      Nothing
847
 *
848
 *========================================================================*/
849
 
850
void pe_team( int i, int leg )
851
{
852
    ty_s_data  *ptra;                            /* Pointer to sort data */
853
    int         found = FALSE;
854
    unsigned    j;
855
 
856
    if( valid_field( i ) )
857
    {
858
        ptra = sort_data;
859
        for( j = 1; j <= sort_num; j++, ptra++ )
860
            if( i == ptra->team )
861
            {
862
                found = TRUE;
863
                break;
864
            }
865
    }
866
    if( found )
867
    {
868
        print( "%4d %4.4s %8s  ",
869
               ptra->team,
870
               pr_place( ptra->place, ptra->flags.bad_times ),
871
               time_fa( ptra->lege[leg], ptra->flags.disqualified ) );
872
    }
873
    else
874
    {
875
        print( "%20s", "" );
876
    }
877
}
878
 
879
/*========================================================================
880
 *
881
 *  Print final results in HTML
882
 *
883
 *  Purpose:
884
 *      This function is called to Print final results with HTML formatting
885
 *      All result files are created
886
 *
887
 *  Parameters:
888
 *      None
889
 *
890
 *  Returns:
891
 *      Nothing
892
 *
893
 *========================================================================*/
894
 
895
void pri_final_html(void)
896
{
897
    /*
898
    **  Generate ALL results with HTML tags
899
    */
900
    report_html = TRUE;
901
    pri_final();
902
    report_html = FALSE;
903
}
904
 
905
 
906
/*========================================================================
907
 *
908
 *  Print final results
909
 *
910
 *  Purpose:
911
 *      This function is called to Print final results
912
 *
913
 *  Parameters:
914
 *      None
915
 *
916
 *  Returns:
917
 *      Nothing
918
 *
919
 *========================================================================*/
920
 
921
void pri_final(void)
922
{
923
    ty_s_data  *ptr;
924
    unsigned    i;
925
    int         j, last_class;
926
    char        suppress_classes;                /* Boolean. Printout class files too */
927
    char        *report_title;
33 - 928
    bool        class_done[MAX_CLASS+1];
1 root 929
 
930
    cur( 0, 5 );
931
    printf( "Generate final result printouts\n" );
932
    if( ck_data( -1, C_ELAPSED ) )
933
        return;                                  /* check data for all legs */
934
 
935
    /*
936
    **  If a non HTML report then ask if the user want to supress the class
937
    **  printout. For an HTML report always do the class reports as the two
938
    **  are interlinked
939
    */
29 - 940
    if ( ! report_html  && ! report_all)
1 root 941
    {
942
        suppress_classes = getyes( "Do you want to suppress class printouts" );
943
    }
944
    else
945
    {
946
        suppress_classes = FALSE;
947
    }
948
 
949
    /*
950
    **  Sort on every thing
951
    **  Then generate all the stats too
952
    */
953
    printf( "\nSorting the data\n" );
954
    do_big_sort();
955
    gen_stats();
956
 
957
    /*
958
     * Now print the data on the printer 
959
     */
960
    printf( "\nGenerating the printed output\n" );
961
    if( !open_printer( "", "finish", 132, report_html, "Finishing Order" ) )
962
        return;
963
 
964
    /*
965
     * Print out the data 
966
     */
967
    print_class_header( -1, TRUE );                      /* Print the header */
968
 
969
    ptr = sort_data;
970
    sort_team_data( 0, S_L );                     /* Re-sort on elapsed time */
971
    for( ptr = sort_data, i = 0; i < sort_num; i++, ptr++ )
972
    {
973
        if ( ptr->class == config.nonequestrian_class )
974
            continue;
975
 
976
        g_record( ptr->team, &team_buf );
977
 
978
        /*
979
        **  If printing an HTML report then we need to mark
980
        **  the entry with a reference so that we can link to it
981
        */
982
        if ( report_html )
983
        {
984
            print( "<A NAME=\"Team_%04d\"></A>",team_buf.numb );
985
        }
986
 
987
        /*
988
        **  Print the basics
989
        **      - Place within complete field
990
        **      - Team number - with HTML reference to team file
991
        **      - Class
992
        */
47 - 993
        print( "%4.4s ", pr_place_ne( team_buf.leg[0].l_place, ptr->flags.bad_times, ptr->flags.non_equestrian ) );
1 root 994
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "name" ,"html"), team_buf.numb );
995
        print( "%4d",  team_buf.numb );
996
        if ( report_html ) print( "</A>" );
997
 
998
        print( " %-*s", 3, team_buf.class == 0 ? "" : config.team_class[team_buf.class - 1].abr );
999
 
1000
        /*
1001
        **  Print the per-leg data
1002
        **      - Time
1003
        **      - Leg place
1004
        **      - End place
1005
        */
1006
        for( j = 1; j <= config.num_legs; j++ )
1007
        {
13 david 1008
            /*
1009
            **  Ensure that non-equestrian leg data is not displayed
1010
            */
1011
            if ( j == config.equestrian_leg && team_buf.flags.non_equestrian )
1012
            {
48 - 1013
                print( "  %-8s %4.4s %4.4s", "-- NE --", "NE","NE");
13 david 1014
            }
1015
            else
1016
            {
1017
                print( "  %-8s %4.4s %4.4s",
1 root 1018
                    time_a( team_buf.leg[j].elapsed ),
47 - 1019
                    pr_place_ne( team_buf.leg[j].l_place, ptr->flags.bad_times, ptr->flags.non_equestrian ),
1020
                    pr_place_ne( team_buf.leg[j].le_place,ptr->flags.bad_times, ptr->flags.non_equestrian )
1 root 1021
                  );
13 david 1022
            }
1 root 1023
        }
1024
 
24 - 1025
       /*
1 root 1026
        **  Print the trailer
1027
        **      - Total time
1028
        **      - Category place - with reference to category file
1029
        */
48 - 1030
//        print( "  %-8s ",  time_a( team_buf.leg[0].elapsed ) );
1031
        print( "  %-8s ", time_a( ptr->lege[0] ) );
1032
 
1 root 1033
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">",p_filename(filebase, config.team_class[team_buf.class - 1].abr ,"html"), team_buf.numb );
47 - 1034
        print( "%-4.4s", pr_place_ne( team_buf.leg[0].lc_place, ptr->flags.bad_times, ptr->flags.non_equestrian ) );
1 root 1035
        if ( report_html ) print( "</A>" );
1036
 
1037
        print( "\n" );
1038
    }
1039
 
1040
    print_class_stats( -1, TRUE );              /* Print statistics */
18 david 1041
    print_legend(-1, 1 );                       /* Print the legend */
1 root 1042
    close_printer();                            /* Close the printer */
1043
 
1044
    /*
1045
     * Now produce a breakdown on a class by class basis 
1046
     * Now print out the class placement information
1047
     */
1048
 
1049
    if( suppress_classes )
1050
    {
1051
        printf( "WARNING: Class printouts suppressed\n" );
1052
        return;
1053
    }
1054
 
1055
    sort_team_data( 0, S_LC );                 /* Generate class placement data */
1056
    last_class = -1;                           /* Invalid class to start with */
33 - 1057
    memset ( class_done, 0, sizeof(class_done));
1 root 1058
 
33 - 1059
 
1 root 1060
    for( ptr = sort_data, i = 0; i < sort_num; i++, ptr++ )
1061
    {
1062
        /*
1063
        **  Detect a change in the "class"
1064
        **  All data is within the one array of data
1065
        **  Use the in-memory class as this MAY differ from that stored
1066
        **  The non-equestrian class does this.
1067
        */
1068
        if( last_class != ptr->class )
1069
        {
1070
            if( last_class >= 0 )
1071
            {
1072
                print_class_stats( last_class, TRUE );
18 david 1073
                print_legend( last_class, 1 );
1 root 1074
                close_printer();
1075
            }
1076
 
1077
            report_title = tprintf( "Category results for : %-*s", LEN_CLASS_NAME, ptr->class == 0 ? "" : config.team_class[ptr->class - 1].full_name );
1078
 
1079
            if( !open_printer( "", config.team_class[ptr->class - 1].abr, 132, report_html, report_title ) )
1080
                continue;
1081
            print_class_header( last_class = ptr->class, TRUE );
33 - 1082
 
1083
            /*
1084
            **  Mark the class as done
1085
            */
1086
            class_done[ptr->class] = TRUE;
1 root 1087
        }
1088
 
1089
        /*
1090
        **  Now read in the team record
1091
        */
1092
        g_record( ptr->team, &team_buf );
1093
 
1094
        /*
1095
        **  If printing an HTML report then we need to mark
1096
        **  the entry with a reference so that we can link to it
1097
        */
1098
        if ( report_html )
1099
            print( "<A NAME=\"Team_%04d\"></A>",team_buf.numb );
1100
 
1101
        /*
1102
        **  Print the basics
1103
        **      - Place within the class
1104
        **      - Team number - with HTML reference to team file
1105
        **      - Class
1106
        */
1107
 
49 - 1108
        print( "%4.4s ", pr_place_ne( team_buf.leg[0].lc_place, ptr->flags.bad_times, ptr->flags.non_equestrian ) );
1 root 1109
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "name" ,"html"), team_buf.numb );
1110
        print( "%4d",  team_buf.numb );
1111
        if ( report_html ) print( "</A>" );
1112
        print( " %-*s", 3, team_buf.class == 0 ? "" : config.team_class[team_buf.class - 1].abr );
1113
 
1114
        for( j = 1; j <= config.num_legs; j++ )
1115
        {
1116
            /*
1117
            **  Ensure that non-equestrian leg data is not displayed
1118
            */
49 - 1119
            if ( j == config.equestrian_leg && (ptr->class == config.nonequestrian_class || ptr->flags.non_equestrian) )
1 root 1120
            {
13 david 1121
                print( "  %-8s %4.4s %4.4s", "-- NE --", "-","-");
1 root 1122
            }
1123
            else
1124
            {
1125
                print( "  %-8s %4.4s %4.4s", time_a( team_buf.leg[j].elapsed ),
49 - 1126
                       pr_place_ne( team_buf.leg[j].lc_place,  ptr->flags.bad_times, ptr->flags.non_equestrian ),
1127
                       pr_place_ne( team_buf.leg[j].lec_place, ptr->flags.bad_times, ptr->flags.non_equestrian ) );
1 root 1128
            }
1129
        }
1130
 
1131
        /*
1132
        **  Print the trailer
1133
        **      - Total time
1134
        **      - Overall place - with reference to overall place file
1135
        */
1136
        /* print( "  %-8s ", time_a( team_buf.leg[0].elapsed ) ); */
1137
        print( "  %-8s ", time_a( ptr->lege[0] ) );
1138
 
1139
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "finish" ,"html"), team_buf.numb );
49 - 1140
        print( "%4.4s", pr_place_ne( team_buf.leg[0].l_place, ptr->flags.bad_times | (ptr->class == config.nonequestrian_class), ptr->flags.non_equestrian ) );
1 root 1141
        if ( report_html ) print( "</A>" );
1142
 
1143
        print( "\n" );
1144
    }
1145
 
1146
    print_class_stats( last_class, TRUE );
18 david 1147
    print_legend(last_class,1);
1 root 1148
    close_printer();
1149
 
33 - 1150
    /*
1151
    **  Pickup missed classes and create a report
1152
    */
1153
    for( j = 1; j <= config.num_class; j++ )
1154
    {
1155
        if ( class_done[j] )
1156
        {
1157
            continue;
1158
        }
1 root 1159
 
33 - 1160
        report_title = tprintf( "Category results for : %-*s", LEN_CLASS_NAME, config.team_class[j - 1].full_name );
1161
 
1162
        if( !open_printer( "", config.team_class[j - 1].abr, 132, report_html, report_title ) )
1163
            continue;
1164
        print_class_header( j-1, TRUE );
1165
        print( "\nThere were no competitors in this class\n" );
1166
        print_legend(j,1);
1167
        close_printer();
1168
    }
1169
 
1170
 
1 root 1171
    /*
1172
    **  If we are generating an HTML report then we need to create the file
1173
    **  that contains all the team names - the assumption is that this data
1174
    **  is available
1175
    */
1176
    if ( report_html )
1177
    {
1178
        pri_team();
1179
    }
1180
 
1181
    /*
1182
    **  Generate the awards report.
1183
    **  This is only available as an HTML report
1184
    */
1185
    if ( report_html )
1186
    {
1187
        pri_awards();
1188
    }
1189
 
1190
    /*
1191
    **  Generate the master index page
1192
    */
1193
    if ( report_html )
1194
    {
1195
        pri_master_index();
1196
    }
1197
 
18 david 1198
    pri_name_index_body();
1199
 
1 root 1200
}
1201
 
1202
/*========================================================================
1203
 *
1204
 *  Place to text
1205
 *
1206
 *  Purpose:
1207
 *      This function is called to convert a place to text
1208
 *
1209
 *  Parameters:
1210
 *      place
1211
 *
1212
 *  Returns:
1213
 *      text
1214
 *
1215
 *========================================================================*/
1216
 
1217
char *placing ( int place )
1218
{
1219
    if ( place > MAX_PLACE )
1220
    {
1221
        return tprintf( "Place: %d", place);
1222
    }
1223
    return tprintf ("%s Place", place_text[place]);
1224
}
1225
 
1226
/*========================================================================
1227
 *
1228
 *  Print award results
1229
 *
1230
 *  Purpose:
1231
 *      This function is called to Print award results
27 - 1232
 *      Keep the page to 80 cols, so that it can be pronted on A4
1 root 1233
 *
1234
 *  Parameters:
1235
 *      None
1236
 *
1237
 *  Returns:
1238
 *      Nothing
1239
 *
1240
 *========================================================================*/
1241
void pri_awards(void)
1242
{
1243
    int j;
1244
    int i;
1245
    int k;
1246
    int windex;
1247
    ty_s_data  *ptr;
1248
    int         last_class;
1249
 
1250
    report_html = 1;
27 - 1251
    if( !open_printer( "", "awards", 80, report_html, "Prizes and Awards" ) )
1 root 1252
        return;
1253
 
1254
    /*
1255
    **  Generate an index for this page
1256
    */
1257
    print( "\n");
1258
    print( "<hr>" );
1259
    print( "<A NAME=\"%s\"></A>","INDEX");
1260
    print( "Award Categories");
1261
 
1262
    for( j = 1; j <= config.num_class; j++ )
1263
    {
1264
        /*
1265
        **  Header for the class
1266
        */
1267
        if ( config.class_winners[j-1] <= 0 )
1268
            continue;
1269
 
1270
        print( "\n");
1271
        print( "    <A HREF=\"#%s\">",config.team_class[j-1].full_name);
1272
        print( "%s",  config.team_class[j-1].full_name );
1273
        print( "</A>" );
1274
    }
1275
 
1276
    /*
1277
    **  Manual entries
1278
    */
1279
    print( "\n");
1280
    print( "    <A HREF=\"#%s\">","Hall Of Fame");
1281
    print( "%s",  "Hall Of Fame" );
1282
    print( "</A>" );
1283
 
1284
    print( "\n");
1285
    print( "    <A HREF=\"#%s\">","FASTEST");
1286
    print( "%s",  "FASTEST" );
1287
    print( "</A>" );
1288
 
1289
    /*
1290
    **  Sort the data by class
1291
    */
1292
    sort_team_data( 0, S_LC );      /* Generate class placement data */
1293
    last_class = -1;                /* Invalid class to start with */
1294
 
1295
    /*
1296
    **  Process each category
1297
    */
1298
    for( j = 1; ; j++ )
1299
    {
1300
        /*
1301
        **  Tail for previous entry
1302
        */
1303
        if ( j != 1 )
1304
            print( "<A HREF=\"#%s\">Awards Index</A>","INDEX");
1305
 
1306
        if ( j > config.num_class  )
1307
            break;
1308
 
1309
        /*
1310
        **  Header for the class
1311
        */
1312
        print( "\n");
1313
        print( "<hr>" );
1314
        print( "<A name=\"%s\"></A>",config.team_class[j-1].full_name);
1315
        print( "<A HREF=\"%s\">",p_filename(filebase, config.team_class[j - 1].abr ,"html"));
1316
        print( "%s",  config.team_class[j-1].full_name );
1317
        print( "</A>" );
1318
 
1319
                if ( config.class_winners[j-1] <= 0 )
1320
        {
1321
            print( "\n");
1322
            print( "No winners awarded" );
1323
            continue;
1324
        }
1325
 
1326
        /*
1327
        **  Enties for 'n' the best teams as configured
1328
        */
1329
        windex = 0;                     /* Winners done */
1330
        for( ptr = sort_data, i = 0; i < sort_num; i++, ptr++ )
1331
        {
1332
            if ( ptr->class != j )
1333
            {
1334
                continue;
1335
            }
1336
 
1337
            /*
1338
            **  Now read in the team record
1339
            */
1340
            if( valid_field( ptr->team ) && g_record( ptr->team, &team_buf ) )
1341
            {
1342
                windex++;
1343
 
1344
                /*
1345
                **  If printing an HTML report then we need to mark
1346
                **  the entry with a reference so that we can link to it
1347
                */
1348
                print( "\n");
1349
                print( "<A NAME=\"Team_%04d\">",team_buf.numb );
1350
                print( "</A>" );
1351
 
1352
                /*
1353
                **  Basic information
1354
                **      - Team number - with Xref back to full result
1355
                **      - Full team name
1356
                **      - Full categoray name
1357
                */
1358
                print( "%s", placing(windex) );
1359
 
1360
                print( "  Team Name: <A HREF=\"%s#Team_%04d\">", p_filename(filebase, "name" ,"html"), team_buf.numb );
1361
                print( "%-*s ",     MAX_TM_NAME, team_buf.name );
1362
                print( "</A>" );
1363
 
1364
                print( "  Number: <A HREF=\"%s#Team_%04d\">", p_filename(filebase, "finish" ,"html"), team_buf.numb );
1365
                print( "%4d",       team_buf.numb );
1366
                print( "</A>" );
1367
 
1368
 
1369
                for( k = 0; k < MAX_MEMB; k++ )
1370
                {
1371
 
1372
                    /*
1373
                    **  Skip equestrian leg in the non-equestion display
1374
                    */
1375
                    if ( k + 1 == config.equestrian_leg && ptr->class == config.nonequestrian_class)
1376
                        continue;
1377
 
1378
                    print( "\n");
1379
                    print( "    ");
1380
                    print( "%-*s", MAX_PERSON_NAME, config.leg_name[k] ? config.leg_name[k] : "Competitor"  );
1381
                    print( " %-*s", MAX_PERSON_NAME, team_buf.members[k].name );
1382
 
1383
                    print( "  %-8s", time_a( team_buf.leg[k+1].elapsed ) );
1384
                }
1385
 
1386
                print( "\n");
1387
                print( "    ");
1388
                print_bold( TRUE );
1389
                print( "%-*s %-*s  %-8s", MAX_PERSON_NAME , "Total" ,MAX_PERSON_NAME, "",time_a( team_buf.leg[0].elapsed ) );
1390
                print_bold( FALSE );
1391
                print( "\n" );
1392
            }
1393
 
1394
 
1395
            /*
1396
            **  More to do
1397
            */
1398
            if ( windex >= config.class_winners[j-1] )
1399
            {
1400
                break;
1401
            }
1402
        }
1403
    }
1404
 
1405
    /*
1406
    **  Generate the Hall of Fame information
1407
    */
1408
    print( "\n");
1409
    print( "<hr>" );
1410
    print( "<A name=\"%s\"></A>","Hall Of Fame");
1411
    print( "%s",  "Hall of Fame" );
1412
 
1413
    if ( config.num_fame  )
1414
    {
1415
        for( i = 1; i <= config.num_fame; i++ )
1416
        {
1417
            print( "\n    %-*s", MAX_PERSON_NAME, config.hall_fame[i-1] );
1418
        }
1419
    }
1420
    else
1421
    {
1422
        printf( "\n    There are no new stars for the Hall of Fame");
1423
    }
1424
    print( "<p><A HREF=\"#%s\">Awards Index</A>","INDEX");
1425
 
1426
    /*
1427
    **  Generate the FASTEST information
1428
    */
1429
    print( "<hr>" );
1430
    print( "<A name=\"%s\"></A>","FASTEST");
1431
    print( "%s",  "FASTEST" );
1432
 
1433
    /*
1434
    **  Sort the data and then generate the stats - again
1435
    */
1436
    do_big_sort();
1437
    gen_stats();
1438
 
1439
    for( i = 1; i <= config.num_legs; i++ )
1440
    {
1441
        g_record( stats.fast.team[i][0], &team_buf );
1442
 
1443
        print( "\n");
1444
        print( "    %-13s ", config.leg_name[i - 1] );
17 david 1445
        print( "  Name: <A HREF=\"%s#Team_%04d\">", p_filename(filebase, "name" ,"html"), team_buf.numb );
1 root 1446
        print( "%-*s", MAX_PERSON_NAME, team_buf.members[i-1].name );
1447
        print( "</A>" );
1448
        print( "  Team :<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "finish" ,"html"), team_buf.numb );
27 - 1449
        print( "%4d" , stats.fast.team[i][0] );
1450
        print( "</A> " );
1451
        print( "Time:%s ", time_a( stats.fast.time[i][0] ) );
1 root 1452
 
1453
    }
1454
 
1455
 
17 david 1456
 
1457
 
1 root 1458
    print( "<p><A HREF=\"#%s\">Awards Index</A>","INDEX");
1459
    close_printer();
1460
}
1461
 
1462
/*========================================================================
1463
 *
1464
 *  pri_master_index
1465
 *
1466
 *  Purpose:
1467
 *      This function is called to create an HTML page that references all
1468
 *      the other pages that have been generated
1469
 *
1470
 *      Assume that they are in the same directory
1471
 *
1472
 *  Parameters:
1473
 *      None
1474
 *
1475
 *  Returns:
1476
 *      Nothing
1477
 *
1478
 *========================================================================*/
1479
void pri_master_index_entry(char *name, char *text)
1480
{
1481
    print( "<tr><td>");
1482
    print ("<A HREF=\"%s\">%s</A>\n", p_filename(filebase, name ,"html"), text );
1483
}
1484
 
1485
 
1486
void pri_master_index(void)
1487
{
1488
    int j;
1489
 
1490
    report_html = 1;
1491
    if( !open_printer( "", "index", 132, report_html, "Master Index" ) )
1492
        return;
1493
 
1494
    /*
1495
    **  Names
1496
    */
1497
    print( "<TABLE border=0 align=center>" );
18 david 1498
    pri_master_index_entry( "name", "Team list" );
1499
    pri_master_index_entry( "competitor", "Competitor list" );
1 root 1500
    pri_master_index_entry( "finish", "Finishing Order for all Teams" );
1501
    pri_master_index_entry( "awards", "Prizes and Awards" );
1502
    print( "<tr><td>\n" );
1503
 
1504
    print( "\n" );
1505
    for( j = 1; j <= config.num_class; j++ )
1506
    {
1507
        pri_master_index_entry( config.team_class[j - 1].abr, tprintf("Category Results for: %s", config.team_class[j-1].full_name) );
1508
    }
32 - 1509
 
1 root 1510
    print( "</TABLE>" );
1511
 
1512
    close_printer();
32 - 1513
 
1514
    /*
1515
    **  A small page to hold the Leg End displays
1516
    */
1517
 
1518
    if( !open_printer( "", "legindex", 132, report_html, "Master Index with trace data" ) )
1519
        return;
1520
 
1521
    /*
1522
    **  Names
1523
    */
1524
    print( "<TABLE border=0 align=center>" );
1525
#if 1
1526
    pri_master_index_entry( "name", "Team list" );
1527
    pri_master_index_entry( "competitor", "Competitor list" );
1528
    pri_master_index_entry( "finish", "Finishing Order for all Teams" );
1529
    pri_master_index_entry( "awards", "Prizes and Awards" );
1530
    print( "<tr><td>\n" );
1531
 
1532
    print( "\n" );
1533
    for( j = 1; j <= config.num_class; j++ )
1534
    {
1535
        pri_master_index_entry( config.team_class[j - 1].abr, tprintf("Category Results for: %s", config.team_class[j-1].full_name) );
1536
    }
1537
#endif
1538
    print( "<tr><td>\n" );
1539
 
1540
    print( "\n" );
1541
    for ( leg = 1; leg <= config.num_legs; leg ++ )
1542
    {
1543
        pri_master_index_entry( tprintf("lg%1.1d", leg), tprintf("Leg End Results for: %d", leg) );    
1544
    }
1545
 
1546
    print( "<tr><td>\n" );
1547
    print( "\n" );
1548
 
1549
    for ( leg = 1; leg <= config.num_legs; leg ++ )
1550
    {
1551
        pri_master_index_entry( tprintf("le%1.1d", leg), tprintf("Leg Elapsed Time Results for: %d", leg) );
1552
    }    
1553
 
1554
 
1555
    print( "</TABLE>" );
1556
 
1557
    close_printer();
1558
 
1 root 1559
}
1560
 
1561
 
1562
/*========================================================================
1563
 *
1564
 *  Print interim results
1565
 *
1566
 *  Purpose:
1567
 *      This function is called to Print interim results
1568
 *
1569
 *  Parameters:
1570
 *      None
1571
 *
1572
 *  Returns:
1573
 *      Nothing
1574
 *
1575
 *========================================================================*/
1576
 
1577
void pri_interim(void)
1578
{
1579
    ty_s_data  *ptr;
1580
    unsigned    i;
1581
    int         j, last_class;
29 - 1582
    char        suppress_classes = FALSE;                /* Boolean. Printout class files too */
1 root 1583
    char       *report_title;
1584
 
29 - 1585
    if ( ! report_all )
1586
    {
1587
        cur( 0, 5 );
1588
        printf( "Generate interim result printouts\n" );
1589
        ck_data( -1, C_DISQUAL );                    /* Check the data - dummy check */
1590
        suppress_classes = getyes( "Do you want to suppress class printouts" );
1591
        printf( "\nSorting the data\n" );
1592
    }
1 root 1593
    do_big_sort();                             /* Sort on every thing */
1594
    gen_stats();                               /* Generate the stats too */
1595
 
1596
    printf( "\nGenerating the printed output\n" );
1597
 
1598
    /*
1599
     * Now print the data on the printer 
1600
     */
1601
 
1602
    if( !open_printer( "", "int", 132, report_html, "Interim Results" ) )
1603
        return;
1604
 
1605
    /*
1606
     * Print out the data 
1607
     */
1608
    print_class_header( -1, FALSE );                     /* Print the header */
1609
 
1610
    ptr = sort_data;
1611
    sort_team_data( 0, S_TEAM );                   /* Re-sort on team number */
1612
    for( ptr = sort_data, i = 0; i < sort_num; i++, ptr++ )
1613
    {
1614
        if ( ptr->class == config.nonequestrian_class )
1615
            continue;
1616
 
1617
        g_record( ptr->team, &team_buf );
1618
 
1619
        print( "%4d %4.4s %-*s",
1620
               team_buf.numb,
1621
               pi_place( team_buf.leg[config.num_legs].le_place,
1622
                         ptr->flags.disqualified, team_buf.leg[0].elapsed ),
1623
               3,
1624
               team_buf.class ==
1625
 
1626
        for( j = 1; j <= config.num_legs; j++ )
1627
        {
1628
            print( "  %-8s %4.4s %4.4s",
1629
                   time_fa( team_buf.leg[j].elapsed,
1630
                            ptr->flags.disqualified ),
1631
                   pi_place( team_buf.leg[j].l_place, ptr->flags.disqualified,
1632
                             team_buf.leg[j].elapsed ),
1633
                   pi_place( team_buf.leg[j].le_place,
1634
                             ptr->flags.disqualified,
1635
                             team_buf.leg[j].elapsed ) );
1636
        }
1637
        print( "  %-8s %4.4s\n",
1638
               time_fa( team_buf.leg[0].elapsed, ptr->flags.disqualified ),
1639
               pi_place( team_buf.leg[config.num_legs].lec_place,
1640
                         ptr->flags.disqualified, team_buf.leg[0].elapsed ) );
1641
    }
1642
 
1643
    print_class_stats( -1, FALSE );             /* Print statistics */
18 david 1644
    print_legend(-1, 1);                        /* Print the legend */
1 root 1645
    close_printer();                            /* Close the printer */
1646
 
1647
 
1648
    /*
1649
     * Now produce a breakdown on a class by class basis 
1650
     * Now print out the class placement information
1651
     */
1652
 
1653
    if( suppress_classes )
1654
    {
1655
        printf( "WARNING: Class printouts suppressed\n" );
1656
        return;
1657
    }
1658
 
1659
    sort_team_data( 0, S_CLASS );              /* Generate class placement data */
1660
    last_class = -1;                             /* Invalid class to start with */
1661
 
1662
    for( ptr = sort_data, i = 0; i < sort_num; i++, ptr++ )
1663
    {
1664
        /*
1665
        **  Detect a change in the "class"
1666
        **  All data is within the one array of data
1667
        **  Use the in-memory class as this MAY differ from that stored
1668
        **  The non-equestrian class does this.
1669
        */
1670
        if( last_class != ptr->class )
1671
        {
1672
            if( last_class >= 0 )
1673
            {
1674
                print_class_stats( last_class, TRUE );
18 david 1675
                print_legend(last_class, 1);
1 root 1676
                close_printer();
1677
            }
1678
 
1679
            report_title = tprintf( "Interim Category results for : %-*s", LEN_CLASS_NAME, team_buf.class == 0 ? "" : config.team_class[ptr->class - 1].full_name );
1680
 
1681
            if( !open_printer( "", tprintf( "i%2s", config.team_class[ptr->class - 1].abr ), 132, report_html, report_title ) )
1682
                continue;
1683
            print_class_header( last_class = ptr->class, FALSE );
1684
        }
1685
 
1686
        /*
1687
        **  Now read in the team record
1688
        */
1689
        g_record( ptr->team, &team_buf );
1690
        print( "%4d %4.4s %-*s",
1691
               team_buf.numb,
1692
               pi_place( team_buf.leg[config.num_legs].lec_place,
1693
                         ptr->flags.disqualified, team_buf.leg[0].elapsed ),
1694
               3,
1695
               team_buf.class ==
1696
 
1697
        for( j = 1; j <= config.num_legs; j++ )
1698
        {
1699
            print( "  %-8s %4.4s %4.4s",
1700
                   time_fa( team_buf.leg[j].elapsed,
1701
                            ptr->flags.disqualified ),
1702
                   pi_place( team_buf.leg[j].lc_place,
1703
                             ptr->flags.disqualified,
1704
                             team_buf.leg[j].elapsed ),
1705
                   pi_place( team_buf.leg[j].lec_place,
1706
                             ptr->flags.disqualified,
1707
                             team_buf.leg[j].elapsed ) );
1708
        }
1709
        print( "  %-8s %4.4s\n",
1710
               time_fa( team_buf.leg[0].elapsed, ptr->flags.disqualified ),
1711
               pi_place( team_buf.leg[config.num_legs].le_place,
1712
                         ptr->flags.disqualified, team_buf.leg[0].elapsed ) );
1713
    }
1714
 
1715
    print_class_stats( last_class, FALSE );
18 david 1716
    print_legend(last_class, 1);
1 root 1717
    close_printer();
1718
 
1719
}
1720
 
1721
/*========================================================================
1722
 *
29 - 1723
 *  Print all reports at once
1724
 ^  Its all so fast, these days ...
1725
 *
1726
 *  Purpose:
1727
 *      This function is called to print all reports at once
1728
 *
1729
 *  Parameters:
1730
 *      None
1731
 *
1732
 *  Returns:
1733
 *      Nothing
1734
 *
1735
 *========================================================================*/
1736
 
1737
void pri_all_reports ( void )
1738
{
1739
    int leg;
1740
    report_all = TRUE;
1741
 
1742
    pri_team();
1743
 
1744
    for ( leg = 1; leg <= config.num_legs; leg ++ )
1745
    {
1746
        pri_leg_body ( leg );
1747
        pri_eleg_body ( leg );
32 - 1748
 
1749
        report_html = TRUE;
1750
 
1751
        pri_leg_body ( leg );
1752
        pri_eleg_body ( leg );        
1753
 
1754
        report_html = FALSE;
29 - 1755
    }
1756
 
1757
    pri_final();
1758
    pri_final_html();
1759
    pri_summary();
1760
    pri_awards();
1761
    pri_master_index();
1762
 
1763
    report_all = FALSE;
1764
}
1765
 
1766
 
1767
/*========================================================================
1768
 *
1 root 1769
 *  Print a class header
1770
 *
1771
 *  Purpose:
1772
 *      This function is called to print a class header
1773
 *
1774
 *  Parameters:
1775
 *      class           Name of this class
1776
 *      final           False - prelim results
1777
 *
1778
 *  Returns:
1779
 *      Nothing
1780
 *
1781
 *========================================================================*/
1782
 
1783
void print_class_header( int class, int final )
1784
{
1785
    int         j;
1786
 
1787
    /*
1788
    **  Give a clear indication that the report is preliminary
1789
    */
1790
 
1791
    if( !final )
1792
        print( "PRELIMINARY RESULTS ONLY\n\n" );
1793
 
1794
    /*
1795
    **  Now printout the column headings
1796
    **  This is a two line display
1797
    **
1798
    **  Line-1  Leg names
1799
    */
1800
    print( "%-*s %-*s %-*s", 4, "", 4, "", 3, "" );
1801
    for( j = 1; j <= config.num_legs; j++ )
1802
    {
1803
        print_bold( TRUE );
1804
        print( "  %-*s", 18, config.leg_name[j - 1] );
1805
        print_bold( FALSE );
1806
    }
1807
    print( "  %-8s %-4s\n", "Total", ( class < 0 ) ? "Cat" : "Fin" );
1808
 
1809
 
1810
    /*
1811
    **  Line-2  Details
1812
    */
1813
    print_underline( TRUE );
1814
    print( "%-*s %*s %-*s", 4, final ? "Plce" : "Team",
1815
                            4, final ? "Team" : "Plce",
1816
                            3, "Cat" );
1817
 
1818
    for( j = 1; j <= config.num_legs; j++ )
1819
        print( "  %-8s %-4s %-4s", "Time", " LP", " EP" );
1820
 
1821
    print( "  %-8s %-4s\n", "Time", "Plce" );
1822
    print_underline( FALSE );
1823
}
1824
 
1825
/*========================================================================
1826
 *
1827
 *  Generate the class stats
1828
 *
1829
 *  Purpose:
1830
 *      This function is called to Generate the class stats
1831
 *
1832
 *  Parameters:
1833
 *      c           Class to print
1834
 *      final       TRUE: Final data
1835
 *                  FALSE: Interim data
1836
 *
1837
 *  Returns:
1838
 *      Nothing
1839
 *
1840
 *========================================================================*/
1841
 
1842
void print_class_stats( int c, int final )
1843
{
1844
    int         i, j;
1845
    char        *title;
1846
 
1847
    if( c < 0 )
1848
    {
1849
        title = "Event";
1850
        c = 0;
1851
    }
1852
    else
1853
    {
1854
        title = "Category";
1855
    }
1856
 
1857
    print( "\n" );
1858
    if ( report_html ) print_underline(TRUE);
1859
    print( "%s statistics", title );
1860
    if ( report_html ) print_underline(FALSE);
1861
    print( "\n" );
1862
 
1863
 
1864
    /*
1865
    **  Print the names of the different legs
1866
    */
1867
    print( "%-*s       ", LEN_CLASS_NAME, "" );
1868
    for( i = 1; i <= config.num_legs; i++ )
1869
    {
1870
        print_bold( TRUE );
1871
        print( "%-13s  ", config.leg_name[i - 1] );
1872
        print_bold( FALSE );
1873
    }
1874
    print( "%-13s  \n", final ? "Total" : "" );
1875
 
1876
    /*
1877
    **  Print the fastest teams for each leg and overall
1878
    **  Add cross references to the team names for the fastest teams
1879
    */
1880
    print( "%*s : ", LEN_CLASS_NAME, "Fastest" );
1881
    for( i = 0; i <= config.num_legs; i++ )
1882
    {
1883
        j = i + 1;
1884
        if( i >= config.num_legs )
1885
        {
1886
            if( final )
1887
                j = 0;                           /* Leg-0 last */
1888
            else
1889
                break;
1890
        }
1891
 
1892
        if ( report_html ) print( "<A HREF=\"%s#Team_%04d\">", p_filename(filebase, "name" ,"html"), stats.fast.team[j][c] );
1893
        print( "%4d",  stats.fast.team[j][c] );
1894
        if ( report_html ) print( "</A>" );
1895
        print( " %s  ", time_a( stats.fast.time[j][c] ) );
1896
    }
1897
    print( "\n" );
1898
 
1899
    /*
1900
    **  Print the average time for each leg
1901
    */
1902
    print( "%*s : ", LEN_CLASS_NAME, "Average" );
1903
    for( i = 0; i <= config.num_legs; i++ )
1904
    {
1905
        j = i + 1;
1906
        if( i >= config.num_legs )
1907
        {
1908
            if( final )
1909
                j = 0;                           /* Leg-0 last */
1910
            else
1911
                break;
1912
        }
1913
        print( "     %s  ", time_a( stats.average[j][c] ) );
1914
    }
1915
}
1916
 
1917
/*========================================================================
1918
 *
1919
 *  Print the legend
1920
 *
1921
 *  Purpose:
1922
 *      This function is called to Print the legend
1923
 *
1924
 *  Parameters:
1925
 *      class       - Class currently being printed
18 david 1926
 *      full        - Display full legend
1 root 1927
 *
1928
 *  Returns:
1929
 *      Nothing
1930
 *
1931
 *========================================================================*/
1932
 
18 david 1933
void print_legend ( int class, int full )
1 root 1934
{
1935
 
1936
    int         i;
1937
    char        line[201];
1938
    FILE       *adfile = NULL;
1939
    int         count;
1940
 
1941
    /*
1942
     * First the categories 
1943
     */
1944
    print( "\n\n" );
1945
    if ( report_html ) print_underline(TRUE);
1946
    print( "Category abbreviations" );
1947
    if ( report_html ) print_underline(FALSE);
1948
    print( "\n" );
1949
 
1950
 
1951
    for( i = 1, count = 0; i <= config.num_class; i++ )
1952
    {
1953
#if 0
1954
        /*
1955
        **  Skip any non-equestrian class in the legend
1956
        **  Don't want to tell the general user whats goes on, unless we actually
1957
        **  creating the non-equestrian report.
1958
        */
1959
        if ( class != config.nonequestrian_class  && i == config.nonequestrian_class )
1960
            continue;
1961
#endif
1962
        if ( report_html ) print( "<A HREF=\"%s\">",p_filename(filebase, config.team_class[i - 1].abr ,"html") );
1963
        print( "%-*s", 3, config.team_class[i - 1].abr );
1964
        if ( report_html ) print( "</A>" );
1965
        print( " : %-*s  ", LEN_CLASS_NAME, config.team_class[i - 1].full_name );
1966
 
1967
        if( !( ++count % 5 ) )
1968
            print( "\n" );
1969
    }
1970
 
1971
    /*
1972
    **  Add link to the finish order report
1973
    */
1974
    if ( report_html )
1975
    {
1976
        print( "<A HREF=\"%s\">", p_filename(filebase, "finish" ,"html") );
1977
        print( "%-*s", 3, "All" );
1978
        print( "</A>" );
1979
        print( " : %-*s  ", LEN_CLASS_NAME, "Finishing Order" );
1980
    }
1981
 
1982
    /*
1983
    **  Country data - if countries have been defined
1984
    */
1985
    if( config.num_countries )
1986
    {
1987
        print( "\n\n" );
1988
        if ( report_html ) print_underline(TRUE);
1989
        print( "Country abbreviations" );
1990
        if ( report_html ) print_underline(FALSE);
1991
        print( "\n" );
1992
 
1993
        for( i = 0, count = 0; i < MAX_COUNTRY; i++ )
1994
        {
1995
            if( config.country_name[i].abr[0] )
1996
            {
1997
                print( "%-*s : %-*s  ", 4, config.country_name[i].abr,
1998
                       LEN_CNTRY_NAME, config.country_name[i].full_name );
1999
                if( !( ++count % 5 ) )
2000
                    print( "\n" );
2001
            }
2002
        }
2003
    }
18 david 2004
    print( "\n" );
1 root 2005
 
2006
    /*
2007
     * Other comments 
2008
     */
18 david 2009
    if ( full )
2010
    {
2011
        print( "\nPlace numbers (LP and EP)\n" );
2012
        print( "LP - Placing based on elapsed time within the leg.                Cat Plce - Placing within the category.\n" );
2013
        print( "EP - Placing based on accumulated times to the end of that leg.   Fin Plce - Overall placing within the event.\n" );
2014
    }
1 root 2015
 
2016
    /*
2017
     *  Insert the contents of the config.addendum file
2018
     *  or a defualt message
2019
     */
2020
    if( config.addendum[0] )
2021
        adfile = fopen( config.addendum, "rt" );  /* Open the file for reading */
2022
 
2023
    if( adfile )
2024
    {
2025
        while( fgets( line, sizeof(line)-1, adfile ) )
2026
            print( "%s", line );
2027
    }
2028
    else
2029
    {
2030
        print( "\nTiming and Results by\n" );
2031
        print( "Embedded Solutions\n" );
2032
    }
2033
}
2034
 
2035
/*========================================================================
2036
 *
2037
 *  Return place data
2038
 *
2039
 *  Purpose:
2040
 *      This function is called to return place data
2041
 *
2042
 *      This routine is called to fill a print team_buffer - to allow for
2043
 *      multiple calls to this function ( before the data is used ) a number
2044
 *      of static team_buffers are maintained
2045
 *
2046
 *  Parameters:
2047
 *      num         place - if not bad_times
2048
 *      disq        Disqualified flag
2049
 *      time        Time data is based on
2050
 *
2051
 *  Returns:
2052
 *      This function returns a pointer to the character string for the
2053
 *      number or a pointer to a bad_times string.
2054
 *
2055
 *========================================================================*/
2056
 
2057
char       *pi_place( int num, int disq, time_t time )
2058
{
2059
    static char store[2][5];                     /* 2 stores for 4 digit numbers */
2060
    static int  i = 0;                           /* Current index into store */
2061
    static char *dis = "D";                      /* Disqualified */
2062
    static char *non = "-";                      /* Invalid time */
2063
 
2064
    if( disq )                                   /* Disqualified team */
2065
        return ( dis );
2066
    if( time <= 0 )                              /* Unknown time */
2067
        return ( non );
2068
 
2069
    i++;
2070
    if( i >= 2 )
2071
        i = 0;                                   /* Select next entry */
2072
    sprintf( store[i], "%4d", num );
2073
    return ( store[i] );
2074
 
2075
}
2076
 
2077
/*========================================================================
2078
 *
2079
 *  Return place data
2080
 *
2081
 *  Purpose:
2082
 *      This function is called to Return place data
2083
 *
2084
 *      This routine is called to fill a print team_buffer - to allow for
2085
 *      multiple calls to this function ( before the data is used ) a number
2086
 *      of static team_buffers are maintained
2087
 *
2088
 *  Parameters:
2089
 *      num         place - if not bad_times
2090
 *      disq        Disqualified flag
2091
 *
2092
 *  Returns:
2093
 *      This function returns a pointer to the character string for the
2094
 *      number or a pointer to a bad_times string.
2095
 *
2096
 *========================================================================*/
2097
 
2098
char *pr_place( int num, int disq )
2099
{
2100
    static char store[2][5];                     /* 2 stores for 4 digit numbers */
2101
    static int  i = 0;                           /* Current index into store */
2102
    static char *dis = "U";
2103
 
2104
    if( disq )
2105
        return ( dis );
2106
 
2107
    i++;
2108
    if( i >= 2 )
2109
        i = 0;                                   /* Select next entry */
2110
    sprintf( store[i], "%4d", num );
2111
    return ( store[i] );
2112
 
2113
}
2114
 
2115
/*========================================================================
2116
 *
47 - 2117
 *  Return place data
2118
 *
2119
 *  Purpose:
2120
 *      This function is called to Return place data
2121
 *
2122
 *      This routine is called to fill a print team_buffer - to allow for
2123
 *      multiple calls to this function ( before the data is used ) a number
2124
 *      of static team_buffers are maintained
2125
 *
2126
 *  Parameters:
2127
 *      num         place - if not bad_times
2128
 *      disq        Disqualified flag
2129
 *
2130
 *  Returns:
2131
 *      This function returns a pointer to the character string for the
2132
 *      number or a pointer to a bad_times string.
2133
 *
2134
 *========================================================================*/
2135
 
2136
char *pr_place_ne( int num, int disq, int ne )
2137
{
2138
    static char store[2][5];                     /* 2 stores for 4 digit numbers */
2139
    static int  i = 0;                           /* Current index into store */
2140
    static char *dis = "U";
2141
    static char *nes = "NE";
2142
 
2143
    if ( ne )
2144
        return ( nes );
2145
 
2146
    if( disq )
2147
        return ( dis );
2148
 
2149
    i++;
2150
    if( i >= 2 )
2151
        i = 0;                                   /* Select next entry */
2152
    sprintf( store[i], "%4d", num );
2153
    return ( store[i] );
2154
 
2155
}
2156
 
2157
/*========================================================================
2158
 *
1 root 2159
 *  Check data for bad times
2160
 *
2161
 *  Purpose:
2162
 *      This function is called to Check data for bad times
2163
 *      Scan the sort data structure and locate entries that have incorrect
2164
 *      times.
2165
 *      
2166
 *      Entries that have invalid leg times are displayed to the operator
2167
 *      and the report process can be aborted
2168
 *
2169
 *  Parameters:
2170
 *      leg         Leg to test
2171
 *      mode            Either end or elapsed times to be tested
2172
 *
2173
 *  Returns:
2174
 *      Returns FALSE if the report operation is to be aborted
2175
 *
2176
 *========================================================================*/
2177
 
2178
bool ck_data( int leg, int mode )
2179
{
2180
    ty_s_data  *ptr;
2181
    unsigned    i;
2182
    int         bad = 0;
2183
    int         j = 0;
2184
    int         k, bad_leg;
2185
    time_t     *t;                               /* An array of times */
2186
 
29 - 2187
 
2188
 
1 root 2189
    ptr = sort_data;
2190
    for( i = 1; i <= sort_num; i++, ptr++ )
2191
    {
2192
        bad_leg = 0;
2193
        if( mode == C_DISQUAL )
2194
        {
2195
            ptr->flags.bad_times = ptr->flags.disqualified;
2196
            continue;
2197
        }
2198
 
2199
        if( mode == C_ELAPSED )
2200
            t = ptr->lege;
2201
        else
2202
            t = ptr->leg;
2203
 
2204
        if( ( ptr->flags.bad_times = ptr->flags.disqualified ) == FALSE )
2205
        {
2206
            if( leg <= 0 )
2207
            {
2208
                for( k = 0; k <= config.num_legs; k++ )
2209
                {
2210
                    if ( !(config.equestrian_leg && ptr->flags.non_equestrian && config.equestrian_leg == k  ))
2211
                        bad_leg |= ( t[k] <= 0 );
2212
                }
2213
            }
2214
            else
2215
            {
2216
                bad_leg = t[leg] <= 0;
2217
            }
2218
 
2219
            if( bad_leg )
2220
            {
2221
                ptr->flags.bad_times = TRUE;
29 - 2222
 
2223
                if ( ! report_all )
1 root 2224
                {
29 - 2225
                    if( !bad )
2226
                        printf( "Team with incorrect time information\n" );
2227
                    if( ++j > 15 )
2228
                    {
2229
                        printf( "\n" );
2230
                        j = 0;
2231
                    }
2232
                    printf( "%4d ", ptr->team );
2233
                    bad++;
1 root 2234
                }
2235
            }
2236
        }
2237
    }
2238
 
2239
    if( bad )
2240
    {
2241
        printf( "\n%d teams with incorrect times.\n", bad );
2242
        return ( !getyes
2243
                 ( "These have been flagged as unplaced - continue report" ) );
2244
    }
2245
    return ( FALSE );
2246
}
2247
 
2248
/*========================================================================
2249
 *
2250
 *  Update placing information
2251
 *
2252
 *  Purpose:
2253
 *      This function is called to Update placing information
2254
 *
2255
 *      This routine will rip through the data generating the team placing in
2256
 *      a) Within a leg
2257
 *      b) At the end of a leg
2258
 *      c) Within a leg by  class
2259
 *      d) At the end of a leg by class
2260
 *
2261
 *      This function is provided to allow the display routines to
2262
 *      be accessed and updated without the need to run a report
2263
 *
2264
 *  Parameters:
2265
 *      xxxx        a ptr to the xxxx stuff
2266
 *
2267
 *  Returns:
2268
 *      Nothing
2269
 *
2270
 *========================================================================*/
2271
 
2272
void srt_place(void)
2273
{
2274
    int         i, j;
2275
 
2276
    cur( 0, 5 );
2277
    printf( "Update the team placings to the data base\n" );
2278
    flush_out();
2279
    if( ck_data( -1, C_ELAPSED ) )
2280
        return;
2281
    do_big_sort();
2282
 
2283
    /*
2284
     * Generate the stats and display them on the screen for interest
2285
     * This operation will not hurt - so why not
2286
     */
2287
 
2288
    gen_stats();
2289
    printf( "\nEvent statistics\n\n" );
2290
    printf( "%-*s   %-13s ", LEN_CLASS_NAME, "", "Overall" );
2291
    for( i = 1; i <= config.num_legs; i++ )
2292
        printf( "%-13s ", config.leg_name[i - 1] );
2293
 
2294
    for( j = 0; j <= config.num_class; j++ )
2295
    {
2296
        printf( "\n%-*s : ", LEN_CLASS_NAME,
2297
                j ? config.team_class[j - 1].full_name : "Overall" );
2298
        for( i = 0; i <= config.num_legs; i++ )
2299
        {
2300
            printf( "%4d ", stats.fast.team[i][j] );
2301
            printf( "%s ", time_a( stats.fast.time[i][j] ) );
2302
        }
2303
        printf( "\n%*s : ", LEN_CLASS_NAME, "Average" );
2304
        for( i = 0; i <= config.num_legs; i++ )
2305
        {
2306
            printf( "     %s ", time_a( stats.average[i][j] ) );
2307
        }
2308
    }
2309
    printf( "\nAny key to continue" );
2310
    ( void ) getinp();
2311
}
2312
 
2313
/*========================================================================
2314
 *
2315
 *  Calculate summary information
2316
 *
2317
 *  Purpose:
2318
 *      This function is called to calculate summary information
2319
 *
2320
 *  Parameters:
2321
 *      ptr         - Address of a summary structure to fill in
2322
 *
2323
 *  Returns:
2324
 *      Nothing
2325
 *
2326
 *========================================================================*/
2327
 
2328
void calc_class_summary( t_class_summary * ptr )
2329
{
2330
    int i;
2331
 
2332
    /*
2333
    **  Reset the data
2334
    */
2335
    memset ( ptr, 0, sizeof (*ptr ));
2336
 
2337
    /*
2338
     * Extract the required data from the data base
2339
     * Only save that information required for the operation
2340
     */
2341
 
2342
    for( i = config.min_team; i <= config.max_team; i++ )
2343
    {
2344
        if( valid_field( i ) && g_record( i, &team_buf ) )
2345
        {
2346
            ptr->total.total++;
2347
            ptr->class[team_buf.class].total++;
2348
 
2349
            if ( team_buf.flags.disqualified )
2350
            {
2351
                ptr->class[team_buf.class].disqualified++;
2352
                ptr->total.disqualified++;
2353
            }
2354
 
2355
            if ( config.nonequestrian_class && team_buf.flags.non_equestrian )
2356
            {
2357
                ptr->class[team_buf.class].non_equestrian++;
2358
                ptr->total.non_equestrian++;
2359
            }
2360
        }
2361
    }
13 david 2362
 
2363
    /*
2364
    **  Fix up the totals for the non equestrians
2365
    **  This is not a real category but a summary of the others.
2366
    */
2367
    if ( config.nonequestrian_class  )
2368
    {
2369
        ptr->class[config.nonequestrian_class].total += ptr->total.non_equestrian;
2370
    }
1 root 2371
}
2372
 
2373
/*========================================================================
2374
 *
2375
 *  Display summary information
2376
 *
2377
 *  Purpose:
2378
 *      This function is called to display summary information
2379
 *
2380
 *  Parameters:
2381
 *      None
2382
 *
2383
 *  Returns:
2384
 *      Nothing
2385
 *
2386
 *========================================================================*/
2387
 
2388
void display_summary (void)
2389
{
2390
 
2391
    t_class_summary data;
2392
    int         i;
2393
    int         line = 2;
2394
 
2395
    cur( 0, line );
2396
    printf( "Generating Summary Information" );
2397
    calc_class_summary( & data );
2398
 
2399
 
2400
    /*
2401
    **  Display summary stats
2402
    */
2403
 
2404
    cur( 0, line );
2405
    console_clreol();
2406
    printf( "Summary Information\n\n" );
2407
    printf( "%*s : %-7s %-7s%-7s\n", LEN_CLASS_NAME,
2408
                                      "Category",
2409
                                      "Total",
2410
                                      "Disq",
2411
                                      "NonEq" );
2412
 
2413
    for( i = 0; i < config.num_class; i++ )
2414
    {
2415
        /*
2416
        **  The non-equestrian leg does not have any data
2417
        **  Supress the display
2418
        */
2419
        if ( config.nonequestrian_class == i+1  )
2420
            continue;
2421
 
2422
        printf( "%*s : %-7d %-7d %-7d\n", LEN_CLASS_NAME,
2423
                                          config.team_class[i].full_name,
2424
                                          data.class[i+1].total,
2425
                                          data.class[i+1].disqualified,
2426
                                          data.class[i+1].non_equestrian );
2427
    }
2428
 
2429
    printf( "\n" );
2430
    printf( "%*s : %-7d %-7d %-7d\n", LEN_CLASS_NAME,
2431
                                      "Totals",
2432
                                      data.total.total,
2433
                                      data.total.disqualified,
2434
                                      data.total.non_equestrian );
2435
 
2436
    printf( "\nAny key to continue " );
2437
    getinp();
2438
}
2439
 
13 david 2440
/*========================================================================
2441
 *
2442
 *  Print summary information
2443
 *
2444
 *  Purpose:
2445
 *      This function is called to print summary information
2446
 *
2447
 *  Parameters:
2448
 *      None
2449
 *
2450
 *  Returns:
2451
 *      Nothing
2452
 *
2453
 *========================================================================*/
1 root 2454
 
13 david 2455
void pri_summary (void)
2456
{
2457
 
2458
    t_class_summary data;
2459
    int         i;
2460
    int         line = 2;
2461
 
2462
 
2463
    if( !open_printer( "", "summary", 132, 0, "Summary Information" ) )
2464
        return;
2465
 
2466
    cur( 0, line );
2467
    printf( "Generating Summary Information" );
2468
    calc_class_summary( & data );
2469
 
2470
 
2471
    /*
2472
    **  Display summary stats
2473
    */
2474
 
2475
    print( "%*s : %-7s %-7s%-7s\n", LEN_CLASS_NAME,
2476
                                      "Category",
2477
                                      "Total",
2478
                                      "Disq",
2479
                                      "NonEq" );
2480
 
2481
    for( i = 0; i < config.num_class; i++ )
2482
    {
2483
        /*
2484
        **  The non-equestrian leg does not have any data
2485
        **  Supress the display
2486
        */
2487
        if ( config.nonequestrian_class == i+1  )
2488
            continue;
2489
 
2490
        print( "%*s : %-7d %-7d %-7d\n", LEN_CLASS_NAME,
2491
                                          config.team_class[i].full_name,
2492
                                          data.class[i+1].total,
2493
                                          data.class[i+1].disqualified,
2494
                                          data.class[i+1].non_equestrian );
2495
    }
2496
 
2497
    print( "\n" );
2498
    print( "%*s : %-7d %-7d %-7d\n", LEN_CLASS_NAME,
2499
                                      "Totals",
2500
                                      data.total.total,
2501
                                      data.total.disqualified,
2502
                                      data.total.non_equestrian );
2503
 
2504
    close_printer();
29 - 2505
    if ( !report_all )
2506
    {
2507
        printf( "\nAny key to continue " );
2508
        getinp();
2509
    }
13 david 2510
}
2511
 
2512
 
2513
 
1 root 2514
/*========================================================================
2515
 *
2516
 *  Main sort routine for final data
2517
 *
2518
 *  Purpose:
2519
 *      This function is called to do the report sort routine for final data
2520
 *      This routine will fill all the gaps in the sort_aux structure
2521
 *
2522
 *  Parameters:
2523
 *      None
2524
 *
2525
 *  Returns:
2526
 *      Nothing
2527
 *
2528
 *========================================================================*/
2529
 
2530
void do_big_sort(void)
2531
{
2532
    int         i, k;                            /* Looooopy things */
2533
    unsigned    j;
2534
    ty_s_data  *ptr;                             /* Pointer to sort data */
2535
    int         class;                           /* Current class */
2536
 
2537
    printf( "Sorting it ALL out" );
2538
    flush_out();
2539
 
2540
    for( i = 0; i <= config.num_legs; i++ )
2541
    {
2542
        /*
2543
        **  Sort on leg elapsed time
49 - 2544
        **  Then save the teams elapsed place in each leg
1 root 2545
        */
2546
        sort_team_data( i, S_L );
49 - 2547
        for( j = 1, k = 1, ptr = sort_data; j <= sort_num; ptr++, j++ )
1 root 2548
        {
49 - 2549
            if ( ptr->class == config.nonequestrian_class )
2550
                continue;
2551
 
2552
            sort_aux[ptr->team].l_place[i] = k++;
1 root 2553
            sort_aux[ptr->team].team = ptr->team;
2554
        }
2555
 
2556
        /*
2557
        **  Sort on leg end time
2558
        **  Then save the teams place at the end of each leg
2559
        */
2560
        sort_team_data( i, S_LE );
49 - 2561
        for( j = 1, k = 1, ptr = sort_data; j <= sort_num; ptr++, j++ )
2562
        {
2563
            if ( ptr->class == config.nonequestrian_class )
2564
                continue;
2565
 
2566
            sort_aux[ptr->team].le_place[i] = k++;
2567
        }
1 root 2568
 
2569
        /*
2570
        **  Sort on elapsed time per class
2571
        **  The save the teams elapsed place in each leg per class
2572
        */
2573
        sort_team_data( i, S_LC );
2574
        class = -1;
2575
        for( k = 1, j = 1, ptr = sort_data; j <= sort_num; j++, ptr++ )
2576
        {
2577
            if( class != ptr->class )
2578
            {
2579
                k = 1;
2580
                class = ptr->class;
2581
            }
2582
            sort_aux[ptr->team].lc_place[i] = k++;
2583
        }
2584
 
2585
        /*
2586
        **  Sort on end time per class
2587
        **  Then save the teams place at the end of each leg per class
2588
        */
2589
        sort_team_data( i, S_LEC );
2590
        class = -1;
2591
        for( k = 1, j = 1, ptr = sort_data; j <= sort_num; j++, ptr++ )
2592
        {
2593
            if( class != ptr->class )
2594
            {
2595
                k = 1;
2596
                class = ptr->class;
2597
            }
2598
            sort_aux[ptr->team].lec_place[i] = k++;
2599
        }
2600
    }
2601
 
2602
    /*
2603
    **  Write the place information back to disk for use in the displays
2604
    */
2605
    printf( "\nWriting it all back to the disk file" );
2606
    flush_out();
2607
 
2608
    for( i = config.min_team; i <= config.max_team; i++ )
2609
    {
2610
        if( sort_aux[i].team && valid_field( i ) && g_record( i, &team_buf ) )
2611
        {
2612
            for( k = 0; k <= config.num_legs; k++ )
2613
            {
2614
                team_buf.leg[k].l_place = sort_aux[i].l_place[k];
2615
                team_buf.leg[k].le_place = sort_aux[i].le_place[k];
2616
                team_buf.leg[k].lc_place = sort_aux[i].lc_place[k];
2617
                team_buf.leg[k].lec_place = sort_aux[i].lec_place[k];
2618
            }
2619
            put_team_record( i, &team_buf );
2620
        }
2621
    }
2622
}
2623
 
2624
/*========================================================================
2625
 *
2626
 *  Sort in memory buffer
2627
 *
2628
 *  Purpose:
2629
 *      This function is called to Sort in memory buffer
2630
 *
2631
 *  Parameters:
2632
 *      leg         Requested leg
2633
 *      mode        Defines the sort mode
2634
 *
2635
 *  Returns:
2636
 *      Nothing
2637
 *
2638
 *========================================================================*/
2639
 
2640
void sort_team_data( int leg, int mode )
2641
{
2642
 
2643
    unsigned    j;
2644
    ty_s_data  *ptr;
2645
 
2646
    sort_leg = leg;                              /* Leg is global for the comparison function */
2647
    sort_mode = mode;                            /* Mode is global for compare function */
2648
 
2649
    qsort( ( char * ) sort_data, sort_num, sizeof( ty_s_data ), sort_comp );
2650
 
2651
    /*
2652
     * Insert "place data" into the sorted data
2653
     * This simply the index into the array of data - after its been
2654
     * sorted.
2655
     */
2656
    ptr = sort_data;
2657
    for( j = 1; j <= sort_num; j++, ptr++ )
2658
        ptr->place = j;
2659
 
2660
}
2661
 
2662
/*========================================================================
2663
 *
2664
 *  qsort comparison function
2665
 *
2666
 *  Purpose:
2667
 *      This function is called by qsort as a Sort comparison function
2668
 *
2669
 *  Parameters:
2670
 *      a       - 1st record
2671
 *      b       - 2nd record
2672
 *
2673
 *  Returns:
2674
 *      value to qsort
2675
 *
2676
 *========================================================================*/
2677
 
2678
int sort_comp( const void * aa, const void * bb )
2679
{
2680
    const ty_s_data * a = aa;
2681
    const ty_s_data * b = bb;
2682
 
2683
 
2684
    int         i;                               /* One of those */
2685
    time_t      ta, tb;                          /* Leg times */
2686
    int         na, nb;                          /* Number of valid legs */
2687
    time_t      tta, ttb;                        /* Temp times */
2688
 
2689
    /*
2690
    **  Sorting on Team Number
2691
    */
2692
    if( sort_mode == S_TEAM )
2693
        return ( a->team - b->team );
2694
 
2695
    /*
2696
    **  Sorting on Class and Team Number
2697
    */
2698
    if( sort_mode == S_CLASS )
2699
    {
2700
        if( a->class != b->class )
2701
            return ( a->class - b->class );
2702
        else
2703
            return ( a->team - b->team );
2704
    }
2705
 
2706
    /*
2707
    **  Sorting within a class
2708
    **  First sort on the class
2709
    */
2710
    if( sort_mode == S_LEC || sort_mode == S_LC )   /* Sort within a class */
2711
        if( a->class != b->class )
2712
            return ( a->class - b->class );
2713
 
49 - 2714
#if 1
1 root 2715
    /*
49 - 2716
    **  Always put the nonequestrian_class at the end
2717
    **  Simplifies the creation of ordered lists as these
2718
    **  Entries are not present in the main body
2719
    */
2720
    if ( a->class == config.nonequestrian_class ||  b->class == config.nonequestrian_class )
2721
    {
2722
        if ( a->class == config.nonequestrian_class &&  b->class == config.nonequestrian_class )
2723
        {
2724
        }
2725
        else
2726
        {
2727
            return ( a->class == config.nonequestrian_class ? 1 : -1 );
2728
        }
2729
 
2730
    }
2731
#endif
2732
 
2733
    /*
1 root 2734
    **  Now we need to examine the times as we have sorted
2735
    **  on every thing else.
2736
    **
2737
    **  If one of the teams has bad_times, then that team is placed
2738
    **  lower in the sorting order. If both teams have bad times
2739
    **  then sort on team number. ie: Unplaced teams are sorted on
2740
    **  team number
47 - 2741
    **
2742
    **  If not sorting within a class (ie Overall), then Non_Equestrian
2743
    **  is better than a bad time. Places NE before disqualified
2744
    **
2745
    **
2746
    **  Note: NE also have bad_times set
1 root 2747
    */
49 - 2748
#if 1
1 root 2749
    if( a->flags.bad_times || b->flags.bad_times )  /* Valid data has precedence */
2750
    {
48 - 2751
        if( a->flags.bad_times && b->flags.bad_times )
47 - 2752
        {
49 - 2753
            if( sort_mode == S_LE || sort_mode == S_L || 1 ) /* Sort NOT within a class */
47 - 2754
            {
48 - 2755
                if( a->flags.non_equestrian || b->flags.non_equestrian )
47 - 2756
                {
48 - 2757
                    if( a->flags.non_equestrian && b->flags.non_equestrian )
2758
                    {
2759
                        /*
2760
                        **  Both are non equestrian
2761
                        **  Let the time sort operate ...
2762
                        */
49 - 2763
                        //return ( a->team - b->team );
48 - 2764
                    }
2765
                    else
2766
                    {
2767
                        /* Good times better than NE */
2768
                        return ( a->flags.non_equestrian ? -1 : 1 );
2769
                    }
47 - 2770
                }
2771
            }
48 - 2772
            else
2773
               return ( a->team - b->team );
47 - 2774
        }
1 root 2775
        else
2776
            return ( a->flags.bad_times ? 1 : -1 );
2777
    }
49 - 2778
#else
2779
    if( a->flags.bad_times || b->flags.bad_times )  /* Valid data has precedence */
2780
    {
2781
        if( a->flags.bad_times && b->flags.bad_times )
2782
            return ( a->team - b->team );
2783
        else
2784
            return ( a->flags.bad_times ? 1 : -1 );
2785
    }
1 root 2786
 
49 - 2787
    /*
2788
    **  Not sorting within a class ie: Overall
2789
    **  Non-Equestrian is at the end, so that it doesn't get counted in the
2790
    **  finishing order
2791
    */
2792
    if( sort_mode == S_LE || sort_mode == S_L )     /* Sort NOT within a class */
2793
    {
2794
        if( a->flags.non_equestrian || b->flags.non_equestrian )
2795
        {
2796
            if( a->flags.non_equestrian && b->flags.non_equestrian )
2797
                return ( a->team - b->team );
2798
            else
2799
                return ( a->flags.non_equestrian ? 1 : -1 );
2800
        }
2801
    }
2802
#endif
1 root 2803
 
2804
    /*
2805
    **  Before we sort on times we must determine which time to
2806
    **  use. Finish time, Leg end times, Leg Elapsed times.
2807
    */
2808
 
2809
    switch ( sort_mode )
2810
    {
2811
      /*
2812
      **    Sort on finish times
2813
      */
2814
      case S_FIN:
2815
        ta = a->leg[sort_leg];
2816
        tb = b->leg[sort_leg];
2817
        break;
2818
 
2819
 
2820
      /*
2821
      **    Sort on accumulated leg times
2822
      */
2823
      case S_LE:
2824
      case S_LEC:
2825
        if( sort_leg )
2826
        {
2827
            /*
2828
            **  Calculate accumulated time up to the desired leg
2829
            **  If the two teams have a different number of valid
2830
            **  leg times then order by the team that has completed
2831
            **  more legs.
2832
            */
2833
            ta = tb = ( time_t ) 0;
2834
            na = nb = 0;
2835
            for( i = 1; i <= sort_leg; i++ )
2836
            {
2837
                tta = a->lege[i];
2838
                ttb = b->lege[i];
2839
                if( tta > 0 )
2840
                {
2841
                    na++;
2842
                    ta += tta;
2843
                }
2844
                if( ttb > 0 )
2845
                {
2846
                    nb++;
2847
                    tb += ttb;
2848
                }
2849
            }
2850
            if( na != nb )
2851
                return ( nb - na );
2852
        }
2853
        else
2854
        {
2855
            ta = a->leg[sort_leg] - a->start;
2856
            tb = b->leg[sort_leg] - b->start;
2857
        }
2858
        break;
2859
 
2860
      /*
2861
      **    Sort on Elapsed times
2862
      */
2863
      case S_LC:
2864
      case S_L:
2865
        ta = a->lege[sort_leg];
2866
        tb = b->lege[sort_leg];
2867
        break;
2868
 
2869
      /*
2870
      **    Just to be sure ...
2871
      */
2872
      default:
2873
        return ( 0 );
2874
    }
2875
 
2876
    /*
2877
    **  Finally. Compare the required team times
2878
    */
2879
    if( ta == tb )
2880
        return ( a->team - b->team );
2881
    if( ( ta > 0 ) && ( tb > 0 ) )
2882
        return ( ( int ) ( ta - tb ) );
2883
    return ( ( ta > 0 ) ? -1 : 1 );
2884
}
2885
 
2886
/*========================================================================
2887
 *
18 david 2888
 *  qsort comparison function - competitor names
2889
 *
2890
 *  Purpose:
2891
 *      This function is called by qsort as a Sort comparison function
2892
 *
2893
 *  Parameters:
2894
 *      a       - 1st record
2895
 *      b       - 2nd record
2896
 *
2897
 *  Returns:
2898
 *      value to qsort
2899
 *
2900
 *========================================================================*/
2901
 
2902
int sort_comp_cname( const void * aa, const void * bb )
2903
{
25 - 2904
    ty_s_namedata * a = (ty_s_namedata *)aa;
2905
    ty_s_namedata * b = (ty_s_namedata *)bb;
18 david 2906
 
2907
 
2908
    int         i;                               /* One of those */
2909
 
2910
    /*
2911
    **  Sort by name
2912
    */
2913
    i = strcmp ( a->name, b->name );
2914
    if ( i )
2915
        return ( i );
2916
    a->multi=1;
2917
    b->multi=1;
2918
 
2919
    /*
2920
    **  Sort by Leg
2921
    */
2922
    i = a->leg - b->leg;
2923
    if ( i )
2924
        return ( i );
2925
 
2926
    /*
2927
    **  Sorting on Team Number
2928
    */
2929
    return ( a->team - b->team );
2930
 
2931
}
2932
 
2933
/*========================================================================
2934
 *
1 root 2935
 *  load report data into memory
2936
 *
2937
 *  Purpose:
2938
 *      This routine will pull all the data into memory 
2939
 *      Not all the team data is loaded. Only that essential for the
2940
 *      operation of the sort routine is loaded
2941
 *
2942
 *  Parameters:
2943
 *      None
2944
 *
2945
 *  Returns:
2946
 *      TRUE - All is well
2947
 *
2948
 *========================================================================*/
2949
 
2950
bool load_report_data(void)
2951
{
2952
 
2953
    ty_s_data  *ptr;                             /* pointer to sort data type */
48 - 2954
    ty_s_data  *last;
1 root 2955
    int         j;
2956
    unsigned    num;
2957
 
2958
    printf( "Loading team information - This will not hurt" );
2959
    flush_out();
2960
 
2961
    /*
2962
     * Fetch memory for the data store
2963
     */
2964
 
2965
    if( sort_data )
2966
        free( ( char * ) sort_data );
2967
    sort_data = 0;
2968
 
2969
    if( sort_aux )
2970
        free( ( char * ) sort_aux );
2971
    sort_aux = 0;
2972
    sort_num = 0;                                /* Counter of records in the array */
2973
 
2974
    /*
2975
    **  Allocate memory for the data structures
2976
    **  This will be free'd
2977
    */
2978
    num = config.max_team - config.min_team + 1 ;
2979
 
2980
    /*
2981
    **  Allow for non-equestrian teams - since some of the data is loaded twice
2982
    **  Take a guess that at most 1/2 the teams will be non-equestrian
2983
    */
2984
    num = num * 3 / 2;
2985
 
2986
    sort_data = ( ty_s_data * ) calloc ( num , sizeof( ty_s_data ) );
2987
    sort_aux = ( ty_s_aux * ) calloc( num + 1, sizeof( ty_s_aux ) );
2988
 
2989
    if( sort_data == 0 || sort_aux == 0 )
2990
    {
2991
        printf( "\n\nError in allocating memory\n" );
2992
        sleep( 5 );
2993
        return ( FALSE );
2994
    }
2995
 
2996
    /*
2997
    **  Load data into the memory based data structure
2998
    **  Only load data for valid-teams
2999
    **  Load essential data
3000
    **      Team Number, class and flags
3001
    **      Leg end and elapsed times
3002
    */
3003
    ptr = sort_data;
3004
    for( team = config.min_team; team <= config.max_team; team++ )
3005
    {
3006
        if( valid_field( team ) )
3007
        {
3008
            g_record( team, &team_buf );
3009
            if( team_buf.flags.valid )
3010
            {
48 - 3011
                last = ptr;
1 root 3012
                ptr->team = team;
3013
                for( j = 0; j < MAX_LEGS + 1; j++ )
3014
                {
3015
                    ptr->lege[j] = team_buf.leg[j].elapsed;
3016
                    ptr->leg[j] = team_buf.leg[j].end;
3017
                }
3018
                ptr->start = team_buf.leg[0].start;
3019
                ptr->class = team_buf.class;
3020
 
3021
                ptr->flags = team_buf.flags;
3022
                ptr++;
3023
                sort_num++;
3024
 
3025
                /*
3026
                **  If non-equestrian support is enabled then
3027
                **  duplicate and modify data for the non-equestrian teams
3028
                **      - Change the class
3029
                **      - Modify the leg time
3030
                */
49 - 3031
#if 1
1 root 3032
                if ( config.nonequestrian_class && team_buf.flags.non_equestrian )
3033
                {
3034
                    ptr->team = team;
3035
                    ptr->lege[0] = 0;
3036
 
3037
                    for( j = 0; j < MAX_LEGS + 1; j++ )
3038
                    {
3039
                        if ( j == config.equestrian_leg )
3040
                        {
48 - 3041
                            last->lege[j] = ptr->lege[j] = 0;
1 root 3042
                            if ( config.equestrian_leg > 1 )
48 - 3043
                                last->leg[j] = ptr->leg[j] = ptr->leg[j-1];
1 root 3044
                        }
3045
                        else
3046
                        {
3047
                            if ( j )
48 - 3048
                                last-> lege[j] = ptr->lege[j] = team_buf.leg[j].elapsed;
3049
                            last->leg[j] = ptr->leg[j] = team_buf.leg[j].end;
1 root 3050
                            ptr->lege[0] += ptr->lege[j] ;
48 - 3051
                            last->lege[0] = ptr->lege[0] ;
1 root 3052
                        }
3053
                    }
3054
 
48 - 3055
                    last->start = ptr->start = team_buf.leg[0].start;
1 root 3056
                    ptr->class = config.nonequestrian_class;
3057
                    ptr->flags = team_buf.flags;
3058
                    ptr->flags.disqualified = 0;
48 - 3059
 
3060
 
1 root 3061
                    ptr++;
3062
                    sort_num++;
3063
                }
49 - 3064
#endif
1 root 3065
            }
3066
        }
3067
    }
3068
    return ( TRUE );
3069
}
3070
 
3071
/*========================================================================
3072
 *
3073
 *  Generate all the stats
3074
 *
3075
 *  Purpose:
3076
 *      This function is called to Generate all the stats
3077
 *
3078
 *  Parameters:
3079
 *      None
3080
 *
3081
 *  Returns:
3082
 *      Nothing
3083
 *
3084
 *========================================================================*/
3085
 
3086
void gen_stats(void)
3087
{
3088
    ty_s_data  *ptr;
3089
    unsigned    i;
3090
    int         j;
3091
    int         k;
3092
 
3093
    /*
3094
     * Init all the stats 
3095
     */
3096
    for( i = 0; i <= MAX_LEGS; i++ )
3097
    {
3098
        for( j = 0; j <= MAX_CLASS; j++ )
3099
        {
3100
            stats.team[i][j] = 0;
3101
            stats.fast.team[i][j] = 0;
3102
            stats.fast.time[i][j] = ( time_t ) - 1;
3103
            stats.average[i][j] = 0;
3104
        }
3105
    }
3106
 
3107
    for( i = 1, ptr = sort_data; i <= sort_num; i++, ptr++ )
3108
    {
3109
        /*
3110
        **  If there is any bad times in the team record, then none
3111
        **  of the data can be trusted.
3112
        **
3113
        **  If the team has been disqualified, then don't use any
3114
        **  of the data.
3115
        */
3116
        if( ptr->flags.bad_times || ptr->flags.disqualified )
3117
            continue;
3118
 
3119
        for( j = 0; j <= config.num_legs; j++ )
3120
        {
3121
            if( ptr->lege[j] <= 0 )              /* Ignore bad data */
3122
                continue;
3123
 
3124
            /*
3125
            **  Determine fastest team : overall
3126
            **  Ignore the non-equestrian data as this is in the list twice
3127
            */
3128
            if( ( ptr->lege[j] < stats.fast.time[j][0] )
3129
                || ( stats.fast.time[j][0] < 0 ) )
3130
            {
3131
                if ( ptr->class != config.nonequestrian_class )
3132
                {
3133
                    stats.fast.team[j][0] = ptr->team;
3134
                    stats.fast.time[j][0] = ptr->lege[j];
3135
                }
3136
            }
3137
 
3138
            /*
3139
            **  Determine fastest team : within a class
3140
            */
3141
            if( ( ptr->lege[j] < stats.fast.time[j][ptr->class] )
3142
                || stats.fast.time[j][ptr->class] < 0 )
3143
            {
3144
                stats.fast.team[j][ptr->class] = ptr->team;
3145
                stats.fast.time[j][ptr->class] = ptr->lege[j];
3146
            }
3147
 
3148
            /*
3149
            **  Sum the end times : overall
3150
            */
3151
            if ( ptr->class != config.nonequestrian_class )
3152
            {
3153
                stats.average[j][0] += ptr->lege[j];
3154
                stats.team[j][0]++;
3155
            }
3156
 
3157
 
3158
            /*
3159
            **  Sum the end times : within a class
3160
            */
3161
            stats.average[j][ptr->class] += ptr->lege[j];
3162
            stats.team[j][ptr->class]++;
3163
        }
3164
    }
3165
 
3166
    /*
3167
     * Calculate the averages
3168
     */
3169
    for( k = 0; k <= config.num_legs; k++ )
3170
    {
3171
        for( j = 0; j <= config.num_class; j++ )
3172
        {
3173
            if( stats.team[k][j] )
3174
                stats.average[k][j] /= stats.team[k][j];
3175
            else
3176
                stats.average[k][j] = ( time_t ) - 1;
3177
        }
3178
    }
3179
}
3180
 
3181
/********************************* EOF ***********************************/