//	"PI_CPP - example for SCS"
//	(C) by Grigori G.Fursin
//	1998
//
//	              OO
//	             ----
//	             \       n        4
//	Formula: PI=  |  (-1)  *  --------- 
//	             /             2*n + 1
//	             ----
//	             n=0

#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h> // for atoi

#include "fggcfg.h"
CFGGCfg* fggcfg=NULL;
#define CfgMaxParam 5

#define StrMaxLen 1024

ofstream fout; // Output to cout & fout !!!

int main(void)
{
	char cfg[]="pi_cpp.cfg";
	char out[]="pi_cpp.out";
	
	ifstream fin;

	int ret;

	char str[StrMaxLen];

	int t_loop;				// Type of loop
	unsigned long n_it;		// Number of iterations
	unsigned long n_it_p;	// Period to print
	int t_er;				// If error ...
	unsigned long n_er;		// Number of iteration, when error

	unsigned long i;

	time_t time_start, time_finish;

	double time_diff;

	double pi_std = 3.1415926535897932;
	double pi_my;
	double f1;

	// Preparing 
	cout.setf(ios::unitbuf);
	
	strcpy(str, "\"PI_CPP - example for SCS\"  (C) by Grigori G.Fursin  1998\n");
	cout << str;
	
	fout.open(out);
	if (!fout)
	{
		cout << "\nERROR: Can't open output file \"" << out << "\"!\n";
		return 1;
	}

	fout.setf(ios::unitbuf);
	fout << str;
	
	static CFGGCfg CSCS_CCfg(CfgMaxParam, StrMaxLen, cfg);

	fggcfg=&CSCS_CCfg;
	ret=CSCS_CCfg.Load();
	if (ret!=0)
	{
		switch (ret)
		{
		case 1:
			strcpy(str, "Can't find file with configuration \"");
			strcat(str, cfg);
			strcat(str, "\"");

			break;
		case 2:
			strcpy(str, "Line is too long in file with configuration \"");
			strcat(str, cfg);
			strcat(str, "\"");

			break;
		case 3:
			strcpy(str, "File with configuration \"");
			strcat(str, cfg);
			strcat(str, "\" is incomplete!");

			break;
		default:
			strcpy(str, "Can't load file with configuration \"");
			strcat(str, cfg);
			strcat(str, "\"");

			break;
		}
		
		cout << "ERROR:" << str << "!\n";
		fout << "ERROR:" << str << "!\n";

		fout.close();

		return 1;
	}
	
	// Reading configuration

	// t_loop = 1 - Loop is INFINITE, 
	//          otherwise Loop is INFINITIE
	t_loop=atoi(fggcfg->Get(1));
	
	// n_it = Number of iterations
	n_it=atol(fggcfg->Get(2));

	// n_it_p = Period when print results
	n_it_p=atol(fggcfg->Get(3));

	// t_er = 1 - If error will be generated, 
	//        otherwise error will not be generated 
	t_er=atoi(fggcfg->Get(4));
	
	// If t_er = 1, n_er = number of iteration, 
	//                     when error is generated
	n_er=atol(fggcfg->Get(5));
	
	// Checking
	if (t_loop!=1) 
	{
		if (n_it<1) n_it=1;
		if (n_it_p<1) n_it_p=1;
	}

	time(&time_start);
	
	// Begin of algorithm
	i=1;
	f1=1;
	pi_my=4; // When i=0!!!
	
	strcpy(str,"\n   Iteration:                PI:             Error:\n\n");
	cout << str;
	fout << str;
	
	do
	{
		f1*=(-1);
		
		pi_my+=4*f1*(1/(1+2*(double)i));
				
		if ((i%n_it_p)==0)
		{
			cout.width(12);
			cout << i << ") ";
			cout.setf(ios::fixed);
			cout.width(18);
			cout.precision(16);
			cout << pi_my;
			cout << " ";
			cout.setf(ios::fixed);
			cout.width(18);
			cout.precision(16);
			cout << fabs(pi_my-pi_std);
			cout << "\n";

			fout.width(12);
			fout << i << ") ";
			fout.setf(ios::fixed);
			fout.width(18);
			fout.precision(16);
			fout << pi_my;
			fout << " ";
			fout.setf(ios::fixed);
			fout.width(18);
			fout.precision(16);
			fout << fabs(pi_my-pi_std);
			fout << "\n";
		}
		i++;

		if ((t_er==1)&&(i==n_er))
		{
			assert(0!=0);

			// i=0;
			// pi_my=1/i;
			
			return 255;
		}
	}
	while ((i<=n_it)||(t_loop==1));
	// End of algorithm
	
	time(&time_finish);

	time_diff=difftime(time_finish, time_start);

	strcpy(str, "\nPI (from program) = ");
	cout << str;
	cout.setf(ios::fixed);
	cout.width(18);
	cout.precision(16);
	cout << pi_my << "\n";
	fout << str;
	fout.setf(ios::fixed);
	fout.width(18);
	fout.precision(16);
	fout << pi_my << "\n";
	
	strcpy(str, "PI (standard)     = ");
	cout << str;
	cout.setf(ios::fixed);
	cout.width(18);
	cout.precision(16);
	cout << pi_std << "\n";
	fout << str;
	fout.setf(ios::fixed);
	fout.width(18);
	fout.precision(16);
	fout << pi_std << "\n";

	strcpy(str, "Error             = ");
	cout << str;
	cout.setf(ios::fixed);
	cout.width(18);
	cout.precision(16);
	cout << fabs(pi_my-pi_std) << "\n";
	fout << str;
	fout.setf(ios::fixed);
	fout.width(18);
	fout.precision(16);
	fout << fabs(pi_my-pi_std) << "\n";
		
	strcpy(str, "\nProgram takes");
	cout << str;
	cout.setf(ios::fixed);
	cout.width(6);
	cout.precision(0);
	cout << time_diff << " second(s).\n";
	fout << str;
	fout.setf(ios::fixed);
	fout.width(6);
	fout.precision(0);
	fout << time_diff << " second(s).\n";
	
	strcpy(str, "\nEnd of Program!\n");
	cout << str;
	fout << str;

	fout.close();

	return 0;
}
