/*--------------------------------------------------------------------------*/
/* ALBERTA_UTIL:  tools for messages, memory allocation, parameters, etc.   */
/*                                                                          */
/* file:     msg.c                                                          */
/*                                                                          */
/* description:  utilities for messages                                     */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*  authors:   Alfred Schmidt                                               */
/*             Zentrum fuer Technomathematik                                */
/*             Fachbereich 3 Mathematik/Informatik                          */
/*             Universitaet Bremen                                          */
/*             Bibliothekstr. 2                                             */
/*             D-28359 Bremen, Germany                                      */
/*                                                                          */
/*             Kunibert G. Siebert                                          */
/*             Institut fuer Mathematik                                     */
/*             Universitaet Augsburg                                        */
/*             Universitaetsstr. 14                                         */
/*             D-86159 Augsburg, Germany                                    */
/*                                                                          */
/*  http://www.alberta-fem.de/                                              */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*  (c) by A. Schmidt and K.G. Siebert (1996-2004)                          */
/*                                                                          */
/*     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    */
/*     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.                         */
/*--------------------------------------------------------------------------*/

/**Versuche, die Ausgaben ein bisschen einzuruecken*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include <alberta.h>
#include <alberta_util.h>
#if (defined(ALBERTA_VER) && (ALBERTA_VER==2))
//# include <alberta_inlines.h>
//#include <alberta_util_inlines.h>
# include "alberta1_wrapper.h"
#endif

#include "newalberta.hh"

int print_depth=0;

/*--------------------------------------------------------------------------*/
/*  global variable funcName; used if no local funcName declared            */
/*--------------------------------------------------------------------------*/

const char   *funcName = nil;

/*--------------------------------------------------------------------------*/
/*  global variables for util.c                                             */
/*--------------------------------------------------------------------------*/

/*  static FILE  *out_file = stdout, *error_file = stderr; */
static FILE  *out_file = nil, *error_file = nil;
static const char *old_func_name = nil;
static char  func_name[256];

void alberta_wait(const char *funcName, int wait)
{
  if (wait)
  {
    char   line[10];
    MSG("wait for <enter> ...");
    fgets(line, 9, stdin);
  }
  return;
}

void change_msg_out(FILE *fp)
{
  FUNCNAME("change_msg_out");
  
  if (fp)
  {
    if (out_file  &&  out_file != stdout  &&  out_file != stderr)
      fclose(out_file);

    out_file = fp;
  }
  else
  {
    ERROR("file pointer is pointer to nil;\n");
    ERROR("use previous stream for messages furthermore\n");
  }
  return;
}

void open_msg_file(const char *filename, const char *type)
{
  FUNCNAME("open_msg_file");
  FILE  *fp;

  if (filename  &&  (fp = fopen(filename, type)))
  {
    if (out_file  &&  out_file != stdout  &&  out_file != stderr)
      fclose(out_file);

    out_file = fp;
  }
  else
  {
    if (filename)
      ERROR("can not open %s;\n", filename);
    else
      ERROR("no filename specified;\n");
    ERROR("use previous stream for messages furthermore\n");
  }
  return;
}

void change_error_out(FILE *fp)
{
  FUNCNAME("change_error_out");
  if (fp)
  {
    if (error_file  &&  error_file != stdout  &&  error_file != stderr)
      fclose(error_file);

    error_file = fp;
  }
  else
  {
    ERROR("file pointer is pointer to nil;\n");
    ERROR("use previous stream for errors furthermore\n");
  }

  return;
}

void open_error_file(const char *filename, const char *type)
{
  FUNCNAME("open_error_file");
  FILE  *fp;

  if (filename  &&  (fp = fopen(filename, type)))
  {
    if (error_file  &&  error_file != stdout  &&  error_file != stderr)
      fclose(error_file);

    error_file = fp;
  }
  else
  {
    if (filename)
      ERROR("can not open %s;\n", filename);
    else
      ERROR("no filename specified;\n");
    ERROR("use previous stream for errors furthermore\n");
  }
  return;
}

int print_funcname(const char *funcname)
{
  if (!out_file) out_file = stdout;
   char  depth[256]="";

  for (int i=0; i<2*print_depth; i++) strcat(depth," ");

  if (funcname  &&  old_func_name != funcname)
  {
   strcpy(func_name, funcname);
    strcat(func_name, ": ");
  }
  else if (!funcname)
  {
    strcpy(func_name, "*unknown function*");
  }
  else
  {
    strcpy(func_name, "");
  }
  fprintf(out_file, "%s", depth);
//  fprintf(out_file, "%-20s", func_name);
  fprintf(out_file, "%-18s", func_name);
  old_func_name = funcname;
  return 0;
}

int print_error_funcname(const char *funcname, const char *file, int line)
{
  static int        old_line = -1;

  if (!error_file) error_file = stderr;

  if (funcname  &&  old_func_name != funcname)
  {
    strcpy(func_name, funcname);
    strcat(func_name, ": ");
  }
  else if (!funcname)
  {
    strcpy(func_name, "*unknown function*");
  }
  else
  {
    strcpy(func_name, "");
  }
  if (old_func_name != funcname)
    fprintf(error_file, "%-20sERROR in %s, line %d\n", func_name, file, line);
  else if (line - old_line > 5)
    fprintf(error_file, "%-20sERROR in %s, line %d\n", func_name, file, line);

  fprintf(error_file, "%-20s", "");
  old_func_name = funcname;
  old_line = line;

  return 0;
}

int print_error_msg_exit(const char *format, ...)
{
  va_list   arg;

  if (!error_file) error_file = stderr;

  va_start(arg, format);
  vfprintf(error_file, format, arg);
  va_end(arg);

  exit(1);
}

int print_error_msg(const char *format, ...)
{
  va_list   arg;

  if (!error_file) error_file = stderr;

  va_start(arg, format);
  vfprintf(error_file, format, arg);
  va_end(arg);

  return 0;
}

void print_warn_funcname(const char *funcname, const char *file, int line)
{
  static int        old_line = -1;

  if (!out_file) out_file = stdout;

  if (funcname  &&  old_func_name != funcname)
  {
    strcpy(func_name, funcname);
    strcat(func_name, ": ");
  }
  else if (!funcname)
  {
    strcpy(func_name, "*unknown function*");
  }
  else
  {
    strcpy(func_name, "");
  }
  if (old_func_name != funcname)
    fprintf(out_file, "%-20sWARNING in %s, line %d\n", func_name,file,line);
  else if (line - old_line > 5)
    fprintf(out_file, "%-20sWARNING in %s, line %d\n", func_name,file,line);

  fprintf(out_file, "%-20s", "");
  old_func_name = funcname;
  old_line = line;

  return;
}

void print_warn_msg(const char *format, ...)
{
  va_list   arg;

  if (!out_file) out_file = stdout;

  va_start(arg, format);
  vfprintf(out_file, format, arg);
  va_end(arg);

  return;
}


int print_msg(const char *format, ...)
{
  va_list   arg;

  if (!out_file) out_file = stdout;

  va_start(arg, format);
  vfprintf(out_file, format, arg);
  va_end(arg);
  return 0;
}

/*--------------------------------------------------------------------------*/
/*  routines for writing int and REAl vectors to out_file                   */
/*--------------------------------------------------------------------------*/

void print_int_vec(const char *s, const int *vec, int no)
{
  int   i;

  print_msg("%s = (", s);
  for (i = 0; i < no; i++)
    print_msg("%d%s", vec[i], i < no-1 ? ", " : ")\n");
}

void print_real_vec(const char *s, const REAL *vec, int no)
{
  int   i;

  print_msg("%s = (", s);
  for (i = 0; i < no; i++)
    print_msg("%.5lf%s", vec[i], i < no-1 ? ", " : ")\n");
}

