/FileExtraction/Java_unseen/IMS-MAXIMS_openMAXIMS/Source Library/openmaxims_workspace/Nursing/src/ims/nursing/forms/dailypatientprogressdlg/Logic.java
//#############################################################################
//#                                                                           #
//#  Copyright (C) <2015>  <IMS MAXIMS>                                       #
//#                                                                           #
//#  This program is free software: you can redistribute it and/or modify     #
//#  it under the terms of the GNU Affero General Public License as           #
//#  published by the Free Software Foundation, either version 3 of the       #
//#  License, or (at your option) any later version.                          # 
//#                                                                           #
//#  This program is distributed in the hope that it will be useful,          #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of           #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
//#  GNU Affero General Public License for more details.                      #
//#                                                                           #
//#  You should have received a copy of the GNU Affero General Public License #
//#  along with this program.  If not, see <http://www.gnu.org/licenses/>.    #
//#                                                                           #
//#  IMS MAXIMS provides absolutely NO GUARANTEE OF THE CLINICAL SAFTEY of    #
//#  this program.  Users of this software do so entirely at their own risk.  #
//#  IMS MAXIMS only ensures the Clinical Safety of unaltered run-time        #
//#  software that it builds, deploys and maintains.                          #
//#                                                                           #
//#############################################################################
//#EOH
// This code was generated by Alexie Ursache using IMS Development Environment (version 1.45 build 2433.21597)
// Copyright (C) 1995-2006 IMS MAXIMS plc. All rights reserved.

package ims.nursing.forms.dailypatientprogressdlg;

import java.util.ArrayList;

import ims.admin.vo.AppRoleShortVo;
import ims.assessment.configuration.vo.AssessmentQuestionRefVo;
import ims.assessment.helper.DailyPatientProgressHelper;
import ims.assessment.helper.DynamicAssessmentHelper;
import ims.assessment.helper.UserAssessmentInstHelper;
import ims.assessment.helper.DailyPatientProgressHelper.ScoreAndImage;
import ims.assessment.vo.AssessmentRoleVo;
import ims.assessment.vo.DPPQuestionGroupShortVo;
import ims.assessment.vo.DPPQuestionGroupShortVoCollection;
import ims.assessment.vo.PatientAssessmentDataVo;
import ims.assessment.vo.PatientAssessmentGroupVo;
import ims.assessment.vo.PatientAssessmentGroupVoCollection;
import ims.assessment.vo.PatientAssessmentQuestionVo;
import ims.assessment.vo.PatientAssessmentVo;
import ims.assessment.vo.UserAssessmentVo;
import ims.assessment.vo.lookups.AnswerStatus;
import ims.assessment.vo.lookups.DPPType;
import ims.assessment.vo.lookups.DPPTypeCollection;
import ims.clinical.vo.lookups.PlanOfCareGroupings;
import ims.configuration.AppRight;
import ims.core.vo.AnswerDetailsVo;
import ims.core.vo.AssessmentQuestionVo;
import ims.core.vo.AuthoringInformationVo;
import ims.core.vo.CareContextShortVo;
import ims.core.vo.HcpLiteVo;
import ims.core.vo.lookups.ContextType;
import ims.core.vo.lookups.LookupHelper;
import ims.core.vo.lookups.PatientAssessmentStatusReason;
import ims.core.vo.lookups.PatientAssessmentStatusReasonCollection;
import ims.framework.Control;
import ims.framework.FormName;
import ims.framework.controls.DynamicGrid;
import ims.framework.controls.DynamicGridCell;
import ims.framework.enumerations.DialogResult;
import ims.framework.enumerations.FormMode;
import ims.framework.exceptions.CodingRuntimeException;
import ims.framework.exceptions.PresentationLogicException;
import ims.framework.interfaces.IAppRole;
import ims.framework.utils.Color;
import ims.framework.utils.DateTime;
import ims.nursing.vo.PlanOfCareHistoryVo;
import ims.nursing.vo.PlanOfCareHistoryVoCollection;
import ims.nursing.vo.PlanOfCareVo;
import ims.nursing.vo.PlanOfCareVoCollection;
import ims.nursing.vo.enums.DPPErrors;
import ims.nursing.vo.lookups.PlanOfCareStatus;

public class Logic extends BaseLogic
{
	private static final int	NOT_APPLICABLE		= 1;
	private static final int	NON_STANDARD		= 2;
	private static final int	DPP					= 3;

	//------------------- Handlers ------------------------
	protected void onFormOpen() throws ims.framework.exceptions.PresentationLogicException
	{
		initialize();
		open();
	}

	protected void onBtnOKClick() throws ims.framework.exceptions.PresentationLogicException
	{
		doSave();
	}

	private void doSave()
	{
		if (save())
		{
			form.getGlobalContext().Nursing.setPatientAssessmentVo(form.getLocalContext().getPatientAssessmentVo());
			engine.close(DialogResult.OK);
		}
	}
	
	protected void onBtnCancelClick() throws ims.framework.exceptions.PresentationLogicException
	{
		engine.close(DialogResult.CANCEL);
	}

	protected void onBtnSelectNAQuestionsClick() throws PresentationLogicException
	{
		PatientAssessmentVo currentAssessment = form.getLocalContext().getPatientAssessmentVo();
		//Get the changes user eventualy made in the questions
		//updatePatientAssessmentWithTheChanges(currentAssessment);
		UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabNonApplicable().dynNonApplic());
		currentAssessment = helper.updateQuestionStatusToAnswered(currentAssessment, AnswerStatus.NOTAPPLICABLE);
		
		form.getLocalContext().setPatientAssessmentVo(currentAssessment);
		populateQuestionsGrid(filterQuestions(currentAssessment, DPP));
		form.lyrTabs().showtabCurrent();
		enableContextMenu();
	}

	/*private void updatePatientAssessmentWithTheChanges(PatientAssessmentVo currentAssessment)
	{
		if(currentAssessment == null)
			return;
		PatientAssessmentDataVo assessmentData = currentAssessment.getAssessmentData();
		if (assessmentData == null)
		{
			assessmentData = new PatientAssessmentDataVo();
			assessmentData.setUserAssessment(form.getGlobalContext().Nursing.getUserAssessmentDPP());
		}

		UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabCurrent().dynQuestions());
		PatientAssessmentGroupVoCollection currentAnswer = helper.getAnswers(assessmentData.getAnswerGroups());
		setPocFlag(currentAnswer, helper);
		//TODO - Check if we have to set the Authoring and Confirming
		//setAuthoringInformation(assessmentData.getAnswerGroups(), currentAnswer);
		//setConfirmingInformation(assessmentData.getAnswerGroups(), currentAnswer);
		PatientAssessmentGroupVoCollection notAvailableAnswColl = getNotApplicableAndNotAnswered(assessmentData.getAnswerGroups());
		removeNotAnswered(assessmentData.getAnswerGroups());
		assessmentData.setAnswerGroups(getAnswerGroups(currentAnswer, notAvailableAnswColl));
		currentAssessment.setAssessmentData(assessmentData);
	}*/

	private void removeNotAnswered(PatientAssessmentGroupVoCollection answerGroups)
	{
		boolean deleted = true;
		while (deleted)
		{
			deleted = false;
			for (int i = 0; answerGroups != null && i < answerGroups.size(); i++)
			{
				for (int j = 0; j < answerGroups.get(i).getAssessmentAnswers().size(); j++)
				{
					AnswerStatus answerStatus = answerGroups.get(i).getAssessmentAnswers().get(j).getIsAnswered();
					// Exclude the Answered ones
					if (answerStatus != null && answerStatus.equals(AnswerStatus.ANSWERED) == false)
					{
						deleted = true;
					}

					if(deleted)
					{
						answerGroups.get(i).getAssessmentAnswers().remove(j);
						break;
					}
				}
				if (deleted)
					break;
			}
		}
	}
	
	protected void onBtnCancelNAQuestionsClick() throws PresentationLogicException
	{
		form.lyrTabs().showtabCurrent();
	}

	protected void onBtnSelectNSQuestionsClick() throws PresentationLogicException
	{
		PatientAssessmentVo currentAssessment = form.getLocalContext().getPatientAssessmentVo();
		//Get the changes user eventualy made in the questions
		//updatePatientAssessmentWithTheChanges(currentAssessment);
		UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabStandardQuestion().dyngrdNonStandard());
		currentAssessment = helper.updateQuestionStatusToAnswered(currentAssessment, AnswerStatus.NOTANSWERED);
		
		form.getLocalContext().setPatientAssessmentVo(currentAssessment);
		currentAssessment = filterQuestions(currentAssessment, DPP);
		populateQuestionsGrid(currentAssessment);
		form.lyrTabs().showtabCurrent();
		enableContextMenu();
	}

	protected void onBtnCancelNSQuestionsClick() throws PresentationLogicException
	{
		form.lyrTabs().showtabCurrent();
	}

	protected void onCmbStatusValueChanged() throws PresentationLogicException
	{
		loadReasonCombo(form.lyrTabs().tabCurrent().cmbStatus().getValue());
		cmbStatusValueChanged();
		enableReasonControls();
	}

	private void cmbStatusValueChanged()
	{
		if(isEditMode())
		{
			//if Non Imcomplete
			if(form.lyrTabs().tabCurrent().cmbStatus().getValue() == null || form.lyrTabs().tabCurrent().cmbStatus().getValue().equals(PatientAssessmentStatusReason.INCOMPLETE) == false)
			{
				form.lyrTabs().tabCurrent().cmbStatusReason().setValue(null);
				form.lyrTabs().tabCurrent().txtStatusReasonText().setValue(null);
			}	
		}
	}

	private void enableReasonControls()
	{
		PatientAssessmentStatusReason reason = form.lyrTabs().tabCurrent().cmbStatus().getValue();
		if(isEditMode() && reason != null && reason.equals(PatientAssessmentStatusReason.INCOMPLETE))
		{
			enableReasonControls(true);
		}
		else
		{
			enableReasonControls(false);
		}
	}
	
	private void enableReasonControls(boolean value)
	{
		form.lyrTabs().tabCurrent().cmbStatusReason().setEnabled(value);
		form.lyrTabs().tabCurrent().txtStatusReasonText().setEnabled(value);
	}

	protected void onDynQuestionsCellValueChanged(DynamicGridCell cell)
	{
		DPPErrors errorsEnum = getHelper(form.lyrTabs().tabCurrent().dynQuestions()).setDPPCellValueChanged(cell);
		if(errorsEnum != null)
		{
			engine.showErrors(new String[]{errorsEnum.getText()});
		}
	}

	protected void onContextMenuItemClick(int menuItemID, Control sender) throws PresentationLogicException
	{
		switch (menuItemID)
		{
			case GenForm.ContextMenus.DPPQuestions.ADD_NON_APPLICABLE_QUESTIONS :
				addNonApplicableQuestions();
			break;

			case GenForm.ContextMenus.DPPQuestions.ADD_NOT_ANSWERED_QUESTION :
				addNonStandardQuestion();
			break;

			default :
			break;
		}
	}
	
	protected void onCmbAssessmentValueChanged() throws PresentationLogicException
	{
		cmbAssessmentValueChanged();
		DPPType asssType = form.lyrTabs().tabCurrent().cmbAssessment().getValue();
		if(asssType == null || asssType.equals(DPPType.OTHER) == false)
			form.lyrTabs().tabCurrent().txtOther().setValue(null);
	}
	
	protected void onFormDialogClosed(FormName formName, DialogResult result) throws PresentationLogicException
	{
		if(formName.equals(form.getForms().Core.YesNoDialog))
		{
			if(result.equals(DialogResult.YES))
			{
				doSave();
			}
			else
			{
				//reset the flag
				form.getLocalContext().setYesNoDisplayed(null);
			}
		}
	}
	
	//------------------- End Handlers ---------------------

	//------------------- Private Methods ------------------
	private void open() throws PresentationLogicException
	{
		PatientAssessmentVo voPatientAssessmentInitial = form.getGlobalContext().Nursing.getPatientAssessmentVo();

		//Why the context is cloning???? - avoid that
		PatientAssessmentVo voPatientAssessment = voPatientAssessmentInitial != null?(PatientAssessmentVo)voPatientAssessmentInitial.clone():null;
		form.getLocalContext().setPatientAssessmentVo(voPatientAssessment);

		boolean isNewRecord = false;
		if(voPatientAssessment == null)
		{
			isNewRecord = true;
			voPatientAssessment = getNewPatientAssessment(voPatientAssessment);
			setPOCData(form.getGlobalContext().Nursing.getPlanOfCareCollection(), voPatientAssessment);
			form.getLocalContext().setPatientAssessmentVo(voPatientAssessment);
		}
		else if(voPatientAssessment.getID_PatientAssessment() == null)
		{
			//Copied assessment
			setPOCData(form.getGlobalContext().Nursing.getPlanOfCareCollection(), voPatientAssessment);
			form.getLocalContext().setPatientAssessmentVo(voPatientAssessment);
		}
		
		populateControlsFromData(voPatientAssessment);
		boolean isNewAssessment = voPatientAssessment.getID_PatientAssessment() == null;
		if(isNewRecord || (isNewAssessment && voPatientAssessment.getAuthoringInformation() == null))
			form.lyrTabs().tabCurrent().customControlAuthoring().initializeComponent();
		
		if(isNewAssessment)
		{
			prepopulateAssessmentTypeForNewRecord();
			cmbAssessmentValueChanged();
			prepopulateStatusComboForNewAssessment();
			cmbStatusValueChanged();
			enableReasonControls();
		}
		else
		{
			cmbAssessmentValueChanged();
			cmbStatusValueChanged();
		}
		
		enableControls();
		if(isSavedRecordCompleted())
		{
			form.setMode(FormMode.VIEW);
		}
	}

	private boolean isSavedRecordCompleted()
	{
		return form.getGlobalContext().Nursing.getIsDppCompletedIsNotNull() && form.getGlobalContext().Nursing.getIsDppCompleted().booleanValue();
	}

	private void prepopulateAssessmentTypeForNewRecord()
	{
		ContextType contextType = getContextType();

		if (isNewRecord() && isFirstRecord())
		{
			if (contextType != null)
			{
				DPPType value = null;
				if (contextType.equals(ContextType.INPATIENT))
					value = DPPType.ADMISSION;
				else if (contextType.equals(ContextType.OUTPATIENT))
					value = DPPType.PREADMISSION;

				if (value != null)
				{
					addAssessmentToCombo(value);
					form.lyrTabs().tabCurrent().cmbAssessment().setValue(value);
				}
			}
		}
	}

	private ContextType getContextType()
	{
		CareContextShortVo careContext = form.getGlobalContext().Core.getCurrentCareContext();
		return careContext != null?careContext.getContext():null;
	}
	
	private void prepopulateStatusComboForNewAssessment()
	{
		form.lyrTabs().tabCurrent().cmbStatus().newRow(PatientAssessmentStatusReason.NOTCOMMENCED, PatientAssessmentStatusReason.NOTCOMMENCED.toString());
		form.lyrTabs().tabCurrent().cmbStatus().setValue(PatientAssessmentStatusReason.NOTCOMMENCED);
	}

	private PatientAssessmentVo getNewPatientAssessment(PatientAssessmentVo voPatientAssessment) throws PresentationLogicException
	{
		UserAssessmentVo voUserAssessment = form.getGlobalContext().Nursing.getUserAssessmentDPP();
		if (voUserAssessment != null)
		{
			voPatientAssessment = new PatientAssessmentVo();
			UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabCurrent().dynQuestions());
			helper.populate(voUserAssessment);
			
			PatientAssessmentDataVo assessmentData = new PatientAssessmentDataVo();
			assessmentData.setUserAssessment(voUserAssessment);
			PatientAssessmentGroupVoCollection voColl = helper.getAnswers(assessmentData.getAnswerGroups());
			voColl = setAsNotAnswerdNonStandardQuestions(voUserAssessment, voColl);
			assessmentData.setAnswerGroups(voColl);
			
			voPatientAssessment.setAssessmentData(assessmentData);
			form.getLocalContext().setPatientAssessmentVo(voPatientAssessment);
		}
		else
		{
			throw new CodingRuntimeException("Cannot Instantiate data with null Daily Patient Record.");
		}
		return voPatientAssessment;
	}

	private boolean save()
	{
		if(hasUIErrors())
			return false;
		
		if(isNonApplicableForCompletedDPP())
			return false;

		return populateCurrentQuestionsData(true);
	}

	private boolean isNonApplicableForCompletedDPP()
	{
		if(wasDialogDisplayed() == false)
		{
			PatientAssessmentStatusReason status = form.lyrTabs().tabCurrent().cmbStatus().getValue();
			if(status != null && status.equals(PatientAssessmentStatusReason.COMPLETED))
			{
				String nonAppQuestions = getNotApplicableQuestions();
				if(nonAppQuestions != null)
				{
					form.getGlobalContext().Core.setYesNoDialogMessage(nonAppQuestions);
					form.getLocalContext().setYesNoDisplayed(Boolean.TRUE);
					engine.open(form.getForms().Core.YesNoDialog);
					return true;
				}
			}
		}
		
		return false;
	}

	private boolean hasUIErrors()
	{
		ArrayList errors = new ArrayList();
		AuthoringInformationVo authoringInfo = form.lyrTabs().tabCurrent().customControlAuthoring().getValue();
		if (authoringInfo == null)
		{
			errors.add("Authoring Information is mandatory");
		}
		else
		{
			if (authoringInfo.getAuthoringDateTime() == null)
				errors.add("Authoring Date/Time is mandatory");
			if (authoringInfo.getAuthoringHcp() == null)
				errors.add("Authoring HCP is mandatory");
		}

		if (form.lyrTabs().tabCurrent().cmbAssessment().getValue() == null)
		{
			ContextType contextType = getContextType();
			boolean isInpatientOrOutpatient = contextType != null && (contextType.equals(ContextType.INPATIENT) || contextType.equals(ContextType.OUTPATIENT));
			if(isInpatientOrOutpatient)
				errors.add("Assessment is mandatory");
		}

		if (form.lyrTabs().tabCurrent().cmbStatus().getValue() == null)
			errors.add("Status is mandatory");

		if (errors.size() > 0)
		{
			String[] uiErrors = new String[errors.size()];
			errors.toArray(uiErrors);
			engine.showErrors(uiErrors);
			return true;
		}
		
		return false;
	}

	private boolean populateCurrentQuestionsData(boolean createPOCRecords)
	{
		PatientAssessmentVo currentAssessment = form.getLocalContext().getPatientAssessmentVo();
		currentAssessment = populateTopControlsFromScreen(currentAssessment);
		boolean valid = populateAssessmentDataFromScreen(currentAssessment, createPOCRecords);
		form.getLocalContext().setPatientAssessmentVo(currentAssessment);
		return valid;
	}

	private PatientAssessmentVo populateTopControlsFromScreen(PatientAssessmentVo vo)
	{
		vo = super.populateDataFromScreen(vo);
		
		//WDEV-11721 - starts here
		vo.setPatient(form.getGlobalContext().Core.getPatientShort());
		vo.setEpisodeOfCare(form.getGlobalContext().Core.getEpisodeofCareShort());
		//WDEV-11721 - ends here
		
		vo.setCareContext(form.getGlobalContext().Core.getCurrentCareContext());
		vo.setClinicalContact(form.getGlobalContext().Core.getCurrentClinicalContact());
		vo.setAuthoringInformation(form.lyrTabs().tabCurrent().customControlAuthoring().getValue());
		vo.setStatus(form.lyrTabs().tabCurrent().cmbStatus().getValue());
		vo.setStatusReason(form.lyrTabs().tabCurrent().cmbStatusReason().getValue());
		vo.setStatusReasonText(form.lyrTabs().tabCurrent().txtStatusReasonText().getValue());

		return vo;
	}

	private boolean populateAssessmentDataFromScreen(PatientAssessmentVo vo, boolean createPOCRecords)
	{
		if(vo == null)
			return false;
		
		PatientAssessmentVo initialAssessment = vo != null ? (PatientAssessmentVo) vo.clone() : null;
		if (vo.getAssessmentData() == null)
		{
			PatientAssessmentDataVo assessmentData = new PatientAssessmentDataVo();
			assessmentData.setUserAssessment(form.getGlobalContext().Nursing.getUserAssessmentDPP());
			vo.setAssessmentData(assessmentData);
		}
  
		UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabCurrent().dynQuestions());
		PatientAssessmentGroupVoCollection currentAnswer = helper.getAnswers(vo.getAssessmentData().getAnswerGroups());

		/*DynamicAssessmentHelper.populateHCPDataForAnswers(initialAssessment, vo, (HcpLiteVo)domain.getHcpLiteUser(), new DateTime());
		DynamicAssessmentHelper.populateConfirmingHCPDataForAnswers(initialAssessment, vo, (HcpLiteVo)domain.getHcpLiteUser(), new DateTime());*/
		
		/*PatientAssessmentGroupVoCollection notAvailableAnswColl = getNotApplicableAndNotAnswered(vo.getAssessmentData().getAnswerGroups());
		removeNotAnswered(vo.getAssessmentData().getAnswerGroups());
		vo.getAssessmentData().setAnswerGroups(getAnswerGroups(currentAnswer, notAvailableAnswColl));*/
		
		DynamicAssessmentHelper.populateHCPDataForAnswers(initialAssessment, vo, (HcpLiteVo)domain.getHcpLiteUser(), new DateTime());
		DynamicAssessmentHelper.populateConfirmingHCPDataForAnswers(initialAssessment, vo, (HcpLiteVo)domain.getHcpLiteUser(), new DateTime());
		
		if (createPOCRecords)
		{
			return populatePlanOfCareVoCollection(currentAnswer, helper);
		}

		return true;
	}

	/*//Set the Authoring Info for an answered record and when the answered changed
	private void setAuthoringInformation(PatientAssessmentGroupVoCollection previousAnswer, PatientAssessmentGroupVoCollection currentAnswer)
	{
		for (int i = 0; currentAnswer != null && i < currentAnswer.size(); i++)
		{
			for (int j = 0; j < currentAnswer.get(i).getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo voAssQuestion = currentAnswer.get(i).getAssessmentAnswers().get(j);
				boolean isAnswered = voAssQuestion.getIsAnsweredIsNotNull() && voAssQuestion.getIsAnswered().equals(AnswerStatus.ANSWERED);
				if (isAnswered)
				{
					boolean answerChanged = answerChanged(previousAnswer, voAssQuestion);
					AuthoringInformationVo previousAuthoringInfo = getPreviousAuthoringInformation(previousAnswer, voAssQuestion);

					for (int k = 0; k < voAssQuestion.getPatientAnswers().size(); k++)
					{
						PatientAssessmentAnswerVo voAssAnswer = voAssQuestion.getPatientAnswers().get(k);
						if (previousAuthoringInfo != null)
						{
							if (answerChanged)
								voAssAnswer.setAuthoringInfo(getLoggedInUserAuthoringInformation());
							else
								voAssAnswer.setAuthoringInfo(previousAuthoringInfo);
						}
						else
						{
							voAssAnswer.setAuthoringInfo(getLoggedInUserAuthoringInformation());
						}
					}
				}
			}
		}
	}
	//Set the Confirming Info when the Confirm checkbox is checked or when the Answer changed 
	private boolean answerChanged(PatientAssessmentGroupVoCollection previousAnswer, PatientAssessmentQuestionVo currentAssessmentQuestion)
	{
		if (currentAssessmentQuestion != null && currentAssessmentQuestion.getAssessmentQuestionIsNotNull() && currentAssessmentQuestion.getAssessmentQuestion().getQuestionIsNotNull())
		{
			QuestionInformationVo question = currentAssessmentQuestion.getAssessmentQuestion().getQuestion();
			for (int i = 0; previousAnswer != null && i < previousAnswer.size(); i++)
			{
				for (int j = 0; j < previousAnswer.get(i).getAssessmentAnswers().size(); j++)
				{
					PatientAssessmentQuestionVo voPrevAssessQuestion = previousAnswer.get(i).getAssessmentAnswers().get(j);
					if (voPrevAssessQuestion.getAssessmentQuestionIsNotNull() && voPrevAssessQuestion.getAssessmentQuestion().getQuestionIsNotNull())
					{
						if (voPrevAssessQuestion.getAssessmentQuestion().getQuestion().equals(question))
						{
							AnswerDetailsVo prevAnswer = getAnswer(voPrevAssessQuestion);
							AnswerDetailsVo currentAnswer = getAnswer(currentAssessmentQuestion);
							// Check to see it they have the same answers
							if (sameAnswer(prevAnswer, currentAnswer) == false)
								return true;
						}
					}
				}
			}
		}

		return false;
	}
	
	private AuthoringInformationVo getPreviousConfirmingInformation(PatientAssessmentGroupVoCollection previousAnswers, PatientAssessmentQuestionVo voAssQuestion)
	{
		return getPreviousAuthoringInformation(previousAnswers, voAssQuestion, true);
	}
	
	private AuthoringInformationVo getPreviousAuthoringInformation(PatientAssessmentGroupVoCollection previousAnswer, PatientAssessmentQuestionVo voAssQuestion)
	{
		return getPreviousAuthoringInformation(previousAnswer, voAssQuestion, false);
	}
	private AuthoringInformationVo getPreviousAuthoringInformation(PatientAssessmentGroupVoCollection previousAnswer, PatientAssessmentQuestionVo voAssQuestion, boolean returnConfirming)
	{
		if(voAssQuestion != null && voAssQuestion.getAssessmentQuestionIsNotNull() && voAssQuestion.getAssessmentQuestion().getQuestionIsNotNull())
		{
			QuestionInformationVo question = voAssQuestion.getAssessmentQuestion().getQuestion();
			
			for (int i = 0; previousAnswer != null && i < previousAnswer.size(); i++)
			{
				for (int j = 0; j < previousAnswer.get(i).getAssessmentAnswers().size(); j++)
				{
					PatientAssessmentQuestionVo voPrevAssessQuestion = previousAnswer.get(i).getAssessmentAnswers().get(j);
					if(voPrevAssessQuestion.getAssessmentQuestionIsNotNull() && voPrevAssessQuestion.getAssessmentQuestion().getQuestionIsNotNull())
					{
						if (voPrevAssessQuestion.getAssessmentQuestion().getQuestion().equals(question))
						{
							if(returnConfirming)
								return voPrevAssessQuestion.getPatientAnswers().size() > 0 ? voPrevAssessQuestion.getPatientAnswers().get(0).getConfirmingInfo() : null;
							else
								return voPrevAssessQuestion.getPatientAnswers().size() > 0 ? voPrevAssessQuestion.getPatientAnswers().get(0).getAuthoringInfo() : null;
						}
					}
				}
			}
		}

		return null;
	}

	private boolean sameAnswer(AnswerDetailsVo prevAnswer, AnswerDetailsVo currentAnswer)
	{
		if (prevAnswer == null || prevAnswer.getMultiSelectAnswers() == null || currentAnswer == null || currentAnswer.getMultiSelectAnswers() == null)
			return false;

		AnswerOptionVoCollection prevAnswersOptions = prevAnswer.getMultiSelectAnswers();
		AnswerOptionVoCollection currentAnswerOptions = currentAnswer.getMultiSelectAnswers();

		return haveTheSameAnswers(prevAnswersOptions, currentAnswerOptions);
	}

	//Check to see if the collections have the same items
	private boolean haveTheSameAnswers(AnswerOptionVoCollection prevAnswersOptions, AnswerOptionVoCollection currentAnswerOptions)
	{
		if(prevAnswersOptions.size() != currentAnswerOptions.size())
			return false;
		
		//Check against the currentAnswer collection
		for (int i = 0; i < currentAnswerOptions.size(); i++)
		{
			if (prevAnswersOptions.indexOf(currentAnswerOptions.get(i)) < 0)
				return false;
		}
		
		//Check against the prevAnswers collection
		for (int i = 0; i < prevAnswersOptions.size(); i++)
		{
			if (currentAnswerOptions.indexOf(prevAnswersOptions.get(i)) < 0)
				return false;
		}

		return true;
	}

	//Get the answer for the first (and should be only one Answer Detail against a Question - as assumed in the spec)
	private AnswerDetailsVo getAnswer(PatientAssessmentQuestionVo voAssessQuestion)
	{
		if(voAssessQuestion == null)
			return null;
		
		for (int i = 0; i < voAssessQuestion.getPatientAnswers().size(); i++)
		{
			for (int j = 0; j < voAssessQuestion.getPatientAnswers().get(i).getAnswerDetails().size(); j++)
			{
				return voAssessQuestion.getPatientAnswers().get(i).getAnswerDetails().get(0);
			}
		}
		
		return null;
	}

	private void setConfirmingInformation(PatientAssessmentGroupVoCollection previousAnswers, PatientAssessmentGroupVoCollection currentAnswer)
	{
		for (int i = 0; currentAnswer != null && i < currentAnswer.size(); i++)
		{
			for (int j = 0; j < currentAnswer.get(i).getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo voAssQuestion = currentAnswer.get(i).getAssessmentAnswers().get(j);
				boolean isAnswered = voAssQuestion.getIsAnsweredIsNotNull() && voAssQuestion.getIsAnswered().equals(AnswerStatus.ANSWERED);
				boolean isConfirmed = voAssQuestion.getIsConfirmedIsNotNull() && voAssQuestion.getIsConfirmed().booleanValue();
				if (isAnswered && isConfirmed)
				{
					boolean answerChanged = answerChanged(previousAnswers, voAssQuestion);
					AuthoringInformationVo previousConfirmingInfo = getPreviousConfirmingInformation(previousAnswers, voAssQuestion);

					for (int k = 0; k < voAssQuestion.getPatientAnswers().size(); k++)
					{
						PatientAssessmentAnswerVo voAssAnswer = voAssQuestion.getPatientAnswers().get(k);
						if (previousConfirmingInfo != null)
						{
							if(answerChanged)
								voAssAnswer.setConfirmingInfo(getLoggedInUserAuthoringInformation());
							else
								voAssAnswer.setConfirmingInfo(previousConfirmingInfo);
						}
						else
						{
							voAssAnswer.setConfirmingInfo(getLoggedInUserAuthoringInformation());
						}
					}
				}
			}
		}
	
	}*/

	private PatientAssessmentGroupVoCollection getAnswerGroups(PatientAssessmentGroupVoCollection currentAnswer, PatientAssessmentGroupVoCollection notAvailableAnswColl)
	{
		if(currentAnswer != null && currentAnswer.size() > 0)
		{
			for (int i = 0; notAvailableAnswColl != null && i < notAvailableAnswColl.size(); i++)
			{
				//Get the first group and add those questions.....
				PatientAssessmentGroupVo voPatAssGroup = notAvailableAnswColl.get(i);
				//Add all Patient Assessment Question to existing Answers
				for (int j = 0; j < voPatAssGroup.getAssessmentAnswers().size(); j++)
				{
					PatientAssessmentQuestionVo patientAssessmentQuestionVo = voPatAssGroup.getAssessmentAnswers().get(j);
					//Clear the id of the record or we will get a Flush Dirty error - TODO Please check if it can be done differently...
					if(patientAssessmentQuestionVo.getID_PatientAssessmentQuestionIsNotNull())
						patientAssessmentQuestionVo.setID_PatientAssessmentQuestion(null);
					for (int k = 0; patientAssessmentQuestionVo.getPatientAnswersIsNotNull() && k < patientAssessmentQuestionVo.getPatientAnswers().size(); k++)
					{
						patientAssessmentQuestionVo.getPatientAnswers().get(k).setID_PatientAssessmentAnswer(null);
						if(patientAssessmentQuestionVo.getPatientAnswers().get(k).getAnswerDetailsIsNotNull())
						{
							for (int index = 0; index < patientAssessmentQuestionVo.getPatientAnswers().get(k).getAnswerDetails().size(); index++)
							{
								patientAssessmentQuestionVo.getPatientAnswers().get(k).getAnswerDetails().get(index).setID_PatientAnswerDetails(null);	
							}
						}
					}
					//End clear Id
						
					currentAnswer.get(0).getAssessmentAnswers().add(patientAssessmentQuestionVo);						
				}
			}
		}
		else
		{
			return notAvailableAnswColl;	
		}

		return currentAnswer;
	}

	private PatientAssessmentGroupVoCollection getNotApplicableAndNotAnswered(PatientAssessmentGroupVoCollection answerGroupsInitial)
	{
		if(answerGroupsInitial == null)
			return null;
		
		PatientAssessmentGroupVoCollection answerGroups = (PatientAssessmentGroupVoCollection)answerGroupsInitial.clone();
		boolean deleted = true;
		while (deleted)
		{
			deleted = false;
			for (int i = 0; answerGroups != null && i < answerGroups.size(); i++)
			{
				for (int j = 0; j < answerGroups.get(i).getAssessmentAnswers().size(); j++)
				{
					AnswerStatus answerStatus = answerGroups.get(i).getAssessmentAnswers().get(j).getIsAnswered();
					// Exclude the Answered ones
					if (answerStatus == null || answerStatus.equals(AnswerStatus.ANSWERED))
						deleted = true;

/*					//Check Non Standard
					if(answerStatus != null && isNonStandard(answerGroups.get(i).getAssessmentAnswers().get(j)))
						deleted = true;*/
					
					if(deleted)
					{
						answerGroups.get(i).getAssessmentAnswers().remove(j);
						break;
					}
				}
				if (deleted)
					break;
			}
		}

		//remove the empty groups - as we will get validation errors when saving
		deleted = true;
		while(deleted)
		{
			deleted = false;
			for (int i = 0; i < answerGroups.size(); i++)
			{
				if(answerGroups.get(i).getAssessmentAnswers() == null || answerGroups.get(i).getAssessmentAnswers().size() == 0)
				{
					answerGroups.remove(i);
					deleted = true;
					break;
				}	
			}
		}

		return answerGroups;
	}

	private UserAssessmentInstHelper getHelper(DynamicGrid dynGrid)
	{
		return getHelper(dynGrid, false);
	}
	private UserAssessmentInstHelper getHelper(DynamicGrid dynGrid, boolean showSelect)
	{
		boolean isDpp = true;
		boolean displayOnlyAsnwered = false;
		boolean showConfirmation = engine.hasRight(AppRight.CAN_CONFIRM_NURSING_DOCUMENTATION);
		UserAssessmentInstHelper helper = new UserAssessmentInstHelper(dynGrid, form.getImages().Core.QuestionSmall, form.getImages().Core.TextBox, form.getImages().Core.SmallNew, form.getImages().Core.SmallCancel, form.getImages().Core.MandatoryQuestion, isDpp, displayOnlyAsnwered, showConfirmation, showSelect);
		return helper;
	}

	private void initialize()
	{
		prepopulateStatusCombo();
		prePopulateAssessmentTypeCombo();
		form.lyrTabs().tabCurrent().customControlAuthoring().setIsRequiredPropertyToControls(Boolean.TRUE);
		form.lyrTabs().tabCurrent().setHeaderEnabled(true);
		//wdev-10720
		ContextType contextType = getContextType();
		if(contextType != null && (contextType.equals(ContextType.INPATIENT) || contextType.equals(ContextType.OUTPATIENT)))
				form.lyrTabs().tabCurrent().cmbAssessment().setRequired(true);
			
		
		//----------
	}

	private void loadReasonCombo(PatientAssessmentStatusReason parent)
	{
		form.lyrTabs().tabCurrent().cmbStatusReason().clear();
		if (parent == null)
			return;

		PatientAssessmentStatusReasonCollection lookupColl = LookupHelper.getPatientAssessmentStatusReason(domain.getLookupService());
		for (int i = 0; i < lookupColl.size(); i++)
		{
			PatientAssessmentStatusReason reasonLkp = lookupColl.get(i);
			if (reasonLkp.getParent() != null && reasonLkp.getParent().equals(parent))
			{
				form.lyrTabs().tabCurrent().cmbStatusReason().newRow(reasonLkp, reasonLkp.toString());
			}
		}
	}

	private void populateControlsFromData(PatientAssessmentVo voPatientAssessment) throws PresentationLogicException
	{
		if (voPatientAssessment != null)
			loadReasonCombo(voPatientAssessment.getStatus());
		super.populateScreenFromData(voPatientAssessment);
		
		form.lyrTabs().tabCurrent().customControlAuthoring().setValue(voPatientAssessment != null ? voPatientAssessment.getAuthoringInformation() : null);
		populateQuestionsGrid(filterQuestions(voPatientAssessment, DPP));
		enableContextMenu();
	}

	private void populateQuestionsGrid(PatientAssessmentVo voPatientAssessment) throws PresentationLogicException
	{
		if (voPatientAssessment != null)
		{
			UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabCurrent().dynQuestions());
			setReadOnlyFlagRoles(voPatientAssessment.getAssessmentData().getAnswerGroups());
			setIsConfirmedFlag(voPatientAssessment.getAssessmentData().getAnswerGroups());
			helper.populate(voPatientAssessment.getAssessmentData(), voPatientAssessment.getStatusReason());
		}
	}

	//Set "IsAnswered" flag to NOTAPPLICABLE for those configured as such
	private PatientAssessmentGroupVoCollection setAsNotAnswerdNonStandardQuestions(UserAssessmentVo voUserAssessment, PatientAssessmentGroupVoCollection voPatAssGroupVoColl)
	{
		if(voUserAssessment == null || voPatAssGroupVoColl == null)
			return voPatAssGroupVoColl;
		
		for (int i = 0; voPatAssGroupVoColl != null && i < voPatAssGroupVoColl.size(); i++)
		{
			for (int j = 0; j < voPatAssGroupVoColl.get(i).getAssessmentAnswers().size(); j++)
			{
				AssessmentQuestionVo voAssQuestion = voPatAssGroupVoColl.get(i).getAssessmentAnswers().get(j).getAssessmentQuestion();
				if(voAssQuestion.getIsNonStandardIsNotNull() && voAssQuestion.getIsNonStandard().booleanValue())
				{
					voPatAssGroupVoColl.get(i).getAssessmentAnswers().get(j).setIsAnswered(AnswerStatus.NOTANSWERED);
				}
				
			}
		}
		
		return voPatAssGroupVoColl;
	}

	private PlanOfCareVo getPlanOfCareVo(PlanOfCareVo voPlanOfCare, AssessmentQuestionVo voAssessmentQuestion, PatientAssessmentQuestionVo voAnswer)
	{
		if (voAssessmentQuestion == null)
		{
			showError("Please select an Assessment Question");
			return null;
		}
		String questionText = UserAssessmentInstHelper.getDPPQuestionAndAnswers(voAnswer);
		if (voAnswer == null)
		{
			showError("Please select an answer for " + questionText + " question.");
			return null;
		}
		Color levelOfIntervention = getLevelOfIntervention(voAnswer);

		AuthoringInformationVo authoringInfo = getLoggedInUserAuthoringInformation();
		if (authoringInfo != null)
		{
			if (authoringInfo.getAuthoringHcp() == null)
			{
				showError("Please select Authoring HCP");
				return null;
			}

			if (authoringInfo.getAuthoringDateTime() == null)
			{
				showError("Please select Authoring Date/Time");
				return null;
			}
		}

		boolean addPOCToHistory = false;

		if (voPlanOfCare == null)
			voPlanOfCare = new PlanOfCareVo();
		//Populate the fields when creating the vo
		if (voPlanOfCare.getID_PlanOfCare() == null)
		{
			voPlanOfCare.setClinicalContact(form.getGlobalContext().Core.getCurrentClinicalContact());
			voPlanOfCare.setCareContext(form.getGlobalContext().Core.getCurrentCareContext());
			voPlanOfCare.setAuthoringInformation(authoringInfo);
			voPlanOfCare.setStartDateTime(authoringInfo.getAuthoringDateTime());
			voPlanOfCare.setStartHCP((HcpLiteVo) domain.getHcpLiteUser());
			PlanOfCareStatus status = engine.hasRight(AppRight.CAN_CONFIRM_NURSING_DOCUMENTATION)?PlanOfCareStatus.ACTIVE:PlanOfCareStatus.REQUIRES_CONFIRMATION;
			voPlanOfCare.setStatus(status);
			voPlanOfCare.setAssessmentQuestion(voAssessmentQuestion);
			voPlanOfCare.setGroup(getGroup(voAssessmentQuestion));
		}

		//Agreed with analyst - Neill - to add a new Item to History (addPOCToHistory = true) when either the title (which means the answers) or the levelofIntervention changed 
		if (voPlanOfCare.getTitle() == null || voPlanOfCare.getTitle().equals(questionText) == false)
			addPOCToHistory = true;
		voPlanOfCare.setTitle(questionText);

		if (voPlanOfCare.getLevelOfIntervention() == null || voPlanOfCare.getLevelOfIntervention().equals(levelOfIntervention) == false)
			addPOCToHistory = true;
		voPlanOfCare.setLevelOfIntervention(levelOfIntervention);

		//History
		PlanOfCareHistoryVoCollection voHistoryColl = voPlanOfCare.getAnswerHistory();
		if (voHistoryColl == null)
			voHistoryColl = new PlanOfCareHistoryVoCollection();

		//Remove the unsaved history records (it's like clearing the cache between different sessions of opening the dialog)
		boolean removed = true;
		while (removed)
		{
			removed = false;
			for (int i = 0; i < voHistoryColl.size(); i++)
			{
				if (voHistoryColl.get(i).getID_PlanOfCareHistory() == null)
				{
					voHistoryColl.remove(i);
					removed = true;
					break;
				}
			}
		}

		//Add the new Answer to the collection - when we have a new PlanOfCareVo or when data(answers) changed
		if (voPlanOfCare.getID_PlanOfCare() == null || addPOCToHistory)
		{
			AuthoringInformationVo authoringHistory = new AuthoringInformationVo();
			authoringHistory.setAuthoringHcp((HcpLiteVo) domain.getHcpLiteUser());
			authoringHistory.setAuthoringDateTime(new DateTime());

			PlanOfCareHistoryVo voPlanOfCareHistory = new PlanOfCareHistoryVo();
			voPlanOfCareHistory.setAuthoringInformation(authoringHistory);
			voPlanOfCareHistory.setLevelOfIntervention(levelOfIntervention);
			voPlanOfCareHistory.setAnswerText(getAnswerText(voAnswer));
			voHistoryColl.add(voPlanOfCareHistory);
			voPlanOfCare.setAnswerHistory(voHistoryColl);
		}

		return voPlanOfCare;
	}

	private PlanOfCareGroupings getGroup(AssessmentQuestionVo voAssessmentQuestion)
	{
		if (voAssessmentQuestion == null)
			return null;

		UserAssessmentVo voUserAssessment = getCurrentUserAssessment();
		
		DPPQuestionGroupShortVoCollection voColl = form.getLocalContext().getDppQuestionGroup();
		if (voColl == null)
			voColl = domain.listDPPGroupings(voUserAssessment, Boolean.TRUE);
		for (int i = 0; i < voColl.size(); i++)
		{
			DPPQuestionGroupShortVo voDppQGroup = voColl.get(i);
			if (voDppQGroup.getAssessmentQuestionsIsNotNull() && voDppQGroup.getAssessmentQuestions().indexOf(voAssessmentQuestion) >= 0)
				return voDppQGroup.getGroup();
		}

		return null;
	}

	private UserAssessmentVo getCurrentUserAssessment()
	{
		PatientAssessmentVo currentAssessment = form.getLocalContext().getPatientAssessmentVo();
		return currentAssessment != null && currentAssessment.getAssessmentDataIsNotNull()?currentAssessment.getAssessmentData().getUserAssessment():null;
	}

	private String getAnswerText(PatientAssessmentQuestionVo voAnswer)
	{
		if(voAnswer != null)
		{
			return UserAssessmentInstHelper.getDPPQuestionAndAnswers(voAnswer);
		}
		
		return "";
	}

	private Color getLevelOfIntervention(PatientAssessmentQuestionVo voAnswer)
	{
		ScoreAndImage scoreAndImage = getDPPHelper().getScoreImage(voAnswer);
		if (scoreAndImage != null)
			return scoreAndImage.getColor();

		return null;
	}

	private DailyPatientProgressHelper getDPPHelper()
	{
		return new DailyPatientProgressHelper(form.getImages().Core.RedSqaure, form.getImages().Core.YellowSquare, form.getImages().Core.GreenSquare);
	}

	private void showError(String string)
	{
		if (string != null)
			engine.showErrors(new String[]{string});
	}

	private boolean populatePlanOfCareVoCollection(PatientAssessmentGroupVoCollection currentAnswer, UserAssessmentInstHelper helper)
	{
		PlanOfCareVoCollection voColl = form.getGlobalContext().Nursing.getPlanOfCareCollection();

		// Add the records checked
		for (int i = 0; i < currentAnswer.size(); i++)
		{
			PatientAssessmentGroupVo voPatAssessGroup = currentAnswer.get(i);
			for (int j = 0; j < voPatAssessGroup.getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo voPatAssessmQuestion = voPatAssessGroup.getAssessmentAnswers().get(j);
				AssessmentQuestionVo voAssessmQuestion = voPatAssessmQuestion.getAssessmentQuestion();
				//Do not modify the POC if the questions has no Answers 
				if (isPocSelected(helper, voAssessmQuestion) && hasAnswers(voPatAssessmQuestion))
				{
					PlanOfCareVo voPlanOfCare = getPlanOfCareVo(getCurrentPlanOfCare(voAssessmQuestion), voAssessmQuestion, voPatAssessmQuestion);
					if (voPlanOfCare == null)
						return false;

					if (voColl == null)
						voColl = new PlanOfCareVoCollection();
					voColl.add(voPlanOfCare);
				}
			}
		}

		// Remove the unchecked ones which are not saved
		boolean removed = true;
		while (removed)
		{
			removed = false;
			for (int i = 0; voColl != null && i < voColl.size(); i++)
			{
				PlanOfCareVo voPlanOfCare = voColl.get(i);
				if (voPlanOfCare.getID_PlanOfCare() == null && voPlanOfCare.getAssessmentQuestionIsNotNull())
				{
					if (isPocSelected(helper, voPlanOfCare.getAssessmentQuestion()) == false)
					{
						voColl.remove(i);
						removed = true;
					}
				}
			}
		}

		form.getGlobalContext().Nursing.setPlanOfCareCollection(voColl);

		return true;
	}
	
	//Similar Logic to populatePlanOfCareVoCollection (previous method) but only sets the flag
	private void setPocFlag(PatientAssessmentGroupVoCollection currentAnswer, UserAssessmentInstHelper helper)
	{
		// Add the records checked
		for (int i = 0; i < currentAnswer.size(); i++)
		{
			PatientAssessmentGroupVo voPatAssessGroup = currentAnswer.get(i);
			for (int j = 0; j < voPatAssessGroup.getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo voPatAssessmQuestion = voPatAssessGroup.getAssessmentAnswers().get(j);
				AssessmentQuestionVo voAssessmQuestion = voPatAssessmQuestion.getAssessmentQuestion();
				//Do not modify the POC if the questions has no Answers 
				boolean isPocSelected = isPocSelected(helper, voAssessmQuestion) && hasAnswers(voPatAssessmQuestion);
				voPatAssessmQuestion.setIsPoc(new Boolean(isPocSelected));
			}
		}
	}


	//Check if the POC checkbox is selected
	private boolean isPocSelected(UserAssessmentInstHelper helper, AssessmentQuestionRefVo voAssessmQuestion)
	{
		if (helper == null || voAssessmQuestion == null)
			return false;

		return helper.isPocSelected(voAssessmQuestion);
	}

	private PlanOfCareVo getCurrentPlanOfCare(AssessmentQuestionVo voAssessmQuestion)
	{
		PlanOfCareVoCollection voPlanOfCareColl = form.getGlobalContext().Nursing.getPlanOfCareCollection();
		for (int i = 0; voPlanOfCareColl != null && i < voPlanOfCareColl.size(); i++)
		{
			if (voPlanOfCareColl.get(i).getAssessmentQuestionIsNotNull() && voPlanOfCareColl.get(i).getAssessmentQuestion().equals(voAssessmQuestion))
				return voPlanOfCareColl.get(i);
		}
		return null;
	}

	private void addNonApplicableQuestions() throws PresentationLogicException
	{
		form.lyrTabs().showtabNonApplicable();
		UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabNonApplicable().dynNonApplic(), true);
		PatientAssessmentVo voPatientAssessment = form.getLocalContext().getPatientAssessmentVo();
		voPatientAssessment = filterQuestions(voPatientAssessment, NOT_APPLICABLE);
		helper.populate(voPatientAssessment.getAssessmentData(), voPatientAssessment.getStatusReason(), AnswerStatus.NOTAPPLICABLE);
	}
	
	private PatientAssessmentVo filterQuestions(PatientAssessmentVo voPatientAssess, int questionType)
	{
		if(voPatientAssess == null)
			return null;
		
		PatientAssessmentVo voPatientAssessment = (PatientAssessmentVo)voPatientAssess.clone();
		if(voPatientAssessment != null && voPatientAssessment.getAssessmentDataIsNotNull())
		{
			boolean deleted = true;
			while(deleted)
			for (int i = 0; i < voPatientAssessment.getAssessmentData().getAnswerGroups().size(); i++)
			{
				deleted = false;
				//Leave only the questions that were not answered
				for (int j = 0; j < voPatientAssessment.getAssessmentData().getAnswerGroups().get(i).getAssessmentAnswers().size(); j++)
				{
					PatientAssessmentQuestionVo voPatAssQuestion = voPatientAssessment.getAssessmentData().getAnswerGroups().get(i).getAssessmentAnswers().get(j);
					
					if(questionType == NOT_APPLICABLE)
					{
						if(isNotApplicable(voPatAssQuestion) == false)
							deleted = true;
					}
					else if(questionType == NON_STANDARD)
					{
						if(isNonStandard(voPatAssQuestion) == false)
							deleted = true;
					}
					else if(questionType == DPP)
					{
						if(isNotApplicable(voPatAssQuestion) || isNonStandard(voPatAssQuestion))
							deleted = true;
					}
					
					if(deleted)
					{
						voPatientAssessment.getAssessmentData().getAnswerGroups().get(i).getAssessmentAnswers().remove(j);
						break;
					}
				}
				if(deleted)
					break;
			}
		}
		
		return voPatientAssessment;
	}
	

	private boolean isNonStandard(PatientAssessmentQuestionVo voPatAssQuestion)
	{
		if(voPatAssQuestion == null)
			return false;
		
		AnswerStatus answerStatus     = voPatAssQuestion.getIsAnswered();
		AssessmentQuestionVo question = voPatAssQuestion.getAssessmentQuestion();
		boolean isNotAnswered = answerStatus != null && answerStatus.equals(AnswerStatus.NOTANSWERED);
		boolean isNonStandard = question != null && question.getIsNonStandardIsNotNull() && question.getIsNonStandard().booleanValue();
			
		return isNotAnswered && isNonStandard;
	}
	
	private boolean isNotApplicable(PatientAssessmentQuestionVo voPatAssQuestion)
	{
		if(voPatAssQuestion == null)
			return false;
		AnswerStatus answerStatus     = voPatAssQuestion.getIsAnswered();
		return answerStatus != null && answerStatus.equals(AnswerStatus.NOTAPPLICABLE);	
	}

	private void addNonStandardQuestion() throws PresentationLogicException
	{
		form.lyrTabs().showtabStandardQuestion();
		UserAssessmentInstHelper helper = getHelper(form.lyrTabs().tabStandardQuestion().dyngrdNonStandard(), true);
		PatientAssessmentVo voPatientAssessment = form.getLocalContext().getPatientAssessmentVo();
		voPatientAssessment = filterQuestions(voPatientAssessment, NON_STANDARD);
		helper.populate(voPatientAssessment.getAssessmentData(), voPatientAssessment.getStatusReason(), AnswerStatus.NOTANSWERED);
	}

	private void enableContextMenu()
	{
		form.getContextMenus().getDPPQuestionsADD_NON_APPLICABLE_QUESTIONSItem().setVisible(isVisibleNAQuestion());
		form.getContextMenus().getDPPQuestionsADD_NOT_ANSWERED_QUESTIONItem().setVisible(isVisibleNotAsnweredQuestion());
	}

	//Find at least one NOTAPPLICABLE question
	private boolean isVisibleNAQuestion()
	{
		PatientAssessmentVo voPatientAssessment = form.getLocalContext().getPatientAssessmentVo();
		if (voPatientAssessment != null && voPatientAssessment.getAssessmentDataIsNotNull())
		{
			for (int i = 0; i < voPatientAssessment.getAssessmentData().getAnswerGroups().size(); i++)
			{
				PatientAssessmentGroupVo voPatAssGroup = voPatientAssessment.getAssessmentData().getAnswerGroups().get(i);
				for (int j = 0; j < voPatAssGroup.getAssessmentAnswers().size(); j++)
				{
					AnswerStatus answerStatus = voPatAssGroup.getAssessmentAnswers().get(j).getIsAnswered();
					if (answerStatus != null && answerStatus.equals(AnswerStatus.NOTAPPLICABLE))
						return true;
				}
			}
		}

		return false;
	}

	//Find at least one Non Standard Question 
	private boolean isVisibleNotAsnweredQuestion()
	{
		PatientAssessmentVo voPatientAssessment = form.getLocalContext().getPatientAssessmentVo();
		if (voPatientAssessment != null && voPatientAssessment.getAssessmentDataIsNotNull())
		{
			for (int i = 0; i < voPatientAssessment.getAssessmentData().getAnswerGroups().size(); i++)
			{
				PatientAssessmentGroupVo voPatAssGroup = voPatientAssessment.getAssessmentData().getAnswerGroups().get(i);
				for (int j = 0; j < voPatAssGroup.getAssessmentAnswers().size(); j++)
				{
					if(isNonStandard(voPatAssGroup.getAssessmentAnswers().get(j)))
						return true;
				}
			}
		}
		return true;
	}
	
	private Boolean isQuestionRoleReadOnly(AssessmentQuestionVo voAssessmentQuestion)
	{
		Integer roleId = getLoggedInRole();

		UserAssessmentVo voUserAssessment = getCurrentUserAssessment();

		// Check if there is at least one role in the User Assessment
		// If the Role has Answer All = true return false;
		if (roleId != null && voUserAssessment != null)
		{
			for (int i = 0; voUserAssessment != null && i < voUserAssessment.getAssessmentRoles().size(); i++)
			{
				AssessmentRoleVo role = voUserAssessment.getAssessmentRoles().get(i);
				if (userHasRoleAssociated(role.getAppRole(), roleId))
				{
					if (role.getAnswerAllIsNotNull() && role.getAnswerAll().booleanValue())
					{
						return Boolean.FALSE;
					}
				}
			}
		}

		// Find if the AssessmentQuestion has the Role associated with
		for (int j = 0; j < voAssessmentQuestion.getAssessmentAnswerRole().size(); j++)
		{
			if (userHasRoleAssociated(voAssessmentQuestion.getAssessmentAnswerRole().get(j).getAppRole(), roleId))
				return Boolean.FALSE;
		}

		return Boolean.TRUE;
	}
	
	private Integer getLoggedInRole()
	{
		IAppRole appRole = engine.getLoggedInRole();
		if(appRole != null)
			return new Integer(appRole.getId());
		
		return null;
	}

	private boolean userHasRoleAssociated(AppRoleShortVo voAppRole, Integer roleId)
	{
		if(voAppRole == null || roleId == null)
			return false;

		return roleId.equals(voAppRole.getID_AppRole());
	}
	

	private void setReadOnlyFlagRoles(PatientAssessmentGroupVoCollection answerGroups)
	{
		if(answerGroups == null)
			return;
		
		for (int i = 0; i < answerGroups.size(); i++)
		{
			for (int j = 0; j < answerGroups.get(i).getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo patAssQuestionVo = answerGroups.get(i).getAssessmentAnswers().get(j);
				patAssQuestionVo.setIsRoleReadOnly(isQuestionRoleReadOnly(patAssQuestionVo.getAssessmentQuestion()));
				answerGroups.get(i).getAssessmentAnswers().set(j, patAssQuestionVo);
			}
		}
	}
	
	private void setIsConfirmedFlag(PatientAssessmentGroupVoCollection answerGroups)
	{
		if (answerGroups == null)
			return;

		for (int i = 0; i < answerGroups.size(); i++)
		{
			for (int j = 0; j < answerGroups.get(i).getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo patAssQuestionVo = answerGroups.get(i).getAssessmentAnswers().get(j);
				if (isConfirmed(patAssQuestionVo))
					answerGroups.get(i).getAssessmentAnswers().get(j).setIsConfirmed(Boolean.TRUE);
			}
		}
	}
	private boolean isConfirmed(PatientAssessmentQuestionVo patAssQuestionVo)
	{
		boolean isConfirmed = false;
		for (int k = 0; k < patAssQuestionVo.getPatientAnswers().size(); k++)
		{
			if(patAssQuestionVo.getPatientAnswers().get(k).getConfirmingInfoIsNotNull())
			{
				return true;
			}
		}
		return isConfirmed;
	}
	
	private AuthoringInformationVo getLoggedInUserAuthoringInformation()
	{
		AuthoringInformationVo voAuthoringInfo = new AuthoringInformationVo();
		voAuthoringInfo.setAuthoringDateTime(new DateTime());
		voAuthoringInfo.setAuthoringHcp((HcpLiteVo)domain.getHcpLiteUser());
		return voAuthoringInfo;
	}
	
	private void enableControls()
	{
		form.lyrTabs().tabCurrent().setcustomControlAuthoringEnabled(isNewRecord());
		enableAssessmentCombo();
		enableStatusCombo();
		enableReasonControls();
	}

	private void enableAssessmentCombo()
	{
		DPPType value = getCurrentDppType();
		if (value != null && (value.equals(DPPType.ADMISSION) || value.equals(DPPType.PREADMISSION)))
		{
			form.lyrTabs().tabCurrent().cmbAssessment().setEnabled(false);
		}
		else
		{
			form.lyrTabs().tabCurrent().cmbAssessment().setEnabled(isEditMode());
		}
	}
	
	private void enableStatusCombo()
	{
		PatientAssessmentStatusReason assessmentStatusReason = form.lyrTabs().tabCurrent().cmbStatus().getValue();
		if(assessmentStatusReason != null)
		{
			if(assessmentStatusReason.equals(PatientAssessmentStatusReason.NOTCOMMENCED)) 
			{
				form.lyrTabs().tabCurrent().cmbStatus().setEnabled(false);
			}
			else
			{
				form.lyrTabs().tabCurrent().cmbStatus().setEnabled(isEditMode());					
			}
		}
	}
	private boolean isEditMode()
	{
		return form.getMode().equals(FormMode.EDIT);
	}

	boolean isNewRecord()
	{
		PatientAssessmentVo voPatientAssessment = form.getGlobalContext().Nursing.getPatientAssessmentVo();
		return voPatientAssessment == null || voPatientAssessment.getID_PatientAssessment() == null;
	}

	boolean isFirstRecord()
	{
		Boolean firstRecord = form.getGlobalContext().Nursing.getIsFirstDppInstantiation();
		return firstRecord != null && firstRecord.booleanValue();
	}

	private void prePopulateAssessmentTypeCombo()
	{
		form.lyrTabs().tabCurrent().cmbAssessment().clear();
	
		if (isNewRecord())
		{
			if(isFirstRecord() == false)
			{
				populateAssessmentCombo();
			}
		}
		else
		{
			DPPType currentDpp = getCurrentDppType();
			if (currentDpp != null)
			{
				if (currentDpp.equals(DPPType.ADMISSION))
					addAssessmentToCombo(DPPType.ADMISSION);
				else if (currentDpp.equals(DPPType.PREADMISSION))
					addAssessmentToCombo(DPPType.PREADMISSION);
				else
				{
					populateAssessmentCombo();
				}
			}
		}
	}

	private DPPType getCurrentDppType()
	{
		PatientAssessmentVo voPatientAssessment = form.getGlobalContext().Nursing.getPatientAssessmentVo();
		return voPatientAssessment != null ? voPatientAssessment.getDPPType() : null;
	}
	
	private void addAssessmentToCombo(DPPType value)
	{
		form.lyrTabs().tabCurrent().cmbAssessment().newRow(value, value.toString());
	}
	
	private void populateAssessmentCombo()
	{
		DPPTypeCollection excludeColl = new DPPTypeCollection();
		excludeColl.add(DPPType.PREADMISSION);
		if(admissionAssessmentAdded())
			excludeColl.add(DPPType.ADMISSION);
				
		DPPTypeCollection coll = ims.assessment.vo.lookups.LookupHelper.getDPPType(domain.getLookupService());
		for (int i = 0; i < coll.size(); i++)
		{
			if(coll.get(i) != null && excludeColl.indexOf(coll.get(i)) >= 0)
				continue;
			
			addAssessmentToCombo(coll.get(i));
		}
	}

	private void cmbAssessmentValueChanged()
	{
		if(isEditMode())
		{
			DPPType asssType = form.lyrTabs().tabCurrent().cmbAssessment().getValue();
			boolean otherSelected = asssType != null && asssType.equals(DPPType.OTHER);
			form.lyrTabs().tabCurrent().txtOther().setEnabled(otherSelected);
		}
	}
	
	private void prepopulateStatusCombo()
	{
		form.lyrTabs().tabCurrent().cmbStatus().clear();
		if (isNewRecord() == false)
		{
			PatientAssessmentStatusReasonCollection lookupColl = LookupHelper.getPatientAssessmentStatusReason(domain.getLookupService());
			for (int i = 0; i < lookupColl.size(); i++)
			{
				PatientAssessmentStatusReason reasonLkp = lookupColl.get(i);
				if (reasonLkp.getParent() == null)
				{
					if (isNewRecord() == false && reasonLkp.equals(PatientAssessmentStatusReason.NOTCOMMENCED))
						continue;
					
					form.lyrTabs().tabCurrent().cmbStatus().newRow(reasonLkp, reasonLkp.toString());
				}
			}
		}
	}
	
	private boolean admissionAssessmentAdded()
	{
		return form.getGlobalContext().Nursing.getIsDppAdmissionAssessmentAddedIsNotNull() && form.getGlobalContext().Nursing.getIsDppAdmissionAssessmentAdded().booleanValue();
	}
	private void setPOCData(PlanOfCareVoCollection pocVoColl, PatientAssessmentVo voPatAssessment)
	{
		if(voPatAssessment == null)
			return;
		PatientAssessmentDataVo assessmentData = voPatAssessment.getAssessmentData();
		if(assessmentData == null)
			return;
		for (int i = 0; i < assessmentData.getAnswerGroups().size(); i++)
		{
			for (int j = 0; j < assessmentData.getAnswerGroups().get(i).getAssessmentAnswers().size(); j++)
			{
				PatientAssessmentQuestionVo voPatAssQuestionVo = assessmentData.getAnswerGroups().get(i).getAssessmentAnswers().get(j);
				Boolean isPocSaved = getPocValue(voPatAssQuestionVo.getAssessmentQuestion(), pocVoColl);
				voPatAssQuestionVo.setIsPoc(isPocSaved);
				voPatAssQuestionVo.setIsPocSaved(isPocSaved);
				assessmentData.getAnswerGroups().get(i).getAssessmentAnswers().set(j, voPatAssQuestionVo);
			}
		}
	}
	
	private Boolean getPocValue(AssessmentQuestionVo assessmentQuestion, PlanOfCareVoCollection pocVoColl)
	{
		if(assessmentQuestion == null )
			return Boolean.FALSE;

		for (int i = 0; pocVoColl != null && i < pocVoColl.size(); i++)
		{
			if(pocVoColl.get(i).getAssessmentQuestionIsNotNull() && pocVoColl.get(i).getAssessmentQuestion().equals(assessmentQuestion))
				return Boolean.TRUE;
		}
		return Boolean.FALSE;
	}
	
	private boolean hasAnswers(PatientAssessmentQuestionVo voAssessQuestion)
	{
		if(voAssessQuestion == null)
			return false;
		
		for (int i = 0; i < voAssessQuestion.getPatientAnswers().size(); i++)
		{
			for (int j = 0; j < voAssessQuestion.getPatientAnswers().get(i).getAnswerDetails().size(); j++)
			{
				AnswerDetailsVo answerDetail = voAssessQuestion.getPatientAnswers().get(i).getAnswerDetails().get(j);
				if(isMultiSelectAnswer(answerDetail))
				{
					return answerDetail.getMultiSelectAnswers().size() > 0;
				}
			}
		}
		return false;
	}
	
	private boolean isMultiSelectAnswer(AnswerDetailsVo answerDetail)
	{
		ims.core.vo.lookups.QuestionAnswerType questionAnswerType = answerDetail.getAnswerTypeIsNotNull() ? answerDetail.getAnswerType().getAnswerType():null;
		return questionAnswerType != null && questionAnswerType.equals(ims.core.vo.lookups.QuestionAnswerType.MULTISELECT);
	}
	
	private boolean wasDialogDisplayed()
	{
		return form.getLocalContext().getYesNoDisplayedIsNotNull() && form.getLocalContext().getYesNoDisplayed().booleanValue();
	}
	
	private String getNotApplicableQuestions()
	{
		PatientAssessmentVo voPatientAssessment = filterQuestions(form.getLocalContext().getPatientAssessmentVo(), NOT_APPLICABLE);
		StringBuffer questions = new StringBuffer();
		if (voPatientAssessment != null && voPatientAssessment.getAssessmentDataIsNotNull() && voPatientAssessment.getAssessmentData().getAnswerGroupsIsNotNull())
		{
			for (int i = 0; i < voPatientAssessment.getAssessmentData().getAnswerGroups().size(); i++)
			{
				PatientAssessmentGroupVo group = voPatientAssessment.getAssessmentData().getAnswerGroups().get(i);
				for (int j = 0; j < group.getAssessmentAnswers().size(); j++)
				{
					PatientAssessmentQuestionVo voPatientAssessmentQuestion = group.getAssessmentAnswers().get(j);
					if (voPatientAssessmentQuestion != null && voPatientAssessmentQuestion.getAssessmentQuestionIsNotNull() && voPatientAssessmentQuestion.getAssessmentQuestion().getQuestionIsNotNull())
					{
						questions.append(voPatientAssessmentQuestion.getAssessmentQuestion().getQuestion().getText());
						questions.append("\n");
					}
				}
			}
		}

		if(questions.length() > 0)
		{
			questions.insert(0, "The following questions are marked as Non Applicable:\n");
			questions.append("Please confirm. \n");
			return questions.toString();
		}
		
		return null;
	}
	// ------------------- End Private Methods ---------------
}
