/*
 *       File name:  cnrun/types.hh
 *         Project:  cnrun
 *          Author:  Andrei Zavada <johnhommer@gmail.com>
 *                   building on original work by Thomas Nowotny <tnowotny@ucsd.edu>
 * Initial version:  2008-08-02
 *
 *         Purpose:  Enumerated type for unit ids, and a structure describing a unit type.
 *
 *         License:  GPL-2+
 */

//#define CN_WANT_MORE_NEURONS

#ifndef CNRUN_LIBCN_TYPES_H_
#define CNRUN_LIBCN_TYPES_H_

#if HAVE_CONFIG_H && !defined(VERSION)
#  include "config.h"
#endif

using namespace std;

namespace cnrun {

enum TUnitType {
      // neuron types
        NT_VOID = -1,

        NT_HH_D,
        NT_HH_R,
        NT_HH2_D,
        NT_HH2_R,
//#ifdef CN_WANT_MORE_NEURONS
        NT_EC_D,
        NT_ECA_D,
//#endif
        NT_DOTPOISSON,
        NT_POISSON,
//#ifdef CN_WANT_MORE_NEURONS
//        NT_LV,
        NT_COLPITTS,
        NT_VDPOL,
//#endif
        NT_DOTPULSE,
        NT_MAP,

      // synapse types
        YT_AB_DD,
        YT_AB_DR,
        YT_AB_RD,
        YT_AB_RR,
        YT_MXAB_DD,
        YT_MXAB_DR,

        YT_ABMINUS_DD,
        YT_ABMINUS_DR,
        YT_ABMINUS_RD,
        YT_ABMINUS_RR,
        YT_MXABMINUS_DD,
        YT_MXABMINUS_DR,

        YT_RALL_DD,
        YT_RALL_DR,
        YT_RALL_RD,
        YT_RALL_RR,
        YT_MXRALL_DD,
        YT_MXRALL_DR,

        YT_MAP,
        YT_MXMAP,
};

#define NT_FIRST NT_HH_D
#define NT_LAST  NT_MAP
#define YT_FIRST YT_AB_DD
#define YT_LAST  YT_MXMAP



// traits, used to ensure units being connected are compatible
#define UT_HOSTED        (1 << 0)
#define UT_DDTSET        (1 << 1)
#define UT_OSCILLATOR    (1 << 2)
#define UT_RATEBASED     (1 << 3)
#define UT_SRCISRATE     UT_RATEBASED
#define UT_TGTISRATE     (1 << 4)
#define UT_DOT           (1 << 5)
#define UT_MULTIPLEXING  UT_DOT
#define UT__STUB         (1 << 15)

struct SCNDescriptor {
        int     traits;
        unsigned short
                pno, vno;
        const double *const  stock_param_values;
        const char   *const *stock_param_names;
        const char   *const *stock_param_syms;
        const double *const  stock_var_values;
        const char   *const *stock_var_names;
        const char   *const *stock_var_syms;
        const char   *family,
                     *species;
        const char   *description;
};

TUnitType unit_family_by_string( const string&) __attribute__ ((pure));
TUnitType unit_species_by_string( const string&) __attribute__ ((pure));

inline bool
unit_species_is_valid( const string& id)
{
        return unit_species_by_string(id) != NT_VOID;
}
inline bool
unit_species_is_neuron( const string& id)
{
        TUnitType t = unit_species_by_string(id);
        return t >= NT_FIRST && t <= NT_LAST;
}

inline bool
unit_species_is_synapse( const string& id)
{
        TUnitType t = unit_species_by_string(id);
        return t >= YT_FIRST && t <= YT_LAST;
}

inline bool
unit_family_is_neuron( const string& id)
{
        TUnitType t = unit_family_by_string(id);
        return t >= NT_FIRST && t <= NT_LAST;
}

inline bool
unit_family_is_synapse( const string& id)
{
        TUnitType t = unit_family_by_string(id);
        return t >= YT_FIRST && t <= YT_LAST;
}

extern SCNDescriptor __CNUDT[];

void cnmodel_dump_available_units();



extern const double CN_Params_NeuronHH_d[];
extern const char* const CN_ParamNames_NeuronHH_d[];
extern const char* const CN_ParamSyms_NeuronHH_d[];
extern const double CN_Vars_NeuronHH_d[];
extern const char* const CN_VarNames_NeuronHH_d[];
extern const char* const CN_VarSyms_NeuronHH_d[];

extern const double CN_Params_NeuronHH2_d[];
extern const char* const CN_ParamNames_NeuronHH2_d[];
extern const char* const CN_ParamSyms_NeuronHH2_d[];
extern const double CN_Vars_NeuronHH2_d[];


extern const double CN_Params_NeuronHH_r[];
extern const char* const CN_ParamNames_NeuronHH_r[];
extern const char* const CN_ParamSyms_NeuronHH_r[];
extern const double CN_Vars_NeuronHH_r[];
extern const char* const CN_VarNames_NeuronHH_r[];
extern const char* const CN_VarSyms_NeuronHH_r[];


extern const double CN_Params_NeuronDotPulse[];
extern const char* const CN_ParamNames_NeuronDotPulse[];
extern const char* const CN_ParamSyms_NeuronDotPulse[];
extern const double CN_Vars_NeuronDotPulse[];
extern const char* const CN_VarNames_NeuronDotPulse[];
extern const char* const CN_VarSyms_NeuronDotPulse[];


//#ifdef CN_WANT_MORE_NEURONS
extern const double CN_Params_NeuronEC_d[];
extern const char* const CN_ParamNames_NeuronEC_d[];
extern const char* const CN_ParamSyms_NeuronEC_d[];
extern const double CN_Vars_NeuronEC_d[];
extern const char* const CN_VarNames_NeuronEC_d[];
extern const char* const CN_VarSyms_NeuronEC_d[];


extern const double CN_Params_NeuronECA_d[];
extern const char* const CN_ParamNames_NeuronECA_d[];
extern const char* const CN_ParamSyms_NeuronECA_d[];
extern const double CN_Vars_NeuronECA_d[];
extern const char* const CN_VarNames_NeuronECA_d[];
extern const char* const CN_VarSyms_NeuronECA_d[];
//#endif

extern const double CN_Params_NeuronMap[];
extern const char* const CN_ParamNames_NeuronMap[];
extern const char* const CN_ParamSyms_NeuronMap[];
extern const double CN_Vars_NeuronMap[];
extern const char* const CN_VarNames_NeuronMap[];
extern const char* const CN_VarSyms_NeuronMap[];


extern const double CN_Params_OscillatorPoissonDot[];
extern const char* const CN_ParamNames_OscillatorPoissonDot[];
extern const char* const CN_ParamSyms_OscillatorPoissonDot[];
extern const double CN_Vars_OscillatorPoissonDot[];
extern const char* const CN_VarNames_OscillatorPoissonDot[];
extern const char* const CN_VarSyms_OscillatorPoissonDot[];

extern const double CN_Params_OscillatorPoisson[];
extern const char* const CN_ParamNames_OscillatorPoisson[];
extern const char* const CN_ParamSyms_OscillatorPoisson[];
extern const double CN_Vars_OscillatorPoisson[];
extern const char* const CN_VarNames_OscillatorPoisson[];
extern const char* const CN_VarSyms_OscillatorPoisson[];


/*
extern const double CN_Params_OscillatorLV[];
extern const char* const CN_ParamNames_OscillatorLV[];
extern const char* const CN_ParamSyms_OscillatorLV[];
extern const double CN_Vars_OscillatorLV[];
extern const char* const CN_VarNames_OscillatorLV[];
extern const char* const CN_VarSyms_OscillatorLV[];
*/

extern const double CN_Params_OscillatorColpitts[];
extern const char* const CN_ParamNames_OscillatorColpitts[];
extern const char* const CN_ParamSyms_OscillatorColpitts[];
extern const double CN_Vars_OscillatorColpitts[];
extern const char* const CN_VarNames_OscillatorColpitts[];
extern const char* const CN_VarSyms_OscillatorColpitts[];


extern const double CN_Params_OscillatorVdPol[];
extern const char* const CN_ParamNames_OscillatorVdPol[];
extern const char* const CN_ParamSyms_OscillatorVdPol[];
extern const double CN_Vars_OscillatorVdPol[];
extern const char* const CN_VarNames_OscillatorVdPol[];
extern const char* const CN_VarSyms_OscillatorVdPol[];
//#endif



extern const double CN_Params_SynapseAB_dd[];
extern const char* const CN_ParamNames_SynapseAB_dd[];
extern const char* const CN_ParamSyms_SynapseAB_dd[];
extern const double CN_Vars_SynapseAB[];
extern const char* const CN_VarNames_SynapseAB[];
extern const char* const CN_VarSyms_SynapseAB[];

extern const double CN_Params_SynapseABMinus_dd[];

extern const double CN_Params_SynapseMxAB_dd[];

extern const char* const CN_ParamNames_SynapseAB_dr[];
extern const char* const CN_ParamSyms_SynapseAB_dr[];

extern const double CN_Params_SynapseMxAB_dr[];

extern const double CN_Params_SynapseAB_rr[];
extern const char* const CN_ParamNames_SynapseAB_rr[];
extern const char* const CN_ParamSyms_SynapseAB_rr[];


extern const double CN_Params_SynapseRall_dd[];
extern const char* const CN_ParamNames_SynapseRall_dd[];
extern const char* const CN_ParamSyms_SynapseRall_dd[];
extern const double CN_Vars_SynapseRall[];
extern const char* const CN_VarNames_SynapseRall[];
extern const char* const CN_VarSyms_SynapseRall[];


extern const double CN_Params_SynapseMap[];
extern const char* const CN_ParamNames_SynapseMap[];
extern const char* const CN_ParamSyms_SynapseMap[];

#define CN_PU_CONDUCTANCE "μS/cm²"
#define CN_PU_RESISTANCE "MΩ"
#define CN_PU_POTENTIAL "mV"
#define CN_PU_VOLTAGE "mV"
#define CN_PU_CURRENT "nA"
#define CN_PU_CAPACITY_DENSITY "μF/cm²"
#define CN_PU_TIME "msec"
#define CN_PU_TIME_MSEC "msec"
#define CN_PU_RATE "1/msec"
#define CN_PU_FREQUENCY "Hz"
#define CN_PU_TIME_SEC "sec"

}
#endif

// Local Variables:
// Mode: c++
// indent-tabs-mode: nil
// tab-width: 8
// c-basic-offset: 8
// End:
