// define class name and unique id
#define MODEL_IDENTIFIER Sum
#define MODEL_GUID "{1c302156-9f89-4e47-989e-82f4cd9069f8}"

// include fmu header files, typedefs and macros
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "openmodelica.h"
#include "openmodelica_func.h"
#include "simulation_data.h"
#include "util/omc_error.h"
#include "Sum_functions.h"
#include "simulation/solver/initialization/initialization.h"
#include "simulation/solver/events.h"
#include "fmu2_model_interface.h"

#ifdef __cplusplus
extern "C" {
#endif

void setStartValues(ModelInstance *comp);
void setDefaultStartValues(ModelInstance *comp);
void eventUpdate(ModelInstance* comp, fmi2EventInfo* eventInfo);
fmi2Real getReal(ModelInstance* comp, const fmi2ValueReference vr);
fmi2Status setReal(ModelInstance* comp, const fmi2ValueReference vr, const fmi2Real value);
fmi2Integer getInteger(ModelInstance* comp, const fmi2ValueReference vr);
fmi2Status setInteger(ModelInstance* comp, const fmi2ValueReference vr, const fmi2Integer value);
fmi2Boolean getBoolean(ModelInstance* comp, const fmi2ValueReference vr);
fmi2Status setBoolean(ModelInstance* comp, const fmi2ValueReference vr, const fmi2Boolean value);
fmi2String getString(ModelInstance* comp, const fmi2ValueReference vr);
fmi2Status setString(ModelInstance* comp, const fmi2ValueReference vr, fmi2String value);
fmi2Status setExternalFunction(ModelInstance* c, const fmi2ValueReference vr, const void* value);

// define model size
#define NUMBER_OF_STATES 0
#define NUMBER_OF_EVENT_INDICATORS 0
#define NUMBER_OF_REALS 0
#define NUMBER_OF_INTEGERS 9
#define NUMBER_OF_STRINGS 0
#define NUMBER_OF_BOOLEANS 0
#define NUMBER_OF_EXTERNALFUNCTIONS 0

// define variable data for model
#define $Pu_vr 0 
#define $Pu1_vr 1 
#define $Py_vr 2 
#define $Psum1$Pk$lB1$rB_vr 3 // "Input gains"
#define $Psum1$Pk$lB2$rB_vr 4 // "Input gains"
#define $Psum1$Pnu_vr 5 // "Number of input connections"
#define $Psum1$Pu$lB1$rB_vr 6 // "Vector of Integer input signals"
#define $Psum1$Pu$lB2$rB_vr 7 // "Vector of Integer input signals"
#define $Psum1$Py_vr 8 // "Integer output signal"


// define initial state vector as vector of value references
#define STATES {  }
#define STATESDERIVATIVES {  }


// implementation of the Model Exchange functions
extern void Sum_setupDataStruc(DATA *data);
#define fmu2_model_interface_setupDataStruc Sum_setupDataStruc
#include "fmu2_model_interface.c"

// Set values for all variables that define a start value
void setDefaultStartValues(ModelInstance *comp) {
  comp->fmuData->modelData->integerVarsData[0].attribute.start = 0;
  comp->fmuData->modelData->integerVarsData[1].attribute.start = 0;
  comp->fmuData->modelData->integerVarsData[2].attribute.start = 0;
  comp->fmuData->modelData->integerParameterData[0].attribute.start = 1;
  comp->fmuData->modelData->integerParameterData[1].attribute.start = 1;
  comp->fmuData->modelData->integerParameterData[2].attribute.start = 2;
}
// Set values for all variables that define a start value
void setStartValues(ModelInstance *comp) {
  comp->fmuData->modelData->integerVarsData[0].attribute.start =  comp->fmuData->localData[0]->integerVars[0];
  comp->fmuData->modelData->integerVarsData[1].attribute.start =  comp->fmuData->localData[0]->integerVars[1];
  comp->fmuData->modelData->integerVarsData[2].attribute.start =  comp->fmuData->localData[0]->integerVars[2];
  comp->fmuData->modelData->integerParameterData[0].attribute.start = comp->fmuData->simulationInfo->integerParameter[0];
  comp->fmuData->modelData->integerParameterData[1].attribute.start = comp->fmuData->simulationInfo->integerParameter[1];
  comp->fmuData->modelData->integerParameterData[2].attribute.start = comp->fmuData->simulationInfo->integerParameter[2];
}

// Used to set the next time event, if any.
void eventUpdate(ModelInstance* comp, fmi2EventInfo* eventInfo) {
}

fmi2Real getReal(ModelInstance* comp, const fmi2ValueReference vr) {
  switch (vr) {
    default:
      return 0;
  }
}

fmi2Status setReal(ModelInstance* comp, const fmi2ValueReference vr, const fmi2Real value) {
  switch (vr) {
    default:
      return fmi2Error;
  }
  return fmi2OK;
}

fmi2Integer getInteger(ModelInstance* comp, const fmi2ValueReference vr) {
  switch (vr) {
    case $Pu_vr : return comp->fmuData->localData[0]->integerVars[0]; break;
    case $Pu1_vr : return comp->fmuData->localData[0]->integerVars[1]; break;
    case $Py_vr : return comp->fmuData->localData[0]->integerVars[2]; break;
    case $Psum1$Pk$lB1$rB_vr : return comp->fmuData->simulationInfo->integerParameter[0]; break;
    case $Psum1$Pk$lB2$rB_vr : return comp->fmuData->simulationInfo->integerParameter[1]; break;
    case $Psum1$Pnu_vr : return comp->fmuData->simulationInfo->integerParameter[2]; break;
    case $Psum1$Pu$lB1$rB_vr : return getInteger(comp, $Pu_vr); break;
    case $Psum1$Pu$lB2$rB_vr : return getInteger(comp, $Pu1_vr); break;
    case $Psum1$Py_vr : return getInteger(comp, $Py_vr); break;
    default:
      return 0;
  }
}
fmi2Status setInteger(ModelInstance* comp, const fmi2ValueReference vr, const fmi2Integer value) {
  switch (vr) {
    case $Pu_vr : comp->fmuData->localData[0]->integerVars[0] = value; break;
    case $Pu1_vr : comp->fmuData->localData[0]->integerVars[1] = value; break;
    case $Py_vr : comp->fmuData->localData[0]->integerVars[2] = value; break;
    case $Psum1$Pk$lB1$rB_vr : comp->fmuData->simulationInfo->integerParameter[0] = value; break;
    case $Psum1$Pk$lB2$rB_vr : comp->fmuData->simulationInfo->integerParameter[1] = value; break;
    case $Psum1$Pnu_vr : comp->fmuData->simulationInfo->integerParameter[2] = value; break;
    case $Psum1$Pu$lB1$rB_vr : return setInteger(comp, $Pu_vr, value); break;
    case $Psum1$Pu$lB2$rB_vr : return setInteger(comp, $Pu1_vr, value); break;
    case $Psum1$Py_vr : return setInteger(comp, $Py_vr, value); break;
    default:
      return fmi2Error;
  }
  return fmi2OK;
}
fmi2Boolean getBoolean(ModelInstance* comp, const fmi2ValueReference vr) {
  switch (vr) {
    default:
      return fmi2False;
  }
}

fmi2Status setBoolean(ModelInstance* comp, const fmi2ValueReference vr, const fmi2Boolean value) {
  switch (vr) {
    default:
      return fmi2Error;
  }
  return fmi2OK;
}

fmi2String getString(ModelInstance* comp, const fmi2ValueReference vr) {
  switch (vr) {
    default:
      return "";
  }
}

fmi2Status setString(ModelInstance* comp, const fmi2ValueReference vr, fmi2String value) {
  switch (vr) {
    default:
      return fmi2Error;
  }
  return fmi2OK;
}

fmi2Status setExternalFunction(ModelInstance* c, const fmi2ValueReference vr, const void* value){
  switch (vr) {
    default:
      return fmi2Error;
  }
  return fmi2OK;
}


#ifdef __cplusplus
}
#endif

