package divconq.db.update;

import org.joda.time.DateTime;

import divconq.db.IDatabaseManager;
import divconq.lang.BigDateTime;
import divconq.struct.FieldStruct;
import divconq.struct.RecordStruct;
import divconq.struct.Struct;

/**
 * Use this field to update DynamicScalar structures in dcDatabase.
 * 
 * @author Andy
 *
 */
public class DynamicScalarField extends ListField {
	protected BigDateTime from = null;
	
	/**
	 * @return when this value became valid
	 */
	public BigDateTime getWhen() {
		return this.from;
	}
	
	/**
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param value of field
	 * @param from date data became valid (null if unknown, or if from beginning of record's life)
	 * @param tags meta data for the field (alphanumeric and ':' are allowed in tag)
	 */
	public DynamicScalarField(String name, String subkey, Object value, BigDateTime from, FieldTags tags) {
		super(name, subkey, value, tags);
		this.from = from;
	}
	
	/**
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param value of field
	 * @param from date data became valid (null if unknown, or if from beginning of record's life)
	 * @param tags meta data for the field (alphanumeric and ':' are allowed in tag)
	 */
	public DynamicScalarField(String name, String subkey, Object value, DateTime from, FieldTags tags) {
		super(name, subkey, value, tags);
		this.from = (from != null) ? new BigDateTime(from) : null;
	}
	
	/**
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param value of field
	 * @param from date data became valid (null if unknown, or if from beginning of record's life)
	 */
	public DynamicScalarField(String name, String subkey, Object value, BigDateTime from) {
		super(name, subkey, value);
		this.from = from;
	}
	
	/**
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param value of field
	 * @param from date data became valid (null if unknown, or if from beginning of record's life)
	 */
	public DynamicScalarField(String name, String subkey, Object value, DateTime from) {
		super(name, subkey, value);
		this.from = (from != null) ? new BigDateTime(from) : null;
	}
	
	/**
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param value of field
	 * @param tags meta data for the field (alphanumeric and ':' are allowed in tag)
	 */
	public DynamicScalarField(String name, String subkey, Object value, FieldTags tags) {
		super(name, subkey, value, tags);
	}
	
	/**
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param value of field
	 */
	public DynamicScalarField(String name, String subkey, Object value) {
		super(name, subkey, value);
	}
	
	/**
	 * Mark a field as Retired.
	 * 
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param from date data became valid (null if unknown, or if from beginning of record's life)
	 * @param tags meta data for the field (alphanumeric and ':' are allowed in tag)
	 */
	public DynamicScalarField(String name, String subkey, FieldTags tags) {
		super(name, subkey, tags);
	}
	
	/**
	 * Mark a field as Retired.
	 * 
	 * @param name of field
	 * @param subkey id for this item in the list (leave null to assign new id)
	 * @param from date data became valid (null if unknown, or if from beginning of record's life)
	 */
	public DynamicScalarField(String name, String subkey) {
		super(name, subkey);
	}

	/* (non-Javadoc)
	 * @see divconq.db.update.ListField#convert(divconq.struct.RecordStruct, divconq.db.IDatabaseManager)
	 */
	@Override
	public Struct convert(RecordStruct fields, IDatabaseManager dbm) {
		RecordStruct data = new RecordStruct( 
				new FieldStruct("Data", dbm.convertValue(this.value).getResult())
		);
		
		if (this.tags != null)
			data.setField("Tags", this.tags);
		
		if (this.retired)
			data.setField("Retired", true);
		
		if (this.from != null) 
			data.setField("From", this.from);
		
		Struct ff = (fields != null) ? fields.getField(this.name) : null;
		
		// create a new one if needed, add to existing otherwise
		RecordStruct ret = (ff instanceof RecordStruct) ? (RecordStruct)ff : new RecordStruct();

		ret.setField(this.subkey, data);		
		
		return ret;
	}
}
