/*****
 NAME
 	psystem.h - prototype for System class group
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#if !defined(PSYSTEM_H_INCLUDED)
#define PSYSTEM_H_INCLUDED

#include <coconut/pobject.h>
#include <coconut/pallocator.h>
#include <coconut/pstream.h>
#include <coconut/toptparser.h>

@protocol POptParser <PObject>

  /*
   * Following methods must be called before execute "startAnalysis" method.
   */
  - (id <PError>) defineOption: (arg_t) typ code: (int) code 
    long_name: (const char *) lname short_name: (char) sname
    result: (void *) result
    desc: (const char *) desc arg_desc: (const char *) argdesc ;

  - setCallbackFunc: (optparser_callback_func_t) func param: (void *) param ;
  - includeOptions: (id <POptParser>) obj desc: (const char *) desc ;

  /*****
     method:
   */
  - (id <PError>) setOnedashProperty ;
  - (id <PError>) setDocHiddenProperty ;
  - (id <PError>) setOptionalProperty ;

  - (id <PError>) load: (const char *) config ;

  - finishOption ;
  - startAnalysis: (const char *) appname argc: (int) argc
      argv: (const char **) argv ;
  - resetAnalysis ;

  /*
   * Following methods must be called after execute "startAnalysis" method.
   */

    /* Provide text to replace default "[OPTION...]" in help/usage output */
  - setHelpString: (const utf8_char *) msg ;

  - (int) nextOpt ;
  - (const char *) optArg ;

  - (const char *) arg ;
    /* get rest of all arguments. terminated by NULL */
  - (const char **) allArgs ;

  - printHelp ;
  - printUsage ;

  - (int) getErrorMessage: (char *) buf size:(size_t) size code:(int) code ;

  - (void *) exportTable ;

@end

@protocol PSystemFactory 
 + retainMainLoop ;
 + releaseMainLoop: (id <PError>) err ;
   /* if the system does not execute event loop, this routine returns 0 */
 + (u_int) getMainLoopNest ;

   /* this method returns the pointer p */
 + (void *) checkPtr: (void *) p ;

 + (const char *) applicationName ;
 + setApplicationName: (const char *) name ;

 + exit: (id <PError>) code ;

 + incErrorCount ;
 + (int) errorCount ;

 + incWarningCount ;
 + (int) warningCount ;

 + incNoteCount ;
 + (int) noteCount ;

 + (char *) getEnv: (const char *) name ;
   /* define or re-define the environment variable */
 + setEnv: (const char *) name value: (const char *) value ;
   /* if the environment variable "name" is not exist, defined it. */
 + setEnvIfNotExist: (const char *) name value: (const char *) value ;

 + unsetEnv: (const char *) name ;
@end

@protocol PCommonSystem <PObject>
 - (id <PError>) main ;
   /* if the system does not execute event loop, this routine does nothing */
 - exitMainLoop: (id <PError>) err ;

   /* if the system does not execute event loop, this routine returns 0 */
 - (u_int) getMainLoopNest ;
@end

@protocol PSystem <PCommonSystem>
 - retainMainLoop ;
 - releaseMainLoop: (id <PError>) err ;

 - (id <PError>) prologue: (int) argc argv: (const char **) argv ;
 - (id <PError>) epilogue: (id <PError>) preerror ;

 - (id <PError>) setupOption: (id <POptParser>) parser ;
 - (id <PError>) decodeOption: (id <POptParser>) parser ;
 - (id <PError>) analyzeOption: (id <POptParser>) parser ;

 - (id <PObstack>) systemObstack ;

 /* exception handling. see "start_program" function in CSystem.m */
 - (id <PError>) recoverPrologue: (id <PError>) preerror ;
 - (id <PError>) recoverMain: (id <PError>) preerror ;
 - (id <PError>) recoverEpilogue: (id <PError>) preerror ;

   /* return the help-string used for "usage: command help-string" */
 - (const utf8_char *) helpString ;

 - printUsage ;
 - printVersion ;

@end

/* this protocol is used to make and generate message for the user.
 */
#define	MSG_BUF_SIZE		64
@protocol PMessage
 + setErrorStream: (id <PStream>) errstream ;

    /* make the message contains filename, 
    	"file-name:X [category] message"
       o buf ... the buffer which contain the result. 
           WARN: the size of buffer must be bigger than MSG_BUF_SIZE
       o fname ... the file name where the problem is occured.
       o lineno ... the line number where the problem is occured.
       the result value means the total length of the generated message.
     */
 + (u_int) makeFileMessage: (char *) buf file: (const char *) fname
     lineno: (u_int) lineno ;

    /* make category ("note", "message" or "error")
        o buf ... the buffer which contain the result
           WARN: the size of buffer must be bigger than MSG_BUF_SIZE
     */
 + (u_int) makeCategoryMessage: (char *) buf type: (message_t) type
     code: (int) code ;

 + message: (message_t) type code: (int) code 
     format: (const char *) form, ... ;
 + vmessage: (message_t) type code: (int) code format: (const char *) 
     form valist: (va_list) args ;

 + fmessage: (const char *) fname lineno: (u_int) lineno 
     type: (message_t) type code: (int) code format: (const char *) form, ... ;
 + vfmessage: (const char *) fname lineno: (u_int) lineno 
     type: (message_t) type code: (int) code
     format: (const char *) form valist: (va_list) args ;
@end

/* the event driven application */
@protocol PEventSystem <PCommonSystem>
 - (id <PError>) main ;
   /* if the system does not execute event loop, this routine does nothing */
 - exitMainLoop: (id <PError>) err ;

 - (boolean) isRunning ;
 - (boolean) isPending ;
@end

#endif /* !defined(PSYSTEM_H_INCLUDED) */

