package jp.sourceforge.projects.ee2e.core.editors;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.BadLocationException;
/**
 * To change this generated comment edit the template variable "typecomment":
 * Window&gt;Preferences&gt;Java&gt;Templates.
 * To enable and disable the creation of type comments go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation.
 *
 * @author Toshikazu Ando [ ando@park.ruru.ne.jp ]
 */
public final class EE2ELispBase {
    private EE2ELispBase() {
    }
    public static EE2ELispBase get() {
        if (instance == null) {
            instance = new EE2ELispBase();
        }
        return instance;
    }
    private static EE2ELispBase instance;
    /**
     * Move point to beginning of current line.
     * With argument N not nil or 1, move forward N - 1 lines first.
     * If scan reaches end of buffer, stop there without error.
     * Method beginningOfLine.
     * @param offset
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int beginningOfLine(int offset, IDocument document)
        throws BadLocationException {
        if (offset <= 0) {
            return 0;
        }
        offset = findCharsBackward(offset - 1, "\r\n", document);
        if (offset <= 0) {
            return 0;
        }
        offset++;
        if (document.getLength() <= offset) {
            offset = document.getLength() - 1;
        }
        return offset;
    }

    /**
     * Move point to end of current line.
     * @param offset
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int endOfLine(int offset, IDocument document)
        throws BadLocationException {
        offset = findCharsForward(offset, "\r\n", document);
        if (document.getLength() < offset) {
            offset = document.getLength();
        }
        offset--;
        if (offset < 0) {
            offset = 0;
        }
        return offset;
    }

    /**
     * Move point backward, stopping after a char not in STRING, or at pos LIM.
     * @see #skipCharsForward for details.
     * @param offset
     * @param ans
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int findCharsBackward(int offset, String ans, IDocument document)
        throws BadLocationException {
        if (document.getLength() <= offset) {
            offset = document.getLength() - 1;
        }
        for (; 0 < offset; offset--) {
            char dChar = document.getChar(offset);
            int i;
            for (i = 0; i < ans.length(); i++) {
                if (dChar == ans.charAt(i)) {
                    return offset;
                }
            }
        }
        return offset;
    }

    /**
     * Move point forward, stopping before a char not in STRING, or at pos LIM.
     * @param offset
     * @param ans
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int findCharsForward(int offset, String ans, IDocument document)
        throws BadLocationException {
        return findCharsForward(offset, ans, document, document.getLength());
    }

    /**
     * Move point forward, stopping before a char not in STRING, or at pos LIM.
     * @param offset
     * @param ans
     * @param document
     * @param limmit
     * @return int
     * @throws BadLocationException
     */
    public int findCharsForward(
        int offset,
        String ans,
        IDocument document,
        int limmit)
        throws BadLocationException {
        for (; offset < limmit; offset++) {
            char dChar = document.getChar(offset);
            int i;
            for (i = 0; i < ans.length(); i++) {
                if (dChar == ans.charAt(i)) {
                    return offset;
                }
            }
        }
        return offset;
    }

    /**
     * Move point backward, stopping after a char not in STRING, or at pos LIM.
     * @see #skipCharsForward for details.
     * @param offset
     * @param ans
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int skipCharsBackward(int offset, String ans, IDocument document)
        throws BadLocationException {
        return skipCharsBackward(offset, ans, document, 0);
    }

    /**
     * Move point backward, stopping after a char not in STRING, or at pos LIM.
     * @see #skipCharsForward for details.
     * @param offset
     * @param ans
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int skipCharsBackward(
        int offset,
        String ans,
        IDocument document,
        int limit)
        throws BadLocationException {
        for (; limit < offset; offset--) {
            char dChar = document.getChar(offset);
            int i;
            for (i = 0; i < ans.length(); i++) {
                if (dChar == ans.charAt(i)) {
                    break;
                }
            }
            if (ans.length() <= i) {
                break;
            }
        }
        return offset;
    }

    /**
    * Move point forward, stopping before a char not in STRING, or at pos LIM.
    * @param offset
    * @param ans
    * @param document
    * @return int
    * @throws BadLocationException
    */
    public int skipCharsForward(int offset, String ans, IDocument document)
        throws BadLocationException {
        return skipCharsForward(offset, ans, document, document.getLength());
    }

    /**
     * Move point forward, stopping before a char not in STRING, or at pos LIM.
     * @param offset
     * @param ans
     * @param document
     * @param limmit
     * @return int
     * @throws BadLocationException
     */
    public int skipCharsForward(
        int offset,
        String ans,
        IDocument document,
        int limmit)
        throws BadLocationException {
        for (; offset < limmit; offset++) {
            char dChar = document.getChar(offset);
            int i;
            for (i = 0; i < ans.length(); i++) {
                if (dChar == ans.charAt(i)) {
                    break;
                }
            }
            if (ans.length() <= i) {
                break;
            }
        }
        return offset - 1;
    }

    /**<pre>
    *(defun epoxml-indent-to (number)
    *  "指定された number だけインデントを入れる"
    *  (beginning-of-line) ; 行頭に移動
    *  (if (&lt; number 0) (setq number 0)) ; 一応保険のため
    *  (let ((start) (end) (len) (char-data))
    *    (setq start (point))
    *    (skip-chars-forward " \t") ; 文字始めまで移動
    *    (setq end (point)
    *     len (- end start)
    *     char-data (char-before))
    *    (if (and (= number len) char-data (not (= char-data ?\t))) nil
    *      (delete-region start end) ; 空白を消す
    *      (indent-to number)))) ; 必要空白追加
    * </pre>
     * @param offset
     * @param size
     * @param document
     * @throws BadLocationException
    **/
    protected void indentTo(int offset, int size, IDocument document)
        throws BadLocationException {
        if (size < 0) {
            size = 0;
        }
        int realSize = 0;
        int len = 0;
        boolean tabNotUsedFlag = true;
        int begin = this.beginningOfLine(offset, document);
        for (int i = begin; i < document.getLength(); i++) {
            if (document.getChar(i) == ' ') {
                realSize++;
                len++;
            } else if (document.getChar(i) == '\t') {
                realSize++;
                len += 4;
                tabNotUsedFlag = false;
            } else {
                break;
            }
        }
        if ((size == len) && tabNotUsedFlag) {
            return;
        }
        StringBuffer buff = new StringBuffer();
        for (int i = 0; i < size; i++) {
            buff.append(' ');
        }
        document.replace(begin, realSize, buff.toString());
    }

    /**<pre>
    *(defun epoxml-indent-len ()
    *  "インデント数を計算する"
    *  (beginning-of-line) ; 行頭に移動
    *  (let ((start))
    *    (setq start (point))
    *    (skip-chars-forward " \t") ; 文字始めまで移動
    *    (- (point) start)))
    *</pre>
     * @param offset
     * @param document
     * @return int
     * @throws BadLocationException
     */
    public int indentLen(int offset, IDocument document)
        throws BadLocationException {
        int begin = this.beginningOfLine(offset, document);
        int len = 0;
        for (int i = begin; i < document.getLength(); i++) {
            if (document.getChar(i) == ' ') {
                len++;
            } else if (document.getChar(i) == '\t') {
                len += 4;
            } else {
                break;
            }
        }
        return len;
    }

    protected boolean lookingAt(
        int argumentOffset,
        String target,
        IDocument document)
        throws BadLocationException {
        int offset = argumentOffset;
        for (int i = 0; i < target.length(); i++) {
            if (document.getLength() <= (offset + i)) {
                return false;
            }
            char targetChar = target.charAt(i);
            char documentChar = document.getChar(offset + i);
            if (targetChar != documentChar) {
                return false;
            }
        }
        return true;
    }
}
