/***************************************************************************
                            KCmdLineArgs.h -  description
                             -------------------
    begin                : Fri Mar  8 13:55:08 2002
    copyright            : (C) 2000-2002 Lost Highway Ltd. All rights reserved.
    email                : Lost_Highway@tipitina.demon.co.uk
    generated by         : duke@tipitina on Fri Mar  8 13:55:08 2002, using kalyptus 0.9.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                       *
 *                                                                         *
 ***************************************************************************/

#ifndef KCMDLINEARGS_H
#define KCMDLINEARGS_H

#include <Foundation/NSObject.h>
#include <Foundation/NSString.h>
#include <qtobjc/QtSupport.h>

/**

  Simple access to the command-line arguments.

  It takes into account Qt-specific options, KDE-specific options
  and application specific options.

  This class is used in -main via the static method
  @ref -init.

  A typical KDE application should look like this:

  <pre>
  int main(int argc, char *argv[])
  {
     // Initialize command line args
     -[KCmdLineArgs init](argc, argv, appName, description, version);

     // Tell which options are supported
     -[KCmdLineArgs addCmdLineOptions]( options );

     // Add options from other components
     -[KUniqueApplication addCmdLineOptions];

     ....

     // Create application object without passing 'argc' and 'argv' again.
     KUniqueApplication app;

     ....

     // Handle our own options/argments
     // A KApplication will usually do this in main but this is not
     // necassery.
     // A KUniqueApplication might want to handle it in -newInstance.

     KCmdLineArgs *args = -[KCmdLineArgs parsedArgs];

     // A binary option (on / off)
     if (-[args isSet]("some-option"))
        ....

     // An option which takes an additional argument
     QCString anotherOptionArg = -[args getOption]("another-option");

     // Arguments (e.g. files to open)
     for(int i = 0; i < -[args count]; i++) // Counting start at 0! 
     {
        // don't forget to convert to Unicode!        
        openFile( -[QFile decodeName]( -[args arg]));
        // Or more convenient:
        // openURL( -[args url]);

     }

     -[args clear]; // Free up some memory. 
     ....
  }
  </pre>

  options are defined as follow

  <pre>
  static KCmdLineOptions options[] = 
  {
     { "a", I18N_NOOP("A short binary option."), 0 },
     { "b <file>", I18N_NOOP("A short option which takes an argument."), 0 },
     { "c <speed>", I18N_NOOP("As above but with a default value."), "9600" },
     { "option1", I18N_NOOP("A long binary option, off by default."), 0 },
     { "nooption2", I18N_NOOP("A long binary option, on by default."), 0 },
     { "option3 <file>", I18N_NOOP("A long option which takes an argument."), 0 },
     { "option3 <speed>", I18N_NOOP("As above with 9600 as default."), "9600" },
     { "d", 0, 0 },
     { "option4", I18N_NOOP("A long option which has a short option as alias."), 0 }, 
     { "e", 0, 0 },
     { "nooption5", I18N_NOOP("Another long option with an alias."), 0 },
     { "f", 0, 0 },
     { "option6 <speed>", I18N_NOOP("'--option6 speed' is same a '-f speed'"), 0 },
     { "!option7 <cmd>", I18N_NOOP("All options following this one will be treated as arguments", 0 },
     { "+file", I18N_NOOP("A required argument 'file'.), 0 },
     { "+[arg1]", I18N_NOOP("An optional argument 'arg1'."), 0 },
     { "!+command", I18N_NOOP("A required argument 'command', that can contain multiple words, even starting with '-'.), 0 },
     { 0, 0, 0 } // End of options.
  };
  </pre>

  The I18N_NOOP macro is used to indicate that these strings should be
  marked for translation. The actual translation is done by KCmdLineArgs.
  You can't use -i18n here because we are setting up a static data 
  structure and can't do translations at compile time.

  Note that a program should define the options before any arguments.

  When a long option has a short option as alias. A program should
  only check for the long option.

  With the above options a command line could look like:
  <pre>
     myapp -a -c 4800 --display localhost:0.0 --nooption5 -d /tmp/file 
  </pre>

  Long binary options can be in the form 'option' and 'nooption'.
  A command line may contain the same binary option multiple times,
  the last option determines the outcome:
  <pre>
     myapp --nooption4 --option4 --nooption4
  </pre>
  is the same as:
  <pre>
     myapp --nooption4
  </pre>

  Normally if an option value is provided multiple times only the last 
  value is used:
  <pre>
     myapp -c 1200 -c 2400 -c 4800
  </pre>
  is usually the same as:
  <pre>
     myapp -c 4800
  </pre>

  However, an application can choose to use all values specified as well.
  E.g. to specify a number of directories to use:
  <pre>
     myapp -I /usr/include -I /opt/kde/include -I /usr/X11/include
  </pre>
  When an application does this it should mention this in the description
  of the option. @ref -getOptionList

 @author Waldo Bastian

 @version 0.0.4
 
 @short A class for command-line argument handling.

*/
@class KAboutData; 
@class KURL;

@interface  KCmdLineArgs : NSObject <QtSupport>
{
@private
	void * _qt;
	BOOL  _allocatedInObjcWorld;
}

/** 
  Read out a string option.

*/
- (NSString *) getOption: (NSString *)option;

/** 
  Read out all occurences of a string option.

*/
- (NSArray *) getOptionList: (NSString *)option;

/** 
  Read out a boolean option or check for the presence of string option.

          If the option is listed as '<option> <arg>'
          this function returns @p true if the option was present
          and @p false otherwise.

   
*/
- (BOOL) isSet: (NSString *)option;

/** 
  Read the number of arguments that aren't options (but,
  for example, filenames).

*/
- (int) count;

/** 
  Read out an argument.

*/
- (NSString *) arg: (int)n;

/** 
  Read out an argument representing a URL.

  The argument can be 

*/
- (KURL*) url: (int)n;

/** 
  Clear all options and arguments.
   
*/
- clear;

/** 
 Initialize class.

 This function should be called as the very first thing in
  your application.

*/
+ init: (int)_argc _argv: (NSString *)_argv _appname: (NSString *)_appname _description: (NSString *)_description _version: (NSString *)_version noKApp: (BOOL)noKApp;
+ init: (int)_argc _argv: (NSString *)_argv _appname: (NSString *)_appname _description: (NSString *)_description _version: (NSString *)_version ;

/** 
 Initialize class.

 This function should be called as the very first thing in
  your application.

*/
+ init: (int)_argc _argv: (NSString *)_argv about: (KAboutData*)about noKApp: (BOOL)noKApp;
+ init: (int)_argc _argv: (NSString *)_argv about: (KAboutData*)about ;

/** 
 Initialize Class

 This function should be called as the very first thing in
  your application.
 This method is exactly the same as calling
 @ref init(0,0, const KAboutData *about, true)
 This method will rarely be used

   
*/
+ init: (KAboutData*)about;

/** 
 Add options to your application.

 You must make sure that all possible options have been added before
 any class uses the command line arguments. 

 The list of options should look like this:

 static KCmdLineOptions options[] =
 {
    { "option1 <argument>", I18N_NOOP("Description 1"), "default" },
    { "o", 0, 0 },
    { "option2", I18N_NOOP("Description 2"), 0 },
    { "nooption3", I18N_NOOP("Description 3"), 0 },
    { 0, 0, 0}
 }

 In BNF:
 cmd = myapp [options] file
 options = (option)*
 option = --option1 <argument> | 
          (-o | --option2 | --nooption2) |
          ( --option3 | --nooption3 )

 Instead of "--option3" one may also use "-option3"

 Usage examples:

*/
//+ addCmdLineOptions: (KCmdLineOptions*)options name: (NSString *)name identifier: (NSString *)identifier afterId: (NSString *)afterId;
//+ addCmdLineOptions: (KCmdLineOptions*)options ;

/** 
 Access parsed arguments.

 This function returns all command line arguments that your code
 handles. If unknown command-line arguments are encountered the program
 is aborted and usage information is shown. 

*/
+ (KCmdLineArgs*) parsedArgs: (NSString *)identifier;
+ (KCmdLineArgs*) parsedArgs;

/** 
 Get the CWD (Current Working Directory) associated with the
 current command line arguments.

 Typically this is needed in -[KUniqueApplication newInstance]
 since the CWD of the process may be different from the CWD
 where the user started a second instance.

*/
+ (NSString *) cwd;

/** 
 Get the appname according to argv[0]

*/
+ (NSString *) appName;

/** 
 Print the usage help to stdout and exit.

*/
+ usage: (NSString *)identifier;
+ usage;

/** 
 Print an error to stderr and the usage help to stdout and exit.

*/
+ usage: (NSString *)error;

/** 
 Enable i18n to be able to print a translated error message.

 N.B.: This function leaks memory, therefore you are expected to exit 
 afterwards (e.g., by calling @ref -usage).

*/
+ enable_i18n;

/** 
 Used by @ref url
 Made public for apps that don't use KCmdLineArgs

*/
+ (KURL*) makeURL: (NSString *)urlArg;

/** 
 Made public for apps that don't use KCmdLineArgs
 To be done before @ref makeURL, to set the current working
 directory in case @ref makeURL needs it.
   
*/
+ setCwd: (NSString *)cwd;

/** 

  Constructor.
   
*/
//- initWithCmdLineOptions: (KCmdLineOptions*)_options _id: (NSString *)_id _name: (NSString *)_name;

/** 

  Use @ref -clear if you want to free up some memory.

  Destructor.
   
*/
- (void) dealloc;
@end

#endif
