package org.incava.jagol;

import java.io.*;
import java.util.*;
import org.incava.log.Log;


/**
 * Base class of all options, except for booleans.
 */
public abstract class NonBooleanOption extends Option
{
    public NonBooleanOption(String longName, String description)
    {
        super(longName, description);
    }

    /**
     * Sets from a list of command-line arguments. Returns whether this option
     * could be set from the current head of the list.
     */
    public boolean set(String arg, List args) throws OptionException
    {
        // String arg = (String)args.get(0);

        Log.log("considering: " + arg);
        
        if (arg.equals("--" + longName)) {
            Log.log("matched long name");

            // args.remove(0);
            if (args.size() == 0) {
                throw new InvalidTypeException(longName + " expects following " + getType() + " argument");
            }
            else {
                String value = (String)args.remove(0);
                setValue(value);
            }
        }
        else if (arg.startsWith("--" + longName + "=")) {
            Log.log("matched long name + equals");

            // args.remove(0);
            int pos = ("--" + longName + "=").length();
            Log.log("position: " + pos);
            if (pos >= arg.length()) {
                throw new InvalidTypeException(longName + " expects argument of type " + getType());
            }
            else {
                String value = arg.substring(pos);
                setValue(value);
            }
        }
        else if (shortName != 0 && arg.equals("-" + shortName)) {
            Log.log("matched short name");

            // args.remove(0);
            if (args.size() == 0) {
                throw new InvalidTypeException(shortName + " expects following " + getType() + " argument");
            }
            else {
                String value = (String)args.remove(0);
                setValue(value);
            }                
        }
        else {
            Log.log("not a match");
            return false;
        }
        Log.log("matched");
        return true;
    }

    /**
     * Returns the option type.
     */
    protected abstract String getType();

}
