// These "include" code from the C++ library and SFML too
/* Adapted from Java code at 
TEACHING RECURSION USING RECURSIVELY-GENERATED
GEOMETRIC DESIGNS*
Aaron Gordon
Department of Computer Science and Information Systems
Fort Lewis College
Durango, CO 81301
970.247.7436
gordon_a@fortlewis.edu
*/
#include "stdafx.h"
#define _USE_MATH_DEFINES
#define wWidth  760
#define wHeight 760
#include <iostream>
#include <cmath> // sin()
#include <vector>
using std::vector;
#include <SFML/Graphics.hpp>

struct Point {
	float x, y, r, theta;
	Point(float xin, float yin) : x(xin), y(yin) {
		r = sqrt(x*x + y*y);
		theta = atan2(y, x);
	}
	Point() {};
};

std::ostream& operator<<(std::ostream& os, const Point& p) {
	os << "(x,y) = (" << p.x << ',' << p.y << ")\n"
	   << "(r,theta) = (" << p.r << ',' << p.theta << ")";
	return os;
}

void rdraw(sf::RenderWindow& w, 
		   vector<Point>& points, 
		   float factor, 
		   unsigned nsides = 3, 
		   int level = 5) {
	sf::VertexArray lines(sf::LineStrip, nsides+1);
	//std::cout << "here\n";
	//for (unsigned i = 0; i < nsides; ++i)
		//lines[i].position = sf::Vector2f(points[i].x, points[i].y);
	for(int i = 0; i <= nsides; ++i)
		lines[i].position = sf::Vector2f(points[i%nsides].x, points[i%nsides].y);

	w.draw(lines);
	if (level > 1) {//recurse
		for (unsigned k = 0; k < nsides; k++) {
			float xdot = points[k].x;
			float ydot = points[k].y; //to optimize
			points[k].x = xdot + factor * (points[(k+1)%nsides].x - xdot);
			points[k].y = ydot + factor * (points[(k+1)%nsides].y - ydot);
		}
		// tie up the end
		//points[nsides-1].x = points[nsides-1].x + factor*(points[0].x-points[nsides-1].x);
		//points[nsides-1].y = points[nsides-1].y + factor*(points[0].y-points[nsides-1].y);
		//std::cout << "level = " << level << '\n';
		//std::cin.get();
		rdraw(w, points, factor, nsides, level-1); // recursive call
	}//if
	else for (unsigned i = 0; i < nsides; ++i)
		points[i] = Point(wWidth/2 * (1 + cos(2 * M_PI*i / nsides)), 
						  wHeight/2 * (1 + sin(2 * M_PI*i / nsides)));
}//draw 

int main() {
	int n{ 1 }; //recursive depth
	int N{ 3 }; //N-gon

	sf::RenderWindow window(sf::VideoMode(wWidth, wHeight), "Recursive Figure");
	window.setFramerateLimit(0.5);
	std::cout << "How many sides in the polygon?\n";
	std::cin >> N;
	
	std::cout << "How deep goes your fractal?\n";
	std::cin >> n;
	
	// set coordinates of initial vertices
	vector<Point> points(N); // = { 100,wWidth - 100,wWidth / 2 };
	for (unsigned i = 0; i < N; ++i)
		points[i] = Point(wWidth/2*(1+cos(2 * M_PI*i / N)), 
						  wHeight/2*(1+sin(2 * M_PI*i / N)));
	
	for (Point p : points) {
		std::cout << p << '\n';
		//std::cin.get();
	}
	// This "while" loop goes round and round- perhaps forever
	float fctr = 0.5;
	while (window.isOpen()) {
		// The next 6 lines of code detect if the window is closed
		// And then shuts down the program
		sf::Event event;
		while (window.pollEvent(event)) {
			if (event.type == sf::Event::Closed)
				// Someone closed the window- bye
				window.close();
		}
		// Clear everything from the last run of the while loop
		window.clear();
		// draw the scene
		rdraw(window, points, fctr, N, n);
		// Show everything we just drew
		fctr += 0.01;
		if (fctr >= 1.0)
			fctr = 0.5;
		window.display();
	}
}

