/*
  translator.icc -- declare Translator glue wiring.

  source file of the GNU LilyPond music typesetter

  (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/

#ifndef TRANSLATOR_ICC
#define TRANSLATOR_ICC

#include "array.hh"
#include "translator.hh"

/**
   A macro to automate administration of translators.
*/
#define ADD_THIS_TRANSLATOR(T)						\
  SCM T::static_description_ = SCM_EOL;					\
  static void _ ## T ## _adder ()					\
  {									\
    T *t = new T;							\
    T::static_description_ = t->static_translator_description ();	\
    scm_permanent_object (T::static_description_);			\
    add_translator (t);							\
  }									\
  SCM T::translator_description () const				\
  {									\
    return static_description_;						\
  }									\
  ADD_GLOBAL_CTOR (_ ## T ## _adder);

#define ADD_TRANSLATOR(classname, desc, grobs, accepted, read, write)	\
  Array<Acknowledge_information> classname::acknowledge_static_array_;	\
  IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname);			\
  ADD_THIS_TRANSLATOR (classname);					\
  Engraver_void_function_engraver_grob_info				\
  classname::static_get_acknowledger (SCM sym)				\
  {									\
    return generic_get_acknowledger (sym, &acknowledge_static_array_);	\
  }									\
  SCM									\
  classname::static_translator_description () const			\
  {									\
    SCM static_properties = SCM_EOL;					\
    /*  static_properties = acons (name , gh_str02scm (Translator::name (self_scm ())),	\
	static_properties_);						\
    */									\
    static_properties = scm_acons (ly_symbol2scm ("grobs-created"),	\
				   parse_symbol_list (grobs), static_properties); \
									\
    static_properties = scm_acons (ly_symbol2scm ("description"),	\
				   scm_makfrom0str (desc), static_properties); \
									\
    static_properties = scm_acons (ly_symbol2scm ("events-accepted"),	\
				   parse_symbol_list (accepted), static_properties); \
									\
    static_properties = scm_acons (ly_symbol2scm ("properties-read"),	\
				   parse_symbol_list (read), static_properties); \
									\
    static_properties = scm_acons (ly_symbol2scm ("properties-written"), \
				   parse_symbol_list (write), static_properties); \
									\
    return static_properties;						\
  }

#define IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS(T)			\
  void									\
  T::fetch_precomputable_methods (Translator_void_method_ptr ptrs[])	\
  {									\
    ptrs[START_TRANSLATION_TIMESTEP] =					\
      ((Translator_void_method_ptr) & T::start_translation_timestep ==	\
       (Translator_void_method_ptr) & Translator::start_translation_timestep) \
      ? 0								\
      : (Translator_void_method_ptr) & T::start_translation_timestep;	\
									\
    ptrs[STOP_TRANSLATION_TIMESTEP] =					\
      ((Translator_void_method_ptr) & T::stop_translation_timestep == (Translator_void_method_ptr) & Translator::stop_translation_timestep) \
      ? 0								\
      : (Translator_void_method_ptr) & T::stop_translation_timestep;	\
									\
    ptrs[PROCESS_MUSIC] =						\
      ((Translator_void_method_ptr) & T::process_music == (Translator_void_method_ptr) & Translator::process_music) \
      ? 0								\
      : (Translator_void_method_ptr) & T::process_music;		\
									\
    ptrs[PROCESS_ACKNOWLEDGED] =					\
      ((Translator_void_method_ptr) & T::process_acknowledged == (Translator_void_method_ptr) & Translator::process_acknowledged) \
      ? 0								\
      : (Translator_void_method_ptr) & T::process_acknowledged;		\
  }

void add_acknowledger (Engraver_void_function_engraver_grob_info ptr,
		       char const *func_name,
		       Array<Acknowledge_information> *ack_array);

Engraver_void_function_engraver_grob_info
generic_get_acknowledger (SCM sym,
			  Array<Acknowledge_information> const *ack_array);

#define ADD_ACKNOWLEDGER(CLASS, NAME)					\
  void CLASS ## NAME ## _ack_adder ()					\
  {									\
    add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_); \
  }									\
  ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder);


#endif /* TRANSLATOR_ICC */

