/*
 * This header file contains some functions used in phy351 C++ programs
 * To compile and run the programs successfully you need a Tempate aware
 * compiler (such as Gnu(FREE), Borland, Microsoft, Watchcom etc...)
 */

#ifndef __LIB351_T__
#define __LIB351_T__

#ifndef __IOSTREAM_H
#include<iostream.h>  //for C++ style input and output
#endif

#ifndef __MATH_H
#include<math.h>      //math functions and constants
#endif

#ifndef __FSTREAM_H
#include<fstream.h>   //for C++ style file I/O
#endif

#include<string>      //STL string class

#include<iomanip.h>     //manipulator class
//_____________________________________________________________________





//---------------------------------------------------------------------
//                      FUNCTIONS
//---------------------------------------------------------------------

int pseudoRandomInt (int upperN, int *X){
  int generatedInt;
  *X *= 899;
  *X -= 32768 * int(floor(*X/32768));
  generatedInt =  int(float(*X) / 32768 * upperN  + 1);
  return(generatedInt);
}

//---------------------------------------------------------------------

float pseudoRandomFloat ( int *X){
  float generatedFloat;
  const int MAX = 32767;
  generatedFloat = float( pseudoRandomInt(MAX, X) / MAX);
  return(generatedFloat);
}

//---------------------------------------------------------------------

float deg2rad ( float degrees ){
  float radians;
  radians = degrees * 3.1415926536 / 180;
  return (radians);
}

//---------------------------------------------------------------------

template <class T>
void makeZeros ( int dimension, T *arrayName){
  for (int i = 0; i < dimension; i++){
    arrayName[i] = 0;
  }
}

//---------------------------------------------------------------------

void line (int length, char simbol){
  for (int i = 0; i < length; i++)
    cout<<simbol;

}

//---------------------------------------------------------------------

template <class T>
void lineOutput (int length, T simbol, ofstream* outStr){
  for (int i = 0; i < length; i++)
    *outStr<<simbol;
}

//---------------------------------------------------------------------

template <class T>
void d2ArrayOutput( int maxX, int maxY, T **d2ArrayName, ofstream* outStr){
  for (int i = 0; i < maxX ; i++){
    for (int j = 0; j < maxY; j++){
      *outStr<<d2ArrayName[i][j]<<" ";
    }
    *outStr<<endl;
  }
}
//---------------------------------------------------------------------

template <class T>
void d2bArrayOutput( int maxX, int maxY, T **d2ArrayName, ofstream* outStr){
  for (int i = 0; i < maxX ; i++){
    for (int j = 0; j < maxY; j++){
      *outStr<<d2ArrayName[i][j];
    }
    *outStr<<endl;
  }
}
//---------------------------------------------------------------------

template <class T>
void d2aArrayOutput( int maxX, int maxY, T **d2ArrayName, ofstream* outStr){
  for (int i = 0; i < maxX ; i++){
    for (int j = 0; j < maxY; j++){
		*outStr<<setiosflags(ios::fixed)<<setprecision(2)<<setw(5)<<d2ArrayName[i][j]<<" ";
	}
    *outStr<<endl<<endl;
  }
}
//---------------------------------------------------------------------

template <class T>
void d1ArrayOutput( int maxX, T *d1ArrayName, ofstream* outStr){
  for (int i = 0; i < maxX ; i++){
    *outStr<<d1ArrayName[i]<<' ';
  }
  *outStr<<endl;
}

//---------------------------------------------------------------------

bool query(){
  char answer;
  while(true){
    cout<<"Would you like to do this again using new values? (Y/N)"<<endl;
    cin>>answer;
    cout<<endl;
    if(answer == 'Y' || answer == 'y'){
      return false;
    }
    else if (answer == 'N' || answer == 'n'){
      return true;
    }
    cout<<"Please, answer Y or N :"<<endl;
  }
}

//---------------------------------------------------------------------
//                           INPUT_FILE
//---------------------------------------------------------------------

void inputFileFinder( char dataFileName[80], ifstream* inputStream){
  int goout = 0;
  while (!goout){
    inputStream -> open(dataFileName);
    if (! inputStream){
      cerr<<"Error reading parameter file. No such file."<<endl;
      cout<<endl<<"Please supply the parameter file name"<<endl;
      cin>>dataFileName;
    }
    else{
      goout = 1;
    }
  }
}

//---------------------------------------------------------------------

template <class T>
void readANumber(T *number, ifstream* inputStream){
  char inputCommentLine[400];
  while (inputStream -> peek() == '#' ){
    inputStream -> getline(inputCommentLine, 400);
  }
  *inputStream>>*number;
  inputStream -> getline(inputCommentLine, 400);
}

//---------------------------------------------------------------------

template <class T>
void readArray(T *arr, int max, ifstream* inputStream){
  char inputCommentLine[400];
  while (inputStream -> peek() == '#' ){
    inputStream -> getline(inputCommentLine, 400);
  }
  for(int i = 0; i < max; i++){
    *inputStream>>*(arr + i);
  }
  inputStream -> getline(inputCommentLine, 400);
}

//---------------------------------------------------------------------
//                        OUTPUT_FILE
//---------------------------------------------------------------------


void outFileMaker( char outFileName[80], ofstream* outStream ){
  int goout = 0;
  while (!goout){
    outStream -> open(outFileName);
    if (! outStream){
      cerr<<"Cannot open your file for output"<<endl;
    }
    else{
      goout = 1;
    }
  }
}

//---------------------------------------------------------------------

void fileClose( char outFileName[80], ofstream* outStream ){
  outStream -> open(outFileName);
}

//---------------------------------------------------------------------

void writeALine (int length, char simbol, ofstream* outStream ){
  for (int i = 0; i < length; i++){
    *outStream<<simbol;
  }
}

#endif     //-----------lib350_T-----------//
