gt: 			for (int i=0; i < voRehab.getRehabActivity().size(); i++)
context: //#############################################################################
  //#                                                                           #
  //#  Copyright (C) <2014>  <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/>.    #
  //#                                                                           #
  //#############################################################################
  //#EOH
  // This code was generated by Rory Fitzpatrick using IMS Development Environment (version 1.40 build 2194.25473)
  // Copyright (C) 1995-2006 IMS MAXIMS plc. All rights reserved.
  
  package ims.therapies.forms.rehab;
  
  import java.util.ArrayList;
  
  import ims.core.vo.Hcp;
  import ims.core.vo.HcpCollection;
  import ims.core.vo.HcpFilter;
  import ims.core.vo.PersonName;
  import ims.domain.exceptions.StaleObjectException;
  import ims.framework.cn.data.TreeNode;
  import ims.framework.enumerations.FormMode;
  import ims.framework.exceptions.PresentationLogicException;
  import ims.domain.exceptions.UniqueKeyViolationException;
  import ims.framework.utils.DateTime;
  import ims.framework.utils.Color;
  import ims.spinalinjuries.vo.lookups.LookupHelper;
  import ims.spinalinjuries.vo.lookups.RehabActivity;
  import ims.spinalinjuries.vo.lookups.RehabActivityCollection;
  import ims.spinalinjuries.vo.lookups.RehabEnvAdaptation;
  import ims.spinalinjuries.vo.lookups.RehabEnvAdaptationCollection;
  import ims.spinalinjuries.vo.lookups.RehabEquipment;
  import ims.spinalinjuries.vo.lookups.RehabEquipmentCollection;
  import ims.spinalinjuries.vo.lookups.RehabTechnique;
  import ims.spinalinjuries.vo.lookups.RehabTechniqueCollection;
  import ims.therapies.forms.rehab.GenForm;
  import ims.therapies.vo.RehabilitationVo;
  import ims.therapies.vo.RehabilitationShortVo;
  import ims.therapies.vo.RehabilitationShortVoCollection;
  import ims.therapies.vo.RehabilitationActivityVo;
  import ims.therapies.vo.RehabilitationActivityVoCollection;
  
  public class Logic extends BaseLogic
  {
  	protected void onFormOpen() throws ims.framework.exceptions.FormOpenException
  	{		
  		initialize();
  		open();		
  	}
  	public void initialize() 
  	{		
  		form.ctnDetail().setCollapsed(true);
  		loadTypeCombo();		
  	}	
  	protected void onBtnOkActivityClick() throws ims.framework.exceptions.PresentationLogicException
  	{
  		addOrUpdateNotSavedChild();
  	}
  	private boolean addOrUpdateNotSavedChild()
  	{
  		if (form.getLocalContext().getGoldenInstanceSelected().equals(Boolean.FALSE))			
  			if(!newParentNode(form.getLocalContext().getSelectedParentInstance()))
  				return false;			
  				
  		RehabilitationActivityVo voRehabActivity = form.getLocalContext().getSelectedChildInstance();		
  			
  		if (voRehabActivity == null)
  			voRehabActivity = new RehabilitationActivityVo(); 
  
  		populateChildInstanceData(voRehabActivity);
  
  		if (form.grdActivity().getValue() instanceof RehabilitationActivityVo && form.getLocalContext().getSelectedChildInstanceIsNotNull())
  		{
  			RehabilitationActivityVo voRehabActivitySelected = (RehabilitationActivityVo)form.grdActivity().getValue();
  			
  			if (voRehabActivitySelected.getID_RehabilitationActivity() == null) 
  			{
  				//allow update of selected child that is not saved yet.
  				promoteUpdatedChild(voRehabActivity);
  				newChildInstance();
  				updateControlsState();
  			}
  		}
  		else
  		{
  			if(newChildNode(voRehabActivity))
  				return true;			
  		}
  		return false;		
  	}
  	
  	/**
  	 * Invoked when the user clicks OK to add a new element to the child array
  	 * Basically we update the hierarchy grid with the newly added details clearing the control
  	 * to facilitate new input. We then update the local conte xt variable with the new child 
  	 *
  	 */
  	private boolean newChildNode(RehabilitationActivityVo voRehabActivity) 
  	{
  		if (form.getLocalContext().getSelectedChildInstance() != null) return false;
  		
  		if (voRehabActivity.countFieldsWithValue() > 0)
  		{
  			String strErrors[] = voRehabActivity.validate();
  		
  			if(strErrors != null && strErrors.length > 0)
  			{
  				engine.showErrors(strErrors);
  				return true;
  			}
  	 				
  			promoteChild(voRehabActivity);			
  			clearChildInstanceControls();
  			loadEquipment();
  			loadAdaptation();
  			loadTechnique();
  		}
  		return false;
  	}
  	private void promoteChild(RehabilitationActivityVo voRehabActivity) 
  	{
  		if (voRehabActivity == null) return;
  		GenForm.grdActivityRow childRow = null;
  		form.grdActivity().setValue(form.getLocalContext().getSelectedParentInstance());
  		if(form.grdActivity().getSelectedRow().getValue() instanceof RehabilitationActivityVo)
  			childRow = form.grdActivity().getSelectedRow().getParentRow().getRows().newRow();
  		else
  			childRow = form.grdActivity().getSelectedRow().getRows().newRow();		
  		populateChildNode(childRow, voRehabActivity);	
  	}
  	public void updateControlsState()
  	{				
  		// The new button
  		form.btnNew().setVisible(form.getMode().equals(FormMode.VIEW) 
  				&& form.getGlobalContext().Core.getCurrentClinicalContactIsNotNull()
  				&& form.getLocalContext().getGoldenInstanceFound().booleanValue() == false);
  
  		form.btnUpdate().setVisible(form.getMode().equals(FormMode.VIEW) 
  				&& form.getGlobalContext().Core.getCurrentClinicalContactIsNotNull()
  				&& form.grdActivity().getValue() instanceof RehabilitationActivityVo
  				&& form.getLocalContext().getGoldenInstanceFound().booleanValue() == true);
  		
  		// The collapsible container
  		form.ctnDetail().setCollapsed(form.getLocalContext().getSelectedParentInstance() == null);						
  
  		// The empty tab
  		//if (form.grdHierarchy().getValue() == null)
  			//form.ctnDetail().lyrUltra().showtabEmpty();
  
  		// Show Header and/or Detail
  		showHeaderOrDetails();																				
  
  		// The context menus
  		updateContextMenusState();		
  	}
  	private void showHeaderOrDetails() 
  	{
  		if (form.getMode().equals(FormMode.VIEW))
  		{
  			form.ctnDetail().dtimAuthoring().setEnabled(false);
  			form.ctnDetail().qmbAuthoringCP().setEnabled(false);			
  			form.ctnDetail().setCollapsed(false);
  			form.ctnDetail().cmbActivity().setEnabled(false);
  			form.ctnDetail().cmbCategory().setEnabled(false);
  			form.ctnDetail().cmbGroup().setEnabled(false);
  			form.ctnDetail().cmbIndependence().setEnabled(false);
  			form.ctnDetail().cmbLocation().setEnabled(false);
  			form.ctnDetail().cmbPurpose().setEnabled(false);
  			form.ctnDetail().cmbTypes().setEnabled(false);
  			form.ctnDetail().grdEnvironment().setReadOnly(true);
  			form.ctnDetail().grdEquipment().setReadOnly(true);
  			form.ctnDetail().grdTechnique().setReadOnly(true);
  		}
  		else
  		{
  			if (form.getLocalContext().getSelectedParentInstanceIsNotNull() && (form.getLocalContext().getSelectedParentInstance().getID_RehabilitationIsNotNull()))
  			{
  				//this is an update
  				form.ctnDetail().dtimAuthoring().setEnabled(false);
  				form.ctnDetail().qmbAuthoringCP().setEnabled(false);
  			}
  			else
  			{
  				//this is an new record
  				form.ctnDetail().dtimAuthoring().setEnabled(true);
  				form.ctnDetail().qmbAuthoringCP().setEnabled(true);				
  			}
  			
  			form.ctnDetail().cmbActivity().setEnabled(true);
  			form.ctnDetail().cmbCategory().setEnabled(true);
  			form.ctnDetail().cmbGroup().setEnabled(true);
  			form.ctnDetail().cmbIndependence().setEnabled(true);
  			form.ctnDetail().cmbLocation().setEnabled(true);
  			form.ctnDetail().cmbPurpose().setEnabled(true);
  			form.ctnDetail().cmbTypes().setEnabled(true);
  			form.ctnDetail().grdEnvironment().setReadOnly(false);
  			form.ctnDetail().grdEquipment().setReadOnly(false);
  			form.ctnDetail().grdTechnique().setReadOnly(false);			
  		}
  		enableDetailsButtons();
  	}	
  	/**
  	 * Set's the visibility of the OK and Cancel buttons.
  	 * Essentially if we are adding a new child then we want to see both buttons
  	 * Otherwise we don't
  	 */
  	private void enableDetailsButtons()
  	{					
  		boolean boolVisible = (form.getMode().equals(FormMode.EDIT) &&
  							  form.getLocalContext().getSelectedChildInstance() == null);
  		
  		form.ctnDetail().btnOkActivity().setVisible(boolVisible);
  		form.ctnDetail().btnCancelActivity().setVisible(boolVisible);
  	}
  	private void updateContextMenusState()
  	{						
  		if (form.getGlobalContext().Core.getCurrentClinicalContactIsNotNull())
  		{
  			if(form.getLocalContext().getGoldenInstanceSelected().booleanValue())
  			{
  				// If the golden instance is currently selected we change the text of the update context menu
  				// based on whether a parent or child node is selected in the grid.
  				if (form.grdActivity().getValue() instanceof RehabilitationShortVo)
  					form.getContextMenus().getGenericGridUpdateItem().setVisible(false);						
  				else if (form.grdActivity().getValue() instanceof RehabilitationActivityVo)
  					form.getContextMenus().getGenericGridUpdateItem().setText("Edit Rehab Activity");
  				
  				// If the golden node is selected we can now only add child nodes so set the menu text accordingly.
  				form.getContextMenus().getGenericGridAddItem().setText("Add Rehab Activity");			
  	
  				// Only show the update menu if the user has selected an item to update.
  				form.getContextMenus().getGenericGridUpdateItem().setVisible((form.getMode().equals(FormMode.VIEW)&& 
  																			 form.grdActivity().getSelectedRowIndex()>=0) &&
  																			 form.grdActivity().getValue() instanceof RehabilitationActivityVo ||
  																			 (form.getMode().equals(FormMode.EDIT) &&
  																			 form.grdActivity().getValue() instanceof RehabilitationActivityVo &&
  																			 ((RehabilitationActivityVo)form.grdActivity().getValue()).getID_RehabilitationActivity() == null));																								
  			}
  			else
  			{
  				// If the golden instance has been found but NOT selected hide the context menu's 
  				if (form.getLocalContext().getGoldenInstanceFound().booleanValue() == true)
  				{
  					form.getContextMenus().hideAllGenericGridMenuItems();
  					return;
  				}
  				else
  				{
  					form.getContextMenus().getGenericGridAddItem().setText("New Rehabilitation");
  					form.getContextMenus().getGenericGridUpdateItem().setVisible(false);				
  				}
  			}
  			
  			form.getContextMenus().getGenericGridAddItem().setVisible(form.getMode().equals(FormMode.VIEW));
  			form.getContextMenus().getGenericGridRemoveItem().setVisible(form.getMode().equals(FormMode.EDIT) &&
  					 form.grdActivity().getValue() instanceof RehabilitationActivityVo &&
  					 ((RehabilitationActivityVo)form.grdActivity().getValue()).getID_RehabilitationActivity() == null);
  		}
  		else
  		{
  			form.getContextMenus().hideAllGenericGridMenuItems();
  		}
  	}
  
  	private void newChildInstance() 
  	{
  		clearChildInstanceControls();
  		form.getLocalContext().setSelectedChildInstance(null);
  		loadEquipment();
  		loadAdaptation();
  		loadTechnique();
  		if (form.grdActivity().getValue() instanceof RehabilitationShortVo)
  			form.grdActivity().setValue(form.grdActivity().getSelectedRow().getValue());
  		else if (form.grdActivity().getValue() instanceof RehabilitationActivityVo)
  			form.grdActivity().setValue(form.grdActivity().getSelectedRow().getParentRow().getValue());
  			
  	}	
  	private void promoteUpdatedChild(RehabilitationActivityVo voRehabActivity) 
  	{
  		if (voRehabActivity == null) return;
  		populateChildNode(form.grdActivity().getSelectedRow(),voRehabActivity);		
  	}
  	private void populateParentInstanceData(RehabilitationVo voRehab) 
  	{
  		voRehab.setAuthoringCP(form.ctnDetail().qmbAuthoringCP().getValue());
  		voRehab.setAuthoringDateTime(form.ctnDetail().dtimAuthoring().getValue());	
  	}
  	private void populateChildInstanceData(RehabilitationActivityVo voRehabActivity) 
  	{
  		voRehabActivity.setActivity(form.ctnDetail().cmbActivity().getValue());
  		voRehabActivity.setActivityCategory(form.ctnDetail().cmbCategory().getValue());
  		voRehabActivity.setActivityGroup(form.ctnDetail().cmbGroup().getValue());
  		voRehabActivity.setActivityType(form.ctnDetail().cmbTypes().getValue());
  		
  		RehabEnvAdaptationCollection voCollAdpt = new RehabEnvAdaptationCollection();
  		RehabEquipmentCollection voCollEquip = new RehabEquipmentCollection();
  		RehabTechniqueCollection voCollTech = new RehabTechniqueCollection();
  		
  		//adaptations
  		if (form.ctnDetail().grdEnvironment().getRows() != null)
  		{
  			
  	
  			for(int i = 0 ; i < form.ctnDetail().grdEnvironment().getRows().size(); i++)
  			{
  				if (form.ctnDetail().grdEnvironment().getRows().get(i).getColSelect())
  					voCollAdpt.add(form.ctnDetail().grdEnvironment().getRows().get(i).getValue());
  			}
  			if (voCollAdpt.size() > 0)
  				voRehabActivity.setEnvAdaptations(voCollAdpt);
  			else
  				voRehabActivity.setEnvAdaptations(null);					
  		}
  		
  		//equipment
  		if (form.ctnDetail().grdEquipment().getRows() != null)
  		{
  			for(int i = 0 ; i < form.ctnDetail().grdEquipment().getRows().size(); i++)
  			{
  				if (form.ctnDetail().grdEquipment().getRows().get(i).getColSelect())
  					voCollEquip.add(form.ctnDetail().grdEquipment().getRows().get(i).getValue());
  			}
  			if (voCollEquip.size() > 0)
  				voRehabActivity.setEquipment(voCollEquip);
  			else
  				voRehabActivity.setEquipment(null);					
  		}
  		
  		//Technique
  		if (form.ctnDetail().grdTechnique().getRows() != null)
  		{
  			
  	
  			for(int i = 0 ; i < form.ctnDetail().grdTechnique().getRows().size(); i++)
  			{
  				if (form.ctnDetail().grdTechnique().getRows().get(i).getColSelect())
  					voCollTech.add(form.ctnDetail().grdTechnique().getRows().get(i).getValue());
  			}
  			if (voCollTech.size() > 0)
  				voRehabActivity.setTechnique(voCollTech);
  			else
  				voRehabActivity.setTechnique(null);					
  		}
  		
  		voRehabActivity.setIndependenceLevel(form.ctnDetail().cmbIndependence().getValue());		
  		voRehabActivity.setLocation(form.ctnDetail().cmbLocation().getValue());
  		voRehabActivity.setPurpose(form.ctnDetail().cmbPurpose().getValue());
  				
  	}
  
  	private boolean newParentNode(RehabilitationVo voNewParent) 
  	{
  		if (voNewParent == null) return true;
  		
  		RehabilitationShortVo voParentShort = new RehabilitationShortVo();
  		voParentShort.setAuthoringCP(form.ctnDetail().qmbAuthoringCP().getValue());
  		voParentShort.setAuthoringDateTime(form.ctnDetail().dtimAuthoring().getValue());
  		voParentShort.setClinicalContact(voNewParent.getClinicalContact());
  		
  		String[] errors = voParentShort.validate();
  		
  		if(errors != null && errors.length > 0)
  		{
  			engine.showErrors(errors);
  			return false;
  		}
  		
  		GenForm.grdActivityRow parentRow = form.grdActivity().getRows().newRow();	
  		StringBuffer text =  new StringBuffer();
  		if(voParentShort.getAuthoringDateTime()!=null){
  			text.append(voParentShort.getAuthoringDateTime().toString());
  			text.append(" ");
  		}
  		if(voParentShort.getAuthoringCP()!=null)
  			text.append(voParentShort.getAuthoringCP().toString());
  		parentRow.setColDateTime(text.toString());			
  		parentRow.setValue(voParentShort);
  		parentRow.setBackColor(Color.Beige);
  		form.getLocalContext().setGoldenInstanceSelected(new Boolean(true));
  		parentRow.setExpanded(true);
  		form.grdActivity().setValue(voParentShort);	
  		
  		return true;
  	}
  	
  	protected void onBtnCancelActivityClick() throws ims.framework.exceptions.PresentationLogicException
  	{
  		clearChildInstanceControls();
  		newChildInstance();
  	}
  	
  	protected void onBtnCancelClick() throws ims.framework.exceptions.PresentationLogicException
  	{
  		open();
  	}
  	
  	protected void onBtnSaveClick() throws ims.framework.exceptions.PresentationLogicException
  	{
  		if (save())
  			open();					
  	}
  	/**
  	 * Invoked as part of the save routine. The user may have entered data in the details tab and not 
  	 * bothered clicking ok. This method counts thae vo fields to decide if it should promote the unsaved
       * data entry to the hierarchy grid before saving.	 	
  	 **/ 
  	private boolean checkForUnsavedChild() 
  	{
  		if (form.getLocalContext().getSelectedChildInstance() == null)
  		{				
  			if(addOrUpdateNotSavedChild())
  				return true;
  		}
  		return false;
  	}
  	public String[] validateUIRules()
  	{
  		return null;
  	}
  	private boolean save() 
  	{				
  		if (form.grdActivity().getValue() == null) {
  			engine.showMessage("Add Rehab Activity to grid.");
  			return false;
  		}
  		
  		if(checkForUnsavedChild())
  			return false;
  							
  		RehabilitationVo voRehab  = populateInstanceData(form.getLocalContext().getSelectedParentInstance());
  		
  		if (voRehab.getClinicalContact() == null)
  			voRehab.setClinicalContact(form.getGlobalContext().Core.getCurrentClinicalContact());
  				
  		String[] arrErrors =  voRehab.validate(validateUIRules());	
  		
  		if(arrErrors != null)
  		{
  			engine.showErrors(arrErrors);
  			return false;
  		}
  		
  		try
  		{
  			form.getLocalContext().setSelectedParentInstance(domain.saveRehabVo(voRehab));
  			
  		}
  		catch(StaleObjectException e)
  		{
  			engine.showMessage(ims.configuration.gen.ConfigFlag.UI.STALE_OBJECT_MESSAGE.getValue());
  			open();
  			return false;
  		} 
  		catch (UniqueKeyViolationException e) 
  		{
  			engine.showMessage("A Rehab record already exists for this SOAP clinical contact. " + e.getMessage());
  			open();
  			return false;
  		}
  		
  		setUpdatedChild();
  		return true;		
  	}
  	// We need to store the node which was last updated
  	private void setUpdatedChild() 
  	{
  		// Straight child update - Select the currently being updated child as the one so show - post save
  		if (form.grdActivity().getValue() instanceof RehabilitationActivityVo)		
  		{
  			form.getLocalContext().setUpdatedChild((RehabilitationActivityVo) form.grdActivity().getValue());
  		}
  		else
  		{
  			// Find the most recently added child
  			if (form.getLocalContext().getUpdatingParent().equals(Boolean.FALSE))
  			{
  				form.getLocalContext().getSelectedParentInstance().getRehabActivity().sort();
  				form.getLocalContext().setUpdatedChild(
  						form.getLocalContext().getSelectedParentInstance().getRehabActivity().get(
  								form.getLocalContext().getSelectedParentInstance().getRehabActivity().size() - 1));
  			}
  			
  		}
  	}
  	private RehabilitationVo populateInstanceData(RehabilitationVo voRehab)
  	{
  
  		if (voRehab == null)
  			voRehab = new RehabilitationVo();
  				
  		populateParentInstanceData(voRehab);						
  
  		if (form.getLocalContext().getSelectedChildInstance() == null)
  		{
  			populateChildCollectionFromGrid(voRehab);			
  		}
  		else 		// Update child instance.
  		{
  			RehabilitationActivityVo voRehabActivity = form.getLocalContext().getSelectedChildInstance();
  			populateChildInstanceData(voRehabActivity);
  			form.getLocalContext().setSelectedChildInstance(voRehabActivity);
  			
  