Subversion Repositories svn1-original

Rev

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