1/*
2 * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
3 *
4 * This software is distributable under the BSD license. See the terms of the
5 * BSD license in the documentation provided with this software.
6 */
7package jline;
8
9import java.util.*;
10
11/**
12 *  <p>
13 *  A completor that contains multiple embedded completors. This differs
14 *  from the {@link ArgumentCompletor}, in that the nested completors
15 *  are dispatched individually, rather than delimited by arguments.
16 *  </p>
17 *
18 *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
19 */
20public class MultiCompletor implements Completor {
21    Completor[] completors = new Completor[0];
22
23    /**
24     *  Construct a MultiCompletor with no embedded completors.
25     */
26    public MultiCompletor() {
27        this(new Completor[0]);
28    }
29
30    /**
31     *  Construct a MultiCompletor with the specified list of
32     *  {@link Completor} instances.
33     */
34    public MultiCompletor(final List completors) {
35        this((Completor[]) completors.toArray(new Completor[completors.size()]));
36    }
37
38    /**
39     *  Construct a MultiCompletor with the specified
40     *  {@link Completor} instances.
41     */
42    public MultiCompletor(final Completor[] completors) {
43        this.completors = completors;
44    }
45
46    public int complete(final String buffer, final int pos, final List cand) {
47        int[] positions = new int[completors.length];
48        List[] copies = new List[completors.length];
49
50        for (int i = 0; i < completors.length; i++) {
51            // clone and save the candidate list
52            copies[i] = new LinkedList(cand);
53            positions[i] = completors[i].complete(buffer, pos, copies[i]);
54        }
55
56        int maxposition = -1;
57
58        for (int i = 0; i < positions.length; i++) {
59            maxposition = Math.max(maxposition, positions[i]);
60        }
61
62        // now we have the max cursor value: build up all the
63        // candidate lists that have the same cursor value
64        for (int i = 0; i < copies.length; i++) {
65            if (positions[i] == maxposition) {
66                cand.addAll(copies[i]);
67            }
68        }
69
70        return maxposition;
71    }
72
73    public void setCompletors(final Completor[] completors) {
74        this.completors = completors;
75    }
76
77    public Completor[] getCompletors() {
78        return this.completors;
79    }
80}
81