//******************************************************************
// IMPLEMENTATION FILE (tclist.cpp)
// This file implements the TimeCardList class member functions.
// List representation: an array of TimeCard objects and an
// integer variable giving the current length of the list
//******************************************************************
#include "tclist.h"
#include <iostream>

using namespace std;

// Private members of class:
//    int      length;              Current length of list
//    TimeCard data[MAX_LENGTH];    Array of TimeCard objects

//******************************************************************

TimeCardList::TimeCardList()

// Default constructor

// Postcondition:
//     Each element of data array has an ID number of 0
//     and a time of 0:0:0 (via implicit call to each array
//     element's default constructor)
//  && length == 0

{
    length = 0;
}

//******************************************************************

void TimeCardList::ReadAll( /* inout */ ifstream& inFile )

// Precondition:
//     inFile has been opened for input
// Postcondition:
//     data[0..length-1] contain employee time cards as read
//     from inFile
//  && 0 <= length <= MAX_LENGTH
//  && IF inFile contains more than MAX_LENGTH time cards
//         Warning message has been printed and excess time cards
//         are ignored

{
    long idNum;      // Employee ID number
    int  hours;      // Employee punch-in time
    int  minutes;
    int  seconds;

    inFile >> idNum >> hours >> minutes >> seconds;
    while (inFile && length < MAX_LENGTH)
    {
        data[length].SetID(idNum);
        data[length].Punch(hours, minutes, seconds);
        length++;
        inFile >> idNum >> hours >> minutes >> seconds;
    }
    if (inFile)
        // Assert: inFile is not at end-of-file
        cout << "More than " << MAX_LENGTH << " time cards "
             << "in input file.  Remainder are ignored." << endl;
}

//******************************************************************

void TimeCardList::SelSort()

// Postcondition:
//     data array contains the same values as data@entry, rearranged
//     into ascending order of employee ID

{
   TimeCard temp;         // Used for swapping
   int      passCount;    // Loop control variable
   int      searchIndx;   // Loop control variable
   int      minIndx;      // Index of minimum so far

   for (passCount = 0; passCount < length - 1; passCount++)
   {
      minIndx = passCount;

      // Find the index of the smallest component
      // in data[passCount..length-1]

      for (searchIndx = passCount + 1; searchIndx < length;
                                                       searchIndx++)
         if (data[searchIndx].IDPart() < data[minIndx].IDPart())
            minIndx = searchIndx;

      // Swap data[minIndx] and data[passCount]

      temp = data[minIndx];
      data[minIndx] = data[passCount];
      data[passCount] = temp;
   }
}

//******************************************************************

void TimeCardList::BinSearch( /* in */  long      idNum,
                              /* out */ bool&     found,
                              /* out */ TimeCard& card  ) const

// Precondition:
//     data[0..length-1] are in ascending order of employee ID
//  && idNum is assigned
// Postcondition:
//     IF time card for employee idNum is in list at position i
//         found == true  &&  card == data[i]
//     ELSE
//         found == false  &&  value of card is undefined

{
    int first = 0;            // Lower bound on list
    int last = length - 1;    // Upper bound on list
    int middle;               // Middle index

    found = false;
    while (last >= first && !found)
    {
        middle = (first + last) / 2;
        if (idNum < data[middle].IDPart())
            // Assert: idNum is not in data[middle..last]
            last = middle - 1;
        else if (idNum > data[middle].IDPart())
            // Assert: idNum is not in data[first..middle]
            first = middle + 1;
        else
            // Assert: idNum is in data[middle]
            found = true;
    }
    if (found)
        card = data[middle];
}
