/* LanguageTool, a natural language style checker
 * Copyright (C) 2013 Daniel Naber (http://www.danielnaber.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package org.languagetool.dev.wikipedia;

import xtc.tree.Location;

public class LocationHelper {

  private LocationHelper() {
  }

  /**
   * Get an absolute position (character-based) for a line/column-based location.
   */
  public static int absolutePositionFor(Location location, String text) {
    int line = 1;
    int col = 1;
    int pos = 0;
    int ignoreLevel = 0;
    boolean inReference = false;
    StringBuilder relevantLine = new StringBuilder();
    for (int i = 0; i < text.length(); i++) {
      char ch = text.charAt(i);
      if (line == location.line) {
        relevantLine.append(ch);
      }
      //System.out.println(line  + "/" + col + ", ignoreLevel: " + ignoreLevel);
      if (line == location.line && col == location.column) {
        return pos;
      }
      char prevCh = i > 0 ? text.charAt(i - 1) : '-';
      if (isReferenceStart(text, i)) {
        ignoreLevel++;
        inReference = true;
      } else if (inReference && (isFullReferenceEndTag(text, i) || isShortReferenceEndTag(text, i))) {
        ignoreLevel--;
        inReference = false;
        if (isShortReferenceEndTag(text, i)) {
          // this makes SuggestionReplacerTest.testReference2() work, not sure why
          col++;
        }
      } else if (isHtmlCommentStart(text, i)) {
        ignoreLevel++;
      } else if (isHtmlCommentEnd(text, i)) {
        ignoreLevel--;
      } else if (ch == '}' && prevCh == '}') {
        if (ignoreLevel > 0) {
          ignoreLevel--;
        }
      } else if (ch == '{' && prevCh == '{') {
        // ignore templates
        ignoreLevel++;
      } else if (ch == '\n' && ignoreLevel == 0) {
        line++;
        col = 1;
      } else if (ignoreLevel == 0) {
        col++;
      }
      pos++;
    }
    if (line == location.line && col == location.column) {
      return pos;
    }
    throw new RuntimeException("Could not find location " + location + " in text. " +
            "Max line/col was: " + line + "/" + col + ", Content of relevant line (" + location.line + "): '"
            + relevantLine + "' (" + relevantLine.length() + " chars)");
  }

  private static boolean isReferenceStart(String text, int i) {
    return text.startsWith("<ref", i);
  }

  private static boolean isFullReferenceEndTag(String text, int i) {
    return text.startsWith("</ref>", i);
  }

  private static boolean isShortReferenceEndTag(String text, int i) {
    return text.startsWith("/>", i);
  }

  private static boolean isHtmlCommentStart(String text, int i) {
    return text.startsWith("<!--", i);
  }

  private static boolean isHtmlCommentEnd(String text, int i) {
    return text.startsWith("-->", i);
  }

}
