import AquaCrop # We can't use Length{Float64} as that is a Union type const Tlength = typeof(1.0cm) struct AquaCropType name::String group::String minsowdate::Union{Missing,AnnualDate} maxsowdate::Union{Missing,AnnualDate} end cropname(ct::AquaCropType) = ct.name mutable struct AquaCropState croptype::AquaCropType height::Length{Float64} # TODO: remove height field, supply from cropstate cropstate::AquaCrop.AquaCropField function AquaCropState(croptype::AquaCropType, height::Length{Float64}=0.0cm) runtype = AquaCrop.TomlFileRun() parentdir = AquaCrop.test_toml_dir # TODO: hardcoded croptype ac_cropfield, all_ok = AquaCrop.start_cropfield(; parentdir, runtype) if ! all_ok.logi error("AquaCrop.start_cropfield() failed, status = $all_ok") end AquaCrop.setup_cropfield!(ac_cropfield, all_ok; runtype=runtype) if ! all_ok.logi error("AquaCrop.setup_cropfield!() failed, status = $all_ok") end return new(croptype, height, ac_cropfield) end end croptype(cs::AquaCropState) = cs.croptype cropname(cs::AquaCropState) = cropname(croptype(cs)) cropheight(cs::AquaCropState) = cs.height # TODO: use AquaCrop state info cropcover(cs::AquaCropState) = AquaCrop.canopycover(cs.cropstate) cropyield(cs::AquaCropState) = AquaCrop.dryyield(cs.cropstate) # TODO: there is also freshyield isharvestable(cs::AquaCropState) = true # TODO: implement this correctly """ stepagent!(cropstate, model) Update a crop state by one day. """ function stepagent!(cs::AquaCropState, model::SimulationModel) AquaCrop.dailyupdate!(cs.cropstate) end """ sow!(cropstate, model, cropname) Change the cropstate to sow the specified crop. """ function sow!(cs::AquaCropState, model::SimulationModel, cropname::String) cs.croptype = model.crops[cropname] cs.height = 0.0cm # TODO: other things needed for AquaCrop? end """ harvest!(cropstate, model) Harvest the crop of this cropstate. """ function harvest!(cs::AquaCropState, model::SimulationModel) # TODO: implement this return 0.0u"g/m^2" end