package gov.nasa.arc.mct.scenario.component;

import gov.nasa.arc.mct.components.AbstractComponent;
import gov.nasa.arc.mct.components.JAXBModelStatePersistence;
import gov.nasa.arc.mct.components.ModelStatePersistence;
import gov.nasa.arc.mct.components.PropertyDescriptor;
import gov.nasa.arc.mct.components.PropertyDescriptor.VisualControlDescriptor;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Represents an Decision user object.
 * 
 * Decisions have start and end times, which should fill the gap between two other 
 * Activity siblings. A Decision represents some external consideration/evaluation 
 * which must be performed within a certain time before a timeline proceeds.  
 *
 */
public class DecisionComponent extends AbstractComponent implements DurationCapability {

	private final AtomicReference<DecisionModelRole> model = new AtomicReference<DecisionModelRole>(new DecisionModelRole());
	
	public DecisionData getData() {
		return getModel().getData();
	}
	
	public String getDisplay(){
		return this.getDisplayName();
	}
	
	@Override
	protected <T> T handleGetCapability(Class<T> capability) {
		// Note: Don't report self as capability until initialized.
		if (capability.isAssignableFrom(getClass()) && getData().getEndTime() != null) {
			return capability.cast(this);
		}
		if (capability.isAssignableFrom(ModelStatePersistence.class)) {
		    JAXBModelStatePersistence<DecisionModelRole> persistence = new JAXBModelStatePersistence<DecisionModelRole>() {

				@Override
				protected DecisionModelRole getStateToPersist() {
					return model.get();
				}

				@Override
				protected void setPersistentState(DecisionModelRole modelState) {
					model.set(modelState);
				}

				@Override
				protected Class<DecisionModelRole> getJAXBClass() {
					return DecisionModelRole.class;
				}
		        
			};
			
			return capability.cast(persistence);
		}
		return null;
	}
	
	public DecisionModelRole getModel() {
		return model.get();
	}

	@Override
	public List<PropertyDescriptor> getFieldDescriptors()  {

		// Provide an ordered list of fields to be included in the MCT Platform's InfoView.
		List<PropertyDescriptor> fields = new ArrayList<PropertyDescriptor>();


		// Describe MyData's field "doubleData". 
		// We specify a mutable text field.  The control display's values are maintained in the business model
		// via the PropertyEditor object.  When a new value is to be set, the editor also validates the prospective value.
		PropertyDescriptor startTime = new PropertyDescriptor("Start Time", 
				new DecisionStartTimePropertyEditor(this),  VisualControlDescriptor.TextField);
		startTime.setFieldMutable(true);
		PropertyDescriptor endTime = new PropertyDescriptor("End Time", 
				new DecisionEndTimePropertyEditor(this),  VisualControlDescriptor.TextField);
		endTime.setFieldMutable(true);

		fields.add(startTime);
		fields.add(endTime);

		return fields;
	}

	@Override
	public long getStart() {
		return getData().getStartTime().getTime();
	}

	@Override
	public long getEnd() {
		return getData().getEndTime().getTime();
	}

	@Override
	public void setStart(long start) {
		getData().setStartDate(new Date(start));
		save();
	}

	@Override
	public void setEnd(long end) {
		getData().setEndDate(new Date(end));
		save();
	}

	@Override
	public boolean isLeaf() {
		return true;
	}

}
@@ -996,103 +996,145 @@
 %0A%09%0A%09
-public DecisionData getData() %7B%0A%09%09return getModel().getData();%0A%09%7D%0A%09%0A%09public String getDisplay
+/**%0A%09 * Get underlying data about this decision (specifically,%0A%09 * start and end times.)%0A%09 * @return%0A%09 */%0A%09public DecisionData getData
 ()
+ 
 %7B%0A%09%09
@@ -1144,27 +1144,26 @@
 urn 
-this.getDisplayName
+getModel().getData
 ();%0A
@@ -2022,16 +2022,176 @@
 l;%0A%09%7D%0A%09%0A
+%09/**%0A%09 * Get a container for internal data about this decision%0A%09 * (specifically, its start and end times.)%0A%09 * @return contained data about this decision%0A%09 */%0A
 %09public 
@@ -2481,51 +2481,8 @@
 );%0A%0A
-%0A%09%09// Describe MyData's field %22doubleData%22.
  %0A%09%09
@@ -3564,14 +3564,79 @@
 rn true;
+ // Decisions should never have children in the user object graph
 %0A%09%7D%0A%0A%7D

Clean up code & add comments for DecisionComponent