package lux.lucene;

import java.io.IOException;

import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.store.Directory;

public class LuxSearcher extends IndexSearcher {

  public LuxSearcher (Directory dir) throws IOException {
    super (dir);
  }

  public DocIdSetIterator search (Query query) throws IOException {
      return new DocIterator (query, false);
  }

  public DocIdSetIterator searchOrdered (Query query) throws IOException {
      return new DocIterator (query, true);
  }
  
  class DocIterator extends DocIdSetIterator {
      
      private final Weight weight;
      private final boolean ordered;
      private int nextReader;
      private int docID;
      private Scorer scorer;
      
      /**
       * @param query the lucene query whose results will be iterated
       * @param ordered whether the docs must be scored in order
       * @throws IOException
       */
      DocIterator (Query query, boolean ordered) throws IOException {
          weight = createNormalizedWeight(query);
          this.ordered = ordered;
          nextReader = 0;
          docID = -1;
          advanceScorer();
      }

      private void advanceScorer () throws IOException {
          while (nextReader < subReaders.length) {
              scorer = weight.scorer(subReaders[nextReader++], ordered, true);
              if (scorer != null) {
                  return;
              }
          }
          scorer = null;
      }
      
    @Override
    public int docID() {
        return docID;
    }

    @Override
    public int nextDoc() throws IOException {
        while (scorer != null) {
            docID = scorer.nextDoc();
            if (docID != NO_MORE_DOCS) {
                return docID;
            }
            advanceScorer();
        }
        return NO_MORE_DOCS;
    }

    @Override
    public int advance(int target) throws IOException {
        while (scorer != null) {
            docID = scorer.advance(target);
            if (docID != NO_MORE_DOCS) {
                return docID;
            }
            advanceScorer();
        }
        return NO_MORE_DOCS;
    }
      
  }
  
}
@@ -884,24 +884,105 @@
 int docID;%0D%0A
+      private int docBase; // add to docID which is relative to each sub-reader%0D%0A
       privat
@@ -995,24 +995,24 @@
 er scorer;%0D%0A
-
       %0D%0A    
@@ -1548,24 +1548,72 @@
 .length) %7B%0D%0A
+              docBase = docStarts%5BnextReader%5D;%0D%0A
             
@@ -2087,32 +2087,42 @@
     return docID
+ + docBase
 ;%0D%0A            %7D
@@ -2350,16 +2350,26 @@
 e(target
+ - docBase
 );%0D%0A    
@@ -2398,32 +2398,32 @@
 O_MORE_DOCS) %7B%0D%0A
-
                 
@@ -2430,24 +2430,34 @@
 return docID
+ + docBase
 ;%0D%0A         

rebase docIDs returned from subsearchers