// This program produces a sales report for DLC, reinterpret_cast
#include <iostream>
#include <iomanip>
using namespace std;

// Function prototype
void calcSales(const int[], const double[], double[], int);
void showOrder(const double[], const int[], int);
void dualSort (int[], double[], int);
void showTotals(const double[], const int[], int);
void swap(double&, double&);
void swap(int&, int&);

int main()
{
    // NUM_PRODS is the number of product produced
    const int NUM_PRODS = 9;
    
    // array with product ID numbers
    int id[NUM_PRODS] = { 914, 915, 916, 917, 918, 919, 920, 921, 922 };
    
    // array with number of units sold for each product
    int units[NUM_PRODS] = { 842, 416, 127, 514, 437, 269, 97, 492, 212 };
    
    // array with product prices
    double prices[NUM_PRODS] = { 12.95, 14.95, 18.95, 16.95, 21.95, 31.95, 
                                 14.95, 14.95, 16.95 };
                                 
    // array to hold the computed sales amounts
    double sales[NUM_PRODS];
    
    // Calculate each product's sales
    calcSales(units, prices, sales, NUM_PRODS);
    
    // sort the elements in the sales array in descending
    // order and shuffle the ID numbers in the id array to
    // keep them in parallel
    dualSort(id, sales, NUM_PRODS);
    
    // set the numeric output formatting
    cout << setprecision(2) << fixed << showpoint;
    
    // display the products and sales amounts
    showOrder(sales, id, NUM_PRODS);
    
    // display total units sold and total sales
    showTotals(sales, units, NUM_PRODS);
    
    return 0;
}

//****************************************************************
// definition of calcSales. accepts unit, prices, and sales      *
// arrays as argument. the size of these array is passed         *
// into the num parameter. this function calculates each         *
// product's sales by multiplying its units sold by each unit's  *
// price. the result is stored in the sales array                *
//****************************************************************

void calcSales(const int units[], const double prices[], double sales[], int num)
{
    for (int index = 0; index < num; index++)
        sales[index] = units[index] * prices[index];
}

//*********************************************************************
// definition of function dualsort. accepts id and sales arrays       *
// as arguments. the size of these arrays is passed into size         *
// tih function performs a descending order selection sort selection  *
// the sales array. The elements of the id array are   exchanged      *
// identically as those of the sales array. size is the numbers       *
// of elements in each array                                          *
//*********************************************************************

void dualSort( int id[], double sales[], int size)
{
    int start, maxIndex, tempid;
    double maxValue;
    
    for (start = 0; start < (size-1); start++)
    {
        maxIndex = start;
        maxValue = sales[start];
        tempid = id[start];
        for (int index = start + 1; index < size; index++)
        {
            if (sales[index] > maxValue)
            {
                maxValue = sales[index];
                tempid = id[index];
                maxIndex = index;
            }
        }
        swap(sales[maxIndex], sales[start]);
        swap(id[maxIndex], id[start]);
    }
}

//*****************************************************
// The swap function swaps doubles a and b in  memory *
//*****************************************************

void swap(double &a, double &b)
{
    double temp = a;
    a = b;
    b = temp;
}

//**************************************************
// the swap function swaps int a and b in memory   *
//**************************************************

void swap(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

//*****************************************************************
// definition of showOrder function. accepts sales and id arrays  *
// as arguments. the size of these arrays is passed into num      *
// the funtion forst desplays a heading, then the sorted list     *
// of product numbers and sales                                   *
//*****************************************************************

void showOrder(const double sales[], const int id[], int num)
{
    cout << "Product Number\tSales\n";
    cout << "___________________________________________\n";
    for(int index = 0; index < num; index++)
    {
        cout << id[index] << "\t\t$";
        cout << setw(8) << sales[index] << endl;
    }
    cout << endl;
}

//**********************************************************************
// definition of showTotals function. accepts sales and id arrays      *
// as arguments. the size of these arrays is passed into num           *
// the function first calculates the total units (of all products)     *
// sold and the total sales. It then displays these                    * 
// amounts                                                             *
//**********************************************************************

void showTotals(const double sales[], const int units[], int num)
{
    int totalUnits = 0;
    double totalSales = 0.0;
    
    for(int index = 0; index < num; index++)
    {
        totalUnits += units[index];
        totalSales += sales[index];
    }
    cout << "Total units Sold: " << totalUnits << endl;
    cout << "Total sales:   $" << totalSales << endl;
}