/*
 *       File name:  libcn/base-synapse.hh
 *         Project:  cnrun
 *          Author:  Andrei Zavada <johnhommer@gmail.com>
 *                   building on original work by Thomas Nowotny <tnowotny@ucsd.edu>
 * Initial version:  2009-03-31
 *
 *         Purpose:  synapse base class
 *
 *         License:  GPL-2+
 */

#ifndef CNRUN_LIBCN_BASESYNAPSE_H_
#define CNRUN_LIBCN_BASESYNAPSE_H_

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

#include <cmath>
#include <vector>
#include <list>
#include <map>

#include "libstilton/lang.hh"
#include "libstilton/containers.hh"
#include "forward-decls.hh"
#include "base-unit.hh"


using namespace std;

namespace cnrun {

class C_BaseSynapse
  : public C_BaseUnit {

        DELETE_DEFAULT_METHODS (C_BaseSynapse)

        friend class CModel;
        friend class C_BaseNeuron;

    protected:
        C_BaseSynapse( TUnitType intype,
                       C_BaseNeuron *insource, C_BaseNeuron *intarget,
                       double ing, CModel *inM, int s_mask = 0);
        virtual ~C_BaseSynapse();

    public:
        bool has_target( const C_BaseNeuron& tgt) const __attribute__ ((pure))
                {
                        return cnrun::alg::member(
                                const_cast<C_BaseNeuron*>(&tgt), _targets);
                }
        C_BaseNeuron* source()  {  return _source;  }

        double g_on_target( C_BaseNeuron&) const;
        void set_g_on_target( C_BaseNeuron&, double);

        C_BaseSynapse *clone_to_target( C_BaseNeuron *nt, double g);
        C_BaseSynapse *make_clone_independent( C_BaseNeuron *target);

        void reset_state()
                {
                        C_BaseUnit::reset_state();
                        t_last_release_started = -INFINITY;
                }

        virtual double Isyn( const C_BaseNeuron &with_neuron, double g) const = 0;
        virtual double Isyn( vector<double> &base, const C_BaseNeuron &with_neuron, double g) const = 0;
        // no gsyn known to the synapse: now C_BaseNeuron::SCleft knows it

        void dump( bool with_params = false, FILE *strm = stdout) const;

    protected:
        C_BaseNeuron
               *_source;
        list<C_BaseNeuron*>
                _targets;

        double t_last_release_started;

    private:
        virtual void update_queue()
                {}
};

}

#endif

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