#include <v_lib.h>

void WriteCreateMaterial(vhandle_t outfile,
	char *fn_name,
	vec3_t diffuse,
	vec3_t specular,
	vec_t specular_level,
	vec_t glossiness,
	vec_t self_illum,
	vec_t opacity,
	vec_t falloff,
	vboolean falloff_to_center,
	vboolean additive_opacity,
	vboolean target_R4)
{
	specular_level *= 100;
	glossiness *= 100;
	self_illum *= 100;
	opacity *= 100;
	falloff *= 100;
	filePrintf(outfile,"fn %s =\n(\n\t"
		"local m = StandardMaterial();\n\t",fn_name);
	/*
	 * R2 shaders:
	 * 1 - Constant
	 * 2 - Phong
	 * 3 - Metal
	 * 4 - Blinn
	 *
	 * R4 shaders:
	 * 0 - Anisotropic
	 * 1 - Blinn
	 * 2 - Metal
	 * 3 - Multi-Layer
	 * 4 - Oren-Nayar-Blinn
	 * 5 - Phong
	 * 6 - Strauss
	 *
	 * Specular parameters:
	 * R2: .shinestrength; R4: .specularlevel
	 * R2: .shininess; R4: .glossiness
	 *
	 * R2 opacityType
	 * 3 - filter
	 * 1 - subtractive
	 * 2 - additive
	 *
	 * R4 opacityType
	 * 0 - filter
	 * 1 - subtractive
	 * 2 - additive
	 *
	 * R2 falloff
	 * 1 - In (opaque boundary)
	 * 2 - Out (opaque center)
	 *
	 * R4 falloff (opacityFallOffType)
	 * 0 - In (opaque boundary)
	 * 1 - Out (opaque center)
	 */
	if(target_R4)
		filePrintf(outfile,"m.shaderType = 1;\n\t");
	else
		filePrintf(outfile,"m.shading = 4;\n\t");
	filePrintf(outfile,"m.Diffuse = (color %g %g %g);\n\t",
		256 * diffuse[0],256 * diffuse[1],256 * diffuse[2]);
	filePrintf(outfile,"m.Specular = (color %g %g %g);\n\t",
		256 * specular[0],256 * specular[1],256 * specular[2]);

	filePrintf(outfile,"m.Opacity = %g;\n\t",opacity);
	filePrintf(outfile,"m.OpacityFalloff = %g;\n\t",falloff);

	if(target_R4)
	{
		filePrintf(outfile,"m.SpecularLevel = %g;\n\t",specular_level);
		filePrintf(outfile,"m.Glossiness = %g;\n\t",glossiness);
		filePrintf(outfile,"m.SelfIllumAmount = %g;\n\t",self_illum);
		filePrintf(outfile,"m.OpacityFallOffType = %d;\n\t",
			falloff_to_center ? 0 : 1);
		filePrintf(outfile,"m.OpacityType = %d;\n\t",
			additive_opacity ? 2 : 0);
	}
	else
	{
		filePrintf(outfile,"m.ShineStrength = %g;\n\t",specular_level);
		filePrintf(outfile,"m.Shininess = %g;\n\t",glossiness);
		filePrintf(outfile,"m.SelfIllum = %g;\n\t",self_illum);
		filePrintf(outfile,"m.FallOff = %d;\n\t",
			falloff_to_center ? 1 : 2);
		filePrintf(outfile,"m.OpacityType = %d;\n\t",
			additive_opacity ? 2 : 3);
	}
	filePuts(outfile,"return m;\n)\n\n");

	/*
	 *   3DS MAX material maps for 'Blinn' & 'Metal' shaders
	 * -------------------------------------------------------
	 * |       map         |      R2/R4        |    R4       |
	 * -------------------------------------------------------
	 * | ambient           | .ambientmap       | .maps[1]    |
	 * | diffuse           | .diffusemap       | .maps[2]    |
	 * | specular color    | .specularmap      | .maps[3]    |
	 * | specular level    | .shinestrengthmap | .maps[4]    |
	 * | glossiness        | .shininessmap     | .maps[5]    |
	 * | self-illumination | .selfillummap     | .maps[6]    |
	 * | opacity           | .opacitymap       | .maps[7]    |
	 * | filter color      | .filtermap        | .maps[8]    |
	 * | bump              | .bumpmap          | .maps[9]    |
	 * | reflection        | .reflectionmap    | .maps[10]   |
	 * | refraction        | .refractionmap    | .maps[11]   |
	 * | displacement      | -                 | .maps[12]   |
	 * -------------------------------------------------------
	 * Map amounts / enables:
	 * R2/R4: .<map_name>amount / .<map_name>enable
	 * R4: .mapAmounts[idx] / .mapEnables[idx]
	 */
}

int main()
{
	vec3_t dc = {0.4,0,0.9};
	vec3_t sc = {0.9,0.9,0.9};
	vhandle_t of = fileOpenWrite("out");
	WriteCreateMaterial(of,"ParticleMaterial",dc,sc,1,0.2,0,1,1,true,true,false);
	fileClose(of);
	return 0;
}
