/* gnu/regexp/RETokenRepeated.java
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.util.regex;

// import java.util.Vector;
// import java.util.Stack;

final class RETokenRepeated extends REToken {
    private REToken token;
    private int min,max;
    private boolean stingy;
    private boolean possessive;
    private int tokenFixedLength;
    
    RETokenRepeated(int subIndex, REToken token, int min, int max) {
	super(subIndex);
	this.token = token;
	this.min = min;
	this.max = max;
	if (token.returnsFixedLengthMatches()) {
	    tokenFixedLength = token.getMaximumLength();
	}
	else {
	    tokenFixedLength = -1;
	}
    }

    /** Sets the minimal matching mode to true. */
    void makeStingy() {
	stingy = true;
    }
    
    /** Queries if this token has minimal matching enabled. */
    boolean isStingy() {
	return stingy;
    }

    /** Sets possessive matching mode to true. */
    void makePossessive() {
        possessive = true;
    }

    /** Queries if this token has possessive matching enabled. */
    boolean isPossessive() {
        return possessive;
    }
    
    /**
     * The minimum length of a repeated token is the minimum length
     * of the token multiplied by the minimum number of times it must
     * match.
     */
    int getMinimumLength() {
	return (min * token.getMinimumLength());
    }

    int getMaximumLength() {
        if (max == Integer.MAX_VALUE) return Integer.MAX_VALUE;
	int tmax = token.getMaximumLength();
	if (tmax == Integer.MAX_VALUE) return tmax;
	return (max * tmax);
    }

    // The comment "MUST make a clone" below means that some tests
    // failed without doing clone(),

    private static class DoablesFinder {
	private REToken tk;
	private CharIndexed input;
	private REMatch rematch;
	private boolean findFirst;

        private DoablesFinder(REToken tk, CharIndexed input, REMatch mymatch) {
	    this.tk = tk;
	    this.input = input;
	    this.rematch = (REMatch) mymatch.clone(); // MUST make a clone
	    this.rematch.backtrackStack = new BacktrackStack();
	    findFirst = true;
	}

	private REMatch find() {
	    int origin = rematch.index;
	    REMatch rem;
	    if (findFirst) {
		rem = tk.findMatch(input, rematch);
		findFirst = false;
	    }
	    else {
	        while (true) {
		    if (rematch.backtrackStack.empty()) {
			rem = null;
			break;
		    }
		    BacktrackStack.Backtrack bt = rematch.backtrackStack.pop();
		    rem = bt.token.backtrack(bt.input, bt.match, bt.param);
		    if (rem != null) break;
		}
	    }
	    if (rem == null) return null;
	    if (rem.index == origin) rem.empty = true;
	    rematch = rem;
	    return (REMatch) rem.clone(); // MUST make a clone.
	}

	boolean noMore() {
	    return rematch.backtrackStack.empty();
	}
    }

    REMatch findMatch(CharIndexed input, REMatch mymatch) {
        if (tokenFixedLength >= 0) return findMatchFixedLength(input, mymatch);
	BacktrackStack stack = new BacktrackStack();
	stack.push(new StackedInfo(input, 0, mymatch, null, null));
	return findMatch(stack);
    }

    REMatch backtrack(CharIndexed input, REMatch mymatch, Object param) {
        if (tokenFixedLength >= 0) return backtrackFixedLength(input, mymatch, param);
	return findMatch((BacktrackStack)param);
    }

    private static class StackedInfo extends BacktrackStack.Backtrack {
        int numRepeats;
	int[] visited;
        DoablesFinder finder;
        StackedInfo(CharIndexed input, int numRepeats, REMatch match,
	        int[] visited, DoablesFinder finder) {
	    super(null, input, match, null);
            this.numRepeats = numRepeats;
	    this.visited = visited;
            this.finder = finder;
	}
    }

    private REMatch findMatch(BacktrackStack stack) {
        // Avoid using recursive calls.
	MAIN_LOOP:
	while (true) {

	if (stack.empty()) return null;
	StackedInfo si = (StackedInfo)(stack.peek());
	CharIndexed input = si.input;
        int numRepeats = si.numRepeats;
        REMatch mymatch = si.match;
	int[] visited = si.visited;
        DoablesFinder finder = si.finder;
        
	if (mymatch.backtrackStack == null)
	  mymatch.backtrackStack = new BacktrackStack();
	
	if (numRepeats >= max) {
	    stack.pop();
	    REMatch m1 = matchRest(input, mymatch);
	    if (m1 != null) {
		if (! stack.empty()) {
	            m1.backtrackStack.push(new BacktrackStack.Backtrack(
		        this, input, mymatch, stack));
		}
		return m1;
	    }
	    if (stingy) {
		continue MAIN_LOOP;
	    }
	    return null;
	}

        if (finder == null) {
	    finder = new DoablesFinder(token, input, mymatch);
	    si.finder = finder;
	}

        if (numRepeats < min) {
	    while (true) {
	        REMatch doable = finder.find();
	        if (doable == null) {
		    if (stack.empty()) return null;
		    stack.pop();
		    continue MAIN_LOOP;
		}
		if (finder.noMore()) stack.pop();
		int newNumRepeats = (doable.empty ? min : numRepeats + 1);
		stack.push(new StackedInfo(
		    input, newNumRepeats, doable, visited, null));
		continue MAIN_LOOP;
	    }
	}

	if (visited == null) visited = initVisited();

	if (stingy) {
	    REMatch nextMatch = finder.find();
	    if (nextMatch != null && !nextMatch.empty) {
	        stack.push(new StackedInfo(
	            input, numRepeats + 1, nextMatch, visited, null));
	    }
	    else {
		stack.pop();
	    }  	
	    REMatch m1 = matchRest(input, mymatch);
	    if (m1 != null) {
		if (!stack.empty()) {
	            m1.backtrackStack.push(new BacktrackStack.Backtrack(
		        this, input, mymatch, stack));
		}
	        return m1;
	    }
	    else {
		continue MAIN_LOOP;
	    }
	}

	visited = addVisited(mymatch.index, visited);

	DO_THIS:
	do {

	    boolean emptyMatchFound = false;

	    DO_ONE_DOABLE:
	    while (true) {

	    REMatch doable = finder.find();
	    if (doable == null) {
		break DO_THIS;
	    }
	    if (doable.empty) emptyMatchFound = true;

	    if (!emptyMatchFound) {
		int n = doable.index;
		if (! visitedContains(n, visited)) {
		    visited = addVisited(n, visited);
	        }
		else {
		    continue DO_ONE_DOABLE;
		}
	        stack.push(new StackedInfo(
		    input, numRepeats + 1, doable, visited, null));
	        REMatch m1 = findMatch(stack);
		if (possessive) {
		    return m1;
		}
		if (m1 != null) {
		    m1.backtrackStack.push(new BacktrackStack.Backtrack(
                        this, input, mymatch, stack));
		    return m1;
		}
	    }
	    else {
	        REMatch m1 = matchRest(input, doable);
		if (possessive) {
		    return m1;
		}
	        if (m1 != null) {
		    if (! stack.empty()) {
		        m1.backtrackStack.push(new BacktrackStack.Backtrack(
                            this, input, mymatch, stack));
		    } 
		    return m1;
		}
	    }

	    } // DO_ONE_DOABLE

	} while (false); // DO_THIS only once;

	if (!stack.empty()) {
	    stack.pop();
        }
	if (possessive) {
	    stack.clear();
	}
	REMatch m1 = matchRest(input, mymatch);
	if (m1 != null) {
	    if (! stack.empty()) {
	        m1.backtrackStack.push(new BacktrackStack.Backtrack(
	            this, input, mymatch, stack));
	    }
	    return m1;
	}

	} // MAIN_LOOP
    }

    boolean match(CharIndexed input, REMatch mymatch) {
	REMatch m1 = findMatch(input, mymatch);
	if (m1 != null) {
	    mymatch.assignFrom(m1);
	    return true;
	}
	return false;
    }    

    // Array visited is an array of character positions we have already
    // visited. visited[0] is used to store the effective length of the
    // array.
    private static int[] initVisited() {
	int[] visited = new int[32];
	visited[0] = 0;
	return visited;
    }

    private static boolean visitedContains(int n, int[] visited) {
	// Experience tells that for a small array like this,
	// simple linear search is faster than binary search.
	for (int i = 1; i < visited[0]; i++) {
	    if (n == visited[i]) return true;
	}
	return false;
    }

    private static int[] addVisited(int n, int[] visited) {
	if (visitedContains(n, visited)) return visited;
	if (visited[0] >= visited.length - 1) {
	    int[] newvisited = new int[visited.length + 32];
	    System.arraycopy(visited, 0, newvisited, 0, visited.length);
	    visited = newvisited;
	}
	visited[0]++;
	visited[visited[0]] = n;
	return visited;
    }

    private REMatch matchRest(CharIndexed input, final REMatch newMatch) {
	if (next(input, newMatch)) {
	    return newMatch;
	}
	return null;
    }

    private REMatch findMatchFixedLength(CharIndexed input, REMatch mymatch) {
	if (mymatch.backtrackStack == null)
	  mymatch.backtrackStack = new BacktrackStack();
        int numRepeats = token.findFixedLengthMatches(input, (REMatch)mymatch.clone(), max);
	if (numRepeats == Integer.MAX_VALUE) numRepeats = min;
	int count = numRepeats - min + 1;
        if (count <= 0) return null;
	int index = 0;
	if (!stingy) index = mymatch.index + (tokenFixedLength * numRepeats);
	else index = mymatch.index + (tokenFixedLength * min);
	return findMatchFixedLength(input, mymatch, index, count);
    }

    private REMatch backtrackFixedLength(CharIndexed input, REMatch mymatch,
    	    Object param) {
	int[] params = (int[])param;
        int index = params[0];
	int count = params[1];
	return findMatchFixedLength(input, mymatch, index, count);
    }        

    private REMatch findMatchFixedLength(CharIndexed input, REMatch mymatch,
    	    	    int index, int count) {
        REMatch tryMatch = (REMatch) mymatch.clone();
	while (true) {
	    tryMatch.index = index;
	    REMatch m = matchRest(input, tryMatch);
	    count--;
	    if (stingy) index += tokenFixedLength;
	    else index -= tokenFixedLength;
	    if (possessive) return m;
	    if (m != null) {
		if (count > 0) {
	            m.backtrackStack.push(new BacktrackStack.Backtrack(
		        this, input, mymatch,
			new int[] {index, count}));
	        }
		return m;
	    }
	    if (count <= 0) return null;
	}
    }		    

    void dump(StringBuffer os) {
	os.append("(?:");
	token.dumpAll(os);
	os.append(')');
	if ((max == Integer.MAX_VALUE) && (min <= 1))
	    os.append( (min == 0) ? '*' : '+' );
	else if ((min == 0) && (max == 1))
	    os.append('?');
	else {
	    os.append('{').append(min);
	    if (max > min) {
		os.append(',');
		if (max != Integer.MAX_VALUE) os.append(max);
	    }
	    os.append('}');
	}
	if (stingy) os.append('?');
    }
}
