//******************************************************************
// Graph program
// This program generates bar graphs of monthly sales
// by department for two Chippendale furniture stores, permitting
// department-by-department comparison of sales
//******************************************************************
#include <iostream>
#include <iomanip>    // For setw()
#include <fstream>    // For file I/O
#include <string>     // For string type

using namespace std;

void GetData( ifstream&, int&, float& );
void OpenForInput( ifstream& );
void PrintData( int, int, float );
void PrintHeading();

int main()
{
    int      deptID1;       // Department ID number for Store 1
    int      deptID2;       // Department ID number for Store 2
    float    sales1;        // Department sales for Store 1
    float    sales2;        // Department sales for Store 2
    ifstream store1;        // Accounting file for Store 1
    ifstream store2;        // Accounting file for Store 2

    cout << "For Store 1," << endl;
    OpenForInput(store1);
    cout << "For Store 2," << endl;
    OpenForInput(store2);
    if ( !store1 || !store2 )                    // Make sure files
        return 1;                                //   were opened

    PrintHeading();

    GetData(store1, deptID1, sales1);            // Priming reads
    GetData(store2, deptID2, sales2);
    while (store1 && store2)                     // While not EOF...
    {
        cout << endl;
        PrintData(deptID1, 1, sales1);           // Process Store 1
        PrintData(deptID2, 2, sales2);           // Process Store 2
        GetData(store1, deptID1, sales1);
        GetData(store2, deptID2, sales2);
    }
    return 0;
}

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

void OpenForInput( /* inout */ ifstream& someFile )    // File to be
                                                       // opened
// Prompts the user for the name of an input file
// and attempts to open the file

// Postcondition:
//     The user has been prompted for a file name
//  && IF the file could not be opened
//         An error message has been printed
// Note:
//     Upon return from this function, the caller must test
//     the stream state to see if the file was successfully opened

{
    string fileName;    // User-specified file name

    cout << "Input file name: ";
    cin >> fileName;

    someFile.open(fileName.c_str());
    if ( !someFile )
        cout << "** Can't open " << fileName << " **" << endl;
}

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

void PrintHeading()

// Prints the title for the bar chart, a heading, and the numeric
// scale for the chart.  The scale uses one mark per $500

// Postcondition:
//     The heading for the bar chart has been printed

{
   cout
     << "Bar Graph Comparing Departments of Store #1 and Store #2"
     << endl << endl
     << "Store  Sales in 1,000s of dollars" << endl
     << "  #    0         5        10        15        20        25"
     << endl
     << "       |.........|.........|.........|.........|.........|"
     << endl;
}

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

void GetData( /* inout */ ifstream& dataFile,   // Input file
              /* out */   int&      deptID,     // Department number
              /* out */   float&    deptSales ) // Department's
                                                //   monthly sales

// Takes an input accounting file as a parameter, reads the
// department ID number and number of days of sales from that file,
// then reads one sales figure for each of those days, computing a
// total sales figure for the month.  This figure is returned in
// deptSales.  (If input of the department ID fails due to
// end-of-file, deptID and deptSales are undefined.)

// Precondition:
//     dataFile has been successfully opened
//  && For each department, the file contains a department ID,
//     number of days, and one sales figure for each day
// Postcondition:
//     IF input of deptID failed due to end-of-file
//          deptID and deptSales are undefined
//     ELSE
//          The data file reading marker has advanced past one
//          department's data
//       && deptID == department ID number as read from the file
//       && deptSales == sum of the sales values for the department

{
    int   numDays;  // Number of business days in the month
    int   day;      // Loop control variable for reading daily sales
    float sale;     // One day's sales for the department

    dataFile >> deptID;
    if ( !dataFile )             // Check for EOF
        return;                  // If so, exit the function

    dataFile >> numDays;
    deptSales = 0.0;
    day = 1;                     // Initialize loop control variable
    while (day <= numDays)
    {
        dataFile >> sale;
        deptSales = deptSales + sale;
        day++;                   // Update loop control variable
    }
}

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

void PrintData( /* in */ int   deptID,       // Department ID number
                /* in */ int   storeNum,     // Store number
                /* in */ float deptSales )   // Total sales for the
                                             //   department

// Prints the department ID number, the store number, and a
// bar graph of the sales for the department.  The bar graph
// is printed at a scale of one mark per $500

// Precondition:
//     deptID contains a valid department number
//  && storeNum contains a valid store number
//  && 0.0 <= deptSales <= 25000.0
// Postcondition:
//     A line of the bar chart has been printed with one * for
//     each $500 in sales, with remainders over $250 rounded up
//  && No stars have been printed for sales <= $250

{
    cout << setw(12) << "Dept " << deptID << endl;
    cout << setw(3) << storeNum << "     ";
    while (deptSales > 250.0)
    {
        cout << '*' ;                     // Print '*' for each $500
        deptSales = deptSales - 500.0;    // Update loop control
    }                                     //   variable
    cout << endl;
}

