Subversion Repositories svn1-original

Rev

Rev 339 | Details | Compare with Previous | Last modification | View Log | RSS feed

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