/FileExtraction/Java_unseen/IMS-MAXIMS_openMAXIMS/Source Library/openmaxims_workspace/RACPC/src/ims/racpc/forms/racpcplanadvice/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 Peter Martin using IMS Development Environment (version 1.70 build 3412.20509)
// Copyright (C) 1995-2009 IMS MAXIMS plc. All rights reserved.

package ims.racpc.forms.racpcplanadvice;

import java.util.ArrayList;

import ims.clinical.vo.RACPPlanAdviceVo;
import ims.domain.exceptions.StaleObjectException;
import ims.domain.exceptions.UniqueKeyViolationException;
import ims.framework.enumerations.FormMode;
import ims.framework.exceptions.PresentationLogicException;
import ims.racpc.forms.racpcplanadvice.GenForm.grdAdviceToGPRow;
import ims.racpc.forms.racpcplanadvice.GenForm.grdAdviceToPatientRow;
import ims.racpc.forms.racpcplanadvice.GenForm.grdPlanRow;
import ims.racpc.forms.racpcplanadvice.GenForm.grdPlanRowCollection;
import ims.core.vo.lookups.AdviceToGPCollection;
import ims.core.vo.lookups.AdviceToPatientCollection;
import ims.core.vo.lookups.LookupHelper;
import ims.core.vo.lookups.PlanOfAction;
import ims.core.vo.lookups.PlanOfActionCollection;

public class Logic extends BaseLogic
{
	private static final long serialVersionUID = 1L;

	@Override
	protected void onFormOpen(Object[] args) throws ims.framework.exceptions.PresentationLogicException
	{
		initialise();
		open();
	}
	private void initialise() {
		prePopulateSportsGrd();
	}
	private void prePopulateSportsGrd()
	{
		PlanOfActionCollection collPlanOfAction = LookupHelper.getPlanOfAction(domain.getLookupService());
		form.getLocalContext().setPlanOfActionCollection(collPlanOfAction);
		form.grdPlan().populateTree(collPlanOfAction);
		form.grdPlan().expandAll();
		
		loadAdviceToPatientGrid(false);
		loadAdviceToGPGrid(false);
	}
	private void loadAdviceToGPGrid(boolean bOnUpdate) {
		form.grdAdviceToGP().getRows().clear();
		
		AdviceToGPCollection adviceToGPCollection = LookupHelper.getAdviceToGP(domain.getLookupService());
		form.getLocalContext().setAdviceToGPCollection(adviceToGPCollection);
		
		for (int i = 0; i < adviceToGPCollection.size(); i++)
		{
			grdAdviceToGPRow row = form.grdAdviceToGP().getRows().newRow();
			row.setcolFinding(adviceToGPCollection.get(i));
		}		
		
		if(bOnUpdate && form.getLocalContext().getPlanAdviceVo().getAdviceGivenToGPIsNotNull()){
			AdviceToGPCollection currentAdviceToGPColl = form.getLocalContext().getPlanAdviceVo().getAdviceGivenToGP();
			for (int i = 0; i < form.grdAdviceToGP().getRows().size(); i++)
			{
				grdAdviceToGPRow row = form.grdAdviceToGP().getRows().get(i);
				for (int j = 0; j < currentAdviceToGPColl.size(); j++)
				{
					if(row.getcolFinding().equals(currentAdviceToGPColl.get(j)))
						row.setcolSelect(true);
				}
			}
		}
	}
	private void loadAdviceToPatientGrid(boolean bOnUpdate) {
		form.grdAdviceToPatient().getRows().clear();
		
		AdviceToPatientCollection adviceToPatientCollection = LookupHelper.getAdviceToPatient(domain.getLookupService());
		form.getLocalContext().setAdviceToPatientCollection(adviceToPatientCollection);	
		
		for (int i = 0; i < adviceToPatientCollection.size(); i++)
		{
			grdAdviceToPatientRow row = form.grdAdviceToPatient().getRows().newRow();
			row.setcolAdvice(adviceToPatientCollection.get(i));
		}		
		
		if(bOnUpdate && form.getLocalContext().getPlanAdviceVo().getAdviceGivenPatientIsNotNull()){
			AdviceToPatientCollection currentAdviceToPatientColl = form.getLocalContext().getPlanAdviceVo().getAdviceGivenPatient();
			for (int i = 0; i < form.grdAdviceToPatient().getRows().size(); i++)
			{
				grdAdviceToPatientRow row = form.grdAdviceToPatient().getRows().get(i);
				for (int j = 0; j < currentAdviceToPatientColl.size(); j++)
				{
					if(row.getcolAdvice().equals(currentAdviceToPatientColl.get(j)))
						row.setcolGiven(true);
				}
			}
		}
	}
	private void open() 
	{
		clearControls();
		
		if(form.getGlobalContext().Core.getCurrentCareContextIsNotNull())
		{
			RACPPlanAdviceVo voRACPPlanAdvice = domain.getPlanAdviceForClinicalContact(form.getGlobalContext().Core.getCurrentCareContext());
			if(voRACPPlanAdvice!=null)
			{
				populateScreen(voRACPPlanAdvice);
			}
		}
		
		form.setMode(FormMode.VIEW);//	WDEV-13437
	}
	
	private void populateScreen(RACPPlanAdviceVo planAdvice) {
		form.getLocalContext().setPlanAdviceVo(planAdvice);
		populatePlanGrid(planAdvice.getPrimaryPlan(), planAdvice.getSecondaryPlans());
		removeUnselectedPlans(null);
		form.cmbOverallImpression().setValue(planAdvice.getOverallImpression());
		form.txtOther().setValue(planAdvice.getOtherDetails());
		populateAdviceToPatientGrid(planAdvice.getAdviceGivenPatient());
		populateAdviceToGPGrid(planAdvice.getAdviceGivenToGP());
	}
	private void removeUnselectedPlans(grdPlanRowCollection collection) {
		if(collection==null)
			collection = form.grdPlan().getRows();
		for (int i = collection.size()-1; i >=0; i--) //WDEV-14061
		{
			GenForm.grdPlanRow rowParent = collection.get(i);
			if(rowParent.getRows()!=null && rowParent.getRows().size()>0)
				removeUnselectedPlans(rowParent.getRows());
			else{
				if(!rowParent.getcolPrimary() && !rowParent.getcolSecondary())
				{
					collection.remove(i);
				}
			}
		}
		
	}
	private void populateAdviceToGPGrid(AdviceToGPCollection adviceGivenToGP) {
		form.grdAdviceToGP().getRows().clear();
		for (int k = 0; k < adviceGivenToGP.size(); k++)
		{
			grdAdviceToGPRow row = form.grdAdviceToGP().getRows().newRow();
			row.setcolFinding(adviceGivenToGP.get(k));
			row.setcolSelect(true);
		}
	}
	private void populateAdviceToPatientGrid(AdviceToPatientCollection adviceGivenPatient) {
		form.grdAdviceToPatient().getRows().clear();
		for (int k = 0; k < adviceGivenPatient.size(); k++)
		{
			grdAdviceToPatientRow row = form.grdAdviceToPatient().getRows().newRow();
			row.setcolAdvice(adviceGivenPatient.get(k));
			row.setcolGiven(true);
		}		
	}
	private void populatePlanGrid(PlanOfAction primaryPlan, PlanOfActionCollection secondaryPlans) {
	
		form.grdPlan().getRows().clear();
		
		PlanOfActionCollection collPlanOfAction = form.getLocalContext().getPlanOfActionCollection();
		
		for (int i = 0; i < collPlanOfAction.size(); i++)
		{
			if(collPlanOfAction.get(i).getParent()==null && hasSelectedItem(collPlanOfAction.get(i), primaryPlan, secondaryPlans))
					putItemHierarchyOnGrid(collPlanOfAction.get(i), form.grdPlan().getRows().newRow());
		}
		
		setSelectedPlans();
		
		form.grdPlan().expandAll();
	}
	private void putItemHierarchyOnGrid(PlanOfAction action, grdPlanRow row) {
		row.setcolPlan(action);
		if(action.getChildInstances().size()>0)
			for (int i = 0; i < action.getChildInstances().size(); i++)
			{
				putItemHierarchyOnGrid((PlanOfAction)action.getChildInstances().get(i), row.getRows().newRow());
			}
	}
	private boolean hasSelectedItem(PlanOfAction action, PlanOfAction primaryPlan, PlanOfActionCollection secondaryPlans) {
		form.getLocalContext().setHasSelectedItem(false);
		searchHierarchyForPrimary( action, primaryPlan);
			
		if(!form.getLocalContext().getHasSelectedItem())
			for (int i = 0; i < secondaryPlans.size(); i++)
				searchHierarchyForSecondary( action, secondaryPlans.get(i));
		
		return form.getLocalContext().getHasSelectedItem();
	}
	private void searchHierarchyForSecondary(PlanOfAction action, PlanOfAction secondaryPlan) {
			if(action.getChildInstances().size()==0)
				if(action.equals(secondaryPlan))
					form.getLocalContext().setHasSelectedItem(true);
			for (int j = 0; j < action.getChildInstances().size(); j++)
			{
				searchHierarchyForSecondary( (PlanOfAction)action.getChildInstances().get(j), secondaryPlan);
				
			}
	}
	private void searchHierarchyForPrimary(PlanOfAction action, PlanOfAction primaryPlan) {
		if(action.getChildInstances().size()==0)
			if(action.equals(primaryPlan))
				form.getLocalContext().setHasSelectedItem(true);
		for (int j = 0; j < action.getChildInstances().size(); j++)
		{
			searchHierarchyForPrimary( (PlanOfAction)action.getChildInstances().get(j), primaryPlan);
			
		}
	}
	private void clearControls() 
	{
		form.cmbOverallImpression().setValue(null);
		form.txtOther().setValue(null);
		for (int i = 0; i < form.grdPlan().getRows().size(); i++)
		{
			grdPlanRow row = form.grdPlan().getRows().get(i);
			row.setcolPrimary(false);
			row.setcolSecondary(false);
			
			clearTreeHierarchy(row);
		}
		for (int i = 0; i < form.grdAdviceToGP().getRows().size(); i++)
		{
			grdAdviceToGPRow row = form.grdAdviceToGP().getRows().get(i);
			row.setcolSelect(false);
		}
		for (int i = 0; i < form.grdAdviceToPatient().getRows().size(); i++)
		{
			grdAdviceToPatientRow row = form.grdAdviceToPatient().getRows().get(i);
			row.setcolGiven(false);
		}
	}
	private void clearTreeHierarchy(grdPlanRow rowParent) {
		for (int j = 0; j < rowParent.getRows().size(); j++)
		{
			grdPlanRow rowChild = rowParent.getRows().get(j);
			rowChild.setcolPrimary(false);
			rowChild.setcolSecondary(false);
			
			clearTreeHierarchy(rowChild);
		}
	}
	@Override
	protected void onBtnNewClick() throws ims.framework.exceptions.PresentationLogicException
	{
		if(isRACPCComplete())//	WDEV-13662
			return;
		
		form.getLocalContext().setPlanAdviceVo(null);
		form.setMode(FormMode.EDIT);
		clearControls();
	}
	
	@Override
	protected void onBtnEditClick() throws ims.framework.exceptions.PresentationLogicException
	{
		if(isRACPCComplete())//	WDEV-13662
			return;
		
		form.setMode(FormMode.EDIT);
		form.grdPlan().populateTree(form.getLocalContext().getPlanOfActionCollection());
		form.grdPlan().expandAll();
		setSelectedPlans();
		
		loadAdviceToPatientGrid(true);
		loadAdviceToGPGrid(true);
	}
	private void setSelectedPlans() {
		PlanOfAction primaryPlanOfAction = form.getLocalContext().getPlanAdviceVo().getPrimaryPlan();
		PlanOfActionCollection collSecondaryPlans = form.getLocalContext().getPlanAdviceVo().getSecondaryPlans();
		boolean bPrimaryPlanFound = true;
		if(primaryPlanOfAction != null){
			for (int i = 0; i < form.grdPlan().getRows().size(); i++)
			{
				GenForm.grdPlanRow rowParent = form.grdPlan().getRows().get(i);
				bPrimaryPlanFound = searchTreeHierarchy(rowParent, primaryPlanOfAction, true);
				if(bPrimaryPlanFound)
					i = form.grdPlan().getRows().size();
			}
		}
		if(collSecondaryPlans != null){
			boolean bSecondaryPlanFound = false; 
			for (int i = 0; i < collSecondaryPlans.size(); i++)
			{
				bSecondaryPlanFound = false;
				for (int j = 0; j < form.grdPlan().getRows().size(); j++)
				{
					GenForm.grdPlanRow rowParent = form.grdPlan().getRows().get(j);
					bSecondaryPlanFound = searchTreeHierarchy(rowParent, collSecondaryPlans.get(i), false);
					if(bSecondaryPlanFound)
						j = form.grdPlan().getRows().size();
				}
			}
		}
	}
	
	private boolean searchTreeHierarchy(grdPlanRow rowParent, PlanOfAction planOfAction, boolean bPrimary) {
		boolean bPlanFound = false;
		if(rowParent.getRows().size()==0)
			if(rowParent.getcolPlan().equals(planOfAction)){
				if(bPrimary)
					rowParent.setcolPrimary(true);
				else
					rowParent.setcolSecondary(true);
				return true;
			}
		for (int j = 0; j < rowParent.getRows().size(); j++)
		{
			grdPlanRow rowChild = rowParent.getRows().get(j);
			if(rowChild.getcolPlan().equals(planOfAction)){
				if(bPrimary)
					rowChild.setcolPrimary(true);
				else
					rowChild.setcolSecondary(true);
				return true;
			}
			
			bPlanFound = searchTreeHierarchy(rowChild, planOfAction, bPrimary);
			
		}
		
		return bPlanFound;		
	}
	
	@Override
	protected void onBtnSaveClick() throws ims.framework.exceptions.PresentationLogicException
	{
		if (save())
			open();
	}
	private boolean save() 
	{
		if(isRACPCComplete())//	WDEV-13662
			return false;
		
		RACPPlanAdviceVo  voPlanAdvice = populateDataFromScreen(form.getLocalContext().getPlanAdviceVo());
		
		ArrayList<String> screenErrors = new ArrayList<String>();
		
		if(noFieldsPopulated(voPlanAdvice))
			screenErrors.add("A minimum of 1 data fields must be entered.");

		String[] arrErrors = voPlanAdvice.validate();
		String[] arrScreenAndVoErrors = addScreenErrorsToVOErrors(screenErrors, arrErrors);
		if (arrScreenAndVoErrors.length == 0)
		{
			try
			{
				voPlanAdvice = domain.savePlanAdviceVo(voPlanAdvice);
			}
			catch (StaleObjectException e)
			{
				engine.showMessage(ims.configuration.gen.ConfigFlag.UI.STALE_OBJECT_MESSAGE.getValue());
				open();
				return false;
			}
			catch (UniqueKeyViolationException e)
			{
				engine.showMessage("A plan with the same criteria already exists.   " + e.getMessage());
				open();
				return false;
			}
		}
		else
		{
			engine.showErrors("Error", arrScreenAndVoErrors);
			return false;
		}
		form.getLocalContext().setPlanAdviceVo(voPlanAdvice);
		return true;
	}
	private boolean noFieldsPopulated(RACPPlanAdviceVo voPlanAdvice) {
		if(voPlanAdvice.getID_RACPPlanAdviceIsNotNull())
				return false;
		else if(voPlanAdvice.countFieldsWithValue()==1)
			return true;
		
		return false;
	}
	private String[] addScreenErrorsToVOErrors(ArrayList screenErrors, String[] arrErrors)
	{
		String[] arrAllErrors = null;

		if (arrErrors != null)
		{
			arrAllErrors = new String[screenErrors.size() + arrErrors.length];
			for (int i = 0; i < screenErrors.size(); i++)
				arrAllErrors[i] = (String) screenErrors.get(i);

			int i = 0;
			for (int p = screenErrors.size(); p < arrAllErrors.length; p++)
			{
				arrAllErrors[p] = arrErrors[i];
				i++;
			}
		}
		else
		{
			arrAllErrors = new String[screenErrors.size()];

			for (int i = 0; i < screenErrors.size(); i++)
				arrAllErrors[i] = (String) screenErrors.get(i);
		}

		return arrAllErrors;
	}
	private RACPPlanAdviceVo populateDataFromScreen(RACPPlanAdviceVo planAdviceVo) {
		if(planAdviceVo == null)
			planAdviceVo = new RACPPlanAdviceVo();
		
		if(planAdviceVo.getCareContext()==null)
			planAdviceVo.setCareContext(form.getGlobalContext().Core.getCurrentCareContext());
			
		form.getLocalContext().setPrimaryPlanOfAction(null);
		populatePrimaryPlanFromGrd(null);
		planAdviceVo.setPrimaryPlan(form.getLocalContext().getPrimaryPlanOfAction());
		PlanOfActionCollection  voPlanOfActionColl = new PlanOfActionCollection ();
		voPlanOfActionColl = populateSecondaryPlansFromGrd(null, voPlanOfActionColl);
		if(voPlanOfActionColl.size()==0)
			planAdviceVo.setSecondaryPlans(null);
		else
			planAdviceVo.setSecondaryPlans(voPlanOfActionColl);
		planAdviceVo.setAdviceGivenPatient(populateAdviceGivenPatientFromGrd());
		planAdviceVo.setAdviceGivenToGP(populateAdviceGivenToGPFromGrd());
		
		planAdviceVo.setOverallImpression(form.cmbOverallImpression().getValue());
		planAdviceVo.setOtherDetails(form.txtOther().getValue());
	
		return planAdviceVo;
	}
	private AdviceToGPCollection populateAdviceGivenToGPFromGrd() {
		AdviceToGPCollection collAdviceToGP = new AdviceToGPCollection();
		
		for (int i = 0; i < form.grdAdviceToGP().getRows().size(); i++)
		{
			grdAdviceToGPRow row = form.grdAdviceToGP().getRows().get(i);
			if(row.getcolSelect())
				collAdviceToGP.add(row.getcolFinding());
		}
		
		if(collAdviceToGP.size()==0)
			return null;
		
		return collAdviceToGP;
	}
	private AdviceToPatientCollection populateAdviceGivenPatientFromGrd() {
		AdviceToPatientCollection collAdviceToPatient = new AdviceToPatientCollection();
		
		for (int i = 0; i < form.grdAdviceToPatient().getRows().size(); i++)
		{
			grdAdviceToPatientRow row = form.grdAdviceToPatient().getRows().get(i);
			if(row.getcolGiven())
				collAdviceToPatient.add(row.getcolAdvice());
		}
		
		if(collAdviceToPatient.size()==0)
			return null;
		
		return collAdviceToPatient;
	}
	private void populatePrimaryPlanFromGrd(grdPlanRowCollection collRows) {
		
		if(collRows==null)
			collRows = form.grdPlan().getRows();

		PlanOfAction primaryPlanOfAction = new PlanOfAction(); 
		for (int i = 0; i < collRows.size(); i++)
		{
			GenForm.grdPlanRow rowParent = collRows.get(i);
			if(rowParent.getRows().size()==0){
				if(rowParent.getcolPrimary()){
					primaryPlanOfAction =   rowParent.getcolPlan();
					if(form.getLocalContext().getPrimaryPlanOfAction()==null)
						form.getLocalContext().setPrimaryPlanOfAction(primaryPlanOfAction);
					i = collRows.size();
				}
			}
			else{
				for (int j = 0; j < rowParent.getRows().size(); j++)
				{
					GenForm.grdPlanRow rowChild = rowParent.getRows().get(j);
					if(rowChild.getcolPrimary()){
						primaryPlanOfAction =   rowChild.getcolPlan();
						if(form.getLocalContext().getPrimaryPlanOfAction()==null)
							form.getLocalContext().setPrimaryPlanOfAction(primaryPlanOfAction);
						j = rowParent.getRows().size();
					}
					if(rowChild.getRows().size()>0){
						populatePrimaryPlanFromGrd(rowChild.getRows());
					}
				}
			}
		}
	}
	private PlanOfActionCollection  populateSecondaryPlansFromGrd(grdPlanRowCollection collRows, PlanOfActionCollection voPlanOfActionColl)
	{
		if(collRows==null)
			collRows = form.grdPlan().getRows();
		
		for (int i = 0; i < collRows.size(); i++)
		{
			GenForm.grdPlanRow rowParent = collRows.get(i);
			if(rowParent.getRows().size()==0){
				if(rowParent.getcolSecondary())
					voPlanOfActionColl.add(rowParent.getcolPlan());
			}
			else{
				for (int j = 0; j < rowParent.getRows().size(); j++)
				{
					GenForm.grdPlanRow rowChild = rowParent.getRows().get(j);
					PlanOfAction voPlanOfAction = rowChild.getcolPlan();
					if(rowChild.getcolSecondary())
						voPlanOfActionColl.add(voPlanOfAction);
					if(rowChild.getRows().size()>0)
						populateSecondaryPlansFromGrd(rowChild.getRows(), voPlanOfActionColl);
				}
			}
		}
		
		return voPlanOfActionColl;	
	}
	@Override
	protected void onBtnCancelClick() throws ims.framework.exceptions.PresentationLogicException
	{
		open();
	}
	@Override
	protected void onGrdPlanGridCheckBoxClicked(int column, grdPlanRow row, boolean isChecked) throws PresentationLogicException {
		if(column==1)
		{
			boolean bPrimary = form.getLocalContext().getPrimaryPlanOfAction()!=null
				&& form.getLocalContext().getPrimaryPlanOfAction().equals(row.getcolPlan());
			//WDEV-14061
			if(!bPrimary && row.getcolPrimary())
			{
				clearPrimaryColumns(form.grdPlan().getRows());
				row.setcolPrimary(true);
				form.getLocalContext().setPrimaryPlanOfAction(row.getcolPlan());	
			}
			
			row.setcolSecondary(false);
			
		}
		else if(column==2)
			row.setcolPrimary(false);
	}
	
	private void clearPrimaryColumns(grdPlanRowCollection collRows) {
		for (int i = 0; i < collRows.size(); i++)
		{
			GenForm.grdPlanRow rowParent = collRows.get(i);
			if(rowParent.getRows().size()==0){
				rowParent.setcolPrimary(false);
			}
			else{
				for (int j = 0; j < rowParent.getRows().size(); j++)
				{
					GenForm.grdPlanRow rowChild = rowParent.getRows().get(j);
					rowChild.setcolPrimary(false);
					if(rowChild.getRows().size()>0)
						clearPrimaryColumns(rowChild.getRows());
				}
			}
		}
	}
	
	//	WDEV-13437
	@Override
	protected void onFormModeChanged() 
	{
		updateControlsState();
	}
	
	//	WDEV-13437
	private void updateControlsState() 
	{
		if(FormMode.VIEW.equals(form.getMode()))
		{
			boolean isReadOnly = domain.isRACPCSummaryComplete(form.getGlobalContext().Core.getCurrentCareContext());
		
			form.btnNew().setVisible(form.getLocalContext().getPlanAdviceVo() == null && !isReadOnly);
			form.btnEdit().setVisible(form.getLocalContext().getPlanAdviceVo() != null && !isReadOnly);
		}
	}
	
	//	WDEV-13662
	private boolean isRACPCComplete() 
	{	
		boolean isRACPCSummaryComplete = domain.isRACPCSummaryComplete(form.getGlobalContext().Core.getCurrentCareContext());//	WDEV-13662
		
		if(isRACPCSummaryComplete)//	WDEV-13662
		{
			engine.showMessage("RACPC Summary has already been completed. The screen will be refreshed.");
			open();
			return true;
		}
		
		return false;
	}
}
