# -*- coding: utf-8 -*-

#-------------------------------------------------------------------------
# drawElements Quality Program utilities
# --------------------------------------
#
# Copyright 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#-------------------------------------------------------------------------

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())
