/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.editor;

import java.io.Reader;
import java.io.Writer;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Segment;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
import org.netbeans.spi.lexer.MutableTextInput;

/**
* Various text analyzes over the document
*
* @author Miloslav Metelka
* @version 1.00
*/

public class Analyzer {

    /** Platform default line separator */
    private static Object platformLS;

    /** Empty char array */
    public static final char[] EMPTY_CHAR_ARRAY = new char[0];

    /** Buffer filled by spaces used for spaces filling and tabs expansion */
    private static char spacesBuffer[] = new char[] { ' ' };

    /** Buffer filled by tabs used for tabs filling */
    private static char tabsBuffer[] = new char[] { '\t' };

    /** Cache up to 50 spaces strings */
    private static final int MAX_CACHED_SPACES_STRING_LENGTH = 50;

    /** Spaces strings cache. */
    private static final String[] spacesStrings
        = new String[MAX_CACHED_SPACES_STRING_LENGTH + 1];

    static {
        spacesStrings[0] = "";
        spacesStrings[MAX_CACHED_SPACES_STRING_LENGTH]
            = new String(getSpacesBuffer(MAX_CACHED_SPACES_STRING_LENGTH),
                0, MAX_CACHED_SPACES_STRING_LENGTH);
    }

    private Analyzer() {
        // no instantiation
    }

    /** Get platform default line separator */
    public static Object getPlatformLS() {
        if (platformLS == null) {
            platformLS = System.getProperty("line.separator"); // NOI18N
        }
        return platformLS;
    }

    /** Test line separator on given semgment. This implementation simply checks
    * the first line of file but it can be redefined to do more thorough test.
    * @param seg segment where analyzes are performed
    * @return line separator type found in the file
    */
    public static String testLS(char chars[], int len) {
        for (int i = 0; i < len; i++) {
            switch (chars[i]) {
            case '\r':
                if (i + 1 < len && chars[i + 1] == '\n') {
                    return BaseDocument.LS_CRLF;
                } else {
                    return BaseDocument.LS_CR;
                }

            case '\n':
                return BaseDocument.LS_LF;
            }
        }
        return null; // signal unspecified line separator
    }

    /** Convert text with generic line separators to line feeds (LF).
    * As the linefeeds are one char long there is no need to allocate
    * another buffer since the only possibility is that the returned
    * length will be smaller than previous (if there were some CRLF separators.
    * @param chars char array with data to convert
    * @param len valid portion of chars array
    * @return new valid portion of chars array after conversion
    */   
    public static int convertLSToLF(char chars[], int len) {
        int tgtOffset = 0;
        short lsLen = 0; // length of separator found
        int moveStart = 0; // start of block that must be moved
        int moveLen; // length of data moved back in buffer

        for (int i = 0; i < len; i++) {
            // first of all - there's no need to handle single '\n'
            if (chars[i] == '\r') { // '\r' found
                if (i + 1 < len && chars[i + 1] == '\n') { // '\n' follows
                    lsLen = 2; // '\r\n'
                } else {
                    lsLen = 1; // only '\r'
                }
            } else if (chars[i] == LineSeparatorConversion.LS || chars[i] == LineSeparatorConversion.PS) {
                lsLen = 1;
            }

            if (lsLen > 0) {
                moveLen = i - moveStart;
                if (moveLen > 0) {
                    if (tgtOffset != moveStart) { // will need to arraycopy
                        System.arraycopy(chars, moveStart, chars, tgtOffset, moveLen);
                    }
                    tgtOffset += moveLen;
                }
                chars[tgtOffset++] = '\n';
                moveStart += moveLen + lsLen; // skip separator
                i += lsLen - 1; // possibly skip '\n'
                lsLen = 0; // signal no separator found
            }
        }

        // now move the rest if it's necessary
        moveLen = len - moveStart;
        if (moveLen > 0) {
            if (tgtOffset != moveStart) {
                System.arraycopy(chars, moveStart, chars, tgtOffset, moveLen);
            }
            tgtOffset += moveLen;
        }

        return tgtOffset; // return current length
    }

    /** Convert string with generic line separators to line feeds (LF).
    * @param text string to convert
    * @return new string with converted LSs to LFs
    */   
    public static String convertLSToLF(String text) {
        char[] tgtChars = null;
        int tgtOffset = 0;
        short lsLen = 0; // length of separator found
        int moveStart = 0; // start of block that must be moved
        int moveLen; // length of data moved back in buffer
        int textLen = text.length();

        for (int i = 0; i < textLen; i++) {
            // first of all - there's no need to handle single '\n'
            if (text.charAt(i) == '\r') { // '\r' found
                if (i + 1 < textLen && text.charAt(i + 1) == '\n') { // '\n' follows
                    lsLen = 2; // '\r\n'
                } else {
                    lsLen = 1; // only '\r'
                }
            } else if (text.charAt(i) == LineSeparatorConversion.LS || text.charAt(i) == LineSeparatorConversion.PS) {
                lsLen = 1;
            }

            if (lsLen > 0) {
                if (tgtChars == null) {
                    tgtChars = new char[textLen];
                    text.getChars(0, textLen, tgtChars, 0); // copy whole array
                }
                moveLen = i - moveStart;
                if (moveLen > 0) {
                    if (tgtOffset != moveStart) { // will need to arraycopy
                        text.getChars(moveStart, moveStart + moveLen, tgtChars, tgtOffset);
                    }
                    tgtOffset += moveLen;
                }
                tgtChars[tgtOffset++] = '\n';
                moveStart += moveLen + lsLen; // skip separator
                i += lsLen - 1; // possibly skip '\n'
                lsLen = 0; // signal no separator found
            }
        }

        // now move the rest if it's necessary
        moveLen = textLen - moveStart;
        if (moveLen > 0) {
            if (tgtOffset != moveStart) {
                text.getChars(moveStart, moveStart + moveLen, tgtChars, tgtOffset);
            }
            tgtOffset += moveLen;
        }

        return (tgtChars == null) ? text : new String(tgtChars, 0, tgtOffset);
    }

    public static boolean isSpace(String s) {
        int len = s.length();
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) != ' ') {
                return false;
            }
        }
        return true;
    }

    /** Return true if the array contains only space chars */
    public static boolean isSpace(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (chars[offset++] != ' ') { //NOI18N
                return false;
            }
            len--;
        }
        return true;
    }

    /** Return true if the array contains only space or tab chars */
    public static boolean isWhitespace(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (!Character.isWhitespace(chars[offset])) {
                return false;
            }
            offset++;
            len--;
        }
        return true;
    }

    /** Return the first index that is not space */
    public static int findFirstNonTab(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (chars[offset] != '\t') { //NOI18N
                return offset;
            }
            offset++;
            len--;
        }
        return -1;
    }

    /** Return the first index that is not space */
    public static int findFirstNonSpace(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (chars[offset] != ' ') { //NOI18N
                return offset;
            }
            offset++;
            len--;
        }
        return -1;
    }

    /** Return the first index that is not space or tab or new-line char */
    public static int findFirstNonWhite(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (!Character.isWhitespace(chars[offset])) {
                return offset;
            }
            offset++;
            len--;
        }
        return -1;
    }

    /** Return the last index that is not space or tab or new-line char */
    public static int findLastNonWhite(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        int i = offset + len - 1;
        while (i >= offset) {
            if (!Character.isWhitespace(chars[i])) {
                return i;
            }
            i--;
        }
        return -1;
    }

    /** Count the number of line feeds in char array.
    * @return number of LF characters contained in array.
    */
    public static int getLFCount(char chars[]) {
        return getLFCount(chars, 0, chars.length);
    }

    public static int getLFCount(char chars[], int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        int lfCount = 0;
        while (len > 0) {
            if (chars[offset++] == '\n') { //NOI18N
                lfCount++;
            }
            len--;
        }
        return lfCount;
    }

    public static int getLFCount(String s) {
        int lfCount = 0;
        int len = s.length();
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) == '\n') { //NOI18N
                lfCount++;
            }
        }
        return lfCount;
    }

    public static int findFirstLFOffset(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (chars[offset++] == '\n') { //NOI18N
                return offset - 1;
            }
            len--;
        }
        return -1;
    }

    public static int findFirstLFOffset(String s) {
        int len = s.length();
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) == '\n') { //NOI18N
                return i;
            }
        }
        return -1;
    }

    public static int findFirstTab(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        while (len > 0) {
            if (chars[offset++] == '\t') { //NOI18N
                return offset - 1;
            }
            len--;
        }
        return -1;
    }

    public static int findFirstTabOrLF(char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N

        while (len > 0) {
            switch (chars[offset++]) {
            case '\t': //NOI18N
            case '\n': //NOI18N
                return offset - 1;
            }
            len--;
        }
        return -1;
    }

    /** Reverses the order of characters in the array. It works from
    * the begining of the array, so no offset is given.
    */
    public static  void reverse(char[] chars, int len) {
        for (int i = ((--len - 1) >> 1); i >= 0; --i) {
            char ch = chars[i];
            chars[i] = chars[len - i];
            chars[len - i] = ch;
        }
    }

    public static boolean equals(String s, char[] chars) {
        return equals(s, chars, 0, chars.length);
    }

    public static boolean equals(String s, char[] chars, int offset, int len) {
        assert offset + len <= chars.length : "Invalid parameters: " //NOI18N
                + "offset = " + offset //NOI18N
                + ", len = " + len //NOI18N
                + ", chars.length = " + chars.length; //NOI18N
        
        if (s.length() != len) {
            return false;
        }
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) != chars[offset + i]) {
                return false;
            }
        }
        return true;
    }

    /** Do initial reading of document. Translate any line separators
    * found in document to line separators used by document. It also cares
    * for elements that were already created on the empty document. Although
    * the document must be empty there can be already marks created. Initial
    * read is equivalent to inserting the string array of the whole document
    * size at position 0 in the document. Therefore all the marks that are
    * not insertAfter are removed and reinserted to the end of the document
    * after the whole initial read is finished.
    * @param doc document for which the initialization is performed
    * @param reader reader from which document should be read
    * @param lsType line separator type
    * @param testLS test line separator of file and if it's consistent, use it
    * @param markDistance the distance between the new syntax mark is put
    */
    public static void initialRead(BaseDocument doc, Reader reader, boolean testLS)
    throws IOException {
        // document MUST be empty
        if (doc.getLength() > 0) {
            return;
        }

        // for valid reader read the document
        if (reader != null) {
            // Size of the read buffer
            int readBufferSize = ((Integer)doc.getProperty(EditorPreferencesKeys.READ_BUFFER_SIZE)).intValue();

            if (testLS) {
                // Construct a reader that searches for initial line separator type
                reader = new LineSeparatorConversion.InitialSeparatorReader(reader);
            }

            /* buffer into which the data from file will be read */
            LineSeparatorConversion.ToLineFeed toLF = new LineSeparatorConversion.ToLineFeed(reader, readBufferSize);
            
            boolean firstRead = true; // first cycle of reading from stream
            int pos = 0; // actual position in the document data
            int line = 0; // Line counter
            int maxLineLength = 0; // Longest line found
            int lineStartPos = 0; // Start offset of the last line
            int markCount = 0; // Total mark count - for debugging only

/*            // array for getting mark array from renderer inner class
            Mark[] origMarks = new Mark[doc.marks.getItemCount()];
            ObjectArrayUtilities.copyItems(doc.marks, 0, origMarks.length,
                origMarks, 0);

            // now remove all the marks that are not insert after
            for (int i = 0; i < origMarks.length; i++) {
                Mark mark = origMarks[i];
                if (!(mark.getInsertAfter()
                        || (mark instanceof MarkFactory.CaretMark))
                   ) {
                    try {
                        mark.remove();
                    } catch (InvalidMarkException e) {
                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
                            e.printStackTrace();
                        }
                    }
                }
            }
*/

            // Enter the loop where all data from reader will be read
            Segment text = toLF.nextConverted();
            // Switch off token hierarchy before loading in case the document is large
            // and it will be read by multiple buffers
            TokenHierarchy<?> hi = TokenHierarchy.get(doc);
            MutableTextInput<? extends Document> mti = (MutableTextInput<? extends Document>)doc.getProperty(MutableTextInput.class);
            boolean deactivateTokenHierarchy = (mti != null && toLF.isReadWholeBuffer()); // Likely a next chunk(s) will follow
            if (deactivateTokenHierarchy) {
                mti.tokenHierarchyControl().setActive(false);
            }
            try {
                while (text != null) {
                    try {
                        doc.insertString(pos, new String(text.array, text.offset, text.count), null);
                    } catch (BadLocationException e) {
                        throw new IllegalStateException(e.toString());
                    }
                    pos += text.count;
                    text = toLF.nextConverted();
                }
            } finally {
                if (deactivateTokenHierarchy) {
                    mti.tokenHierarchyControl().setActive(true);
                }
            }

            if (testLS) {
                doc.putProperty(BaseDocument.READ_LINE_SEPARATOR_PROP,
                    ((LineSeparatorConversion.InitialSeparatorReader)reader).getInitialSeparator());
//                            if (doc.getProperty(BaseDocument.WRITE_LINE_SEPARATOR_PROP) == null) {
//                                doc.putProperty(BaseDocument.WRITE_LINE_SEPARATOR_PROP, newLS);
//                            }
// The property above is left empty so the write() will default to the READ_LINE_SEPARATOR_PROP
            }

/*            // Now reinsert marks that were removed at begining to the end
            for (int i = 0; i < origMarks.length; i++) {
                Mark mark = origMarks[i];
                if (!(mark.getInsertAfter()
                        || (mark instanceof MarkFactory.CaretMark))
                   ) {
                    try {
                        origMarks[i].insert(doc, pos);
                    } catch (InvalidMarkException e) {
                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
                            e.printStackTrace();
                        }
                    } catch (BadLocationException e) {
                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
                            e.printStackTrace();
                        }
                    }
                }
            }
 */

                // Set the line limit document property
// [PENDING]                doc.putProperty(BaseDocument.LINE_LIMIT_PROP, Integer.valueOf(maxLineLength));

        }
    }

    /** Read from some reader and insert into document */
    static void read(BaseDocument doc, Reader reader, int pos)
    throws BadLocationException, IOException {
        int readBufferSize = ((Integer)doc.getProperty(EditorPreferencesKeys.READ_BUFFER_SIZE)).intValue();
        LineSeparatorConversion.ToLineFeed toLF
            = new LineSeparatorConversion.ToLineFeed(reader, readBufferSize);
        
        Segment text = toLF.nextConverted();
        while (text != null) {
            doc.insertString(pos, new String(text.array, text.offset, text.count), null);
            pos += text.count;
            text = toLF.nextConverted();
        }
    }

    /** Write from document to some writer */
    static void write(BaseDocument doc, Writer writer, int pos, int len)
    throws BadLocationException, IOException {
        String lsType = (String)doc.getProperty(BaseDocument.WRITE_LINE_SEPARATOR_PROP);
        if (lsType == null) {
            lsType = (String)doc.getProperty(BaseDocument.READ_LINE_SEPARATOR_PROP);
            if (lsType == null) {
                lsType = BaseDocument.LS_LF;
            }
        }
        int writeBufferSize = ((Integer)doc.getProperty(EditorPreferencesKeys.WRITE_BUFFER_SIZE)).intValue();
        char[] getBuf = new char[writeBufferSize];
        char[] writeBuf = new char[2 * writeBufferSize];
        int actLen = 0;

        while (len > 0) {
            actLen = Math.min(len, writeBufferSize);
            doc.getChars(pos, getBuf, 0, actLen);
            int tgtLen = convertLFToLS(getBuf, actLen, writeBuf, lsType);
            writer.write(writeBuf, 0, tgtLen);
            pos += actLen;
            len -= actLen;
        }

        // Append new-line if not the last char
/*        if (actLen > 0 && getBuf[actLen - 1] != '\n') {
            writer.write(new char[] { '\n' }, 0, 1);
        }
 */

    }

    /** Get visual column. */
    public static int getColumn(char buffer[], int offset,
                                int len, int tabSize, int startCol) {
        int col = startCol;
        int endOffset = offset + len;

        // Check wrong tab values
        if (tabSize <= 0) {
            new Exception("Wrong tab size=" + tabSize).printStackTrace(); // NOI18N
            tabSize = 8;
        }

        while (offset < endOffset) {
            switch (buffer[offset++]) {
            case '\t':
                col = (col + tabSize) / tabSize * tabSize;
                break;
            default:
                col++;
            }
        }
        return col;
    }

    /** Get buffer filled with appropriate number of spaces. The buffer
    * can have actually more spaces than requested.
    * @param numSpaces number of spaces
    */
    public static synchronized char[] getSpacesBuffer(int numSpaces) {
        // check if there's enough space in white space array
        while (numSpaces > spacesBuffer.length) {
            char tmpBuf[] = new char[spacesBuffer.length * 2]; // new buffer
            System.arraycopy(spacesBuffer, 0, tmpBuf, 0, spacesBuffer.length);
            System.arraycopy(spacesBuffer, 0, tmpBuf, spacesBuffer.length, spacesBuffer.length);
            spacesBuffer = tmpBuf;
        }

        return spacesBuffer;
    }

    /** Get string filled with space characters. There is optimization to return
     * the same string instance for up to ceratin number of spaces.
     * @param numSpaces number of spaces determining the resulting size of the string.
     */
    public static synchronized String getSpacesString(int numSpaces) {
        if (numSpaces <= MAX_CACHED_SPACES_STRING_LENGTH) { // Cached
            String ret = spacesStrings[numSpaces];
            if (ret == null) {
                ret = spacesStrings[MAX_CACHED_SPACES_STRING_LENGTH].substring(0, numSpaces);
                spacesStrings[numSpaces] = ret;
            }

            return ret;

        } else { // non-cached
            return new String(getSpacesBuffer(numSpaces), 0, numSpaces);
        }
    }

    /** Get buffer of the requested size filled entirely with space character.
     * @param numSpaces number of spaces in the returned character buffer.
     */
    public static char[] createSpacesBuffer(int numSpaces) {
        char[] ret = new char[numSpaces];
        System.arraycopy(getSpacesBuffer(numSpaces), 0, ret, 0, numSpaces);
        return ret;
    }

    /** Get buffer filled with appropriate number of tabs. The buffer
    * can have actually more tabs than requested.
    * @param numSpaces number of spaces
    */
    public static char[] getTabsBuffer(int numTabs) {
        // check if there's enough space in white space array
        if (numTabs > tabsBuffer.length) {
            char tmpBuf[] = new char[numTabs * 2]; // new buffer

            // initialize new buffer with spaces
            for (int i = 0; i < tmpBuf.length; i += tabsBuffer.length) {
                System.arraycopy(tabsBuffer, 0, tmpBuf, i,
                                 Math.min(tabsBuffer.length, tmpBuf.length - i));
            }
            tabsBuffer = tmpBuf;
        }

        return tabsBuffer;
    }

    /** Get the string that should be used for indentation of the given level.
     * @param indent indentation level
     * @param expandTabs whether tabs should be expanded to spaces or not
     * @param tabSize size substituted visually for the '\t' character
     */
    public static String getIndentString(int indent, boolean expandTabs, int tabSize) {
        return getWhitespaceString(0, indent, expandTabs, tabSize);
    }

    /** Get the string that should be used for indentation of the given level.
     * @param indent indentation level
     * @param expandTabs whether tabs should be expanded to spaces or not
     * @param tabSize size of the '\t' character
     */
    public static String getWhitespaceString(int startCol, int endCol,
    boolean expandTabs, int tabSize) {
        return (expandTabs || tabSize <= 0)
            ? getSpacesString(endCol - startCol)
            : new String(createWhiteSpaceFillBuffer(startCol, endCol, tabSize));
    }

    /** createWhitespaceFillBuffer() with the non-capital 's' should be used.
     * @deprecated
     */
    public static char[] createWhiteSpaceFillBuffer(int startCol, int endCol,
    int tabSize) {
        return createWhitespaceFillBuffer(startCol, endCol, tabSize);
    }

    /** Get buffer filled with spaces/tabs so that it reaches from
    * some column to some other column.
    * @param startCol starting visual column of the whitespace on the line
    * @param endCol ending visual column of the whitespace on the line
    * @param tabSize size substituted visually for the '\t' character
    */
    public static char[] createWhitespaceFillBuffer(int startCol, int endCol,
    int tabSize) {
        if (startCol >= endCol) {
            return EMPTY_CHAR_ARRAY;
        }

        // Check wrong tab values
        if (tabSize <= 0) {
            new Exception("Wrong tab size=" + tabSize).printStackTrace(); // NOI18N
            tabSize = 8;
        }

        int tabs = 0;
        int spaces = 0;
        int nextTab = (startCol + tabSize) / tabSize * tabSize;
        if (nextTab > endCol) { // only spaces
            spaces += endCol - startCol;
        } else { // at least one tab
            tabs++; // jump to first tab
            int endSpaces = endCol - endCol / tabSize * tabSize;
            tabs += (endCol - endSpaces - nextTab) / tabSize;
            spaces += endSpaces;
        }

        char[] ret = new char[tabs + spaces];
        if (tabs > 0) {
            System.arraycopy(getTabsBuffer(tabs), 0, ret, 0, tabs);
        }
        if (spaces > 0) {
            System.arraycopy(getSpacesBuffer(spaces), 0, ret, tabs, spaces);
        }
        return ret;
    }

    /** Loads the file and performs conversion of line separators to LF.
    * This method can be used in debuging of syntax scanner or somewhere else.
    * @param fileName the name of the file to load
    * @return array of loaded characters with '\n' as line separator
    */

    public static char[] loadFile(String fileName) throws IOException {
        File file = new File(fileName);
        char chars[] = new char[(int)file.length()];
        FileReader reader = new FileReader(file);
        reader.read(chars);
        reader.close();
        int len = Analyzer.convertLSToLF(chars, chars.length);
        if (len != chars.length) {
            char copyChars[] = new char[len];
            System.arraycopy(chars, 0, copyChars, 0, len);
            chars = copyChars;
        }
        return chars;
    }

    /** Convert text with LF line separators to text that uses
    * line separators of the document. This function is used when
    * saving text into the file. Segment's data are converted inside
    * the segment's data or new segment's data array is allocated.
    * NOTE: Source segment must have just LFs as separators! Otherwise
    *   the conversion won't work correctly.
    * @param src source chars to convert from
    * @param len length of valid part of src data
    * @param tgt target chars to convert to. The array MUST have twice
    *   the size of src otherwise index exception can be thrown
    * @param lsType line separator type to be used i.e. LS_LF, LS_CR, LS_CRLF
    * @return length of valid chars in tgt array
     */
    public static int convertLFToLS(char[] src, int len, char[] tgt, String lsType) {
        if (lsType != null && lsType.length() == 1) {
            char ls = lsType.charAt(0);
            if (ls == '\r' || ls == LineSeparatorConversion.LS || ls == LineSeparatorConversion.PS) {
                // now do conversion for LS_CR and Unicode LS, PS
                for (int i = 0; i < len; i++) {
                    if (src[i] == '\n') {
                        tgt[i] = ls;
                    } else {
                        tgt[i] = src[i];
                    }
                }
                return len;
            }
        } else if (lsType.equals(BaseDocument.LS_CRLF)) {
            int tgtLen = 0;
            int moveStart = 0; // start of block that must be moved
            int moveLen; // length of chars moved

            for (int i = 0; i < len; i++) {
                if (src[i] == '\n') { // '\n' found
                    moveLen = i - moveStart;
                    if (moveLen > 0) { // will need to arraycopy
                        System.arraycopy(src, moveStart, tgt, tgtLen, moveLen);
                        tgtLen += moveLen;
                    }
                    tgt[tgtLen++] = '\r';
                    tgt[tgtLen++] = '\n';
                    moveStart = i + 1; // skip separator
                }
            }

            // now move the rest if it's necessary
            moveLen = len - moveStart;
            if (moveLen > 0) {
                System.arraycopy(src, moveStart, tgt, tgtLen, moveLen);
                tgtLen += moveLen;
            }
            return tgtLen;
        }
        // Using either \n or line separator is unknown
        System.arraycopy(src, 0, tgt, 0, len);
        return len;
    }

    public static boolean startsWith(char[] chars, char[] prefix) {
        if (chars == null || chars.length < prefix.length) {
            return false;
        }
        for (int i = 0; i < prefix.length; i++) {
            if (chars[i] != prefix[i]) {
                return false;
            }
        }
        return true;
    }

    public static boolean endsWith(char[] chars, char[] suffix) {
        if (chars == null || chars.length < suffix.length) {
            return false;
        }
        for (int i = chars.length - suffix.length; i < chars.length; i++) {
            if (chars[i] != suffix[i]) {
                return false;
            }
        }
        return true;
    }

    public static char[] concat(char[] chars1, char[] chars2) {
        if (chars1 == null || chars1.length == 0) {
            return chars2;
        }
        if (chars2 == null || chars2.length == 0) {
            return chars1;
        }
        char[] ret = new char[chars1.length + chars2.length];
        System.arraycopy(chars1, 0, ret, 0, chars1.length);
        System.arraycopy(chars2, 0, ret, chars1.length, chars2.length);
        return ret;
    }

    public static char[] extract(char[] chars, int offset, int len) {
        char[] ret = new char[len];
        System.arraycopy(chars, offset, ret, 0, len);
        return ret;
    }

    public static boolean blocksHit(int[] blocks, int startPos, int endPos) {
        return (blocksIndex(blocks, startPos, endPos) >= 0);
    }

    public static int blocksIndex(int[] blocks, int startPos, int endPos) {
        if (blocks.length > 0) {
            int onlyEven = ~1;
            int low = 0;
            int high = blocks.length - 2;

            while (low <= high) {
                int mid = ((low + high) / 2) & onlyEven;

                if (blocks[mid + 1] <= startPos) {
                    low = mid + 2;
                } else if (blocks[mid] >= endPos) {
                    high = mid - 2;
                } else {
                    return low; // found
                }
            }
        }

        return -1;
    }

    /** Remove all spaces from the given string.
     * @param s original string
     * @return string with all spaces removed
     */
    public static String removeSpaces(String s) {
        int spcInd = s.indexOf(' ');
        if (spcInd >= 0) {
            StringBuffer sb = new StringBuffer(s.substring(0, spcInd));
            int sLen = s.length();
            for (int i = spcInd + 1; i < sLen; i++) {
                char ch = s.charAt(i);
                if (ch != ' ') {
                    sb.append(ch);
                }
            }
            return sb.toString();
        }
        return s;
    }

}
