<cfcomponent output="false" extends="base">



	<cffunction name="Form" returntype="Struct" output="false" access="public">
		<cfset var FormName = LCase(StructKeyList(Arguments))/>
		<cfset var ThisStream = ArrayContains(This.FormStreams,FormName)/>
		<cfset var Result = Struct
			( Errors  : Array()
			, Success : False
			, Target  : FormName
			)/>

		<cfset var ValidateStream = REReplace(This.FormStreams[ThisStream],'#FormName#.*$','')/>

		<cfset var StreamPos = ""/>
		<cfloop index="StreamPos" list="#ValidateStream#">
			<cfset Result.Errors = ArrayMerge
				( Result.Errors
				, This['validate'&StreamPos](ArgumentCollection=Arguments[1])
				)/>

			<cfif ArrayLen(Result.Errors)>
				<cfset Result.Target = StreamPos/>
				<cfbreak/>
			</cfif>
		</cfloop>

		<cfset Result.Success = (ArrayLen(Result.Errors) EQ 0)/>
		<cfreturn Result/>
	</cffunction>



	<cffunction name="validatePackage">
		<cfset var Errors = Array()/>

		<cfif Exists(Arguments,'hosting_package')>
			<cfif Exists(Arguments,'hosting_level')>
				<cfif NOT ValidPackageLevel( package:Arguments.hosting_package , level:Arguments.hosting_level )>
					<cfset Errors = Append
						( Errors  : Errors
						, Id      : 'hosting_package|hosting_level'
						, Label   : 'Hosting Package|Hosting Level'
						, Message : 'Invalid package/level combination.'
						)/>
				</cfif>
			<cfelse>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'hosting_level'
					, Label   : 'Hosting Level'
					, Message : 'No level chosen.'
					)/>
			</cfif>
		<cfelse>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'hosting_package'
				, Label   : 'Hosting Package'
				, Message : 'No package chosen.'
				)/>
		</cfif>

		<cfif Exists(Arguments,'payment_period')>
			<cfif NOT ValidPeriod(Arguments.payment_period)>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'hosting_package|hosting_level'
					, Label   : 'Hosting Package|Hosting Level'
					, Message : 'Invalid package/level combination.'
					)/>
			</cfif>
		<cfelse>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'payment_period'
				, Label   : 'Payment Period'
				, Message : 'No period chosen.'
				)/>
		</cfif>

		<cfreturn Errors/>
	</cffunction>


	<cffunction name="validateOrder">
		<cfset var Errors = Array()/>

		<cfif NOT Exists(Arguments,'name')>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'name'
				, Label   : 'Name'
				, Message : 'Please supply a name.'
				)/>
		</cfif>

		<cfif Exists(Arguments,'account_id')>
			<cfif Len(Arguments.account_id) GT 8 OR REFindNoCase('[^a-z0-9_]',Arguments.account_id)>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'account_id'
					, Label   : 'Account Id'
					, Message : 'Account Id is limited to eight alpha-numeric characters.'
					)/>
			<cfelse>
				<cfif Account.Exists(Id:Arguments.account_id)>
					<cfset Errors = Append
						( Errors  : Errors
						, Id      : 'account_id'
						, Label   : 'Account Id'
						, Message : 'Specified Account Id already exists.'
							& 'If you already have an account please <a href="#link('login')#">login</a>,'
							& ' otherwise please choose a different id.'
						)/>
				</cfif>
			</cfif>
		<cfelse>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'account_id'
				, Label   : 'Account Id'
				, Message : 'You must provide a unique account id.'
				)/>
		</cfif>

		<cfif Exists(Arguments,'email')>
			<!--- TODO: Check if this is good enough. --->
			<cfif NOT isValid('email',Arguments.email)>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'email'
					, Label   : 'Email Address'
					, Message : 'The email address supplied is not a recognised email.'
					)/>
			</cfif>
		<cfelse>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'email'
				, Label   : 'Email Address'
				, Message : 'An email address is required for account maintenance.'
				)/>
		</cfif>

		<cfif Exists(Arguments,'domain')>
			<cfif NOT Utils.Lookup(domain:Arguments.domain).Found>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'domain'
					, Label   : 'Domain Name'
					, Message : 'Could not find Domain Name #XmlFormat(Arguments.Domain)# - you must have an existing domain before signing up.'
					)/>
			</cfif>
		<cfelse>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'domain'
				, Label   : 'Domain Name'
				, Message : 'Please provide your domain name. You must have an existing domain before signing up.'
				)/>
		</cfif>

		<cfif Exists(Arguments,'ccard_number')>
			<!--- TODO: Validate card number. --->

			<cfif Exists(Arguments,'ccard_expiry')>
				<!--- TODO: Validate expiry date. --->
			<cfelse>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'ccard_expiry'
					, Label   : 'Expiry Date'
					, Message : 'You must enter the expiry date of your payment card.'
					)/>
			</cfif>

			<cfif Exists(Arguments,'ccard_cv2')>
				<cfif NOT (IsNumeric(Arguments.ccard_cv2) AND ListFind('3,4',Len(Arguments.ccard_cv2)))>
					<cfset Errors = Append
						( Errors  : Errors
						, Id      : 'ccard_cv2'
						, Label   : 'Security Code'
						, Message : 'Incorrect security code. Please enter the three-digit number on the rear of the card.'
						)/>
				</cfif>
			<cfelse>
				<cfset Errors = Append
					( Errors  : Errors
					, Id      : 'ccard_cv2'
					, Label   : 'Security Code'
					, Message : 'You must enter the security code on your card.'
					)/>
			</cfif>

		<cfelse>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'ccard_number'
				, Label   : 'Card Number'
				, Message : 'You must provide a payment card number.'
				)/>
		</cfif>

		<cfif NOT Exists(Arguments,'terms')>
			<cfset Errors = Append
				( Errors  : Errors
				, Id      : 'terms'
				, Label   : 'Terms of Service'
				, Message : 'You must agree to the Terms of Service to continue.'
				)/>
		</cfif>

		<!--- Dummy Error: --->
		<cfset ArrayAppend(Errors,'1')/>
		<!--- / --->

		<cfreturn Errors/>
	</cffunction>


	<cffunction name="validateCheckout">
		<cfreturn Array('ERROR:Not Yet Implemented')/>
	</cffunction>


	<cffunction name="validateFinal">
		<cfreturn Array('ERROR:Not Yet Implemented')/>
	</cffunction>




	<cffunction name="Append" returntype="Array" output="false" access="private">
		<cfargument name="Errors" type="Array"/>
		<cfset var eStruct = Duplicate(Arguments)/>
		<cfset StructDelete(eStruct,'Errors')/>
		<cfset ArrayAppend(Arguments.Errors,eStruct)/>
		<cfreturn Arguments.Errors/>
	</cffunction>



	<cffunction name="Exists" returntype="Boolean" output="false" access="private">
		<cfargument name="Scope"   type="Struct"/>
		<cfargument name="VarName" type="String"/>
		<cfreturn
			StructKeyExists(Arguments.Scope,Arguments.VarName)
			AND Len(Trim(Arguments.Scope[Arguments.VarName]))
		/>
	</cffunction>



	<cffunction name="ValidPackageLevel" returntype="Boolean" output="false" access="private">
		<cfargument name="Package" type="String"/>
		<cfargument name="Level"   type="String"/>
		<cfset var ValidLevels = Application.Cfcs.Hosting.Levels(package:Arguments.Package)/>
		<cfreturn ListFind(ValidLevels,Arguments.Level)/>
	</cffunction>



	<cffunction name="ValidPeriod" returntype="Boolean" output="false" access="private">
		<cfreturn ListFind(Application.Cfcs.Hosting.Periods,Arguments[1])/>
	</cffunction>



</cfcomponent>