/* -*- mia-c++ -*-
 *
 * This file is part of viewitgui - a library and program for the
 * visualization of 3D data sets. 
 *
 * Copyright (c) Leipzig, Madrid 1999-2013 Mirco Hellmann, Gert Wollny
 *
 * viewitgui is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * viewitgui is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with viewitgui; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __texture_h
#define __texture_h

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <mia.hh>
#include <GL/gl.h>
#include <string>


using namespace std;

//typedef T2DImage<uint8,float, TRefData> C2DUBImage;

class GLTextureBase {
	GLuint id;
public:	
	GLTextureBase();
	virtual ~GLTextureBase();
	virtual void bind() const=0;
	GLuint get_id() const;
	void gl_attach();
	void gl_detach();
private:
	virtual void do_gl_attach()=0;
	virtual void do_gl_detach();
};

class GL1DAlphaTexture: public GLTextureBase {
public:
	GL1DAlphaTexture();
	void set_texture_data(GLubyte *alpha, int size);
	void bind()const;
	virtual void do_gl_attach();
};


class GL2DHTexture : public GLTextureBase {
	int steps; 
	float ambient;
	float diffuse;
	float specular;
	float shine;
	float tm[16];
public:
	GL2DHTexture(int _steps,float ambient, float diffuse, float specular,float shine);
	void bind()const;
	void create_textur_matrix(const mia::C3DFVector& light_pos,const mia::C3DFVector& camera_pos,const mia::C3DFVector& me);
	void gl_texture_matrix_on()const;
	void gl_texture_matrix_off()const;
private:
	virtual void do_gl_attach();
};

class  GL2DTexture : public GLTextureBase {
private:
	struct TGL2DTextureData *data; 
public:	
  typedef mia::C2DUBImage LuminData;
	
  GL2DTexture(const mia::C2DBounds& in_size);
	~GL2DTexture();
	virtual void set_data(const LuminData& data);
	float get_tex_xcoord(float x) const;
	float get_tex_ycoord(float y) const;
	void bind() const;
	
protected: 
	size_t get_inwidth() const; 
	size_t get_inheight() const; 	
	TGL2DTextureData *get_data() const {
		return data; 
	}
private:
	virtual void do_gl_attach();
};


class  GL3DGrayTexture : public GLTextureBase {
private:
	struct TGL3DGrayTextureData *data; 
public:	
  typedef mia::C3DUBDatafield GrayData;
	
  GL3DGrayTexture(const mia::C3DBounds& in_size);
	~GL3DGrayTexture();
	virtual void set_data(const GrayData& data);
	
	void bind() const;
	
private:
	virtual void do_gl_attach();
};



class GL2DLATexture:public GL2DTexture {
public:	
  GL2DLATexture(const mia::C2DBounds& in_size);
	virtual void set_data(const LuminData& data);
private: 
	void do_gl_attach();
};

class T2DAlphaSphere: public GLTextureBase {
	mia::C2DUBImage shape;
	bool dithered_texture;
public:
	T2DAlphaSphere(int radius);
  T2DAlphaSphere(const mia::C2DUBImage& _shape);
	void bind() const;
	bool has_dithered_texture()const;
private:
	virtual void do_gl_attach();
};

inline GLuint GLTextureBase::get_id() const
{
	return id; 
}


inline bool T2DAlphaSphere::has_dithered_texture()const 
{
	return dithered_texture;
}


#endif
