
/**
 * Object containing reusable methods for invoking server-side JSON validation
 */
function Validator() {
	
	// The code in this class expects the following callback functions to be
	// defined by calling script:
	// 
	//  valfn_getFieldList		No input args
	//  valfn_resultHandler		Input validation result code (0, 1, 2, or 3)
	//  valfn_issueHandler		Input array of numeric issue codes
	//  valfn_stdHandler		Input object with canonical field names as properties
	//  valfn_fieldIsEmpty		Input string containing the data element ID
	
	this.requestId = null;	// Unique ID for this session
	this.valData = [];		// List of data elements we want to validate

	/**
	 * Add an element to the list of data elements to be validated
	 */
	this.initData = function (dataId, dataType) {
		this.valData.push( { "id": dataId, "type": dataType } );
	};
	
	/**
	 * Run the validation routine against data that has been entered so far
	 */
	this.runValidator = function () {
		
		var msg = {
			"messageType": "LeadValidationRequest",
			"requestId": this.requestId,
			"options": {
                "allowRemoteQueries": true,
                "allowPayPerUseQueries": true
                },
			"data": { }
		};
		
		var hasData = false;
		
		for (i = 0; i < this.valData.length; i++) {
			var data = this.valData[i];
			if (!valfn_fieldIsEmpty(data.id)) {
				msg.data[data.id] = {
					"type": data.type,
					"fields": valfn_getFieldList(data.id)
				};
				hasData = true;
			}
		}
	
		if (hasData) {
			this.apiSendRequest(msg);
		}
	};
	
	/**
	 * Convert an object to JSON and post it to the server
	 */
	this.apiSendRequest = function (msg) {
		var client = new XMLHttpRequest();
		client.onreadystatechange = this.apiResponseHandler;
		client.open('POST', 'valpost.php', true);
		client.send(msg.toJSONString());
	};
	
	/**
	 * Callback function for the request sent via apiSendRequest()
	 */
	this.apiResponseHandler = function () {
		
		if (this.readyState != 4) { return;	}
		window.eval('var msg = ' + this.responseText);
	
		switch (msg.messageType) {
		
			case 'ErrorResponse':
				alert('Error #' + msg.errorCode + ' has occurred');
				break;
				
			case 'RequestIdResponse':
				this.requestId = msg.requestId;
				break;
				
			case 'LeadValidationResponse':
				for (dataId in msg.data) {
					if (msg.data[dataId].standardized) {
						valfn_stdHandler(dataId, msg.data[dataId].fields);
					}
					if (msg.data[dataId].valResult) {
						valfn_resultHandler(
							dataId, msg.data[dataId].valResult
						);
					}
					if (msg.data[dataId].issues &&
						msg.data[dataId].issues.length > 0)
					{
						valfn_issueHandler(dataId, msg.data[dataId].issues);
					}
				}
				break;
				
			default:
				alert('An unknown response was received');
				break;
		}
	};
	
	// Request a new request ID from the server
	this.apiSendRequest( { "messageType": "RequestIdRequest" } );

}
