/*
 * Command Line Management
 *
 * Author(s) : Joshua Shapiro
 *
 * File: getopt.hh
 * Created: Mon Aug 27 10:15:57 CDT 2001
 *
 */

#ifndef __GETOPTIONS
#define __GETOPTIONS


#include <iostream>
#include <string>
#include <cstring>
using namespace std;


class optError {
    string err;
public:
    optError (string s) { err = s; }
    string getMessage () { return err; }
};

class getOptions {
    char **arguments;
    int argNumber;
    string control;
    int pos;
public:
    /* Constructors and Destructors */
    getOptions (char *argv[], char *ctrl)
    {
	for (int i = 0; argv[i]; i++)
	    argNumber = i;
	arguments = new char* [argNumber];
	for (int i = 0; i < argNumber; i++)
	    arguments[i] = argv[i];
	control = ctrl;
	pos = 0;
    }
	
    getOptions (int argc, char *argv[], char *ctrl)
    {
	argNumber = argc;
	arguments = new char* [argNumber];
	for (int i = 0; i < argNumber; i++)
	    arguments[i] = argv[i];
	control = ctrl;
	pos = 0;
    }
    ~getOptions () { delete[] arguments;}

    /* Members Functions */
    // Reconsider last n arguments ("-i" and "10" are two different entitites for this function)
    void putBack (int n = 1) throw (optError) 
    { 
	if (pos > 0)
	    pos--;
	else throw optError ("Can't putBack past beginning of argument list");
    }
    
    // Skip over the next n arguments (same, "-i" and "10" are two different entities)
    void skipNext (int n = 1) throw (optError) 
    {
	if (pos < argNumber - 1)
	    pos++;
	else throw optError ("Can't skipNext at end of argument list");
    }
    // Get the type of the next argument
    // Example: -i 10 --> this operation return 'i' 
    //   returned characters are contained by "char *ctrl" provided at initialization 
    //   unknown ones must generate an exception, e.g.: ./a.out -p 20 -i 10 -h --> -p is not specified
    char getNextType () throw (optError);

    // Read the valueof the next argument (Example: -i 10 --> this operation sets arg to 10)
    //   if the wrong method is called an exception must be thrown!
    void getNext (int&) throw (optError);
    void getNext (double&) throw (optError);
    void getNext (string&) throw (optError);
    
       /* Friend Operators */
      // These operations just call specific one of the getNext-s presented above ... )
      friend getOptions& operator >> (getOptions& opt, int&) throw (optError);
      friend getOptions& operator >> (getOptions& opt, double&) throw (optError);
      friend getOptions& operator >> (getOptions& opt, string&) throw (optError);


   };

#endif // __GETOPTIONS



