#ifndef  __JBXL_MATERIAL_PARAM_H_
#define  __JBXL_MATERIAL_PARAM_H_


/**
 Materialパラメータ
*/


#include "Vector.h"
#include "Rotation.h"
#include "buffer.h"




namespace  jbxl {



//////////////////////////////////////////////////////////////////////////////////////
//
// MaterialParam  テクスチャ用パラメータ
//

class  MaterialParam
{
public:
	bool	enable;

	Buffer  texture;	///< テクスチャ名
	Buffer  bumpmap;	///< Bumpmap テクスチャ名
	double  color[4];	///< RGBA
	double  glow;		///< 輝き
	double  specular;	///< specular 
	double	bright;		///< 

	int		mflags;		///< メディアフラグ
	int		mapping;	///< マッピング方法
	//
	double 	shiftU;
	double 	shiftV;
	double 	scaleU;
	double 	scaleV;
	double 	rotate;

	bool	flipU;
	bool	flipV;
	
public:
    MaterialParam(void) { init();}
    virtual ~MaterialParam(void) {}	

public:
	void  	init (void);
	void	free (void) { free_Buffer(&texture); free_Buffer(&bumpmap);}
	void	clear(void) { free(); init();}

    void    dup(MaterialParam m) { *this=m; texture=dup_Buffer(m.texture); bumpmap=dup_Buffer(m.bumpmap);}

	void	setupMaterial(void);

	bool	isSetParam   (void) { return (isSetColor() || isSetGlow() || isSetSpecular() || isSetBright());}
	bool	isSetBumpMap (void) { return (bumpmap.buf!=NULL);}

	bool	isSetAlpha   (void) { return (color[3]!=1.0);}
	bool	isSetColor   (void) { return (color[0]!=1.0 || color[1]!=1.0 || color[2]!=1.0 || isSetAlpha());}
	bool	isSetGlow    (void) { return (glow!=0.0);}
	bool	isSetSpecular(void) { return (specular!=0.0);}
	bool	isSetBright  (void) { return (bright!=0.0);}
	bool	isSetShift   (void) { return (shiftU!=0.0 || shiftV!=0.0);}
	bool	isSetScale   (void) { return (scaleU!=1.0 || scaleV!=1.0);}
	bool	isSetRotate  (void) { return (rotate!=0.0);}

	void	setTexture(const char* name) { free_Buffer(&texture); if(name!=NULL) texture = make_Buffer_bystr(name);}
	void	setBumpMap(const char* name) { free_Buffer(&bumpmap); if(name!=NULL) bumpmap = make_Buffer_bystr(name);}

	void	setAlpha   (double a) { color[3] = a;}
	void	setColor   (double r, double g, double b, double a=1.0) { color[0]=r; color[1]=g; color[2]=b; color[3]=a;}
	void	setGlow    (double g) { glow   = g;}
	void	setSpecular(double s) { specular = s;}
	void	setBright  (double b) { bright = b;}
	void	setRotate  (double r) { rotate = r;}
	void	setShift   (double u, double v) { shiftU = u; shiftV = v;}
	void	setScale   (double u, double v) { scaleU = u; scaleV = v;}

	void  	execTrans (UVMap<double>* uv, int n);		///< Scale, Rotate, Shift
	void  	execShift (UVMap<double>* uv, int n);
	void  	execScale (UVMap<double>* uv, int n);
	void  	execRotate(UVMap<double>* uv, int n);

	void  	execInvTrans (UVMap<double>* uv, int n);	///< Shift, Rotate, Scale
	void  	execInvShift (UVMap<double>* uv, int n);
	void  	execInvScale (UVMap<double>* uv, int n);
	void  	execInvRotate(UVMap<double>* uv, int n);

//	void  	execShift (UVMap<double>* uv, int n, double u, double v) { setShift(u, v); execShift(uv, n);}
//	void  	execScale (UVMap<double>* uv, int n, double u, double v) { setScale(u, v); execScale(uv, n);}
//	void  	execRotate(UVMap<double>* uv, int n, double s) 			 { setRotate(s);   execRotate(uv, n);}

	void 	execFlipU(UVMap<double>* uv, int n) { for(int i=0; i<n; i++) uv[i].u = 1.0 - uv[i].u;}
	void 	execFlipV(UVMap<double>* uv, int n) { for(int i=0; i<n; i++) uv[i].v = 1.0 - uv[i].v;}

public:
	void	PrintParam(FILE* fp);
};




inline MaterialParam*  newMaterialParam(MaterialParam p) { MaterialParam* m = new MaterialParam(); m->dup(p); return m;}

bool   isSameMaterial(MaterialParam a, MaterialParam b);		///< compare texture and color[4]




}		// namespace

#endif

