Subversion Repositories svn1

Rev

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