#pragma once
#include "../stdafx.h"
#include "glLibLocals.h"
#include "glLibMath/glLibMathVec.h"
//#include "glLibShader.cpp" //set_shader

namespace glLib {

class light {
	private:
		int number, gl_light;
		float ambient_color[4], diffuse_color[4], specular_color[4], pos[3], atten[3], type, spot[5];
		//spot[5]: x, y, z direction, exponent, cutoff

	public:
		light(void);
		light(GLenum num);
		light(const glLibFlagLight num);
		~light(void);

		void set_ambient(float new_ambient_color_r, float new_ambient_color_g, float new_ambient_color_b);
		void set_ambient(const float new_ambient_color[4]);
		void set_diffuse(float new_diffuse_color_r, float new_diffuse_color_g, float new_diffuse_color_b);
		void set_diffuse(const float new_diffuse_color[4]);
		void set_specular(float new_specular_color_r, float new_specular_color_g, float new_specular_color_b);
		void set_specular(const float new_specular_color[4]);

		void set_pos(float new_pos_x, float new_pos_y, float new_pos_z);
		void set_pos(const float new_pos[3]);

		void set_atten(float new_const_atten, float new_lin_atten, float new_quad_atten);
		void set_atten(bool real_atten);

		template <typename float_type> void set_spot_dir(const float_type new_direction[3]) {
			for (int i=0;i<3;++i) { spot[i]=new_direction[i]; }
			float spot_dir[3] = {spot[0],spot[1],spot[2]};
			glLightfv(gl_light,GL_SPOT_DIRECTION,spot_dir);
		}
		void set_spot_ex(float new_exponent);
		void set_spot_angle(void);
		void set_spot_angle(float angle);

		void enable(void);
		void disable(void);

		int get_number(void) const;

		template <typename float_type> void get_ambient_color(float_type param[4]) const {
			for (int i=0;i<4;++i) { param[i]=ambient_color[i]; }
		}
		template <typename float_type> void get_diffuse_color(float_type param[4]) const {
			for (int i=0;i<4;++i) { param[i]=diffuse_color[i]; }
		}
		template <typename float_type> void get_specular_color(float_type param[4]) const {
			for (int i=0;i<4;++i) { param[i]=specular_color[i]; }
		}

		template <typename float_type> void get_pos(float_type param[3]) const {
			for (int i=0;i<3;++i) { param[i]=pos[i]; }
		}

		template <typename float_type> void get_atten(float_type param[3]) const {
			for (int i=0;i<3;++i) { param[i]=atten[i]; }
		}

		glLibFlagLighting get_type(void) const;

		/*
	##    def push_attrib(self):
	##        self.past_diffuses.append(self.diffuse_color)
	##        self.past_colors.append(self.color)
	##        self.past_pos.append(self.pos)
	##    def pop_attrib(self):
	##        self.diffuse_color = self.past_diffuses[-1]
	##        self.color = self.past_colors[-1]
	##        self.pos = self.past_pos[-1]
	##        self.past_diffuses = self.past_diffuses[:-1]
	##        self.past_colors = self.past_colors[:-1]
	##        self.past_pos = self.past_pos[:-1]
	##        self.change_diffuse_color(self.diffuse_color)
	##        self.change_color(self.color)
	##        self.change_pos(self.pos)
		*/
		void set(void) const;
		void set_type(const glLibFlagLighting new_type);
		void zero(void);
		void set_default(void);
	private:
		void glLibInternal_make(GLenum num);
		void glLibInternal_set_spot_angle(float angle);

		void glLibInternal_get_color_representation(float color[3]) const {
			Math::Vec::copy3(diffuse_color,color);
			float maximum = Math::Vec::max3(diffuse_color); //Could be max4, but let's ignore the alpha as "representative".
			if (maximum>1.0) Math::Vec::scale3(1.0f/maximum,color); //If block important because want lights < 1.0 to appear < 1.0.
		}
	public:
		void draw_point(int size=1) const {
			glPushAttrib(GL_ENABLE_BIT|GL_LIGHTING_BIT);
			float ptsize; glGetFloatv(GL_POINT_SIZE,&ptsize);

			glDisable(GL_TEXTURE_2D);
			glDisable(GL_LIGHTING);
			glPointSize(size);

			float color[3]; glLibInternal_get_color_representation(color);
			glColor3fv(color);

			glBegin(GL_POINTS);
			glVertex3fv(pos);
			glEnd();

			glPointSize(ptsize);
			glPopAttrib();
		}
		/*def draw_as_sphere(self,size=0.05,detail=10):
			glDisable(GL_LIGHTING)
			glDisable(GL_TEXTURE_2D)
			glPushMatrix()
			glTranslatef(*self.pos)
			Sphere = gluNewQuadric()
			r,g,b,a = glGetFloatv(GL_CURRENT_COLOR)
			glColor3f(*self.glLibInternal_get_color_representation())
			gluSphere(Sphere,size,detail,detail)
			glColor4f(r,g,b,a)
			glPopMatrix()
			glEnable(GL_TEXTURE_2D)
			glEnable(GL_LIGHTING)
		*/
};

};