#include <math.h>
#include "Aktor.h"
#include "Werteks.h"
#include "Wektor.h"

class Kwadryka : public Aktor
{
private:
	int liczbaPasm, liczbaSekcji, liczbaWerteksówWPaśmie;
	float promieńDolny, promieńGórny, położeniePodstawy, wysokość;

	static unsigned int TwórzTablicęWerteksówŚciętegoStożka(CWerteks*& tablicaWerteksów, float promieńDolny, float promieńGórny, float położeniePodstawy, float wysokość, int liczbaSekcji);

	//ukryty konstruktor
	Kwadryka(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promieńDolny, float promieńGórny, float położeniePodstawy, float wysokość, int liczbaSekcji, int liczbaPasm = 1)
		:Aktor(),
		liczbaPasm(liczbaPasm), liczbaSekcji(liczbaSekcji), liczbaWerteksówWPaśmie(2 * (liczbaSekcji + 1)),
		promieńDolny(promieńDolny), promieńGórny(promieńGórny), położeniePodstawy(położeniePodstawy), wysokość(wysokość)
	{
		Inicjuj(atrybutPołożenie, atrybutNormalna, atrybutKolor);
	}

	unsigned int TwórzTablicęWerteksów(CWerteks*& werteksy);

public:
	void Rysuj();

	//pseudokonstruktory 
	static Kwadryka* StwórzŚciętyStożek(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promieńDolny, float promieńGórny, float wysokość, int liczbaSekcji = 20)
	{
		return new Kwadryka(
			atrybutPołożenie, atrybutNormalna, atrybutKolor,
			promieńDolny, promieńGórny, 0.0f, wysokość, liczbaSekcji, 1);
	}

	static Kwadryka* StwórzWalec(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promień, float wysokość, int liczbaSekcji = 20)
	{
		return new Kwadryka(
			atrybutPołożenie, atrybutNormalna, atrybutKolor,
			promień, promień, 0.0f, wysokość, liczbaSekcji, 1);
	}

	static Kwadryka* StwórzStożek(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promieńDolny, float wysokość, int liczbaSekcji = 20)
	{
		return new Kwadryka(
			atrybutPołożenie, atrybutNormalna, atrybutKolor,
			promieńDolny, 0.0f, 0.0f, wysokość, liczbaSekcji, 1);
	}

	static Kwadryka* StwórzDysk(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promieńWewnętrzny, float promieńZewnętrzny, int liczbaSekcji = 20)
	{
		return new Kwadryka(
			atrybutPołożenie, atrybutNormalna, atrybutKolor,
			promieńZewnętrzny, promieńWewnętrzny, 0.0f, 0.0f, liczbaSekcji, 1);
	}
		
	static Kwadryka* StwórzKoło(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promień, int liczbaSekcji = 20)
	{
		return new Kwadryka(
			atrybutPołożenie, atrybutNormalna, atrybutKolor,
			promień, 0.0f, 0.0f, 0.0f, liczbaSekcji, 1);
	}

	static Kwadryka* StwórzSferę(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promień, int liczbaSekcjiNaRównoleżnikach = 20, int liczbaSekcjiNaPołudnikach = 20)
	{
		return new Kwadryka(
			atrybutPołożenie, atrybutNormalna, atrybutKolor,
			promień, 0.0f, 0.0f, 0.0f, liczbaSekcjiNaRównoleżnikach, liczbaSekcjiNaPołudnikach);
	}
};

//-------------------------------------------------------------------

class SferaZBuforemIndeksów : public AktorZBuforemIndeksów
{
private:
	float promień;
	unsigned int liczbaSekcjiNaRównoleżnikach, liczbaSekcjiNaPołudnikach;
	unsigned int TwórzTablicęWerteksów(CWerteks*& werteksy);
	unsigned int TwórzTablicęIndeksów(GLuint*& indeksy);
	int indeks(int i, int j);

public:
	SferaZBuforemIndeksów(
		GLuint atrybutPołożenie, GLuint atrybutNormalna, GLuint atrybutKolor,
		float promień,
		unsigned int liczbaSekcjiNaRównoleżnikach = 20, unsigned int liczbaSekcjiNaPołudnikach = 20)
		:AktorZBuforemIndeksów(), promień(promień), liczbaSekcjiNaRównoleżnikach(liczbaSekcjiNaRównoleżnikach), liczbaSekcjiNaPołudnikach(liczbaSekcjiNaPołudnikach)
	{
		Inicjuj(atrybutPołożenie, atrybutNormalna, atrybutKolor);
	}
};
