/*

  logclass.cc

  class definitions for xlogmaster.cc
  Copyright (C) 1998 Georg C. F. Greve
  This is a GNU program
  
  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  
  
  Contact: 
           mailto:xlogmaster-bugs@gnu.org
           http://www.gnu.org/software/xlogmaster/
  Secondary sources:
           http://porter.desy.de/~greve/xlogmaster/
           http://www.fusebox.hanse.de/xlogmaster/
	 
*/

/*{{{  Header  */

#include "../config.h"
#include "sysinc.H"
#include "../import/import.h"
#include "logclass.H"
#include "extern.H"

/*}}}*/

/*
  Log Class Routines:
 */
/*{{{  Constructor & Destructor  */
Log::Log(){
  mode = EMPTY;
  interval = -1;
  filename = NULL;
  help = NULL;
  buttontext = NULL;
  commandline = NULL;
  tag =  0;
  filter = NULL;
  filterclass = NO_FILTER;
  wd_tag = 0;
  buffer = NULL;
  rbuffer = NULL;
  length = 0;
  chunk = (long) RDBLCK * INTERVAL;

  // to be used out of alert.cc:
  alert_tag = 0;
  fade = last_fade = fadestep = 0;
  pixels[0] = 0;
  pixels[1] = 0;

  active = FALSE;

  return;
};
Log::~Log(){
  if ( filename != NULL ) delete filename;
  if ( help != NULL ) delete help;
  if ( buttontext != NULL ) delete buttontext;
  if ( commandline != NULL ){
    int i = 0;
    while ( commandline[i] != NULL ) delete commandline[i++];
    delete commandline;
  }
  if ( filter != NULL ){
    int i = 0;
    while ( filter[i] != NULL ) delete filter[i++];
    delete filter;
  }
  if ( buffer != NULL ) delete buffer;
  if ( rbuffer != NULL ) delete rbuffer;
  buffer = rbuffer = NULL;

  return;
};
/*}}}*/


/*  
  Filter Class Routines
*/

/*{{{  Constructor & Destructor  */
Filter::Filter()
{
 
  string = NULL;
  regex_pattern = NULL;
  execline = NULL;
  mode = NO_CHANGE;
 
  /* status is zero (no problem) by default */
  regex_status = 0;
  
  return;
};
Filter::~Filter()
{
  
  if ( string != NULL ) delete string;
  if ( regex_pattern != NULL )
    {
      disassemble_regex(regex_pattern);
      regex_pattern = NULL;
    }
  if ( execline != NULL ) delete execline;
  mode = NO_CHANGE;
  
  return;
};
/*}}}*/

/*{{{  init()  */
void
Filter::init(const char* str, gint new_mode)
{
  /* we do not want to preserve the calculation command,
     so we will mask everything but the modes needed during
     runtime out */
  mode = new_mode & RUNTIME_MODES_MASK; 
  
  string = new char[strlen(str)+2];
  strcpy(string, str);

  if ( regex_pattern != NULL )
    {
      disassemble_regex(regex_pattern);
      regex_pattern = NULL;
      regex_status = 0;
    }
  
  if ( ! (new_mode & COMPILE_REGEX) )
    return;
  
  /*
    only if COMPILE_REGEX is given we will actually try to compile
    the REGEX !!!
    This prevents multiple error messages reinitialisation of the program 
    for the same problem because often filter elements are only being
    used as temporary structures.
  */
  
  regex_pattern = new re_pattern_buffer;

  /*
    Make a clean start (pun :-) )
  */
  regex_pattern->start = NULL;
  regex_pattern->buffer = NULL;
  regex_pattern->allocated = 0;
  regex_pattern->re_nsub = 0;
  regex_pattern->se_params = NULL; 
  regex_pattern->syntax_parens = NULL;
  
  /*
    set the translation table according to whether the
    user wants case sensitivity
  */
  if ( mode & CASE_SENSITIVE )
    {
      regex_pattern->translate = NULL;
    }
  else
    {
      regex_pattern->translate = (unsigned char*) case_fold;
    }
  
  /*
    set the REGEX flags according to the mode of
    REGEX matching
  */
  re_set_syntax( XLM_REGEX_SYNTAX );

  /*
    we don't have a fastmap yet
   */
  regex_pattern->fastmap = NULL;

  /*
    compile expression
  */
  const gchar* error = re_compile_pattern( string, strlen(string), regex_pattern );

  if ( error != 0 )
    {
      /* there has been an error during compilation 
	 output error messages to user: */
      cerr << PACKAGE << ": " << "error compiling REGEX ";
      cerr << "' "<< string << " '" << endl;
      cerr << "  re_compile_pattern returned: " << error << endl;
      
      /* and create a popup dialog box */
      gchar* opener = "\n\t     Error while trying to compile REGEX     \t\n\n\t      ";
      gchar* closer = "      \t\n\n\t   calling re_compile_pattern returned:     \t\n\n";
      gchar* text = new gchar[strlen(error) + strlen(opener) + strlen(closer) + strlen(string) + 10 ];
      strcpy ( text, opener );
      strcat ( text, string );
      strcat ( text, closer );
      strcat ( text, error );
      strcat ( text, "\n\t" );
      
      GList* buttons = g_list_alloc();
      GList* functions = g_list_alloc();
      buttons = g_list_append(buttons,
			      (gpointer) "\t   DISMISS   \t");
      functions = g_list_append(functions, NULL );

      popup_dialog("Invalid REGEX", text, buttons, functions);
      delete text;

      /* and the pattern since we can't use it anyways */
      delete regex_pattern;
      regex_pattern = NULL;
    }

  /*
    now allocate the syntax_parens
  */
  regex_pattern->syntax_parens = new gchar[ regex_pattern->re_nsub + 1 ];

  /*
    now create the fastmap if the compilation has been
    successful
  */
  if ( regex_pattern != NULL )
    {
      regex_pattern->fastmap = new gchar[256];
      re_compile_fastmap( regex_pattern );
    }

  
  return;
}
/*}}}*/

/*{{{  purge()  */
void
Filter::purge()
{

  if ( string != NULL ) delete string;
  if ( regex_pattern != NULL )
    {
      disassemble_regex(regex_pattern);
      regex_pattern = NULL;
      regex_status = 0;
    }
  if ( execline != NULL ) delete execline;
  string = NULL;
  execline = NULL;
  mode = NO_CHANGE;

}
/*}}}*/
