Subversion Repositories svn1-original

Rev

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

Rev Author Line No. Line
95 - 1
/*************************************************************************
2
*           Copyright (C) 1995 Embedded Solutions
3
*                       All rights reserved
4
*
5
* file:     src\legtime.c
6
*
7
* purpose:  Leg time calculations
8
*
9
* functions
10
*   set_legs                    - Menu: Setup leg times
11
*   tm_lgs                      - Set up the leg start times for leg
12
*   leg_start                   - Set up the leg start times
13
*   tm_fixedstart               - Set the start time for a specific leg
14
*   tm_staggered                - Set a staggered start time for a specific leg
15
*   tm_clearleg                 - Clear start times on a specific leg
16
*   leg_ini                     - Initialize all stored times
17
*   tm_init                     - Initialize all team data
18
*   tm_gen                      - Generate dummy team names
19
*   legs_start_report           - Generate starters report
20
*   ls_timer                    - print the current leg entry
21
*   ls_team                     - print next ( numeric ) leg entry
22
*   sort_legs                   - Qsort callback function
23
*
24
* programmer: David Purdie
25
*
26
* revision  date        by      reason
27
*           11-Oct-89   DDP     leg-3 starttime. Now has an option to generate
28
*                               a printed report of teams and times
29
*
30
*           21-May-90   MV      now able to set start time and generate
31
*                               a printed report for any leg
32
*   00.0    27/01/95    DDP     Tidies up the program and formatted the file
33
*
34
**************************************************************************/
137 david 35
#include    "QDebug"
199 david 36
#include    "mainwindow.h"
95 - 37
#include    "consts.h"
38
#include    "structs.h"
39
#include    "proto.h"
40
 
41
/*========================================================================
42
 *
43
 *  Set up the leg start times for leg
44
 *
45
 *  Purpose:
46
 *      This function is called to Set up the leg start times for leg
47
 *      The start time is based on category information
48
 *
49
 *  Parameters:
50
 *      None
51
 *
52
 *  Returns:
53
 *      Nothing
54
 *
55
 *========================================================================*/
56
 
135 david 57
void tm_lgs1(int leg, time_t starttime, time_t delta, bool report_it, bool clear_it)
95 - 58
{
59
    t_legs     *data;                            /* Address of table */
60
    t_legs     *dptr;                            /* Moving pointer */
61
    int         num_records;                     /* Number of records in array */
62
    int         i;
174 - 63
    team_type   team_buf;
95 - 64
 
65
 
66
    /*
67
    **  Read existing data into memory
68
    */
69
    data = ( t_legs * ) calloc( ( unsigned ) ( config.max_team - config.min_team + 2 ), sizeof( t_legs ) ); /* Fetch memory */
70
    if( !data )
71
    {
137 david 72
        qDebug( "No memory for report" );
95 - 73
        return;
74
    }
75
 
76
    /*
77
     * Extract the required data from the data base
78
     * Only save that information required for the operation
79
     *      - The end time of the previous leg
80
     */
81
    dptr = data;
82
    num_records = 0;
83
    for( i = config.min_team; i <= config.max_team; i++ )
84
    {
85
        if( valid_field( i ) && g_record( i, &team_buf ) )
86
        {
87
            dptr->numb = team_buf.numb;
88
            dptr->start = team_buf.leg[leg-1].end;
89
            dptr->flags = team_buf.flags;
90
            dptr++;
91
            num_records++;
92
        }
93
    }
94
 
95
    /*
96
     * Sort the data into some logical order 
97
     */
98
    qsort( ( char * ) data, num_records, sizeof( t_legs ), sort_legs );
99
 
100
    /*
101
    **  Update the team information based on the start order
102
    **  Ignore validity flags as the data will have been sorted with
103
    **  these in mind.
104
    */
105
    for( dptr = data, i = 0; i < num_records; i++, dptr++ )
106
    {
107
        if( valid_field( dptr->numb ) )
108
        {
109
            g_record( dptr->numb, &team_buf );
110
            team_buf.leg[leg].start = starttime;
111
            starttime += delta;
112
            team_buf.leg[leg].manual = TRUE;
113
 
114
            set_times( &team_buf );
115
            test_times( &team_buf, 0 );
116
            put_team_record( dptr->numb, &team_buf );
117
        }
118
    }
119
 
120
    /*
121
    **  Release the data
122
    */
123
    free( data );
124
 
125
    if( report_it )
137 david 126
        legs_start_report(leg);
95 - 127
 
128
    if ( clear_it )
137 david 129
        tm_clearleg_specified( leg, TRUE);
95 - 130
}
131
 
132
/*========================================================================
133
 *
134
 *  Set up the leg start times for leg
135
 *
136
 *  Purpose:
137
 *      This function is called to Set up the leg start times for leg
138
 *      The start time is based on current placing with:
139
 *          A constant offset added ( ie: lunch)
140
 *          A fixed increment
141
 *
142
 *  Parameters:
143
 *      None
144
 *
145
 *  Returns:
146
 *      Nothing
147
 *
148
 *========================================================================*/
149
 
134 - 150
void tm_lgs(int leg, time_t delta, bool report_it, bool clear_it)
95 - 151
{
174 - 152
    team_type   team_buf;
153
    int team = config.min_team;                      /* Team we are working with */
95 - 154
    while( team <= config.max_team )
155
    {
156
        if( valid_field( team ) )
157
        {
158
            g_record( team, &team_buf );
159
            if( team_buf.flags.valid && team_buf.leg[leg - 1].end > 0 )
160
            {
161
                team_buf.leg[leg].start = team_buf.leg[leg - 1].end + delta;
162
                team_buf.leg[leg].manual = TRUE;
163
            }
164
            else
165
                team_buf.leg[leg].start = ( time_t ) - 1;
166
 
167
            set_times( &team_buf );
168
            test_times( &team_buf, 0 );
169
            put_team_record( team, &team_buf );
170
        }
171
        team++;
172
    }
173
 
174
    if( report_it )
137 david 175
        legs_start_report(leg);
95 - 176
 
177
    if ( clear_it )
137 david 178
        tm_clearleg_specified( leg, TRUE);
95 - 179
}
180
 
181
/*========================================================================
182
 *
183
 *  Set up the leg start times
184
 *
185
 *  Purpose:
186
 *      This function is called to Set up the leg start times
187
 *
188
 *  Parameters:
189
 *      None
190
 *
191
 *  Returns:
192
 *      Nothing
193
 *
194
 *========================================================================*/
195
 
196
void leg_start(void)
197
{
174 - 198
    team_type   team_buf;
199
    int team = config.min_team;                      /* Team we are working with */
95 - 200
    while( team <= config.max_team )
201
    {
202
        if( valid_field( team ) )
203
        {
204
            ( void ) g_record( team, &team_buf );
205
            if( team_buf.teamclass > 0 && team_buf.teamclass <= config.num_class )
206
                team_buf.leg[0].start =
207
                    config.team_class[team_buf.teamclass - 1].start;
208
            else
209
                team_buf.leg[0].start = ( time_t ) - 1;
210
            team_buf.leg[1].manual = 0;
211
            team_buf.leg[1].start = team_buf.leg[0].start;
212
            team_buf.leg[0].l_place = 0;
213
            team_buf.leg[0].le_place = 0;
214
            team_buf.leg[0].lec_place = 0;
215
            team_buf.leg[0].lc_place = 0;
216
            team_buf.leg[0].manual = FALSE;
217
            set_times( &team_buf );
218
            test_times( &team_buf, 0 );
219
            put_team_record( team, &team_buf );
220
        }
221
        team++;
222
    }
223
}
224
 
225
/*========================================================================
226
 *
227
 *  Set the start time for a specific leg
228
 *
229
 *  Purpose:
230
 *      This function is called to set the start time for a specific
231
 *      leg to a specified and fixed time
232
 *
233
 *  Parameters:
234
 *      None
235
 *
236
 *  Returns:
237
 *      Nothing
238
 *
239
 *========================================================================*/
240
 
135 david 241
void tm_fixedstart(int leg, time_t starttime, bool report_it, bool clear_it)
95 - 242
{
174 - 243
    team_type   team_buf;
244
    int team = config.min_team;                      /* Team we are working with */
95 - 245
    while( team <= config.max_team )
246
    {
247
        if( valid_field( team ) )
248
        {
249
            g_record( team, &team_buf );
250
            if( team_buf.flags.valid )
251
            {
252
                team_buf.leg[leg].start = starttime;
253
                team_buf.leg[leg].manual = TRUE;
254
            }
255
            else
256
                team_buf.leg[leg].start = ( time_t ) - 1;
257
 
258
            set_times( &team_buf );
259
            test_times( &team_buf, 0 );
260
            put_team_record( team, &team_buf );
261
        }
262
        team++;
263
    }
264
 
265
    if( report_it )
137 david 266
        legs_start_report(leg);
95 - 267
 
268
    if ( clear_it )
137 david 269
        tm_clearleg_specified( leg, TRUE );
95 - 270
}
271
 
272
/*========================================================================
273
 *
274
 *  Set a staggered start time for a specific leg
275
 *
276
 *  Purpose:
277
 *      This function is called to set the start time for a specific
278
 *      leg to a specified and a staggered time
279
 *
280
 *  Parameters:
281
 *      None
282
 *
283
 *  Returns:
284
 *      Nothing
285
 *
286
 *========================================================================*/
287
 
135 david 288
void tm_staggered(int leg, time_t starttime, time_t delta, bool report_it, bool clear_it )
95 - 289
{
174 - 290
    team_type   team_buf;
291
    int team = config.min_team;                      /* Team we are working with */
95 - 292
    while( team <= config.max_team )
293
    {
294
        if( valid_field( team ) )
295
        {
296
            g_record( team, &team_buf );
297
            if( team_buf.flags.valid )
298
            {
299
                team_buf.leg[leg].start = starttime;
300
                starttime += delta;
301
                team_buf.leg[leg].manual = TRUE;
302
            }
303
            else
304
                team_buf.leg[leg].start = ( time_t ) - 1;
305
 
306
            set_times( &team_buf );
307
            test_times( &team_buf, 0 );
308
            put_team_record( team, &team_buf );
309
        }
310
        team++;
311
    }
312
 
313
    if( report_it )
137 david 314
        legs_start_report(leg);
95 - 315
 
316
    if ( clear_it )
137 david 317
        tm_clearleg_specified( leg, TRUE );
95 - 318
}
319
 
320
/*========================================================================
321
 *
322
 *  Clear start times on a specific leg
323
 *
324
 *  Purpose:
325
 *      This function is called to clear start times on a specifc leg
326
 *
327
 *  Parameters:
328
 *      cleg                - Leg to clear
329
 *      manual              - Force manual, else leave alone
330
 *
331
 *  Returns:
332
 *      Nothing
333
 *
334
 *========================================================================*/
335
 
174 - 336
void tm_clearleg_specified(int leg, bool manual)
95 - 337
{
174 - 338
    team_type   team_buf;
95 - 339
 
340
    /*
341
    **  Validate the users argument
342
    */
174 - 343
    if( leg == 0 )
95 - 344
        return;                              /* Null leg - just exit */
174 - 345
    if( leg > config.num_legs )             /* Valid leg number - Exit loop */
95 - 346
        return;
347
 
174 - 348
    int team = config.min_team;                 /* Team we are working with */
95 - 349
    while( team <= config.max_team )
350
    {
351
        if( valid_field( team ) )
352
        {
353
            g_record( team, &team_buf );
354
            team_buf.leg[leg].manual = manual;
355
            team_buf.leg[leg].start = ( time_t ) -1;
356
 
357
            set_times( &team_buf );
358
            test_times( &team_buf, 0 );
359
            put_team_record( team, &team_buf );
360
        }
361
        team++;
362
    }
363
}
364
 
365
 
366
/*========================================================================
367
 *
368
 *  Initialize all stored times
369
 *
370
 *  Purpose:
371
 *      This function is called to Initialize all stored times
372
 *
373
 *  Parameters:
374
 *      None
375
 *
376
 *  Returns:
377
 *      Nothing
378
 *
379
 *========================================================================*/
380
 
381
void leg_ini(void)
382
{
383
    int         i;
174 - 384
    team_type   team_buf;
95 - 385
 
386
 
174 - 387
    int team = config.min_team;                      /* Team we are working with */
95 - 388
    while( team <= config.max_team )
389
    {
390
        if( valid_field( team ) )
391
        {
392
            ( void ) g_record( team, &team_buf );
393
            for( i = 0; i <= MAX_LEGS; i++ )
394
            {
395
                team_buf.leg[i].start = team_buf.leg[i].end =
396
                    team_buf.leg[i].elapsed = ( time_t ) - 1;
397
                team_buf.leg[i].l_place = 0;
398
                team_buf.leg[i].le_place = 0;
399
                team_buf.leg[i].lec_place = 0;
400
                team_buf.leg[i].lc_place = 0;
401
                team_buf.leg[i].manual = FALSE;
402
            }
403
            if( team_buf.teamclass > 0 && team_buf.teamclass <= config.num_class )
404
                team_buf.leg[0].start =
405
                    config.team_class[team_buf.teamclass - 1].start;
406
            else
407
                team_buf.leg[0].start = ( time_t ) - 1;
408
 
409
            team_buf.leg[1].start = team_buf.leg[0].start;
410
            team_buf.flags.disqualified = FALSE;
411
            team_buf.flags.non_equestrian = FALSE;
412
            put_team_record( team, &team_buf );
413
        }
414
        team++;
415
    }
416
}
417
 
418
/*========================================================================
419
 *
420
 *  Initialize all team data
421
 *
422
 *  Purpose:
423
 *      This function is called to Initialize all team data
424
 *
425
 *  Parameters:
426
 *      None
427
 *
428
 *  Returns:
429
 *      Nothing
430
 *
431
 *========================================================================*/
432
void tm_init(void)
433
{
174 - 434
    team_type   team_buf;
435
    int team = config.min_team;                      /* Team we are working with */
95 - 436
    while( team <= config.max_team )
437
    {
438
        if( valid_field( team ) )
439
        {
440
            clr_team( team, &team_buf );
441
            put_team_record( team, &team_buf );
442
        }
443
        team++;
444
    }
445
}
446
 
447
/*========================================================================
448
 *
449
 *  Generate dummy team names
450
 *
451
 *  Purpose:
452
 *      This function is called to Generate dummy team names
453
 *
454
 *  Parameters:
455
 *      None
456
 *
457
 *  Returns:
458
 *      Nothing
459
 *
460
 *========================================================================*/
461
 
462
void tm_gen(void)
463
{
174 - 464
    team_type   team_buf;
465
    int team = config.min_team;                      /* Team we are working with */
95 - 466
    while( team <= config.max_team )
467
    {
468
        if( valid_field( team ) )
469
        {
470
            ( void ) g_record( team, &team_buf );
471
            team_buf.flags.valid = TRUE;
472
            sprintf( team_buf.name, "Team - %4.4d", team );
473
            team_buf.teamclass = 1;                  /* Set default class */
474
            put_team_record( team, &team_buf );
475
        }
476
        team++;
477
    }
478
}
479
 
480
 
481
/*========================================================================
482
 *
483
 *  Generate starters report
484
 *
485
 *  Purpose:
486
 *      This routine is used to generate a list of leg start times
487
 *      This system can cope with a break at the start of leg
488
 *
489
 *  Parameters:
490
 *      None
491
 *
492
 *  Returns:
493
 *      Nothing
494
 *
495
 *========================================================================*/
496
 
137 david 497
void legs_start_report(int leg)
95 - 498
{
499
    int         i;
500
    t_legs     *data;                            /* Address of table */
501
    t_legs     *dptr;                            /* Moving pointer */
502
    int         last_team;
503
    int         num_records = 0;                 /* Number of records in array */
504
    char        l_s[40];                         /* Name of start time file */
174 - 505
    team_type   team_buf;
95 - 506
 
507
    data = ( t_legs * ) calloc( ( unsigned ) ( config.max_team - config.min_team + 2 ), sizeof( t_legs ) ); /* Fetch memory */
508
 
509
    if( !data )
510
    {
199 david 511
        MainWindow::showMessage("No memory for report");
95 - 512
        return;
513
    }
514
 
515
    /*
516
     * Extract the required data from the data base
517
     * Only save that information required for the operation
518
     */
519
 
520
    dptr = data;
521
    for( i = config.min_team; i <= config.max_team; i++ )   /* Print team order data */
522
    {
523
        if( valid_field( i ) && g_record( i, &team_buf ) )
524
        {
525
            dptr->numb = team_buf.numb;
526
            dptr->start = team_buf.leg[leg].start;
527
            dptr->flags = team_buf.flags;
528
            dptr++;
529
            num_records++;
530
        }
531
    }
532
 
533
 
534
    /*
535
     * Sort the data into some logical order 
536
     */
537
    qsort( ( char * ) data, num_records, sizeof( t_legs ), sort_legs );
538
 
539
    /*
540
    **  Now print the data on the printer
541
    **      - Generte the name of the printer file
542
    **      - Open the printer
543
    */
544
 
545
    sprintf( l_s, "l_%d", leg );
546
    if( !open_printer( "", l_s, 80, text, "Starters Report" ) )
547
        return;
548
 
549
    /*
550
     * Print out the header for the file 
551
     */
552
    print( "\nStarters report for leg:%d %-*s\n", leg, 18, config.leg_name[leg - 1] );
553
    print( "Team order listing\n\n" );
554
 
555
    print_underline (TRUE);
556
    print( "%-8s   %-5s   %-8s   |   %-5s   %-8s", "Time", "Team", "DeltaT", "Team", "Time" );
557
    print_underline (FALSE);
558
    print( "\n" );
559
 
560
    last_team = 0;
561
    for( dptr = data, i = 0; i < num_records; i++ )
562
    {
563
        ls_timer( dptr++, i );
564
        print( "   |   " );
565
        ls_team( &last_team, data );
566
        print( "\n" );
567
    }
568
 
569
    print( "\nTeams without marked times will be started when ALL marked teams\n" );
570
    print( "have been started.\n" );
571
 
572
    /*
573
    **  Release the resources
574
    **      - Printer
575
    **      - Memory
576
    */
577
    close_printer();
578
    free( data );
207 - 579
 
580
    /*
581
     ** Tell the main system about this new report
582
     */
583
    MainWindow::registerReport(getPrinterFile(), "Leg Start");
584
 
95 - 585
}
586
 
587
/*========================================================================
588
 *
589
 *  print the current leg entry
590
 *
591
 *  Purpose:
592
 *      This function is a helper routine to print the current leg entry
593
 *      in time : Team number order
594
 *
595
 *  Parameters:
596
 *      ptr     Pointer to entry
597
 *      num     Entry index
598
 *
599
 *  Returns:
600
 *      Nothing
601
 *
602
 *========================================================================*/
603
 
604
void ls_timer( t_legs * ptr, int num )
605
{
606
    time_t      time;
607
    time_t      delta;
230 - 608
    bool        flags;
95 - 609
 
610
    if( num == 0 )
611
        delta = ( time_t ) - 1;
612
    else
613
        delta = ptr[0].start - ptr[-1].start;
614
 
615
    time = ptr->start;
230 - 616
    flags =  ptr->flags.disqualified || ptr->flags.non_equestrian || ptr->flags.vet_check;
617
    if(flags)
95 - 618
        time = ( time_t ) - 1;
619
 
230 - 620
    print( "%-8s   %-5d", time_fa( time, flags ), ptr->numb );
95 - 621
    print( "   %-8s", time_fa( delta, TRUE ) );
622
}
623
 
624
 
625
/*========================================================================
626
 *
627
 *  print next ( numeric ) leg entry
628
 *
629
 *  Purpose:
630
 *      This helper function is called to print next ( numeric ) leg entry
631
 *      in Team # time order
632
 *
633
 *  Parameters:
634
 *      last        Last one found
635
 *                  Used to relocate my self
636
 *      data        Start of data
637
 *
638
 *  Returns:
639
 *      Nothing
640
 *
641
 *========================================================================*/
642
 
643
void ls_team( int *last, t_legs * data )
644
{
645
    t_legs     *min;
646
    time_t      time;
230 - 647
    bool        flags;
95 - 648
 
649
    for( min = 0; data->numb; data++ )
650
    {
651
        if( data->numb > *last && ( min == 0 || data->numb < min->numb ) )
652
            min = data;
653
    }
654
    *last = min->numb;                           /* Save current team as done */
655
 
656
    time = min->start;
230 - 657
    flags =  min->flags.disqualified || min->flags.non_equestrian || min->flags.vet_check;
658
    if( flags )
95 - 659
        time = ( time_t ) - 1;
230 - 660
    print( "%-5d   %-8s", min->numb, time_fa( time, flags ) );
95 - 661
}
662
 
663
/*========================================================================
664
 *
665
 *  Qsort callback function
666
 *
667
 *  Purpose:
668
 *      This function is provided to Qsort() to sort the teams
669
 *
670
 *  Parameters:
671
 *      a           - Leg entry to compare
672
 *      b           - Leg entry to compare
673
 *
674
 *
675
 *  Returns:
676
 *      -1      a < b
677
 *       0      a = b
678
 *       1      a > b
679
 *
680
 *========================================================================*/
681
 
682
int sort_legs( const void * aa, const void * bb )
683
{
684
 
685
    const t_legs * a = (const t_legs *)aa;
686
    const t_legs * b = (const t_legs *)bb;
687
 
688
    int         a_bad;
689
    int         b_bad;
690
 
226 - 691
    a_bad = a->flags.disqualified || a->flags.non_equestrian || a->start <= 0;
692
    b_bad = b->flags.disqualified || b->flags.non_equestrian || b->start <= 0;
95 - 693
 
694
    if( a_bad || b_bad )                         /* Valid data has precedence */
695
    {
696
        if( a_bad && b_bad )
697
            return ( a->numb - b->numb );
698
        else
699
            return ( a_bad ? 1 : -1 );
700
    }
701
 
702
    if( a->start == b->start )
703
        return ( a->numb - b->numb );
704
    else
705
    {
706
        if( ( a->start > 0 ) && ( b->start > 0 ) )
707
            return ( ( int ) ( a->start - b->start ) );
708
        else
709
            return ( ( a->start > 0 ) ? -1 : 1 );
710
    }
711
}
712
 
713
/********************************* EOF ***********************************/