Subversion Repositories svn1-original

Rev

Rev 180 | Rev 193 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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