import sys
import itertools
import operator

import genutil

from genutil import Scalar, Vec2, Vec3, Vec4, Uint, UVec2, UVec3, UVec4, CaseGroup


# Templates

ARTIHMETIC_CASE_TEMPLATE = """
case ${{NAME}}
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values
	{
		${{VALUES}}
	}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		void main()
		{
			${SETUP}
			out0 = ${{EXPR}};
			${OUTPUT}
		}
	""
end
""".strip()

FUNCTIONS_CASE_TEMPLATE = """
case ${{NAME}}
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values
	{
		${{VALUES}}
	}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		${{OUTTYPE}} func (${{OUTTYPE}} a)
		{
			return a * ${{OUTTYPE}}(2);
		}

		void main()
		{
			${SETUP}
			out0 = func(in0);
			${OUTPUT}
		}
	""
end
""".strip()

ARRAY_CASE_TEMPLATE = """
case ${{NAME}}
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values
	{
		${{VALUES}}
	}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		void main()
		{
			${SETUP}
			${{ARRAYTYPE}}[] x = ${{ARRAYTYPE}}[] (${{ARRAYVALUES}});
			out0 = ${{EXPR}};
			${OUTPUT}
		}
	""
end
""".strip()

STRUCT_CASE_TEMPLATE = """
case ${{NAME}}
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values
	{
		${{VALUES}}
	}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		void main()
		{
			${SETUP}
			struct {
				${{OUTTYPE}} val;
			} x;

			x.val = ${{STRUCTVALUE}};

			out0 = ${{EXPR}};
			${OUTPUT}
		}
	""
end
""".strip()

INVALID_CASE_TEMPLATE = """
case ${{NAME}}
	expect compile_fail
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values
	{
		${{VALUES}}
	}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		void main()
		{
			${SETUP}
			out0 = in0 + ${{OPERAND}};
			${OUTPUT}
		}
	""
end
""".strip()

INVALID_ARRAY_CASE_TEMPLATE = """
case ${{NAME}}
	expect compile_fail
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values {}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		void main()
		{
			${SETUP}
			${{EXPR}}
			${OUTPUT}
		}
	""
end
""".strip()

INVALID_STRUCT_CASE_TEMPLATE = """
case ${{NAME}}
	expect compile_fail
	version 310 es
	require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment }
	values {}

	both ""
		#version 310 es
		precision highp float;
		${DECLARATIONS}

		void main()
		{
			${SETUP}
			struct { ${{INTYPE}} value; } a;
			struct { ${{OUTTYPE}} value; } b;
			a = ${{INVALUE}};
			b = a;
			${OUTPUT}
		}
	""
end
""".strip()


# Input values

IN_ISCALAR = [  2,  1,  1,  3,  5 ]
IN_USCALAR = [  1,  3,  4,  7, 11 ]

IN_IVECTOR = [
	( 1,  2,  3,  4),
	( 2,  1,  2,  6),
	( 3,  7,  2,  5),
]

IN_UVECTOR = [
	( 2,  3,  5,  8),
	( 4,  6,  2,  9),
	( 1, 13,  7,  4),
]

IN_VALUES = {
	"int":		[Scalar(x)								for x in IN_ISCALAR],
	"uint":		[Scalar(x)								for x in IN_USCALAR],
	"ivec2":	[Vec2(x[0], x[1])						for x in IN_IVECTOR],
	"uvec2":	[Vec2(x[0], x[1])						for x in IN_UVECTOR],
	"ivec3":	[Vec3(x[0], x[1], x[2])					for x in IN_IVECTOR],
	"uvec3":	[Vec3(x[0], x[1], x[2])					for x in IN_UVECTOR],
	"ivec4":	[Vec4(x[0], x[1], x[2], x[3])			for x in IN_IVECTOR],
	"uvec4":	[Vec4(x[0], x[1], x[2], x[3])			for x in IN_UVECTOR],
	"float":	[Scalar(x).toFloat()					for x in IN_ISCALAR],
	"vec2":		[Vec2(x[0], x[1]).toFloat()				for x in IN_IVECTOR],
	"vec3":		[Vec3(x[0], x[1], x[2]).toFloat()		for x in IN_IVECTOR],
	"vec4":		[Vec4(x[0], x[1], x[2], x[3]).toFloat()	for x in IN_IVECTOR],
}

VALID_CONVERSIONS = {
	"int":		["float", "uint"],
	"uint":		["float"],
	"ivec2":	["uvec2", "vec2"],
	"uvec2":	["vec2"],
	"ivec3":	["uvec3", "vec3"],
	"uvec3":	["vec3"],
	"ivec4":	["uvec4", "vec4"],
	"uvec4":	["vec4"]
}

SCALAR_TO_VECTOR_CONVERSIONS = {
	"int":		["vec2", "vec3", "vec4", "uvec2", "uvec3", "uvec4"],
	"uint":		["vec2", "vec3", "vec4"]
}

VALID_ASSIGNMENTS = {
	"int":		["ivec2", "ivec3", "ivec4"],
	"uint":		["uvec2", "uvec3", "uvec4"],
	"ivec2":	["int", "float"],
	"ivec3":	["int", "float"],
	"ivec4":	["int", "float"],
	"uvec2":	["uint", "float"],
	"uvec3":	["uint", "float"],
	"uvec4":	["uint", "float"],
	"float":	["vec2", "vec3", "vec4"],
	"vec2":		["float"],
	"vec3":		["float"],
	"vec4":		["float"]
}

IN_TYPE_ORDER = [
	"int", 	 "uint",
	"ivec2", "uvec2", "ivec3",
	"uvec3", "ivec4", "uvec4",

	"float",
	"vec2",  "vec3",  "vec4"
]

def isScalarTypeName (name):
	return name in ["float", "int", "uint"]

def isVec2TypeName (name):
	return name in ["vec2", "ivec2", "uvec2"]

def isVec3TypeName (name):
	return name in ["vec3", "ivec3", "uvec3"]

def isVec4TypeName (name):
	return name in ["vec4", "ivec4", "uvec4"]

# Utilities

def scalarToVector(a, b):
	if isinstance(a, Scalar) and isinstance(b, Vec2):
		a = a.toVec2()
	elif isinstance(a, Scalar) and isinstance(b, Vec3):
		a = a.toVec3()
	elif isinstance(a, Scalar) and isinstance(b, Vec4):
		a = a.toVec4()
	return a

def isUintTypeName (type_name):
	return type_name in ["uint", "uvec2", "uvec3", "uvec4"]

def convLiteral (type, value):
	if isUintTypeName(type):
		return int(value)
	else:
		return value

def valueToStr(value_type, value):
	if isinstance(value, Scalar):
		return str(value)
	else:
		assert isinstance(value, genutil.Vec)
		out = value_type + "("
		out += ", ".join([str(convLiteral(value_type, x)) for x in value.getScalars()])
		out += ")"
		return out


def valuesToStr(prefix, value_type, values):
	def gen_value_strs(value_list, value_type):
		for value in value_list:
			yield valueToStr(value_type, value)
	return "%s = [ %s ];" % (prefix, " | ".join(gen_value_strs(values, value_type)))


# Test cases

class ArithmeticCase(genutil.ShaderCase):
	def __init__(self, name, op, in_type, out_type, reverse=False):
		self.op_func = {
			"+":	operator.add,
			"-":	operator.sub,
			"*":	operator.mul,
			"/":	operator.div,
		}
		self.name		= name
		self.op			= op
		self.in_type	= in_type
		self.out_type	= out_type
		self.reverse	= reverse

	def __str__(self):
		params = {
			"NAME":		self.name,
			"EXPR":		self.get_expr(),
			"VALUES":	self.gen_values(),
		}
		return genutil.fillTemplate(ARTIHMETIC_CASE_TEMPLATE, params)

	def apply(self, a, b):
		assert(self.op in self.op_func)
		a = scalarToVector(a, b)

		if self.reverse:
			b, a = a, b

		return self.op_func[self.op](a, b)

	def get_expr(self):
		expr = ["in0", self.op, str(self.get_operand())]

		if self.reverse:
			expr.reverse()

		return " ".join(expr)

	def get_operand(self):
		operands = {
			"float":	Scalar(2.0),
			"vec2":		Vec2(1.0, 2.0),
			"vec3":		Vec3(1.0, 2.0, 3.0),
			"vec4":		Vec4(1.0, 2.0, 3.0, 4.0),
			"uint":		Uint(2),
			"uvec2":	UVec2(1, 2),
			"uvec3":	UVec3(1, 2, 3),
			"uvec4":	UVec4(1, 2, 3, 4),
		}
		assert self.out_type in operands
		return operands[self.out_type]

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]

		y			= self.get_operand()
		out_values	= [self.apply(x, y) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)


class ComparisonsCase(ArithmeticCase):
	def __init__(self, name, op, in_type, out_type, reverse=False):
		super(ComparisonsCase, self).__init__(name, op, in_type, out_type, reverse)

		self.op_func = {
			"==":	operator.eq,
			"!=":	operator.ne,
			"<":	operator.lt,
			">":	operator.gt,
			"<=":	operator.le,
			">=":	operator.ge,
		}

	def apply(self, a, b):
		assert(self.op in self.op_func)

		if isinstance(a, Scalar) and isinstance(b, Scalar):
			a, b = float(a), float(b)

		if self.reverse:
			b, a = a, b

		return Scalar(self.op_func[self.op](a, b))

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]

		y			= self.get_operand()
		out_values	= [self.apply(x, y) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output bool out0", "bool", out_values))

		return "\n".join(out)


class ParenthesizedCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type, reverse=False, input_in_parens=False):
		self.name				= name
		self.in_type			= in_type
		self.out_type			= out_type
		self.reverse			= reverse
		self.input_in_parens	= input_in_parens

	def __str__(self):
		params = {
			"NAME":		self.name,
			"EXPR":		self.get_expr(),
			"VALUES":	self.gen_values(),
		}
		return genutil.fillTemplate(ARTIHMETIC_CASE_TEMPLATE, params)

	def apply(self, a):
		b, c	= self.get_operand(0), self.get_operand(1)
		a		= scalarToVector(a, b)

		if self.input_in_parens:
			return b*(a+c)
		else:
			return a*(b+c)

	def get_expr(self):
		def make_paren_expr():
			out = [
				"in0" if self.input_in_parens else self.get_operand(0),
				"+",
				self.get_operand(1)
			]
			return "(%s)" % (" ".join([str(x) for x in out]))

		expr = [
			"in0" if not self.input_in_parens else self.get_operand(0),
			"*",
			make_paren_expr()
		]

		if self.reverse:
			expr.reverse()

		return " ".join([str(x) for x in expr])

	def get_operand(self, ndx=0):
		return IN_VALUES[self.out_type][ndx]

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]

		out_values	= [self.apply(x) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)


class FunctionsCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type

	def __str__(self):
		params = {
			"NAME":		self.name,
			"OUTTYPE":	self.out_type,
			"VALUES":	self.gen_values(),
		}
		return genutil.fillTemplate(FUNCTIONS_CASE_TEMPLATE, params)

	def apply(self, a):
		if isUintTypeName(self.out_type):
			return a.toUint() * Uint(2)
		else:
			return a.toFloat() * Scalar(2.0)

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]
		out_values	= [self.apply(x) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)


class ArrayCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type, reverse=False):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type
		self.reverse	= reverse

	def __str__(self):
		params = {
			"NAME":			self.name,
			"VALUES":		self.gen_values(),
			"ARRAYTYPE":	self.out_type,
			"ARRAYVALUES":	self.gen_array_values(),
			"EXPR":			self.get_expr(),
		}
		return genutil.fillTemplate(ARRAY_CASE_TEMPLATE, params)

	def apply(self, a):
		b = IN_VALUES[self.out_type][1]
		a = scalarToVector(a, b)

		return a + b

	def get_expr(self):
		if not self.reverse:
			return "in0 + x[1]"
		else:
			return "x[1] + in0"

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]
		out_values	= [self.apply(x) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)

	def gen_array_values(self):
		out = [valueToStr(self.out_type, x) for x in IN_VALUES[self.out_type]]
		return ", ".join(out)


class ArrayUnpackCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type

	def __str__(self):
		params = {
			"NAME":			self.name,
			"VALUES":		self.gen_values(),
			"ARRAYTYPE":	"float",
			"ARRAYVALUES":	self.gen_array_values(),
			"EXPR":			self.get_expr(),
		}
		return genutil.fillTemplate(ARRAY_CASE_TEMPLATE, params)

	def apply(self, a):
		if isinstance(a, Scalar) and isVec2TypeName(self.out_type):
			a = a.toVec2()
		elif isinstance(a, Scalar) and isVec3TypeName(self.out_type):
			a = a.toVec3()
		elif isinstance(a, Scalar) and isVec4TypeName(self.out_type):
			a = a.toVec4()

		b = IN_VALUES["float"]

		out = [Scalar(x)+y for x, y in zip(a.getScalars(), b)]

		if self.out_type == "float":
			return out[0].toFloat()
		elif self.out_type == "uint":
			return out[0].toUint()
		elif self.out_type == "vec2":
			return Vec2(out[0], out[1]).toFloat()
		elif self.out_type == "uvec2":
			return Vec2(out[0], out[1]).toUint()
		elif self.out_type == "vec3":
			return Vec3(out[0], out[1], out[2]).toFloat()
		elif self.out_type == "uvec3":
			return Vec3(out[0], out[1], out[2]).toUint()
		elif self.out_type == "vec4":
			return Vec4(out[0], out[1], out[2], out[3]).toFloat()
		elif self.out_type == "uvec4":
			return Vec4(out[0], out[1], out[2], out[3]).toUint()

	def get_expr(self):
		def num_scalars(typename):
			return IN_VALUES[typename][0].getNumScalars()

		def gen_sums():
			in_scalars	= num_scalars(self.in_type)
			out_scalars	= num_scalars(self.out_type)

			for ndx in range(out_scalars):
				if in_scalars > 1:
					yield "in0[%i] + x[%i]" % (ndx, ndx)
				else:
					yield "in0 + x[%i]" % (ndx)

		return "%s(%s)" % (self.out_type, ", ".join(gen_sums()))

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]
		out_values	= [self.apply(x) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)

	def gen_array_values(self):
		out = [valueToStr(self.out_type, x) for x in IN_VALUES["float"]]
		return ", ".join(out)


class StructCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type, reverse=False):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type
		self.reverse	= reverse

	def __str__(self):
		params = {
			"NAME":			self.name,
			"VALUES":		self.gen_values(),
			"OUTTYPE":		self.out_type,
			"STRUCTVALUE":	self.get_struct_value(),
			"EXPR":			self.get_expr(),
		}
		return genutil.fillTemplate(STRUCT_CASE_TEMPLATE, params)

	def apply(self, a):
		if isinstance(a, Scalar) and isVec2TypeName(self.out_type):
			a = a.toVec2()
		elif isinstance(a, Scalar) and isVec3TypeName(self.out_type):
			a = a.toVec3()
		elif isinstance(a, Scalar) and isVec4TypeName(self.out_type):
			a = a.toVec4()

		b = IN_VALUES[self.out_type][0]

		return a + b

	def get_expr(self):
		if not self.reverse:
			return "in0 + x.val"
		else:
			return "x.val + in0"

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]
		out_values	= [self.apply(x) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)

	def get_struct_value(self):
		return valueToStr(self.out_type, IN_VALUES[self.out_type][0])


class InvalidCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type

	def __str__(self):
		params = {
			"NAME":		self.name,
			"OPERAND":	str(self.get_operand()),
			"VALUES":	self.gen_values(),
		}
		return genutil.fillTemplate(INVALID_CASE_TEMPLATE, params)

	def apply(self, a, b):
		return b

	def get_operand(self):
		return IN_VALUES[self.out_type][0]

	def gen_values(self):
		in_values	= IN_VALUES[self.in_type]

		y			= self.get_operand()
		out_values	= [self.apply(x, y) for x in in_values]

		out = []
		out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values))
		out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values))

		return "\n".join(out)


class InvalidArrayCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type

	def __str__(self):
		params = {
			"NAME":	self.name,
			"EXPR":	self.gen_expr(),
		}
		return genutil.fillTemplate(INVALID_ARRAY_CASE_TEMPLATE, params)

	def gen_expr(self):
		in_values = [valueToStr(self.out_type, x) for x in IN_VALUES[self.in_type]]

		out = "%s a[] = %s[] (%s);" % (self.out_type, self.in_type, ", ".join(in_values))

		return out


class InvalidStructCase(genutil.ShaderCase):
	def __init__(self, name, in_type, out_type):
		self.name		= name
		self.in_type	= in_type
		self.out_type	= out_type

	def __str__(self):
		params = {
			"NAME":		self.name,
			"INTYPE":	self.in_type,
			"OUTTYPE":	self.out_type,
			"INVALUE":	self.get_value(),
		}
		return genutil.fillTemplate(INVALID_STRUCT_CASE_TEMPLATE, params)

	def get_value(self):
		return valueToStr(self.in_type, IN_VALUES[self.in_type][0])


# Case file generation

def genConversionPairs(order=IN_TYPE_ORDER, scalar_to_vector=True, additional={}):
	def gen_order(conversions):
		key_set = set(conversions.iterkeys())
		for typename in order:
			if typename in key_set:
				yield typename
	conversions = {}

	for in_type in VALID_CONVERSIONS:
		conversions[in_type] = [] + VALID_CONVERSIONS[in_type]
		if in_type in SCALAR_TO_VECTOR_CONVERSIONS and scalar_to_vector:
			conversions[in_type] += SCALAR_TO_VECTOR_CONVERSIONS[in_type]

	for key in additional.iterkeys():
			value = conversions.get(key, [])
			conversions[key] = value + additional[key]

	for in_type in gen_order(conversions):
		for out_type in conversions[in_type]:
			yield (in_type, out_type)


def genInvalidConversions():
	types = IN_TYPE_ORDER
	valid_pairs = set(genConversionPairs(additional=VALID_ASSIGNMENTS))

	for pair in itertools.permutations(types, 2):
		if pair not in valid_pairs:
			yield pair


def genArithmeticCases(reverse=False):
	op_names = [
		("add", "Addition",			"+"),
		("sub", "Subtraction",		"-"),
		("mul", "Multiplication",	"*"),
		("div", "Division",			"/")
	]

	for name, desc, op in op_names:
		casegroup = CaseGroup(name, desc, [])
		for in_type, out_type in genConversionPairs():
			if op == "-" and isUintTypeName(out_type):
				continue # Can't handle at the moment
			name = in_type + "_to_" + out_type
			casegroup.children.append(ArithmeticCase(name, op, in_type, out_type, reverse))
		yield casegroup


def genComparisonCases(reverse=False):
	op_names = [
		("equal",				"Equal",					"=="),
		("not_equal",			"Not equal",				"!="),
		("less",				"Less than",				"<"),
		("greater",				"Greater than",				">"),
		("less_or_equal",		"Less than or equal",		"<="),
		("greater_or_equal",	"Greater than or equal",	">="),
	]

	for name, desc, op in op_names:
		casegroup	= CaseGroup(name, desc, [])
		type_order	= IN_TYPE_ORDER if name in ["equal", "not_equal"] else ["int", "uint"]

		for in_type, out_type in genConversionPairs(order=type_order, scalar_to_vector=False):
			name = in_type + "_to_" + out_type
			casegroup.children.append(ComparisonsCase(name, op, in_type, out_type, reverse))
		yield casegroup


def genParenthesizedCases():
	for reverse in [True, False]:
		if reverse:
			name = "paren_expr_before_literal"
			desc = "Parenthesized expression before literal"
		else:
			name = "literal_before_paren_expr"
			desc = "Literal before parenthesized expression"
		reversegroup = CaseGroup(name, desc, [])

		for input_in_parens in [True, False]:
			if input_in_parens:
				name = "input_in_parens"
				desc = "Input variable in parenthesized expression"
			else:
				name = "input_outside_parens"
				desc = "Input variable outside parenthesized expression"
			casegroup = CaseGroup(name, desc, [])

			for in_type, out_type in genConversionPairs():
				name = in_type + "_to_" + out_type
				casegroup.children.append(
					ParenthesizedCase(name, in_type, out_type, reverse, input_in_parens)
				)
			reversegroup.children.append(casegroup)
		yield reversegroup


def genArrayCases(reverse=False):
	for in_type, out_type in genConversionPairs():
		name = in_type + "_to_" + out_type
		yield ArrayCase(name, in_type, out_type, reverse)


def genArrayUnpackCases(reverse=False):
	for in_type, out_type in genConversionPairs():
		name = in_type + "_to_" + out_type
		yield ArrayUnpackCase(name, in_type, out_type)


def genFunctionsCases():
	for in_type, out_type in genConversionPairs(scalar_to_vector=False):
		name = in_type + "_to_" + out_type
		yield FunctionsCase(name, in_type, out_type)


def genStructCases(reverse=False):
	for in_type, out_type in genConversionPairs():
		name = in_type + "_to_" + out_type
		yield StructCase(name, in_type, out_type, reverse)


def genInvalidCases(reverse=False):
	for in_type, out_type in genInvalidConversions():
		name = in_type + "_to_" + out_type
		yield InvalidCase(name, in_type, out_type)


def genInvalidArrayCases():
	for in_type, out_type in genConversionPairs(scalar_to_vector=False):
		name = in_type + "_to_" + out_type
		yield InvalidArrayCase(name, in_type, out_type)


def genInvalidStructCases():
	for in_type, out_type in genConversionPairs(scalar_to_vector=False):
		name = in_type + "_to_" + out_type
		yield InvalidStructCase(name, in_type, out_type)


def genAllCases():
	yield CaseGroup(
		"arithmetic", "Arithmetic operations",
		[
			CaseGroup("input_before_literal", "Input before literal",
					  genArithmeticCases(reverse=False)),
			CaseGroup("literal_before_input", "Literal before input",
					  genArithmeticCases(reverse=True)),
		]
	)

	yield CaseGroup(
		"comparisons", "Comparisons",
		[
			CaseGroup("input_before_literal", "Input before literal",
					  genComparisonCases(reverse=False)),
			CaseGroup("literal_before_input", "Literal before input",
					  genComparisonCases(reverse=True)),
		]
	)

	yield CaseGroup(
		"array_subscripts", "Array subscripts",
		[
			CaseGroup("input_before_subscript", "Input before subscript",
					  genArrayCases(reverse=False)),
			CaseGroup("subscript_before_input", "Subscript before input",
					  genArrayCases(reverse=True)),
		#	CaseGroup("unpack", "Unpack array and repack as value",
		#			  genArrayUnpackCases()),
		]
	)

	yield CaseGroup("functions", "Function calls",
					genFunctionsCases())

	yield CaseGroup("struct_fields", "Struct field selectors",
		[
			CaseGroup("input_before_field", "Input before field",
					  genStructCases(reverse=False)),
			CaseGroup("field_before_input", "Field before input",
					  genStructCases(reverse=True)),
		]
	)

	yield CaseGroup("parenthesized_expressions", "Parenthesized expressions",
					genParenthesizedCases())

	yield CaseGroup(
		"invalid", "Invalid conversions",
		[
			CaseGroup("variables", "Single variables",
					  genInvalidCases()),
			CaseGroup("arrays", "Arrays",
					  genInvalidArrayCases()),
			CaseGroup("structs", "Structs",
					  genInvalidStructCases()),
		]
	)


if __name__ == "__main__":
	print "Generating shader case files."
	genutil.writeAllCases("implicit_conversions.test", genAllCases())
