/*
 *
 *  argsParser.java, v1.0, 2005
 *  Program arguments parser
 *  
 *  constructor:
 *	argsParser( String[] args, String optstr )
 *  method:
 *	getopt()
 *	// getopt_long ... net yet
 *
 */


public class argsParser {
    
    
    //protected boolean opterr = false;
    protected int optopt;	// the current option
    protected String optarg;	// the current argument
    protected int optind = 0;	// option index
    
    private String[] argv;	// arguments passed to the program 
    private String optstr;	// a string representing valid options
    
    
    /*************
    * Constructor
    **************/
    
    /** constructor
    *	@param argument list passed to the program
    *	@param valid options description
    **/
    public argsParser( String[] argv, String optstr ) {
	this.argv   = argv;
	this.optstr = optstr;
    }
    
    /*********
    * Method
    *********/
    
    /** parse argument one by one and return a char representation
    *	of the current valid option or '?' for an invalid option,
    *	set the current argument value to the optarg property
    **/
    private int nextind = 1;
    public int getopt() {
	
	optarg = null;

	// set th end of option scanning (if needed)
	if (optind == argv.length) return -1;
	if (argv[optind].equals("--") || argv[optind].startsWith("--")) return -1;
	
	
	String next = argv[optind]; // parse the next argument
	//int retopt  = optopt;	    // by default set the return value to the current option
	
	// for a new option found :
	// chech if this option are valid or not
	// check if this option require an argument or not
	if (next.startsWith("-")) {
	    
	    optopt = next.charAt(nextind);
	    int i  = optstr.indexOf(optopt);
	    int c  = optstr.indexOf(":", i);
	    
	    if ( i!=-1 )
	    { // for a valid option
		if ( c==-1 || (( c!=optstr.length()-1) && (optstr.charAt(c+1)==':')) )
		{ // optional argument
		    if ( next.charAt(next.length()-1) != optopt )
		    { // for a 'grouped' options or
		      // in case of if the argument is attach to the option value
			nextind++;
			if ( optstr.indexOf(next.charAt(nextind))==-1 )
			    getarg(next.substring(nextind)); // attach
			return optopt;
		    }
		    else
		    { // for a single option
			optind++;
			if ( optind == argv.length || argv[optind].startsWith("-") ) return optopt;
			else return getopt();
		    }
		}
		else
		{ // argument require
		    if ( next.length()>2 )
		    { // argument is join to the option value
			getarg(next.substring(2));
			return optopt;
		    }
		    else
		    {
			optind++;
			if ( optind == argv.length || argv[optind].startsWith("-") ) return ':';
			else return getopt();
		    }
		}
	    }
	    else
	    { // for an invalid option
		optind++;
		return '?';
	    }
	}

	// get argument value and
	// prepare the next option scanning
	getarg(next);
	return optopt;
    }
    
    /** set optarg as the new founded argument
    *	@param argument string value
    **/
    private void getarg( String arg ) {
	optarg  = arg;
	nextind = 1;
	optind++;
    }
}
