#include <stdio.h>
#include <math.h>
#include "genlib.h"
#include "simpio.h"
#include "graphics.h"

#define PI 3.1415926535897932384626433832795

/* Programa para desenhar curvas de Hilbert.   */

/*
 *  Prototipos das funcoes.
 */
void a(int k, double x, double y, double comp);
void b(int k, double x, double y, double comp);
void c(int k, double x, double y, double comp);
void d(int k, double x, double y, double comp);

void DrawLineDirection(double length, double direction);

/**********************************************************************/

main()
{
  int d;

  printf("Qual nivel de recursao voce deseja? ");
  d = GetInteger();
  
  InitGraphics();
  a(d, GetWindowWidth()/2, GetWindowHeight()/2, GetWindowWidth()/4);
}

/**********************************************************************/

void DrawLineDirection(double length, double direction)
{
  double dx, dy;

  dx = length * cos(direction);
  dy = length * sin(direction);

  DrawLine(dx, dy);
}

/*
 *  A
 */
void  a(int k, double x, double y, double comp) {
  if (k > 0) {
        MovePen(x + comp/2, y + comp/2);
	d(k-1, x + comp/2, y + comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), -PI);
	a(k-1, x - comp/2, y + comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), -PI/2);
	a(k-1, x - comp/2, y - comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), 0);
	b(k-1, x + comp/2, y - comp/2, comp/2);
  }
}
/*
 *  B
 */
void  b(int k, double x, double y, double comp) {
  if (k > 0) {
        MovePen(x - comp/2, y - comp/2);
	c(k-1, x - comp/2, y - comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), PI/2);
	b(k-1, x - comp/2, y + comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), 0);
	b(k-1, x + comp/2, y + comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), -PI/2);
	a(k-1, x + comp/2, y - comp/2, comp/2);
  }
}

/*
 *  C
 */
void  c(int k, double x, double y, double comp) {
  if (k > 0) {
        MovePen(x - comp/2, y - comp/2); 
	b(k-1, x - comp/2, y - comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), 0);
	c(k-1, x + comp/2, y - comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), PI/2);
	c(k-1, x + comp/2, y + comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), -PI);
	d(k-1, x - comp/2, y + comp/2, comp/2);
  }
}

/*
 *  D
 */
void  d(int k, double x, double y, double comp) {
  if (k > 0) {
        MovePen(x + comp/2, y + comp/2);
	a(k-1, x + comp/2, y + comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), -PI/2);
	d(k-1, x + comp/2, y - comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), -PI);
	d(k-1, x - comp/2, y - comp/2, comp/2);
	DrawLineDirection(comp/(1 << (k-1)), PI/2);
	c(k-1, x - comp/2, y + comp/2, comp/2);
  }
}

