
#include <iostream.h>
#include <fstream.h>
#include "Gate.h"
#include "Boolean.h"
#include "Circuit.h"
#include "Dictionary.h"
#include "Set.h"
#include "Strngs.h"
#include "SortArray.h"
#include "Range.h"
#include "Array2.h"

int s = 0;
void sum(int x, void *)
{ s += x;
}

FreeArray<3,5,int> XX;
void rxx(int x, FreeArray<3,4,int> * a)
{	cin >> (*a)[x];
}
void wxx(int x, FreeArray<3,4,int> * a)
{	cout << (*a)[x] << ' ';
}

void main()
{  cout << "Gate test."<<endl;
	Gate TG(true);
	Gate FG(false);
	AndGate And1;
	AndGate And2;
	OrGate  Or1;
	NotGate Not1;

	And1.connect(&TG);
	And1.connect(&FG);
	Or1.connect(&And1);
	Or1.connect(&FG);
	Not1.connect(&Or1);
	cout << int(Not1.output())<<endl;

cout << "Circuit Test."<<endl;

	Adder Add2 (&FG,&FG);
	Array<Boolean> out = Add2.output();
	cout << int(out[1]) << int(out[0])<<endl;

	Switch s1(true);
	Switch s2(true);
	Switch s3(true);
	Switch s4(true);
//   s1.flip();
	FullAdder FA1(&s1,&s2,&FG);
	out = FA1.output();
	cout << int(out[1]) << int(out[0])<<endl;
	FullAdder FA2(&s3, &s4, FA1.output(1));
   cout<<int(FA2.output()[1])<<int(FA2.output()[0])<<int(FA1.output()[0])<<endl;

cout<< "Dictionary test" <<endl;
Dictionary<String, int> DD;
DD.atPut("These are the times.",1);
DD.atPut("Those were the times.",2);
cout<< DD["Those were the times."] <<endl;
DD["Those were the times."] = 333;
cout<< DD["Those were the times."] <<endl;
cout << DD<<endl;
//Dictionary<int,int> DD;
//DD.atPut(1,2);
//DD.atPut(3,4);

ofstream fs("dict.sav");
saveDictionary(fs, DD);
cout<<endl;
fs.close();
ifstream is("dict.sav");
Dictionary<String,int> DC;
restoreDictionary(is,DC);
cout << DC<<endl;

if(DC == DD) cout <<"equal sets"<<endl;

Range<1,10> v1(5);
Range<2, 12> v2(8);
cout << v1<<endl;
v1 = 3;
v1 = 1 + v1;
cout << v1<<endl;
v1 = v2;
cout << v1 + v2<<endl;

FreeArray<-2,2,int> Arr;
Arr[-2] = 999;
cout << Arr[-2]<<endl;
int i,j;
Range <-2,2> v0;
for(i = -2; i<=2;i++)
	cin>>Arr[i];
	
for(v0 = -2; v0<=2; v0++)
{	cout<<Arr[v0];
	if (v0==2)break; // must avoid the last increment
}
cout<<endl<<v0<<endl;
v0 = v0.first();
while(v0 <= v0.last())  // infinite loop actually.
{	cout<<Arr[v0];
	if (v0 < v0.last()) ++v0; else break;
}
cout<<endl<<v0<<endl;

FreeArray2<-1,1,2,3,int> F2;
F2(-1,2) = 1;
F2(-1,3) = 2;
F2(0,2) = 3;
F2(0,3) = 4;
F2(1,2) = 5;
F2(1,3) = 6;
for(i=-1; i<2; i++)
	for(j=2; j<4; j++)
		cout<<F2(i,j)<<' ';
cout<<endl;

FreeArray2<-1,1,2,3,int> F3(55);
for(i=-1; i<2; i++)
	for(j=2; j<4; j++)
		cout<<F3(i,j)<<' ';
cout<<endl;
FreeArray2<-1,1,2,3,int> F4;
F4 = F3;
for(i=-1; i<2; i++)
	for(j=2; j<4; j++)
		cout<<F4(i,j)<<' ';
cout<<endl;

FreeArray<2,3,int> FX = F2[-1];
	for(j=2; j<4; j++)
		cout<<FX[j]<<' ';
cout<<endl;

Range<1,10> vv(8);
vv.forall(sum,NULL);
cout << s <<endl;

Range<3,4> v34;
v34.forall((Range<3,4>::action)rxx, &XX);
v34.forall((Range<3,4>::action)wxx, &XX);
cout<<endl<<endl;

Array2<int> aa2(10,5);
for(i=0; i< 10; i++)
for(j=0; j<5; j++)
	aa2(i,j) = i+j;
	
for(i=0; i< 10; i++)
for(j=0; j<5; j++)
	cout<< aa2(i,j) << ' ';
cout<<endl<<endl;
	
Array<int> &aa2r = aa2[3]; // without & it makes a copy.
aa2r[4] = 99;
for(j=0; j<5; j++)
	cout<< aa2r[j] << ' ';
cout<<endl<<endl;
aa2r.extendBy(5,222);
cout << aa2r[8]<<endl;
cout << aa2[3][8]<<endl;
for(i=0; i< 10; i++)
for(j=0; j<5; j++)
	cout<< aa2(i,j) << ' ';
cout<<endl<<endl;

Array2<int> aa3(3,3,555);
for(i=0; i< 3; i++)
for(j=0; j<3; j++)
	cout<< aa3(i,j) << ' ';
cout<<endl<<endl;

for(i=0; i< 3; i++)
for(j=0; j<3; j++)
	cout<< aa3[i][j] << ' ';
cout<<endl<<endl;

aa3[2][2] = 666;
for(i=0; i< 3; i++)
for(j=0; j<3; j++)
	cout<< aa3[i][j] << ' ';
cout<<endl<<endl;

// Don't actually need array2. We can create them on the fly and even
// initialize them. (And extend them)
Array<Array<int> > fooo(3, Array<int> (4,111));
for(i=0; i< 3; i++)
for(j=0; j<4; j++)
	cout<< fooo[i][j] << ' ';
cout<<endl<<endl;
	
fooo.extendBy(1, Array<int>(4,222));
for(i=0; i<4; i++)
	fooo[i].extendBy(1,333);
for(i=0; i< 4; i++)
{for(j=0; j<5; j++)
	cout<< fooo[i][j] << ' ';
	cout<<endl;
}
cout<<endl<<endl;
	
{ // new scope
cout<<"sets"<<endl;
	Set<int> S;
	S.insert(1);
	S.insert(2);
	S.insert(3);
	Set<int>::Iterator IT(S);
	for(IT.reset(); !IT.atEnd(); )
		cout<<*IT++<<' ';
}
	
cout<<endl<<endl;
{	Dictionary<int,Gate> DDD;
//	cout<< DDD<<endl;
}
}

