<?xml version="1.0" encoding="utf-8"?>
<xs:schema
	targetNamespace="https://CodeEffects.com/schemas/rule/41"
	xmlns="https://CodeEffects.com/schemas/rule/41"
	xmlns:xs="https://www.w3.org/2001/XMLSchema"
	xmlns:ui="https://CodeEffects.com/schemas/ui/41"
	attributeFormDefault="unqualified"
	elementFormDefault="qualified"
>
	<xs:import namespace="https://CodeEffects.com/schemas/ui/41"/>

	<xs:element name="codeeffects" type="codeeffects" />

	<xs:complexType name="codeeffects">
		<xs:sequence>
			<xs:element name="rule" type="rule" minOccurs="1" maxOccurs="unbounded" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="rule">
		<xs:sequence>
			<xs:element name="name" type="xs:string" minOccurs="0" />
			<xs:element name="description" type="xs:string" minOccurs="0" />
			<xs:element name="definition" type="definition" />
			<xs:element name="format" type="format" minOccurs="0" />
		</xs:sequence>
		<xs:attribute name="id" type="xs:string" use="required" />
		<xs:attribute name="eval" type="xs:boolean" use="required" />
		<xs:attribute name="webrule" type="xs:string" use="optional" />
		<xs:attribute name="utc" type="xs:string" use="optional" />
		<xs:attribute name="type" type="xs:string" use="optional" />
	</xs:complexType>

	<xs:complexType name="definition">
		<xs:choice minOccurs="0">
			<xs:element name="if" type="if" minOccurs="0" maxOccurs="unbounded" />
			<xs:element name="while" type="while" />
			<xs:element name="rule" type="ruleReference" />
			<xs:group ref="coreStatements" />
		</xs:choice>
	</xs:complexType>

	<xs:complexType name="format">
		<xs:sequence>
			<xs:element name="lines" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="if">
		<xs:sequence>
			<xs:element name="clause" type="clause" />
			<xs:element name="then" type="thenelse" />
			<xs:element name="else" type="thenelse" minOccurs="0" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="while">
		<xs:sequence>
			<xs:element name="clause" type="clause" />
			<xs:element name="then" type="thenelse" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="clause">
		<xs:group ref="statements" />
	</xs:complexType>

	<xs:complexType name="thenelse">
		<xs:choice maxOccurs="unbounded">
			<xs:element name="if" type="if" />
			<xs:element name="method" type="method" />
			<xs:element name="set" type="set" />
		</xs:choice>
	</xs:complexType>

	<xs:complexType name="set">
		<xs:sequence>
			<xs:element name="property" type="property" />
			<xs:choice>
				<xs:group ref="coreStatements" />
				<xs:element name="expression" type="expression" />
			</xs:choice>
		</xs:sequence>
	</xs:complexType>

	<xs:group name="coreStatements">
		<xs:choice>
			<xs:element name="and" type="logicalMultiOperator" />
			<xs:element name="or" type="logicalMultiOperator" />
			<xs:element name="not" type="not" />
			<xs:element name="condition" type="condition" />
			<xs:element name="method" type="method" />
			<xs:element name="property" type="property" />
			<xs:element name="value" type="value" />
			<xs:element name="self" />
		</xs:choice>
	</xs:group>

	<xs:group name="statements">
		<xs:choice>
			<xs:group ref="coreStatements" />
			<xs:element name="rule" type="ruleReference" />
			<xs:element name="expression" type="expression" />
		</xs:choice>
	</xs:group>

	<xs:complexType name="not">
		<xs:group ref="statements" />
	</xs:complexType>

	<xs:group name="mathOperators">
		<xs:choice>
			<xs:element name="add" type="binaryMathOperator" />
			<xs:element name="subtract" type="binaryMathOperator" />
			<xs:element name="multiply" type="binaryMathOperator" />
			<xs:element name="divide" type="binaryMathOperator" />
		</xs:choice>
	</xs:group>

	<xs:complexType name="expression">
		<xs:group ref="mathOperators" />
	</xs:complexType>

	<xs:complexType name="binaryMathOperator">
		<xs:choice minOccurs="2" maxOccurs="2">
			<xs:group ref="mathOperators" />
			<xs:element name="method" type="method" />
			<xs:element name="property" type="property" />
			<xs:element name="value" type="value" />
			<xs:element name="self" nillable="true" />
		</xs:choice>
		<xs:attribute ref="ui:block" use="optional"/>
	</xs:complexType>

	<xs:complexType name="method">
		<xs:sequence>
			<xs:group ref="statements" minOccurs="0" maxOccurs="unbounded" />
		</xs:sequence>
		<xs:attribute name="name" use="required" />
		<xs:attribute name="instance" type="xs:boolean" use="optional" />
		<xs:attribute name="type" type="xs:string" use="optional" />
	</xs:complexType>

	<xs:complexType name="logicalMultiOperator">
		<xs:group ref="statements" minOccurs="1" maxOccurs="unbounded" />
		<xs:attribute ref="ui:block" use="optional"/>
	</xs:complexType>

	<xs:complexType name="condition">
		<xs:group ref="statements" minOccurs="1" maxOccurs="3" />
		<xs:attribute name="type" type="conditionType" use="required" />
		<xs:attribute name="stringComparison" type="stringComparison" use="optional" />
	</xs:complexType>

	<xs:complexType name="property">
		<xs:attribute name="name" type="xs:string" />
		<xs:attribute name="itemType" type="xs:string" use="optional" />
	</xs:complexType>

	<xs:complexType name="value">
		<xs:complexContent mixed="true">
			<xs:extension base="xs:anyType">
				<xs:attribute name="type" type="valueType" use="optional" />
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>

	<xs:complexType name="ruleReference">
		<xs:sequence>
			<xs:element name="property" type="property" minOccurs="0" />
		</xs:sequence>
		<xs:attribute name="id" type="xs:string" use="required" />
		<xs:attribute name="operator" type="selectionType" use="optional" />
	</xs:complexType>

	<xs:simpleType name="valueType">
		<xs:union memberTypes="xs:string">
			<xs:simpleType>
				<xs:restriction base="xs:string">
					<xs:enumeration value="bool" />
					<xs:enumeration value="time" />
					<xs:enumeration value="date" />
					<xs:enumeration value="datetime" />
					<xs:enumeration value="integer" />
					<xs:enumeration value="numeric" />
					<xs:enumeration value="double" />
					<xs:enumeration value="string" />
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>

	<xs:simpleType name="conditionType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="equal" />
			<xs:enumeration value="notEqual" />
			<xs:enumeration value="less" />
			<xs:enumeration value="lessOrEqual" />
			<xs:enumeration value="greater" />
			<xs:enumeration value="greaterOrEqual" />
			<xs:enumeration value="isNull" />
			<xs:enumeration value="isNotNull" />
			<xs:enumeration value="between" />
			<xs:enumeration value="contains" />
			<xs:enumeration value="doesNotContain" />
			<xs:enumeration value="startsWith" />
			<xs:enumeration value="doesNotStartWith" />
			<xs:enumeration value="endsWith" />
			<xs:enumeration value="doesNotEndWith" />
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="selectionType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="exists" />
			<xs:enumeration value="doesNotExist" />
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="stringComparison">
		<xs:restriction base="xs:string">
			<xs:enumeration value="CurrentCulture" />
			<xs:enumeration value="CurrentCultureIgnoreCase" />
			<xs:enumeration value="InvariantCulture" />
			<xs:enumeration value="InvariantCultureIgnoreCase" />
			<xs:enumeration value="Ordinal" />
			<xs:enumeration value="OrdinalIgnoreCase" />
		</xs:restriction>
	</xs:simpleType>
</xs:schema>