﻿// HealthDeclaration.js

// **************************************************
//							Constants
// **************************************************

var c_sClassCorrect = ' correct';
var c_sClassIncorrect = ' incorrect';
var c_sClassAccordionClosed = ' accordion-closed';
var c_sClassAccordionOpen = ' AccordionOpenDummy';
var c_sTagRadioTruePostfix = 'True';
var c_sTagRadioFalsePostfix = 'False';
var c_sTagErrorPostfix = 'Error';
var c_sErrorControlMarginRight = '2.5em';
var ValidationErrorEnum = { InvalidFormat:0,RequiredField:1 };
var GroupHealthAnswerEnum = { ValidAndInvalid:0,OnlyInvalid:1 };

// NOTE: the values of the following (constant) variables are set in server code
var HealthAnswerTypeEnum;
var c_sTagPersonExpandedPrefix;
var c_sTagPersonExpandedHiddenPrefix;
var c_sTagPersonCorrectPrefix;
var c_nUndefined = -1;
var c_sTagPostedAnswerPrefix;
var c_sTagErrorRequiredField;
var c_sTagErrorInvalidFormat;
var c_sTagErrorGeneralMessageControlID;
var c_sTagDisplayRequiredFieldError;
var c_sTagPagewarningID;
var c_sTagPagewarningText;

// **************************************************
//							Global Variables
// **************************************************

var g_aHealthQuestion = new Array();
var g_aPerson = new Array();

// **************************************************
//							HealthQuestion
// **************************************************

function HealthQuestion()
{
}

function AddHealthQuestion(p_nLevel, p_nParentHealthQuestionEnumIndex, p_eHealthAnswerType, p_bIsInOptionalRequiredGroup)
{
	var oHealthQuestion = new HealthQuestion();
	
	oHealthQuestion.Level = p_nLevel;
	oHealthQuestion.HealthQuestionEnumIndex = g_aHealthQuestion.length;
	oHealthQuestion.HealthAnswerTypeEnum = p_eHealthAnswerType;
	oHealthQuestion.IsInOptionalRequiredGroup = p_bIsInOptionalRequiredGroup;
	oHealthQuestion.ChildHealthQuestionList = new Array();

	WSUtilArrayAdd(g_aHealthQuestion, oHealthQuestion);
	
	if (p_nParentHealthQuestionEnumIndex != c_nUndefined)
	{
		WSUtilArrayAdd(GetHealthQuestion(p_nParentHealthQuestionEnumIndex).ChildHealthQuestionList, oHealthQuestion);
	}
}

function GetHealthQuestion(p_nHealthQuestionEnumIndex)
{
	return g_aHealthQuestion[p_nHealthQuestionEnumIndex];
}

// **************************************************
//							Person
// **************************************************

function Person()
{
}

function AddPerson(p_nPersonIndex, p_bPersonExanded)
{
	var oPerson = new Person();
	
	oPerson.PersonIndex = p_nPersonIndex;
	oPerson.PersonExpandedControl = document.getElementById(c_sTagPersonExpandedPrefix + '_' + p_nPersonIndex);
	oPerson.PersonExpandedHiddenControl = document.getElementById(c_sTagPersonExpandedHiddenPrefix + '_' + p_nPersonIndex);
	oPerson.PersonCorrectControl = document.getElementById(c_sTagPersonCorrectPrefix + '_' + p_nPersonIndex);
	oPerson.HealthAnswerList = new Array();

	SetPersonExpanded(oPerson, p_bPersonExanded);
	
	WSUtilArrayAdd(g_aPerson, oPerson);
}

function GetPerson(p_nPersonIndex)
{
	var nCnt;
	var oPerson;
	
	for (nCnt = 0; nCnt < g_aPerson.length; nCnt++)
	{
		oPerson = g_aPerson[nCnt];
		if (oPerson.PersonIndex == p_nPersonIndex)
		{
			return oPerson;
		}
	}
	
	return null;
}

function IsPersonExpanded(p_oPerson)
{
	return (p_oPerson.PersonExpandedHiddenControl.value == 'true');
}

function SetPersonExpanded(p_oPerson, p_bExpanded)
{
	p_oPerson.PersonExpandedHiddenControl.value = p_bExpanded;
	ReplaceControlClassName(p_oPerson.PersonExpandedControl, c_sClassAccordionClosed, c_sClassAccordionOpen, p_bExpanded);
}

function SetPersonCorrect(p_oPerson, p_bCorrect)
{
	ReplaceControlClassName(p_oPerson.PersonCorrectControl, c_sClassIncorrect, c_sClassCorrect, p_bCorrect);
	
	return p_bCorrect;
}

function TogglePersonExpanded(p_nPersonIndex)
{
	var oPerson = GetPerson(p_nPersonIndex);
	
	SetPersonExpanded(oPerson, !IsPersonExpanded(oPerson));
}

// **************************************************
//							HealthAnswer
// **************************************************

function HealthAnswer()
{
}

function AddHealthAnswer(p_nPersonIndex, p_nHealthQuestionEnumIndex)
{
	var oHealthAnswer = new HealthAnswer();
	var oPerson = GetPerson(p_nPersonIndex);
	var sControlID = c_sTagPostedAnswerPrefix + '_' + p_nPersonIndex + '_' + p_nHealthQuestionEnumIndex;
	var sErrorControlMarginRight = null;
	
	oHealthAnswer.HealthQuestion = GetHealthQuestion(p_nHealthQuestionEnumIndex);
	oHealthAnswer.Person = oPerson;
	
	switch (oHealthAnswer.HealthQuestion.HealthAnswerTypeEnum)
	{
		case HealthAnswerTypeEnum.Selection:
		case HealthAnswerTypeEnum.String:
			sErrorControlMarginRight = c_sErrorControlMarginRight;
			// Fall through
		case HealthAnswerTypeEnum.Int:
			oHealthAnswer.Control = document.getElementById(sControlID);
			oHealthAnswer.ErrorControl = document.getElementById(sControlID + '_' + c_sTagErrorPostfix);
			if (sErrorControlMarginRight != null)
			{
				oHealthAnswer.ErrorControl.style.marginRight = sErrorControlMarginRight;
			}
			break;
		case HealthAnswerTypeEnum.Bool:
			oHealthAnswer.RadioTrueControl = document.getElementById(sControlID + '_' + c_sTagRadioTruePostfix);
			oHealthAnswer.RadioFalseControl = document.getElementById(sControlID + '_' + c_sTagRadioFalsePostfix);
			oHealthAnswer.ErrorControl = document.getElementById(sControlID + '_' + c_sTagErrorPostfix);
			break;
	}

	WSUtilArrayAdd(oPerson.HealthAnswerList, oHealthAnswer);
}

function GetHealthAnswer(p_nHealthQuestionEnumIndex, p_oPerson)
{
	var nCnt;
	var oHealthAnswer;
	
	for (nCnt = 0; nCnt < p_oPerson.HealthAnswerList.length; nCnt++)
	{
		oHealthAnswer = p_oPerson.HealthAnswerList[nCnt];
		if (oHealthAnswer.HealthQuestion.HealthQuestionEnumIndex == p_nHealthQuestionEnumIndex)
		{
			return oHealthAnswer;
		}
	}
	
	return null;
}

function GetHealthAnswerList(p_aHealthQuestion, p_oPerson)
{
	var nCnt;
	var aHealthAnswer = new Array();
	var oHealthAnswer;
	
	for (nCnt = 0; nCnt < p_aHealthQuestion.length; nCnt++)
	{
		oHealthAnswer = GetHealthAnswer(p_aHealthQuestion[nCnt].HealthQuestionEnumIndex, p_oPerson);
		
		if (oHealthAnswer != null)
		{
			WSUtilArrayAdd(aHealthAnswer, oHealthAnswer);
		}
	}
	
	return aHealthAnswer;
}

function ValidateHealthAnswer(p_oHealthAnswer)
{
	var bIsValid = true;
	var bIsValidFormat = true;

	switch (p_oHealthAnswer.HealthQuestion.HealthAnswerTypeEnum)
	{
		case HealthAnswerTypeEnum.Int:
			bIsValidFormat = IsNumeric(p_oHealthAnswer.Control.value);
			// Fall through
		case HealthAnswerTypeEnum.String:
		case HealthAnswerTypeEnum.Selection:
		    p_oHealthAnswer.Control.value = p_oHealthAnswer.Control.value.replace(/^\s+|\s+$/g, '') ;
			bIsValid = (p_oHealthAnswer.Control.value.length > 0);
			if (bIsValidFormat == false)
			{
				ShowHideHealthAnswerError(p_oHealthAnswer, ValidationErrorEnum.InvalidFormat, bIsValidFormat == false);
			}
			else
			{
				ShowHideHealthAnswerError(p_oHealthAnswer, ValidationErrorEnum.RequiredField, bIsValid == false);
			}
			break;
		case HealthAnswerTypeEnum.Bool:
			if (p_oHealthAnswer.RadioTrueControl.checked == true)
			{
				// Validate Child Answers
				bIsValid =  ValidateHealthAnswerList
										(
											GetHealthAnswerList
											(
												p_oHealthAnswer.HealthQuestion.ChildHealthQuestionList,
												p_oHealthAnswer.Person
											),
											p_oHealthAnswer.HealthQuestion.Level + 1
										);
			}
			else if (p_oHealthAnswer.RadioFalseControl.checked == false)
			{
				bIsValid = false;
			}
			ShowHideHealthAnswerError
			(
				p_oHealthAnswer,
				ValidationErrorEnum.RequiredField,
				bIsValid == false && p_oHealthAnswer.RadioTrueControl.checked == false
			);
			break;
	}

	return (bIsValid == true && bIsValidFormat == true);
}

function ValidateHealthAnswerList(p_aHealthAnswer, p_nCriteriaLevel)
{
	var bIsValid = true;
	var bIsValidCurrent;
	var nCnt;
	var oHealthAnswer;
	var aGroupHealthAnswer = new Array();

	for (nCnt = 0; nCnt < p_aHealthAnswer.length; nCnt++)
	{
		oHealthAnswer = p_aHealthAnswer[nCnt];
		
		// Only validate answers of the incoming p_nCriteriaLevel
		if (oHealthAnswer.HealthQuestion.Level != p_nCriteriaLevel)
		{
			continue;
		}

		bIsValidCurrent = ValidateHealthAnswer(oHealthAnswer);
		
		if (oHealthAnswer.HealthQuestion.IsInOptionalRequiredGroup == true)
		{
			AddGroupHealthAnswer(aGroupHealthAnswer, oHealthAnswer, bIsValidCurrent);
		}
		else if (bIsValidCurrent == false)
		{
			bIsValid = false;
		}
	}
	
	// Rectify / Hide OptionalRequiredGroup Validation where needed
	if (aGroupHealthAnswer.length > 0)
	{
	  if (GroupHealthAnswerListContains(aGroupHealthAnswer, GroupHealthAnswerEnum.ValidAndInvalid) == true)
		{
			for (nCnt = 0; nCnt < aGroupHealthAnswer.length; nCnt++)
			{
				ShowHideHealthAnswerError
				(
					aGroupHealthAnswer[nCnt].HealthAnswer,
					ValidationErrorEnum.RequiredField,
					false
				);
			}
		}
		
		if (GroupHealthAnswerListContains(aGroupHealthAnswer, GroupHealthAnswerEnum.OnlyInvalid) == true)
		{
			bIsValid = false
		}
	}
	
	return bIsValid;
}

function ShowHideHealthAnswerError(p_oHealthAnswer, p_eValidationError, p_bShowError)
{
	var bVisible;
	var sError;

	switch (p_eValidationError)
	{
		case ValidationErrorEnum.InvalidFormat:
			bVisible = (p_bShowError == true);
			sError = c_sTagErrorInvalidFormat;
			break;
		case ValidationErrorEnum.RequiredField:
			bVisible = (p_bShowError == true && GetDisplayRequiredFieldError() == true);
			sError = c_sTagErrorRequiredField;
			break;
	}

	p_oHealthAnswer.ErrorControl.innerHTML = "<P class='first'>" + sError + "</p>";
	SetControlVisibilityByControl(p_oHealthAnswer.ErrorControl, bVisible);
}

// **************************************************
//							GroupHealthAnswer
// **************************************************

function GroupHealthAnswer()
{
}

function AddGroupHealthAnswer(p_aGroupHealthAnswer, p_oHealthAnswer, p_bIsValid)
{
	var oGroupHealthAnswer = new GroupHealthAnswer();

	oGroupHealthAnswer.HealthAnswer = p_oHealthAnswer;
	oGroupHealthAnswer.IsValid = p_bIsValid;

	WSUtilArrayAdd(p_aGroupHealthAnswer, oGroupHealthAnswer);
}

function GroupHealthAnswerListContains(p_aGroupHealthAnswer, p_eGroupHealthAnswer)
{
	var bListHasValidEntry = false;
	var bListHasInvalidEntry = false;
	var bContains = false;
	var nCnt;
	
	for (nCnt = 0; nCnt < p_aGroupHealthAnswer.length; nCnt++)
	{
		if (p_aGroupHealthAnswer[nCnt].IsValid == true)
		{
			bListHasValidEntry = true;
		}
		else
		{
			bListHasInvalidEntry = true;
		}
	}
	
	switch (p_eGroupHealthAnswer)
	{
		case GroupHealthAnswerEnum.ValidAndInvalid:
			bContains = (bListHasValidEntry == true && bListHasInvalidEntry == true);
			break;
		case GroupHealthAnswerEnum.OnlyInvalid:
			bContains = (bListHasValidEntry == false && bListHasInvalidEntry == true);
			break;
	}
	
	return bContains;
}

// **************************************************
//									Misc Functions
// **************************************************

function ValidateHealthDeclaration(p_bDisplayRequiredFieldError)
{
	var nCntPerson;
	var oPerson;
	var bIsValid = true;

	if (p_bDisplayRequiredFieldError == true)
	{
		SetDisplayRequiredFieldError(true);
	}

	for (nCntPerson = 0; nCntPerson < g_aPerson.length; nCntPerson++)
	{
		oPerson = g_aPerson[nCntPerson];

		if
		(
			SetPersonCorrect
			(
				oPerson,
				ValidateHealthAnswerList
				(
					oPerson.HealthAnswerList,
					0
				)
			) == false
		)
		{
			bIsValid = false;
		}
	}
	
	SetControlVisibility
	(
		c_sTagPagewarningID,
		GetDisplayRequiredFieldError() == true && bIsValid == false
	);
	
	return bIsValid;
}

function SetDisplayRequiredFieldError(p_bDisplayRequiredFieldError)
{
	SetControlValue(c_sTagDisplayRequiredFieldError, p_bDisplayRequiredFieldError);
}

function GetDisplayRequiredFieldError()
{
	return (GetControlValue(c_sTagDisplayRequiredFieldError) == 'true');
}

function SetControlVisibility(p_sControlID, p_bVisible)
{
	SetControlVisibilityByControl(document.getElementById(p_sControlID), p_bVisible);
}

function SetControlVisibilityByControl(p_oControl, p_bVisible)
{
  var sVisible = '';

  if (p_bVisible == false)
  {
    sVisible = 'none';
  }

  p_oControl.style.display = sVisible;
}

function SetControlValue(p_sControlID, p_oValue)
{
	document.getElementById(p_sControlID).value = p_oValue;
}

function GetControlValue(p_sControlID)
{
	return document.getElementById(p_sControlID).value;
}

function ReplaceControlClassName(p_oControl, p_sSrcClass, p_sDstClass, p_bSrcToDst)
{
	if (p_bSrcToDst == true)
	{
		p_oControl.className = p_oControl.className.replace(p_sSrcClass, p_sDstClass);
	}
	else
	{
		p_oControl.className = p_oControl.className.replace(p_sDstClass, p_sSrcClass);
	}
}

function IsNumeric(p_sText)
{
	var sValidChars = "0123456789";
	var sChar;
	var nCnt;

	for (nCnt = 0; nCnt < p_sText.length; nCnt++) 
	{
		sChar = p_sText.charAt(nCnt); 
		if (sValidChars.indexOf(sChar) == -1) 
		{
			return false;
		}
	}
	
	return true;
}

// **************************************************
//								Array functions 
// **************************************************

function WSUtilArrayAdd(p_aArray, p_oObject)
{
  p_aArray[p_aArray.length] = p_oObject;
}

function WSUtilIsArray(p_oObject)
{
  if (p_oObject == null)
  {
    return false;
  }
  return p_oObject.constructor == Array;
}

