//  This may look like C code, but it is really -*- C++ -*-

//  ------------------------------------------------------------------
//  The Goldware Library
//  Copyright (C) 1990-1999 Odinn Sorensen
//  Copyright (C) 2000 Alexander S. Aganichev
//  ------------------------------------------------------------------
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library 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
//  Library General Public License for more details.
//
//  You should have received a copy of the GNU Library General Public
//  License along with this program; if not, write to the Free
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
//  MA 02111-1307, USA
//  ------------------------------------------------------------------
//  $Id$
//  ------------------------------------------------------------------
//  Log file class.
//  ------------------------------------------------------------------

#include <cstdarg>
#include <gtimall.h>
#include <gstrall.h>
#include <gdbgerr.h>
#include <glog.h>


//  ------------------------------------------------------------------

struct tm glog::time_now;
int       glog::count = 0;
time32_t  glog::secs_now;
char      glog::timebuf[20];


//  ------------------------------------------------------------------

glog::glog() {

  bufsize = 0;
  logtype = GLOG_FD;
  progname = NULL;
  status = GOLD_NO_ERROR;
  storelines = -1;
}


//  ------------------------------------------------------------------

glog::~glog() {

  close();
}


//  ------------------------------------------------------------------

int glog::open(const char* filename, const char* name, const char* shortname, int type, uint bufsz, int shflag)
{
  fp.Fopen(filename, "at", shflag);
  if (fp.status)
  {
    status = fp.status;
    return status;
  }

  count++;
  bufsize = bufsz;
  fp.SetvBuf(NULL, bufsize ? _IOFBF : _IONBF, bufsize);

  init(name, shortname, type);

  return status;
}


//  ------------------------------------------------------------------

void glog::close()
{
  fp.Fclose();
  count--;
}


//  ------------------------------------------------------------------

void glog::init(const char* name, const char* shortname, int type) {

  lineswritten = 0;
  logtype = (type!=GLOG_NONE) ? type : logtype;
  progname = name ? name : progname;
  shortprogname = shortname ? shortname : (shortprogname ? shortprogname : progname);
}


//  ------------------------------------------------------------------

void glog::printf(const char* format, ...) {

  va_list argptr;
  char buf[256];
  char logbuf[256];

  secs_now = gtime(NULL);
  glocaltime(&time_now, &secs_now);

  lineswritten++;

  if(lineswritten == 1) {

    switch(logtype) {

      case GLOG_FD:
        sprintf(logbuf, "\n----------  %s, %s\n", strftimei(timebuf, 20, "%a %d %b %y", &time_now), progname);
        break;

      case GLOG_MAX:
        sprintf(logbuf, "\n+ %s %4.4s Begin, %s\n", strftimei(timebuf, 20, "%d %b %H:%M:%S", &time_now), shortprogname, progname);
        break;

      case GLOG_BINK:
        sprintf(logbuf, "\n> %s %4.4s %s\n", strftimei(timebuf, 20, "%d-%b %H:%M:%S", &time_now), shortprogname, progname);
        break;

      case GLOG_QBBS:
        sprintf(logbuf, "\n%s  **************************************************\n%s  %s\n", strftimei(timebuf, 20, "%d-%b-%y %H:%M", &time_now), timebuf, progname);
        break;

      case GLOG_DB:
        sprintf(logbuf, "\n%s  %s\n", strftimei(timebuf, 20, "%m/%d/%y %H:%M", &time_now), progname);
        break;
    }

    if (fp.isopen())
      fp.Printf("%s", logbuf);
  }

  *buf = NUL;
  va_start(argptr, format);
  vsprintf(buf, format, argptr);
  va_end(argptr);

  if(*buf == '!')
    store();

  switch(logtype) {

    case GLOG_FD:
      sprintf(logbuf, "%c %s  %s", *buf, strftimei(timebuf, 10, "%H:%M:%S", &time_now), buf+2);
      break;

    case GLOG_MAX:
      sprintf(logbuf, "%c %s %4.4s %s", *buf, strftimei(timebuf, 20, "%d %b %H:%M:%S", &time_now), shortprogname, buf+2);
      break;

    case GLOG_BINK:
      sprintf(logbuf, "%c %s %4.4s %s", *buf, strftimei(timebuf, 20, "%d-%b %H:%M:%S", &time_now), shortprogname, buf+2);
      break;

    case GLOG_QBBS:
      sprintf(logbuf, "%s  %s", strftimei(timebuf, 20, "%d-%b-%y %H:%M", &time_now), buf+2);
      break;

    case GLOG_DB:
      sprintf(logbuf, "%s  %s", strftimei(timebuf, 20, "%m/%d/%y %H:%M", &time_now), buf+2);
      break;
  }
  if (fp.isopen())
  {
    fp.Printf("%s\n", logbuf);
    fp.Fflush();
  }
  if(storelines != -1) {
    if(storelines < GLOG_STORELINES)
      strxcpy(storeline[storelines], logbuf, 79);
    storelines++;
  }
}


//  ------------------------------------------------------------------

void glog::store() {

  if(storelines == -1)
    storelines = 0;
}


//  ------------------------------------------------------------------

glog LOG;


//  ------------------------------------------------------------------
