Subversion Repositories svn1

Rev

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

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