/*
 *       File name:  cnrun/cnhost.hh
 *         Project:  cnrun
 *          Author:  Andrei Zavada <johnhommer@gmail.com>
 * Initial version:  2008-11-04
 *
 *         Purpose:  C host side for cn lua library
 *
 *         License:  GPL-2+
 */

#ifndef CNRUN_CNRUN_CNHOST_H_
#define CNRUN_CNRUN_CNHOST_H_

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

#include <list>
#include <string>
extern "C" {
#include <lua.h>
}

#include "libcnrun/model.hh"

namespace cnrun {

struct SHostOptions
  : public cnrun::SModelOptions {
        string  working_dir;

        SHostOptions ()
              : working_dir (".")
                {}
        SHostOptions (const SHostOptions& rv)
              : cnrun::SModelOptions (rv),
                working_dir (rv.working_dir)
                {}
};


class CHost
  : public cnrun::stilton::C_verprintf {

        DELETE_DEFAULT_METHODS (CHost)

    public:
        CHost (const SHostOptions& rv)
              : options (rv)
                {}
        virtual ~CHost ()
                {
                        for ( auto& m : models )
                                delete m.second;
                }

        SHostOptions
                options;

        bool have_model( const string& name) const
                {
                        return models.find(name) != models.end();
                }
        list<const char*> list_models() const
                {
                        list<const char*> L;
                        for ( auto& x : models )
                                L.push_back(x.first.c_str());
                        return move(L);
                }
        CModel* get_model( const string& name)
                {
                        return models.at(name);
                }
        bool new_model( CModel& M)
                {
                        if ( models.find(M.name) == models.end() ) {
                                models[M.name] = &M;
                                return 0;
                        } else
                                return -1;
                }
        void del_model( const string& name)
                {
                        if ( models.find(name) != models.end() )
                                delete models[name];
                        models.erase( name);
                }
        // cmd_new_model( const TArgs&);
        // cmd_delete_model( const TArgs&);
        // cmd_import_nml( const TArgs&);
        // cmd_export_nml( const TArgs&);
        // cmd_reset_model( const TArgs&);
        // cmd_cull_deaf_synapses( const TArgs&);
        // cmd_describe_model( const TArgs&);
        // cmd_get_model_parameter( const TArgs&);
        // cmd_set_model_parameter( const TArgs&);
        // cmd_advance( const TArgs&);
        // cmd_advance_until( const TArgs&);

        // cmd_new_neuron( const TArgs&);
        // cmd_new_synapse( const TArgs&);
        // cmd_get_unit_properties( const TArgs&);
        // cmd_get_unit_parameter( const TArgs&);
        // cmd_set_unit_parameter( const TArgs&);
        // cmd_get_unit_vars( const TArgs&);
        // cmd_reset_unit( const TArgs&);

        // cmd_get_units_matching( const TArgs&);
        // cmd_get_units_of_type( const TArgs&);
        // cmd_set_matching_neuron_parameter( const TArgs&);
        // cmd_set_matching_synapse_parameter( const TArgs&);
        // cmd_revert_matching_unit_parameters( const TArgs&);
        // cmd_decimate( const TArgs&);
        // cmd_putout( const TArgs&);

        // cmd_new_tape_source( const TArgs&);
        // cmd_new_periodic_source( const TArgs&);
        // cmd_new_noise_source( const TArgs&);
        // cmd_get_sources( const TArgs&);
        // cmd_connect_source( const TArgs&);
        // cmd_disconnect_source( const TArgs&);

        // cmd_start_listen( const TArgs&);
        // cmd_stop_listen( const TArgs&);
        // cmd_start_log_spikes( const TArgs&);
        // cmd_stop_log_spikes( const TArgs&);

      // vp
        int verbose_threshold() const
                {  return options.verbosely;  }
    private:
        map<string, CModel*>
                models;

        // enum class TIssueType { warning, syntax_error, system_error };
        // static const char* _issue_type_s(TIssueType);
        // void _report_script_issue( TIssueType, const char* fmt, ...) const
        //         __attribute__ ((format (printf, 3, 4)));
    public:
        static list<string> list_commands();
};

}

#endif

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