/* Assume In.java has been downloaded to this directory
 * URL for file and documentation: http://www.cs.princeton.edu/introcs/stdlib/In.java.html
 * (save it in the directory that contains this program)
 */

/** An instance holds a text with lie spans delimited */
public class LieData {
    
    /** lie spans in text are demarcated by matching spanStart/spanEnd pairs.
      * text is all lowercase, with no embedded spans.
      * spanStart and spanEnd must not be super- or substrings of each other, 
      * and must be at least one character long (once initialized). 
      */
    private String text; 
    private String spanStart;
    private String spanEnd;
    
    /** Constructor: a LieData whose text's lies are assumed to be delimited by 
      *  <span style="background-color: yellow;"> and </span>.
      * Preconditions: source is the name of a file containing all lower-case
      * text and containing at least one character but no embedded spans.
      */
    public LieData(String sourceFile) {
        text= (new In(sourceFile)).readAll();  
        spanStart= "<span style=\"background-color: yellow;\">";
        spanEnd= "</span>";
    }
    
    /** Constructor: a LieData whose text's lies are delimited by
      * matching spanStart and spanEnd pairs.
      * Preconditions: source is the name of a file containing all lower-case
      * text and containing at least one character but no embedded spans.
      * spanStart and spanEnd must not be super- or substrings of each other, 
      * and must be at least one character long. 
      */
    public LieData(String sourceFile, String spanStart, String spanEnd) {
        text= (new In(sourceFile)).readAll();
        this.spanStart= spanStart;
        this.spanEnd= spanEnd;
    }
    
    
    /** = a TallyPair whose hits (respectively misses) are the number of non-overlapping
      * occurrences of w in text within a span (respectively not within a span)
      * starting at i (if i >= text.length(), the TallyPair will have 0 hits and misses).   
      * Preconditions: none of w, spanStart, and spanEnd are super/substrings of one of the others;
      * text and w both contain at least one character
      * and are all lowercase; i >= 0.
      */
    // Note that this method is private, because it's a helper function
    private TallyPair countsFrom(String w, int i) {
        
        if (i >= text.length()) { // first base case
            return new TallyPair(); // 0 hits and misses
        }
        
        int iW= text.indexOf(w, i);
        if (iW == -1) { // second base case
            return new TallyPair(); // 0 hits and misses
        }
        
        // get counts for part of text AFTER w at iW
        TallyPair p= countsFrom(w,iW+w.length());
        
        if (isHit(w,iW)) {
            p.hits= p.hits+1;
        } else {
            p.misses= p.misses+1;
        }
        return p;
        
    }
    
    /** = a String of the form "hits: h; misses: m", where h (respectively m)
      * is the number of non-overlapping occurrences of w inside (respectively outside) delimited spans
      * in the text this LieFile stores.
      * Precondition: w is not a superstring or substring of either span delimiter, 
      * and contains at least one character, and is all lowercase;
      * the text from the source file is all lowercase, contains at least one character, 
      * no embedded spans.
      */
    public String counts(String w) {
        
        TallyPair totalCounts= countsFrom(w, 0);
        return totalCounts.toString();
    }
  
   
    /** = "w at index iW in text is a hit (in a span)"
      * Precondition:  iW is an index of an instance of w in text */
    // needs to be made public to use JUnit testing cases
    private boolean isHit(String w, int iW) {
                   
        // get index of closest spanEnd to the right of w
        int iEnd= text.indexOf(spanEnd, iW+w.length());
        
        // = "there is such a spanEnd and its matching spanStart
        // is before iW, so iW is in a span."
        return iEnd != -1 && 
            text.lastIndexOf(spanStart, iEnd) < iW; 
        
    }
    
}