/*************************************************/
// R. A. Hillyard
// november 2001
//
//Program to demonstrate the use of dynamic arrays and classes
/*************************************************/
/*************************************************/
// 
// The  Inventory class
// 
/*************************************************/
//dynamicInventory.h
/*************************************************/
#ifndef INVENTORY_H
#define INVENTORY_H

class Inventory
  {
  public:
    //constructors
    Inventory();
    Inventory (int num);
    Inventory (int num, int stock, double price);
   
    //overload insertion and extraction operators
    friend std::ostream& operator <<(std::ostream& outs, const Inventory& anyPart);
    friend std::istream& operator >>(std::istream& ins, Inventory& anyPart);
      
    //accessor functions for each data menber
    int getPartNum() const;
    int getInStock() const;
    double getCost() const;
    //mutator functions for each data menber
    void setPartNum(int num);
    void setInStock(int stock);
    void setCost(double price);

  private:
    int partNum;
    int inStock;
    double cost;
  };
#endif
/*************************************************/
/*************************************************/
// dynamicInventory.cpp
/*************************************************/
#include <iostream>
#include <iomanip>
#include "dynamicInventory.h"

using namespace std;

//#define DEBUG //uncomment to enable debugging

/****************************************************************/
// Constructors for the inventory class
/****************************************************************/

/****************************************************************/
//default constructor
/****************************************************************/
Inventory::Inventory()
  {
  #ifdef DEBUG
    cout << "In default constructor\n";
  #endif
  
  partNum = -1;
  inStock = 0;
  cost = 0.0;
  }
/****************************************************************/
//single argument constructor
/****************************************************************/
Inventory::Inventory (int num)
  {
  #ifdef DEBUG
    cout << "In single argument constructor\n";
  #endif
     
  partNum = num;
  inStock = 0;
  cost = 0.0;
  }
/****************************************************************/
//three argument constructor
/****************************************************************/
Inventory::Inventory (int num, int stock, double price)
  {
  #ifdef DEBUG
    cout << "In three argument constructor\n";
  #endif
  
  partNum = num;
  inStock = stock;
  cost = price;
  }
/****************************************************************/
//Overload insertion and extraction operators
/****************************************************************/
ostream& operator <<(ostream& outs, const Inventory& anyPart)
  {
  outs.setf(ios::showpoint);
  outs.setf(ios::fixed);
  outs.precision(2);
  outs << setw(10) << anyPart.partNum << setw(10) << anyPart.inStock
       << setw(12) << anyPart.cost << endl;
  return outs;
  }
/****************************************************************/
istream& operator >>(istream& ins, Inventory& anyPart)
  {
  cout << "\nenter part number, number in stock, and the cost:\n>";
  cin >> anyPart.partNum >> anyPart.inStock >> anyPart.cost;
  return ins;
  }
/****************************************************************/

/****************************************************************/
//accessor functions for each member variable
/****************************************************************/
int Inventory::getPartNum() const
  { return partNum;  }
/****************************************************************/
int Inventory::getInStock() const
  { return inStock;  }
/****************************************************************/
double Inventory::getCost() const
  { return cost;  }
/****************************************************************/

/****************************************************************/
//mutator functions for each member variable
/****************************************************************/
void Inventory::setPartNum(int num)
  { partNum = num; }
/****************************************************************/
void Inventory::setInStock(int stock)
  { inStock = stock; }
/****************************************************************/
void Inventory::setCost(double price)
  { cost = price; }
/****************************************************************/

// PartList Class
/*************************************************/
//dynamicPartList.h
/*************************************************/
#ifndef PARTLIST_H         //avoid multiple inclusions
#define PARTLIST_H

#include "dynamicInventory.h"    //need to include the Inventory Class

//const int MaxListSize = 10;
const int MinListSize = 3;

class PartList
  {
  public:
    PartList();                    //default constructor
    void addPart(Inventory item);  //add a part to the list
    void deletePart(int num);      //delete a part from the list
    void upDateCost(int num);      //up date the cost of a part
    void display();                //display each element of the list
    int lookupByPartNum(int num);  //return a index based on the part number

  private:
  //Inventory partsList[MaxListSize];  //declare an array of type Inventory
    Inventory *partsList;              //declare an array pointer of type Inventory
    int size;                          //keep track of the actual number of elements
    int moreRoom;                      //keep track of the number of open elements
  };
#endif
/*************************************************/
/*************************************************/
//dynamicPartList.cpp
/*************************************************/
#include<iostream>
#include "dynamicPartList.h"
#include "dynamicInventory.h"

//#define DEBUG

using namespace std;

/*************************************************/
//default constructor
/*************************************************/
PartList::PartList()
  {
  #ifdef DEBUG
    cout << " in PartList default constructor\n";
  #endif 
  partsList = new Inventory[MinListSize];
  size = 0;
  moreRoom= MinListSize;
  }
/*************************************************/
//add a part to the list - if there is room the
//entry is added and the size incremented. if full,
//more memory is allocated and the entry added
/*************************************************/  
void PartList::addPart(Inventory part)
  {
  //check if there is more room and add memory if needed
  if(moreRoom == 0)
    {
    Inventory *oldList = partsList;                //save reference to old list
    partsList = new Inventory[size+MinListSize];   //allocate memory for new list

    //copy old array elements to new array
    for(int i = 0; i < size; i++)
      {
      partsList[i] = oldList[i];
      }
    moreRoom += MinListSize;    //update the amount of room available
    delete [] oldList;          //give back memory for old list
    }

  //add part and update size and moreRoom
  partsList[size] = part;
  size++;
  moreRoom--;
  }
/*************************************************/
//delete a part from the list - find the part to delete
//and shift all "lower" entries up by one index.
/*************************************************/  
void PartList::deletePart(int num)
  {
  //get index of part to delete
  int index = lookupByPartNum(num);

  if(index != -1)   //if in the list shift lower entries up
    {
    for(int j = index; j < size; j++)
      {
      partsList[j] = partsList[j+1];
      }
    size--;    //decrement size of the array
    moreRoom++;

    //check for extra room and reduce size of array if needed
    if(((moreRoom % MinListSize) == 0) && size != MinListSize)
      {
      Inventory *oldList = partsList;
      partsList = new Inventory[size-MinListSize];
      moreRoom -= MinListSize;
      //copy array
      for(int i = 0; i < size; i++)
        {
        partsList[i] = oldList[i];
        }
      }//endif moreRoom

    else
      moreRoom %= MinListSize;
    }//endif index
  else            
    cout << num << " is not in the list - try again\n";
  }
/*************************************************/
//display each entry in list  
/*************************************************/
void PartList::display()
  {
  cout << "The List contains the following " << size << " parts and has room for " << moreRoom << " more\n";
     
  for(int i = 0; i < size; i++)
    cout << partsList[i];  
  
  cout << endl;
  }
/*************************************************/
//update the cost of a part
/*************************************************/
void PartList::upDateCost(int num)
  {
  double newPrice;
  int index = lookupByPartNum(num);
  
  cout << "Enter new price: ";
  cin >> newPrice;
  partsList[index].setCost(newPrice);
  }
/*************************************************/
//given a part number return the array index if it exists
/*************************************************/
int PartList::lookupByPartNum(int num)
  {
  int i;
  for(i = 0; i < size; i++)
    {
    if(partsList[i].getPartNum() == num)
      return i;
    }//end for i
    
  return -1;  
  }
/*************************************************/

/*************************************************/
//main for test of Partlist class
/*************************************************/

#include <iostream>
#include <iomanip>
#include "dynamicInventory.h"
#include "dynamicPartList.h"

using namespace std;

int main()
  {
  //declare a variable of type PartList
  PartList inventoryList;
  
  //declare variables of type Inventory
  Inventory part1(1234, 542, 1022.99);
  Inventory part2(2345, 234, 77.69);
  Inventory part3(3567, 734, 22.34);
  Inventory part4(5678, 124, 337.69);
  //??Inventory part5(2333, 433, 57.69);
  
  //add parts to list
  inventoryList.addPart(part1);
  inventoryList.addPart(part2);
  inventoryList.addPart(part3);
  inventoryList.addPart(part4);
  //inventoryList.addPart(part5);

  int num;     //variable for user input
  char choice; //user menu choice
  
  inventoryList.display();  //display initial lists 
  
  while(true)
    {
    cout << "Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >";
    cin >> choice;
    if(choice == 'A')
      {
      Inventory tempPart;
      cin >> tempPart;
      inventoryList.addPart(tempPart);
      }
    if(choice == 'D')
      {
      cout << "Enter part number to delete\n";
      cin >> num;
      inventoryList.deletePart(num);
      }
    if(choice == 'P')
      {
      inventoryList.display();   //dispaly list 
      }
    if(choice == 'E')
      {
      inventoryList.display();  //dispaly list before exit
      cout << "Bye for now !! \n";
      break;
      }
    }//end while
  }//end main

The List contains the following 4 parts and has room for 2 more
      1234       542     1022.99
      2345       234       77.69
      3567       734       22.34
      5678       124      337.69

Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >A

enter part number, number in stock, and the cost:
>4444 234 987.23
Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >A

enter part number, number in stock, and the cost:
>5566 247 55.66
Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >P
The List contains the following 6 parts and has room for 0 more
      1234       542     1022.99
      2345       234       77.69
      3567       734       22.34
      5678       124      337.69
      4444       234      987.23
      5566       247       55.66

Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >A

enter part number, number in stock, and the cost:
>5567 222 55.55
Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >P
The List contains the following 7 parts and has room for 2 more
      1234       542     1022.99
      2345       234       77.69
      3567       734       22.34
      5678       124      337.69
      4444       234      987.23
      5566       247       55.66
      5567       222       55.55

Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >D
Enter part number to delete
2345
Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >D
Enter part number to delete
5567
Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >P
The List contains the following 5 parts and has room for 1 more
      1234       542     1022.99
      3567       734       22.34
      5678       124      337.69
      4444       234      987.23
      5566       247       55.66

Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >D
Enter part number to delete
4321
4321 is not in the list - try again
Enter Choice: (A)dd, (D)elete, (P)rint List, (E)xit >E
The List contains the following 5 parts and has room for 1 more
      1234       542     1022.99
      3567       734       22.34
      5678       124      337.69
      4444       234      987.23
      5566       247       55.66

Bye for now !!