/FileExtraction/Java_unseen/IMS-MAXIMS_openMAXIMS/Source Library/openmaxims_workspace/Nursing/src/ims/nursing/forms/nutritionalriskassessmentdialog/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 Vasile Purdila using IMS Development Environment (version 1.22 build 41210.1630)
// Copyright (C) 1995-2004 IMS MAXIMS plc. All rights reserved.

package ims.nursing.forms.nutritionalriskassessmentdialog;

import ims.coe.vo.RiskAssessment;
import ims.coe.vo.RiskAssessmentCollection;
import ims.coe.vo.RiskDescription;
import ims.domain.exceptions.DomainInterfaceException;
import ims.domain.exceptions.StaleObjectException;
import ims.framework.enumerations.DialogResult;
import ims.framework.exceptions.PresentationLogicException;
import ims.framework.utils.Color;
import ims.framework.utils.Date;
import ims.framework.utils.DateTime;
import ims.framework.utils.Time;
import ims.nursing.vo.AssessmentComponent;
import ims.nursing.vo.AssessmentHeaderInfo;
import ims.nursing.vo.NutritionalRiskAssessmentDetailsVo;
import ims.nursing.vo.NutritionalRiskAssessmentDetailsVoCollection;
import ims.nursing.vo.NutritionalRiskAssessmentVo;
import ims.spinalinjuries.vo.NurAssessmentEatingVo;
import ims.core.vo.AuthoringInformationVo;
import ims.core.vo.HcpLiteVo;
import ims.core.vo.VSMetrics;
import ims.core.vo.VitalSignsVo;
import ims.core.vo.VitalSignsVoCollection;
import ims.core.vo.lookups.VSType;
import ims.core.vo.lookups.VSTypeCollection;

public class Logic extends BaseLogic
{
	protected void onFormOpen() throws ims.framework.exceptions.FormOpenException
	{
		RiskAssessmentCollection risks = form.getGlobalContext().Nursing.getNutritionalRiskAssessments();
		
		if(risks == null)
		{
			engine.showMessage("Could not retrieve the Nutritional Risk Assessments !");
			return;
		}
		
		NutritionalRiskAssessmentVo nutritionalRisk = form.getGlobalContext().Nursing.getNutritionalRiskRecord();
		
		form.grdAssessment().getRows().clear();
		for(int i = 0; i < risks.size(); i++)
		{
			RiskAssessment risk = risks.get(i);
			
			GenForm.grdAssessmentRow row = form.grdAssessment().getRows().newRow();
			
			row.setRisk(risk.getName());
			row.setBold(true);
			row.setBackColor(Color.Beige);
			row.setValue(risk.getMultiple().booleanValue() == true ? "Y" : "N");
			row.setTooltip(risk.getDescription());
			
			for (int j = 0; j < risk.getRiskFactors().size(); j++)
			{
				GenForm.grdAssessmentRow child = row.getRows().newRow();
				
				RiskDescription descr = risk.getRiskFactors().get(j);
				
				child.setRisk(descr.getName());
				child.setValue(descr.getId());
				child.setTooltip(descr.getDescription());
				
				if(nutritionalRisk != null)
				{
					//update mode
					for(int k = 0; k < nutritionalRisk.getAssessmentDetails().size(); k++)
					{
						if(descr.getId().equals(nutritionalRisk.getAssessmentDetails().get(k).getAssessment().toString()))
						{
							child.setSelect(nutritionalRisk.getAssessmentDetails().get(k).getSelect().booleanValue());
							break;
						}
					}
				}
			}
			
			row.setExpanded(true);
		}

		// make editable if global context Nursing.GetEdit is set to true
		if (form.getGlobalContext().Nursing.getEditIsNotNull())
		{
			form.grdAssessment().setReadOnly(!form.getGlobalContext().Nursing.getEdit().booleanValue());
			form.btnSave().setEnabled(form.getGlobalContext().Nursing.getEdit().booleanValue());
		}
		
		if(nutritionalRisk == null)
		{
			form.dteDate().setValue(new Date());
			form.timTime().setValue(new Time());
			
			form.getLocalContext().setHcp((HcpLiteVo)domain.getHcpLiteUser());
			
			if(form.getLocalContext().getHcp() != null)
				form.txtHcp().setValue(form.getLocalContext().getHcp().getName().toString());
		}
		else
		{
			form.dteDate().setValue(nutritionalRisk.getDateTimeInitiated().getDate());
			form.timTime().setValue(nutritionalRisk.getDateTimeInitiated().getTime());
			
			if(nutritionalRisk.getHcpInitiated() != null && nutritionalRisk.getHcpInitiated().getName() != null)
				form.txtHcp().setValue(nutritionalRisk.getHcpInitiated().getName().toString());
		}
		
		VitalSignsVoCollection metricsColl = null;
		VitalSignsVo metrics = null;
		
		metricsColl = domain.getLastMetrics(form.getGlobalContext().Core.getPatientShort().getID_Patient());				

		if(metricsColl != null)
		{
			if(nutritionalRisk != null) //on an update
			{
				if(nutritionalRisk.getDateTimeInitiatedIsNotNull())
				{
					for(int x=0; x<metricsColl.size(); x++)
					{
						metrics = metricsColl.get(x);
						Time metricsTime = metrics.getAuthoringInformation().getAuthoringDateTime().getTime();
						Time selected = nutritionalRisk.getDateTimeInitiated().getTime();
						if(metricsTime.equals(selected))
						{
							break;						
						}
					}
				}
			}
			else
			{
				//on a new (height should not change, so get the latest)
				metrics = metricsColl.get(0);
			}
		}
		
		if(metrics != null && metrics.getMetrics() != null)
		{
			form.decHeight().setValue(metrics.getMetrics().getHeightValue());
			
			if(form.getGlobalContext().Nursing.getNutritionalRiskRecordIsNotNull())
			{
				//update mode
				form.decWeight().setValue(metrics.getMetrics().getWeightValue());
			}
			calculateBMI();
		}

		if(form.getGlobalContext().Nursing.getNutritionalRiskRecordIsNotNull())
		{
			//update mode
			form.decHeight().setEnabled(false);
			form.decWeight().setEnabled(false);
			
			disableBMITree();
		}
		
		// If there is an associated mobility component for this assessment that is complete
		// we want to disable the save button
		AssessmentComponent comp = form.getGlobalContext().Nursing.getAssessmentComponent();
		if (comp != null && comp.getIsComplete().booleanValue() == true)
		{
			form.btnSave().setEnabled(false);
			form.grdAssessment().setReadOnly(true);
		}
		
		//we can update a Braden record which belongs to an Skin assessment via Skin assessment page only  
		if(form.getGlobalContext().Nursing.getNutritionalRiskRecordIsNotNull() && comp == null)
		{
			Boolean bIsPart = null;
			
			try
			{
				bIsPart = domain.isPartOfEatingAssessment(form.getGlobalContext().Nursing.getNutritionalRiskRecord());
			} catch (DomainInterfaceException e1)
			{
				engine.showMessage("Error retrieving skin assessment record: " + e1.getMessage());
				return;
			}

			if(bIsPart == Boolean.TRUE)
			{
				form.btnSave().setEnabled(false);
				form.grdAssessment().setReadOnly(true);
			}
		}
	}
	protected void onBtnCancelClick() throws ims.framework.exceptions.PresentationLogicException
	{
		engine.close(DialogResult.CANCEL);
	}
	protected void onBtnSaveClick() throws ims.framework.exceptions.PresentationLogicException
	{
		if(bCheckData() == false)
			return;
		
		NutritionalRiskAssessmentVo record = form.getGlobalContext().Nursing.getNutritionalRiskRecord();

		VitalSignsVo voVitalSign = null;
		VSTypeCollection recordedSigns = null;
		
		if(record == null)
		{
			//new
			record = populateDataFromScreen();
			
			voVitalSign = new VitalSignsVo();
			recordedSigns = new VSTypeCollection();

			//add mode
			VSMetrics voMetrics = new VSMetrics();
			
			voMetrics.setHeightValue(form.decHeight().getValue());
			voMetrics.setWeightValue(form.decWeight().getValue());
			voMetrics.setBMI(bodyMassIndex(form.decHeight().getValue().floatValue(), form.decWeight().getValue().floatValue()));
			voMetrics.setSurfaceArea(bodySurfaceArea(form.decHeight().getValue().floatValue(), form.decWeight().getValue().floatValue()));
			voMetrics.setHeightEstimatedMeasured(Boolean.TRUE); //default to measured
			voMetrics.setWeightEstimatedMeasured(Boolean.TRUE); //default to measured
			voMetrics.setPatient(form.getGlobalContext().Core.getPatientShort().toPatientRefVo());
			
			voVitalSign.setMetrics(voMetrics);
			recordedSigns.add(VSType.METRICS);
			voVitalSign.setRecordedSigns(recordedSigns);
	
			//recording datetime
			Date date = form.dteDate().getValue();
			Time time = form.timTime().getValue();
			
			DateTime dt = null;
			if(date != null && time != null)
				dt = new DateTime(date,time);
	
			voVitalSign.setVitalsTakenDateTime(dt);
			//WDEV-2290 
			if (domain.getHcpUser() != null)
			{
				AuthoringInformationVo voAuthoringInformation = new AuthoringInformationVo();
				voAuthoringInformation.setAuthoringDateTime(dt);
				voAuthoringInformation.setAuthoringHcp((HcpLiteVo)domain.getHcpLiteUser());
				voVitalSign.setAuthoringInformation(voAuthoringInformation);
			}
			
			voVitalSign.setClinicalContact(form.getGlobalContext().Core.getCurrentClinicalContact());
	
			
			
			
			//current care context
			voVitalSign.setCareContext(form.getGlobalContext().Core.getCurrentCareContext());
			
			String[] errors = voVitalSign.validate();
			if (errors != null)
			{
				engine.showErrors(errors);
				return;
			}
		}
		else
		{
			//update
			record = populateDataFromScreen(record);
		}	

		if(record == null)
			return;
		
		record.setAssessmentDetails(new NutritionalRiskAssessmentDetailsVoCollection());
		
		for (int i = 0; i < form.grdAssessment().getRows().size(); i++)
		{
			GenForm.grdAssessmentRow row = form.grdAssessment().getRows().get(i);
			
			for (int j = 0; j < row.getRows().size(); j++)
			{
				GenForm.grdAssessmentRow child = row.getRows().get(j);

				NutritionalRiskAssessmentDetailsVo detail = new ims.nursing.vo.NutritionalRiskAssessmentDetailsVo();
				detail.setAssessment(new Integer(child.getValue()));
				detail.setSelect(new Boolean(child.getSelect()));

				record.getAssessmentDetails().add(detail);
			}
		}
		
		if(form.getGlobalContext().Core.getCurrentClinicalContactIsNotNull())
			record.setClinicalContact(form.getGlobalContext().Core.getCurrentClinicalContact());
		
		//current care context
		record.setCareContext(form.getGlobalContext().Core.getCurrentCareContext());
		
		String[] errors = record.validate();
		if (errors != null)
		{
			engine.showErrors(errors);
			return;
		}	

		try
		{
			// If there is an assesment component in the global context, we want to save that too!
			if(form.getGlobalContext().Nursing.getAssessmentComponent() != null && form.getGlobalContext().Nursing.getAssessmentComponent() instanceof NurAssessmentEatingVo)
			{
				NurAssessmentEatingVo comp = (NurAssessmentEatingVo)form.getGlobalContext().Nursing.getAssessmentComponent();
				comp.setNutritionalRiskAssessment(record);
				comp.setNutritionalRiskScore(new Integer(getAssessmentScore()));
				
				String[] arrErrors = comp.validate();
				if(arrErrors != null)
				{
					engine.showErrors("Validation Errors", arrErrors);
					return;
				}
				AssessmentHeaderInfo headerInfo = domain.saveRecord(record, form.getGlobalContext().Nursing.getAssessmentHeaderInfo(), comp, voVitalSign);
				// Go back to the skin assessment form
				form.getGlobalContext().Nursing.setAssessmentHeaderInfo(headerInfo);
			}
			else
			{
				domain.saveRecord(record, null, null, voVitalSign);
			}
			
		} 
		catch (StaleObjectException e) 
		{
			engine.showMessage(ims.configuration.gen.ConfigFlag.UI.STALE_OBJECT_MESSAGE.getValue());
			engine.close(DialogResult.OK);
			return;
		}
		
		if(form.getGlobalContext().Nursing.getDisplayScoreIsNotNull() && form.getGlobalContext().Nursing.getDisplayScore().equals(Boolean.TRUE))
		{
			float fScore = getAssessmentScore();
			form.getGlobalContext().Nursing.setAssessmentScore(new Float(fScore));
		}
		
		engine.close(DialogResult.OK);
	}
	private int getAssessmentScore()
	{
		int nScore = 0;

		RiskAssessment risk = null;
		RiskDescription descr = null;

		int partScore;
		for (int i = 0; i < form.grdAssessment().getRows().size(); i++)
		{
			GenForm.grdAssessmentRow row = form.grdAssessment().getRows().get(i);

			risk = null;
			partScore = 0;
			
			for (int j = 0; j < row.getRows().size(); j++)
			{
				GenForm.grdAssessmentRow child = row.getRows().get(j);
				
				for(int k = 0; k < form.getGlobalContext().Nursing.getNutritionalRiskAssessments().size(); k++)
				{
					risk = form.getGlobalContext().Nursing.getNutritionalRiskAssessments().get(k);
					
					for(int m = 0; m < risk.getRiskFactors().size(); m++)
					{
						descr = risk.getRiskFactors().get(m);
						
						if(child.getValue().toString().equals(descr.getId()) && child.getSelect() == true)
						{
							partScore += Integer.valueOf(descr.getScore()).intValue();
						}
					}
				}
			}
			
			nScore += partScore;
		}
		
		return nScore;
	}
	private boolean bCheckData()
	{
		if(form.decHeight().getValue() == null || form.decHeight().getValue() < 1)
		{
			engine.showMessage("Please enter the Height, of value no less than 1 !");
			return false;
		}

		if(form.decWeight().getValue() == null || form.decWeight().getValue() < 1)
		{
			engine.showMessage("Please enter the Weight, of value no less than 1 !");
			return false;
		}
		
		for (int i = 0; i < form.grdAssessment().getRows().size(); i++)
		{
			GenForm.grdAssessmentRow row = form.grdAssessment().getRows().get(i);
			
			//all questions must be answered
			int nAnswers = 0;
			for (int j = 0; j < row.getRows().size(); j++)
			{
				GenForm.grdAssessmentRow child = row.getRows().get(j);
				
				if(child.getSelect() == true)
				{
					nAnswers++;
					break;
				}
			}
			if(nAnswers == 0)
			{
				engine.showMessage("The question '" + row.getRisk() + "' was not answered !");
				return false;
			}
			
			
			if(row.getValue().equalsIgnoreCase("N"))
			{
				int nFound = 0;
				for (int j = 0; j < row.getRows().size(); j++)
				{
					GenForm.grdAssessmentRow child = row.getRows().get(j);
					
					if(child.getSelect() == true)
						nFound++;
				}
				
				if(nFound > 1)
				{
					engine.showMessage("The answers for risk factor '" + row.getRisk() + "' are mutually exclusive. Please select only one answer.");
					return false;
				}
			}
		}
		
		return true;
	}
	
	protected NutritionalRiskAssessmentVo populateDataFromScreen()
	{
		NutritionalRiskAssessmentVo record = super.populateDataFromScreen();
		
		if(form.getLocalContext().getHcp() != null)
			record.setHcpInitiated(form.getLocalContext().getHcp());
		
		record.setDateTimeInitiated(new DateTime(form.dteDate().getValue(), form.timTime().getValue()));

		return record;
	}
	protected NutritionalRiskAssessmentVo populateDataFromScreen(NutritionalRiskAssessmentVo value)
	{
		NutritionalRiskAssessmentVo record = super.populateDataFromScreen(value);

		//we keep the original HCP
		//if(form.getLocalContext().getHcp() != null)
			//record.setHcpInitiated(form.getLocalContext().getHcp());
		
		record.setDateTimeInitiated(new DateTime(form.dteDate().getValue(), form.timTime().getValue()));
		
		return record;
	}
	protected void populateScreenFromData(NutritionalRiskAssessmentVo value)
	{
		super.populateScreenFromData(value);
	}
	protected void onDecWeightValueChanged() throws PresentationLogicException
	{
		calculateBMI();
	}
	protected void onDecHeightValueChanged() throws PresentationLogicException
	{
		calculateBMI();
	}

	private Float bodyMassIndex(float height/*cm*/, float weight/*kg*/)
	{
		//we have to convert the HEIGHT from cm to m as the formula requires m
		return new Float((float)(weight / (height / 100.0 * height / 100.0)));
	}

	private Float bodySurfaceArea(float height/*cm*/, float weight/*kg*/)
	{
		//we have to convert the HEIGHT from cm to m as the formula requires m
		return new Float((float)(0.20247 * Math.pow(height / 100.0, 0.725) * Math.pow(weight, 0.425)));
	}
	
	private void disableBMITree()
	{
		if(form.decWeight().getValue() == null)
		{
			return;
		}

		if(form.decHeight().getValue() == null)
		{
			return;
		}

		for (int i = 0; i < form.grdAssessment().getRows().size(); i++)
		{
			GenForm.grdAssessmentRow row = form.grdAssessment().getRows().get(i);

			boolean bFound = false;
			for (int j = 0; j < row.getRows().size(); j++)
			{
				GenForm.grdAssessmentRow child = row.getRows().get(j);
			
				if(child.getValue().equals("5") && child.getSelect())
				{
					bFound = true;
					break;
				}
				if(child.getValue().equals("6") && child.getSelect())
				{
					bFound = true;
					break;
				}
				if(child.getValue().equals("7") && child.getSelect())
				{
					bFound = true;
					break;
				}
				if(child.getValue().equals("8") && child.getSelect())
				{
					bFound = true;
					break;
				}
			}
			
			if(bFound == true)
			{
				for (int j = 0; j < row.getRows().size(); j++)
				{
					GenForm.grdAssessmentRow child = row.getRows().get(j);
					child.setReadOnly(true);
				}
				
				break;
			}
		}
	}
	
	private void calculateBMI()
	{
		if(form.decWeight().getValue() == null)
		{
			return;
		}

		if(form.decHeight().getValue() == null)
		{
			return;
		}

		Float bmi = bodyMassIndex(form.decHeight().getValue().floatValue(), form.decWeight().getValue().floatValue());
		
		if(bmi == null)
			return;
		
		for (int i = 0; i < form.grdAssessment().getRows().size(); i++)
		{
			GenForm.grdAssessmentRow row = form.grdAssessment().getRows().get(i);

			boolean bFound = false;
			for (int j = 0; j < row.getRows().size(); j++)
			{
				GenForm.grdAssessmentRow child = row.getRows().get(j);
			
				if(child.getValue().equals("5"))
				{
					child.setSelect(false);
					
					if(bmi.floatValue() >= 20)
					{
						child.setSelect(true);
						bFound = true;
					}
				}
				if(child.getValue().equals("6"))
				{
					child.setSelect(false);
					
					if(bmi.floatValue() >= 18 && bmi.floatValue() < 20)
					{
						child.setSelect(true);
						bFound = true;
					}
				}
				if(child.getValue().equals("7"))
				{
					child.setSelect(false);
					
					if(bmi.floatValue() >= 15 && bmi.floatValue() < 18)
					{
						child.setSelect(true);
						bFound = true;
					}
				}
				if(child.getValue().equals("8"))
				{
					child.setSelect(false);
					
					if(bmi.floatValue() < 15)
					{
						child.setSelect(true);
						bFound = true;
					}
				}
			}
			
			if(bFound == true)
			{
				for (int j = 0; j < row.getRows().size(); j++)
				{
					GenForm.grdAssessmentRow child = row.getRows().get(j);
					child.setReadOnly(true);
				}				
			}
		}
	}
	
}
