#ifndef MAT_USER_STRUCTS_GPU_H_
#define MAT_USER_STRUCTS_GPU_H_

#include <string>
#include <cstring>
#include <cuda_runtime_api.h>

class ContourMap
{
  public:
    ContourMap() = default;

    ContourMap(int id, std::string str) : id(id) {
        set_id(id);
        set_name(str);
    }

    void set_id(int id) {
        this->id = id;
    }

    void set_name(std::string str) {
        if (str.length() <= 40) {
            std::strncpy(this->name, str.c_str(), 40);
        }
    }

    int id;
    char name[40];
};

class UserMatConfig
{
  public:
    UserMatConfig() {
        gpu_enabled = false;
        num_hist = 0;
        pos_epsp = 0;
        pos_temp = 0;
        pos_texture = 0;
        pos_damage = -1;
        erode_flag = 0;
        pos_erode_flag = -1;

        for (int i = 0 ; i < 50 ; ++i) {
            curve[i] = -1;
            contour[i].id = -1;
        }
    }

    bool gpu_enabled;
    int num_hist;
    int pos_epsp;
    int pos_temp;
    int pos_texture;
    int pos_damage;
    int erode_flag;
    int pos_erode_flag;

    int curve[50];
    ContourMap contour[50];
};

class UserMatProp
{
  public:
    UserMatProp() {
        stiffness = 0;
        pos_epsp = -1;
        pos_depsp = -1;
        pos_rate = -1;
        pos_temp = -1;
        pos_evol = -1;
        pos_damage1 = -1;
        pos_damage2 = -1;
        pos_damage_active = -1;
    }

    int stiffness;
    int pos_epsp;
    int pos_depsp;
    int pos_rate;
    int pos_temp;
    int pos_evol;
    int pos_damage1;
    int pos_damage2;
    int pos_damage_active;
};

struct UserMatDevice {
    int* dp_internal_fail;
    int* dp_eroded;
    int* dp_curve_data;
    double* dp_curve_val;
    double* dp_strain;
    double* dp_dstrain;
    double* dp_stress;
    double* dp_f_mat;
    double* dp_u_mat;
    double* dp_init_volume;
    double* dp_volume;
    double* dp_history;
    double* dp_eos_pressure;
    double* dp_cmat; // Reserved, not used
    double* dp_shear;
    double* dp_bulk;
    double* dp_xi;
    double* dp_bfac;
    int eos;
    int num_history;
    int num_ip;
    size_t num_tasks;
    size_t stride;
    double dt0;
    double dt;
    double tt;
};

struct UserMatHost {
    double* p_cmat;
};

#endif // MAT_USER_STRUCTS_GPU_H_
