/* Mutt's extensions.
   Copyright (C) 2003  Ludovic Courtès

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Extension language support */

#include "mutt.h"
#include "extension.h"


/* Hooks that are called when an object is about to be freed, provided the
   object's `extdata' field (extension language data) is not NULL.  */

void (*extension_free_body) (BODY *body) = NULL;
void (*extension_free_header) (HEADER *header) = NULL;
void (*extension_free_envelope) (ENVELOPE *envelope) = NULL;
void (*extension_free_alias) (ALIAS *alias) = NULL;
void (*extension_free_address) (ADDRESS *address) = NULL;

void (*extension_idle_hook) (void) = NULL;


#ifdef GUILE
extern void smutt_init (int argc, char *argv[]);

extern void mutt_init_guile_extension (void *closure /* = NULL */ ,
				       int argc, char *argv[]);

extern int smutt_load_rc_file (const char *filename);
#endif

/* Initialize the extention language system.  This function is expected to not
   return and call mutt_main () afterwards.  */
void
mutt_init_extension (int argc, char *argv[])
{
#ifdef GUILE
  smutt_init (argc, argv);
#endif
}

/* Load the user's configuration from its home directory.  */
int
mutt_load_rc_file (const char *filename)
{
#ifdef GUILE
  return smutt_load_rc_file (filename);
#else
  char errbuf[ERRMSG_SIZE_MAX] = { '\0' };
  BUFFER err;

  err.data = err.dptr = errbuf;
  err.dsize = sizeof (errbuf);

  if (builtin_source_rc_file (filename, &err))
  {
    mutt_error ("%s", err.data);
    return -1;
  }

  return 0;
#endif
}


/* The functions below are just dispatchers to the extension language's
   version of the function.  */

int
cmd_parse_rc_line (const char *line, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_parse_rc_line (line, errmsg);
#else
  return builtin_parse_rc_line (line, errmsg);
#endif
}

int
cmd_execute_command (const char *command, const char *args, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_execute_command (command, args, errmsg);
#else
  return builtin_execute_command (command, args, errmsg);
#endif
}

int
cmd_execute_function (const char *function, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_execute_function (function, errmsg);
#else
  return builtin_execute_function (function, errmsg);
#endif
}

int
cmd_set_option (char *variable, char *value, int hint, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_set_option (variable, value, hint, errmsg);
#else
  return builtin_set_option (variable, value, hint, errmsg);
#endif
}

int
cmd_query_option (char *value, char *variable, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_query_option (value, variable, errmsg);
#else
  return builtin_query_option (value, variable, errmsg);
#endif
}

int
cmd_display_message (HEADER *header)
{
#ifdef GUILE
  return smutt_cmd_display_message (header);
#else
  return builtin_cmd_display_message (header);
#endif
}

int
cmd_define_alias (const char *alias_name, ADDRESS *address,
		  ALIAS **alias, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_define_alias (alias_name, address, alias, errmsg);
#else
  return builtin_define_alias (alias_name, address, alias, errmsg);
#endif
}

int
cmd_save_alias (const ALIAS *alias, const char *filename,
		char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_save_alias (alias, filename, errmsg);
#else
  return builtin_save_alias (alias, filename, errmsg);
#endif
}

int
cmd_generate_message_id (char **messageid)
{
#ifdef GUILE
  return smutt_cmd_generate_message_id (messageid);
#else
  return builtin_generate_message_id (messageid);
#endif
}

int
cmd_make_forward_subject (ENVELOPE *envelope, CONTEXT *context,
			  HEADER *header)
{
#ifdef GUILE
  return smutt_cmd_make_forward_subject (envelope, context, header);
#else
  return builtin_make_forward_subject (envelope, context, header);
#endif
}

int
cmd_score_message (CONTEXT *context, HEADER *header, int update_context)
{
#ifdef GUILE
  return smutt_cmd_score_message (context, header, update_context);
#else
  return builtin_score_message (context, header, update_context);
#endif
}

int
cmd_compile_pattern (pattern_t **pattern, char *string,
		     int flags, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_compile_pattern (pattern, string, flags, errmsg);
#else
  return builtin_compile_pattern (pattern, string, flags, errmsg);
#endif
}

int
cmd_execute_pattern (pattern_t *pattern, HEADER *header,
		     CONTEXT *context, pattern_exec_flag flags)
{
#ifdef GUILE
  return smutt_cmd_execute_pattern (pattern, header, context, flags);
#else
  return builtin_execute_pattern (pattern, header, context, flags);
#endif
}

int
cmd_save_message (HEADER *header, const char *mailbox,
		  int delete, int decode, int decrypt)
{
#ifdef GUILE
  return smutt_cmd_save_message (header, mailbox, delete, decode, decrypt);
#else
  return builtin_save_message (header, mailbox, delete, decode, decrypt);
#endif
}

int
cmd_is_mailing_list (ADDRESS *address)
{
#ifdef GUILE
  return smutt_cmd_is_mailing_list (address);
#else
  return builtin_is_mailing_list (address);
#endif
}

int
cmd_is_subscribed_list (ADDRESS *address)
{
#ifdef GUILE
  return smutt_cmd_is_subscribed_list (address);
#else
  return cmd_is_subscribed_list (address);
#endif
}

int
cmd_addr_is_user (ADDRESS *address)
{
#ifdef GUILE
  return smutt_cmd_addr_is_user (address);
#else
  return builtin_cmd_addr_is_user (address);
#endif
}

int
cmd_default_from_address (ADDRESS **from)
{
#ifdef GUILE
  return smutt_cmd_default_from_address (from);
#else
  return builtin_default_from_address (from);
#endif
}

int
cmd_add_scoring_rule (char *pattern, char *value,
		      SCORE **newrule, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_add_scoring_rule (pattern, value, newrule, errmsg);
#else
  return builtin_add_scoring_rule (pattern, value, newrule, errmsg);
#endif
}

int
cmd_menu_jump (MUTTMENU *menu, unsigned int entry, char *errmsg)
{
#ifdef GUILE
  return smutt_cmd_menu_jump (menu, entry, errmsg);
#else
  return builtin_menu_jump (menu, entry, errmsg);
#endif
}

int
cmd_pipe_message (HEADER *header, const char *command,
		  int print,
		  int decode, int split, const char *separator)
{
#ifdef GUILE
  return smutt_cmd_pipe_message (header, command, print,
				 decode, split, separator);
#else
  return builtin_pipe_message (header, command, print,
			       decode, split, separator);
#endif
}

int
cmd_send_message (HEADER *message)
{
#ifdef GUILE
  return smutt_cmd_send_message (message);
#else
  return builtin_send_message (message);
#endif
}

int
cmd_make_reply_header (ENVELOPE *replyenv, HEADER *current,
		       ENVELOPE *currentenv, CONTEXT *context)
{
#ifdef GUILE
  return smutt_cmd_make_reply_header (replyenv, current, currentenv, context);
#else
  return builtin_make_reply_header (replyenv, current, currentenv, context);
#endif
}

int
cmd_append_signature (FILE *file, HEADER *message)
{
#ifdef GUILE
  return smutt_cmd_append_signature (file, message);
#else
  return builtin_append_signature (file, message);
#endif
}

int
cmd_append_forward_intro (FILE *file, HEADER *forwarded)
{
#ifdef GUILE
  return smutt_cmd_append_forward_intro (file, forwarded);
#else
  return builtin_append_forward_intro (file, forwarded);
#endif
}

int
cmd_append_forward_trailer (FILE *file, HEADER *forwarded)
{
#ifdef GUILE
  return smutt_cmd_append_forward_trailer (file, forwarded);
#else
  return builtin_append_forward_trailer (file, forwarded);
#endif
}

int
cmd_append_message_attribution (FILE *file, HEADER *replied,
				CONTEXT *context)
{
#ifdef GUILE
  return smutt_cmd_append_message_attribution (file, replied, context);
#else
  return builtin_append_message_attribution (file, replied, context);
#endif
}

int
cmd_generate_reply_body (FILE *file, HEADER *message,
			 CONTEXT *context, HEADER *replied)
{
#ifdef GUILE
  return smutt_cmd_generate_reply_body (file, message, context, replied);
#else
  return builtin_generate_reply_body (file, message, context, replied);
#endif
}

int
cmd_generate_forward_body (FILE *file, HEADER *message,
			   CONTEXT *context, HEADER *forwarded)
{
#ifdef GUILE
  return smutt_cmd_generate_forward_body (file, message, context, forwarded);
#else
  return builtin_generate_forward_body (file, message, context, forwarded);
#endif
}

int
cmd_include_reply_body (FILE *file, HEADER *replied, CONTEXT *context)
{
#ifdef GUILE
  return smutt_cmd_include_reply_body (file, replied, context);
#else
  return builtin_include_reply_body (file, replied, context);
#endif
}

int
cmd_include_forward_body (FILE *file, HEADER *forwarded, CONTEXT *context)
{
#ifdef GUILE
  return smutt_cmd_include_forward_body (file, forwarded, context);
#else
  return builtin_include_forward_body (file, forwarded, context);
#endif
}

int
cmd_add_mailbox (BUFFY **mailbox, const char *name)
{
#ifdef GUILE
  return smutt_cmd_add_mailbox (mailbox, name);
#else
  return builtin_add_mailbox (mailbox, name);
#endif
}

int
cmd_remove_mailbox (BUFFY *mailbox)
{
#ifdef GUILE
  return smutt_cmd_remove_mailbox (mailbox);
#else
  return builtin_remove_mailbox (mailbox);
#endif
}

int
cmd_expand_path (char *path, size_t pathlen)
{
#ifdef GUILE
  return smutt_cmd_expand_path (path, pathlen);
#else
  return builtin_expand_path (path, pathlen);
#endif
}

int
cmd_query_exit (void)
{
#ifdef GUILE
  return smutt_cmd_query_exit ();
#else
  return builtin_query_exit ();
#endif
}
