/*

Copyright: 1999, All rights reserved.
Program: Polytropic
Version: 0.0 
Created/Revised: 9/30/99
File: polytropic.cpp
Programmer: C. S. Tritt, Ph.D.
Course: CS-150
Assignment: Example
Compiler: Microsoft Visual C++ 6.0
Target: Win32 Console Application

Description:

  This program calculates the properties for an arbitrary ideal gas.

Revisions:

  There have been no major revisions of this program.

Constants and Variables:

  See code for constant and variable descriptions.

*/

// Included files.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

// These macros mimic the ANSI C++ logical operations.

#define and &&
#define or ||
#define not !

using namespace std;

// Declare and define global constants.

const double C2K = 273.15; // Use for T conversion.
const double UGASCONST = 8.31433; // Universal gas constant in kPa*m^3/(kmole*K).

// Declare and define the Gas class.

class Gas
{
public:
   Gas(double tref, double pref, double m, double cp);
   void set_t(double t);
   double get_t();
 /*  double change_t(double deltat);
   double set_p(double p);
   double change_p(double deltap);
   double get_t();
   double get_p();
   double get_v();
   double get_u();
   double get_h();
   double get_s();
   double get_m(); */
private:
   double _t; // Temperature in K.
	double _p; // Pressure in kPa.
	double _v; // Molar volume in m^3/mole.
	double _tref; // Temperature in K.
	double _pref; // Pressure in kPa.
	double _vref; // Molar volume in m^3/mole.
   double _m; // Molecular weight (g/mole).
	double _cp; // Constant pressure heat capacity in kJ/(mole*K).
   double _cv; // Constant volume heat capacity in kJ/(mole*K).
	const double _r; // Universal gas constant  in kPa*m^3/(kmole*K).
/*	double _u; // Molar internal energy in kJ/mole.
	double _h; // Molar enthalpy in kJ/mole.
	double _s; // Molar entropy in kJ/mole. */
};

Gas::Gas(double tref, double pref, double m, double cp) : _r(UGASCONST)

// Constructor. Stores reference state, properties and sets initial state of gas.

{
   _t = _tref = tref + C2K;
   _p = _pref = pref;
   _m = m;
   _cp = cp ;
   _cv = cp - _r;
   _v = _vref = _r * _tref / _pref;
}

void Gas::set_t(double t)

// Sets T at constant P.

{
   double told = _t;  // Keep copy of old T for calculations.
   _t = t + C2K;
   _v = _v * _t / told;
   return;
}

double Gas::get_t(void)

// Returns current temperature.

{
   return _t;
}

// Define skip_comments function.

int skip_comments(ifstream& file, char mark)
{
// This function skips the all the lines at the start of the specified
// file that begin with the specified character.  The file must already
// be open when this funciton is called.  Error checking not yet
// included.

	const int MAX_CHARS = 100; // This is the maximum characters per line.

   while (file.peek() == mark) {file.ignore(MAX_CHARS, '\n');}

	return 0;
}

int main()
{

// Define constants and major variables.

   const char* FILEID = "ideal.dat";

   ifstream fin;  // Declare the input file stream object.

//  Open the files, check for errors and skip comments.

	fin.open(FILEID, ios::in);
	if (not fin)
	{
		cout << "Can't open input file. Aborting.\n";
		return 1;
	}

   if (skip_comments(fin, '!'))
	{	
		cout << "Error while skipping comments in input file. Aborting\n";
		return 2;
	}

   string datainfo; // Data file information.

   if (not (fin >> datainfo))
   {
      cout << "Error reading data file information. Aborting.\n";
      return 3;
   }
   cout << datainfo << endl;
   
   double pref; // Reference pressure (atm).
   double tref; // Reference temperature (deg. C).
   double m; // Molecular weight (g/mole).
   double cp; // Constant pressure heat capacity (kJ/(kmol*K)).

   if (not (fin >> pref >> tref >> m >> cp))
   {
      cout << "Error reading reference information. Aborting.\n";
      return 3;
   }
   cout << "Pref = " << pref << " atm";
   cout << ", Tref = " << tref << " deg. C";
   cout << ", M = " << m << " g/mole";
   cout << " and Cp = " << cp << " kJ/(kmol*K).\n";

   string term1op; // First term operation.
   double term1; // First term
   string term2op; // Second term operation.
   double term2; // Second term

	// Everything worked.

   while (fin >> term1op >> term1 >> term2op >> term2)
   {

// Echo input.

      cout << "Processing: " << term1op << term2;
      cout << " and " << term2op << term2 << endl;
   }

	return 0;
}