---
title: "extending-resources"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{extending-resources}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(plotly)
library(villager)
```

# Extending Resources
To create resources that have additional properties, subclass the `resource` class.

To add new members to the resource class,

1. Copy the _resource_ class source definition
2. Create the new member variable
3. Add it as a parameter to the `initialize` function
4. Make an entry for it in the `as_table` function

## Resource with an expiration date

To demonstrate how to subclass and run a model with a custom _resource_ class, consier an example of corn and rice resources that expire. To do this, a new variable is added to the resource class, `creation_date` which gets updated when the resource is created. When the model runs, the date at each time step is used to check against the creation date of each resource.

### Custom resource class

```{r}
resource_expiration <- R6::R6Class("resource",
  cloneable = TRUE,
  public = list(
    name = NA,
    quantity = NA,
    creation_date = NA,

    #' Creates a new resource.
    #'
    #' @description Creates a new resource object
    #' @param name The name of the resource
    #' @param quantity The quantity present
    #' @param creation_date The date that the resource was created
    initialize = function(name = NA, quantity = 0, creation_date=NA) {
      self$name <- name
      self$quantity <- quantity
      self$creation_date <- creation_date # New member variable to track the creation date
    },

    #' Returns a data.frame representation of the resource
    #'
    #' @return A data.frame of resources

    as_table = function() {
      return(data.frame(name = self$name, quantity = self$quantity))
    }
  )
)
```

### Initial Condition

The initial condition is a village that has two resource types, corn and rice.

``` {r}
initial_condition <- function(current_state, model_data, agent_mgr, resource_mgr) {
  for (i in 1:10) {
    name <- runif(1, 0.0, 100)
    new_agent <- agent$new(first_name <- name, last_name <- "Smith")
    agent_mgr$add_agent(new_agent)
  }
  # Create two new resources at the current date (The first day)
  corn <- resource_expiration$new("Corn", 10, current_state$step)
  rice <- resource_expiration$new("Rice", 20, current_state$step)
  resource_mgr$add_resource(corn)
  resource_mgr$add_resource(rice)
}
```

### Model

The model checks the current date against the expiration dates on each resource. When the threshold limits
are reached, the quantity is set to zero.

```{r}
# Create the model that, each day, checks to see whether or not any resource expire
model <- function(current_state, previous_state, model_data, agent_mgr, resource_mgr) {
  # Loop over all of the resources and check if any expire
  for (resource in resource_mgr$get_resources()) {
    # Figure out how many days have passed
    days_passed <- current_state$step - resource$creation_date
    if (resource$name == "Corn") {
      if (days_passed > 10 && resource$quantity > 0) {
        print("Setting Corn quantity to 0")
        resource$quantity <- 0
      }
    } else if (resource$name == "Rice" && resource$quantity > 0) {
      if (days_passed > 20) {
        print("Setting Rice quantity to 0")
        resource$quantity <- 0
      }
    }
  }
}
```

### Running

With the required model components complete, we can create a simulation that runs for 15 days. By the end of it, there should be no more corn left, and the rice stocks should still be full.
```{r}
# Create the village and simulation
coastal_village <- village$new("Expiring_Resources", initial_condition, model, resource_class=)
simulator <- simulation$new(16, villages = list(coastal_village))
simulator$run_model()
```

### Results
A timeseries of each resource type is plotted below. The _rice_ resource has clearly not expired while the _corn_ resource has after 10 days.

```{r}
# Load in data
time_series_data <- readr::read_csv("results/Expiring_Resources/resources.csv")

# Get unique dates
unique_step<- sort(unique(time_series_data$step))

# Get corn & rice quantities and dates
corn_date_quantities <- dplyr::filter(time_series_data, name=="Corn")
rice_date_quantities <- dplyr::filter(time_series_data, name=="Rice")

# create data frame for sorted data
reordered_time_series <- data.frame(step = unique_step, Corn = 0, Rice = 0)
for (i in 1:nrow(reordered_time_series)){
  reordered_time_series[i,2] = corn_date_quantities[which(corn_date_quantities$step == reordered_time_series$step[i]),2]
  reordered_time_series[i,3] = rice_date_quantities[which(rice_date_quantities$step == reordered_time_series$step[i]),2]
}

# Plot graph
plotly::plot_ly(reordered_time_series, x = ~step) %>% 
  plotly::add_trace(y = ~Corn, name = 'Corn', type = 'scatter', mode = 'lines') %>% 
  plotly::add_trace(y = ~Rice, name = 'Rice', type = 'scatter', mode = 'lines') %>%
  plotly::layout(title = 'Resource Counts', xaxis = list(title = 'Time Step'),
       yaxis = list(title = 'Quantity'), legend = list(title=list(text='Crop Type')))
```
