Subversion Repositories svn1

Rev

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

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