#include <iostream>
#include "DLList.h" //ist.h"
#include <utility>
#include "fraction.h"
#include <string>
#include <list>
#include <vector>

using namespace std;

/*Fraction mediant(const& Fraction M, const& Fraction Mprime) {
Fraction Mdnt;
Mdnt.setNumerator(M.getNumerator() + Mprime.getNumerator());
Mdnt.setDenominator(M.getDenominator() + Mprime.getDenominator());
return Mdnt;
}*/

#define phi 1.618033988749894848 //20458683436563811772030917980576286213544862270526046281890

List<Fraction> buildLevel(List<Fraction> list) {
	DNode<Fraction>* frac = list.first_DNode;
	while (frac->getNext()) {
		frac->add(list,
			new DNode<Fraction>(frac->data.mediant(frac->getNext()->data)));
		frac = frac->getNext()->getNext();
	}
	return list;
}

int main() {
	//list<Fraction> Farey01;
	//vector<Fraction> Farey01;
	//Fraction F01(0, 1);
	//Fraction F10(1, 0);
	//vector<Fraction>::iterator it = Farey01.begin();
	//Farey01.push_back(F01);
	//Farey01.push_back(F02);
	//for (it = Farey01.begin(); it != nullptr; ++it)
	//for (int i = 0; i < 2; ++i)
	//    cout << Farey01[i]; // *it;
	DNode<Fraction>* Farey01 = new DNode<Fraction>(Fraction(1, 1));
	List<Fraction> FareyList01(Farey01);
	Farey01 = Farey01->insert(FareyList01, new DNode<Fraction>(Fraction(1, 2)));
	Farey01 = Farey01->insert(FareyList01, new DNode<Fraction>(Fraction(3, 5)));
	Farey01 = Farey01->insert(FareyList01, new DNode<Fraction>(Fraction(5, 8)));
	Farey01 = Farey01->insert(FareyList01, new DNode<Fraction>(Fraction(8, 13)));
	print_all(FareyList01);

	DNode<Fraction>* Farey02 = new DNode<Fraction>(Fraction(0, 1));
	List<Fraction> FareyList02(Farey02);
	Farey02 = Farey02->add(FareyList02, new DNode<Fraction>(Fraction(1, 1)));
	Farey02 = Farey02->add(FareyList02, new DNode<Fraction>(Fraction(1, 2)));
	Farey02 = Farey02->add(FareyList02, new DNode<Fraction>(Fraction(2, 3)));
	Farey02 = Farey02->add(FareyList02, new DNode<Fraction>(Fraction(3, 5)));
	print_all(FareyList02);
	//Fraction F03(0,1);
	//Fraction F04(1,0);
	//Farey02.add(new DNode<Fraction>(F03));
	//Farey02.add(new DNode<Fraction>(F04));
	//cout << "Farey02.firstDNode->data = " << Farey02.first_DNode->data << endl;
	//Farey02.printDll();
	//Farey02.add();
	unsigned sz{ 0 };
	cout << "\nHow big is your playing field? ";
	cin >> sz;
	vector<pair<uint64_t, uint64_t>> PPositions;
	PPositions.push_back(pair<uint64_t, uint64_t>(0, 0));
	PPositions.push_back(pair<uint64_t, uint64_t>(1, 2));
	for (unsigned n = 2; n < sz; ++n) {
		PPositions.push_back(pair<uint64_t, uint64_t>
			                     (uint64_t(floor(n*phi)),
			                      uint64_t(floor(n*phi*phi))));
		cout << PPositions[n].first << ", " << PPositions[n].second << endl;
	}
	DNode<Fraction>* F01 = new DNode<Fraction>(Fraction(0,1));
	DNode<Fraction>* F10 = new DNode<Fraction>(Fraction(1,0));
	DNode<Fraction>* F11 = new DNode<Fraction>(Fraction(1,1));
	List<Fraction> TheFractions(F01);
	F01->add(TheFractions, F11);
	//F01->add(TheFractions, 
	//	new DNode<Fraction>(F01->data.mediant(F10->data)));
	for (int i = 0; i < 4; ++i)
		TheFractions = buildLevel(TheFractions);
	print_all(TheFractions);
	cin.ignore();
	cin.get();
	return 0;
}