/**
 * 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.
 */

/*
 * "Buffer.java"
 * Buffer.java 1.8 01/07/30
 */
package org.netbeans.lib.terminalemulator;

import java.util.Vector;

/**
 * The Buffer used by Term is _not_ related to javax.swing.text.Document.
 * <p>
 * The Swing Document is Element based while terms is Line based.
 * <br>
 * The Swing Document uses offsets for coordinates, while term uses cartesian
 * BCoords.
 * <p>
 */
class Buffer {

    /*
     * For some odd reason Vector.removeRange is protected, so 
     * we have to do this to gain access to it.
     */
    private static class OurVector<T> extends Vector<T> {

        @Override
        public void removeRange(int fromIndex, int toIndex) {
            super.removeRange(fromIndex, toIndex);
        }
    }
    private final OurVector<Line> lines = new OurVector<>();	// buffer

    // How is this different from lines.length?
    private int nlines;		// number of lines in buffer

    private int visible_cols;	// number of columns visible in view
    private int extra_cols;	// columns needed to support lines longer
    				// than visible_cols. Only grows.

    /**
     * @return nlines
     */
    int nlines() {
	return nlines;
    }

    public int visibleCols() {
        return visible_cols;
    }

    public int totalCols() {
        return visible_cols + extra_cols;
    }

    public Buffer(int visible_cols) {
        this.visible_cols = visible_cols;
    }

    public void setVisibleCols(int visible_cols) {
        int delta = visible_cols - this.visible_cols;
        this.visible_cols = visible_cols;
        extra_cols -= delta;
        if (extra_cols < 0) {
            extra_cols = 0;
        }
    }

    /*
     * Keep track of the largest column # to help set the extent of 
     * the horizontal scrollbar.
     */
    public void noteColumn(int col) {
        int new_extra = col - visible_cols;
        if (new_extra > extra_cols) {
            extra_cols = new_extra;
        // LATER hrange_listener.adjustHRange(extra_cols);
        }
    }

    /* DEBUG
    public static volatile boolean lock = false;
    
    private void ck_lock() {
    if (lock) {
    System.out.println("Buffer ck_lock fail");	// NOI18N
    printStats();
    Thread.dumpStack();
    }
    }
     */
    Line lineAt(int brow) {
        try {
            return lines.elementAt(brow);
        } catch (ArrayIndexOutOfBoundsException x) {
            //XXX swallowing this exception caused issue 40129.
            //I've put in a null-check on the return value in sel.paint()
            //as a hotfix.  Should find out why bad values are being passed
            //here.  Ivan?

            /* DEBUG
            System.out.println("Buffer.lineAt(" +brow+ ") -> null\n");// NOI18N
            Thread.dumpStack();
             */
            return null;
        }
    }

    Line bottom() {
        return lineAt(nlines);
    }

    public Line appendLine() {
        // DEBUG ck_lock();
        Line l = new Line();
        lines.add(l);
        nlines++;
        return l;
    }

    public Line addLineAt(int row) {
        // DEBUG ck_lock();
        Line l = new Line();
        lines.add(row, l);
        nlines++;
        return l;
    }

    /**
     * Remove 'n' lines starting at 'row'.
     * Return the number of characters deleted as a result.
     */
    public int removeLinesAt(int row, int n) {
        // DEBUG ck_lock();
        int nchars = 0;
        for (int r = row; r < row + n; r++) {
            nchars += lineAt(r).length() + 1;
        }

        lines.removeRange(row, row + n);
        nlines -= n;

        return nchars;
    }

    public void removeLineAt(int row) {
        // DEBUG ck_lock();
        lines.remove(row);
        nlines--;
    }

    public Line moveLineFromTo(int from, int to) {
        // DEBUG ck_lock();
        Line l = lines.remove(from);
        lines.add(to, l);
        return l;
    }

    /**
     * Visit the physical lines from 'begin', through 'end'.
     * <p>
     * If 'newlines' is set, the passed 'ecol' is set to the actual
     * number of columns in the view to signify that the newline is included.
     * This way of doing it helps with rendering of a whole-line selection.
     * Also Line knows about this and will tack on a "\n" when Line.text()
     * is asked for.
     */
    void visitLines(BCoord begin, BCoord end, boolean newlines,
            LineVisitor visitor) {

        // In the general case a range is made up of three
        // rectangles. The partial line at top, the partial line
        // at the bottom and the middle range of fully selected lines.

        Line l;
        if (begin.row == end.row) {
            // range is on one line
            l = lineAt(begin.row);
            visitor.visit(l, begin.row, begin.col, end.col);

        } else {
            boolean cont;

            // range spans multiple lines
            l = lineAt(begin.row);
            if (newlines && !l.isWrapped()) {
                cont = visitor.visit(l, begin.row, begin.col, totalCols());
            } else {
                cont = visitor.visit(l, begin.row, begin.col, l.length() - 1);
            }
            if (!cont) {
                return;
            }

            for (int r = begin.row + 1; r < end.row; r++) {
                l = lineAt(r);
                if (newlines && !l.isWrapped()) {
                    cont = visitor.visit(l, r, 0, totalCols());
                } else {
                    cont = visitor.visit(l, r, 0, l.length() - 1);
                }
                if (!cont) {
                    return;
                }
            }

            l = lineAt(end.row);
            cont = visitor.visit(l, end.row, 0, end.col);
            if (!cont) {
                return;
            }
        }
    }

    /*
     * Like visitLines() except in reverse.
     * <p>
     * Starts at 'end' and goes to 'begin'.
     */
    void reverseVisitLines(BCoord begin, BCoord end, boolean newlines,
            LineVisitor visitor) {

        // very similar to visitLines

        Line l;
        if (begin.row == end.row) {
            // range is on one line
            l = lineAt(begin.row);
            visitor.visit(l, begin.row, begin.col, end.col);

        } else {
            boolean cont;

            // range spans multiple lines
            l = lineAt(end.row);
            cont = visitor.visit(l, end.row, 0, end.col);
            if (!cont) {
                return;
            }

            for (int r = end.row - 1; r > begin.row; r--) {
                l = lineAt(r);
                if (newlines && !l.isWrapped()) {
                    cont = visitor.visit(l, r, 0, totalCols());
                } else {
                    cont = visitor.visit(l, r, 0, l.length() - 1);
                }
                if (!cont) {
                    return;
                }
            }

            l = lineAt(begin.row);
            if (newlines && !l.isWrapped()) {
                cont = visitor.visit(l, begin.row, begin.col, totalCols());
            } else {
                cont = visitor.visit(l, begin.row, begin.col, l.length() - 1);
            }
            if (!cont) {
                return;
            }
        }
    }

    public BExtent find_line(BCoord coord) {
        WordDelineator newLine = WordDelineator.createNewlineDelineator();
        return find_word(newLine, coord);
    }

    public BExtent find_word(WordDelineator word_delineator, BCoord coord) {
        /*
         * Find the boundaries of a "word" at 'coord'.
         */

        int row = coord.row;
        Line startLine = lineAt(row);

        if (coord.col >= startLine.length()) {
            return new BExtent(coord, coord);
        }

        int lx = 0;
        int rx = 0;
        int beginRow = row;
        int endRow = row;
        StringBuffer lineBuffer;

        // Try to use lineVisitor
        while (beginRow >= 0) {
            Line line = lineAt(beginRow);
            lineBuffer = line.stringBuffer();
            int searchCol = (lx == -1) ? line.length() - 1 : coord.col;
            lx = word_delineator.findLeft(lineBuffer, searchCol, true);
            
            if (lx != -1) {
                break;
            } else {
                if (beginRow == 0) {
                    lx = 0;
                } else if (!lineAt(beginRow - 1).isWrapped()) {
                    lx = 0;
                    break;
                }
            }
            beginRow--;
        }
        while (endRow < nlines) {
            Line line = lineAt(endRow);
            lineBuffer = line.stringBuffer();
            int searchCol = (rx == -1) ? 0 : coord.col;
            rx = word_delineator.findRight(lineBuffer, searchCol, true);
            
            if (rx != -1) {
                break;
            } else {
                if (endRow == nlines - 1) {
                    rx = line.length() - 1;
                }
                if (!line.isWrapped()) {
                    rx = line.length() - 1;
                    break;
                }
            }
            endRow++;
        }

        return new BExtent(new BCoord(beginRow, lx),
                new BCoord(endRow, rx));
    }

    /**
     * Back up the coordinate by one character and return new BCoord
     * <p>
     * Travels back over line boundaries
     * <br>
     * Returns null if 'c' is the first character of the buffer.
     */
    public BCoord backup(BCoord c) {
        if (c.col > 0) {
            return new BCoord(c.row, c.col - 1);	// back one in line
        }
        // Cursor is at beginning of line.
        // Need to find the end of previous line, but it might empty,
        // so we go one line back etc
        for (int prevrow = c.row - 1; prevrow >= 0; prevrow--) {
            Line l = lineAt(prevrow);
            if (l.length() != 0) {
                return new BCoord(prevrow, l.length() - 1);
            }
        }

        // prevrow == -1, at beginning of file; nowhere to back to
        return null;
    }

    /*
     * Advance the coordinate by one character and return a new coord.
     * <p>
     * Wraps around line boundaries.
     * <br>
     * Returns null if 'c' is at the last character of the buffer.
     */
    @SuppressWarnings("ValueOfIncrementOrDecrementUsed")
    public BCoord advance(BCoord c) {
        int row = c.row;
        int col = c.col;

        col++;
        Line l = lineAt(row);
        if (col < l.length()) {
            return new BCoord(row, col);
        }

        // Need to wrap, but the next line might be empty ... so we
        // keep going til either we find a non-empty line or the end
        // of the buffer.
        while (++row < nlines) {
            l = lineAt(row);
            if (l.length() != 0) {
                return new BCoord(row, 0);
            }
        }
        return null;
    }

    private int utilization(int nchars, int ncapacity) {
        float u = ((float) nchars) / ((float) ncapacity);
        float p = u * 100.0f;      // convert to percentage
        return (int) p;
    }
    /*
     * Print interesting statistics and facts about this Term
     */

    public void printStats(boolean indented) {
        int chars = 0;
        int charcapacity = 0;

        int nalines = 0;     // lines with attributes
        int attrs = 0;
        int attrcapacity = 0;

        for (int lx = 0; lx < nlines; lx++) {
            Line l = lineAt(lx);
            chars += l.length();
            charcapacity += l.capacity();
            if (l.hasAttributes()) {
                nalines++;
                attrs += l.length();
                attrcapacity += l.capacity();
            }
        }

        Term.indent(indented);
        System.out.println("Buffer:" + // NOI18N
                "  nlines " + nlines);	// NOI18N

        Term.indent(indented);
        System.out.println("       " + // NOI18N
                "  chars " + chars + // NOI18N
                "  charcapacity " + charcapacity + // NOI18N
                "  utilzn %" + utilization(chars, charcapacity));	// NOI18N

        Term.indent(indented);
        System.out.println("       " + // NOI18N
                "  attrs " + attrs + // NOI18N
                "  attrcapacity " + attrcapacity + // NOI18N
                "  utilzn %" + utilization(attrs, attrcapacity));	// NOI18N

        // estimate actual byte consumption
        final int unitObjectSz = 8;
        final int unitReferenceSz = 4;

        final int unitBooleanSz = 4;
        final int unitCharSz = 2;
        final int unitIntSz = 4;

        final int unitCharArraySz = 12;
        final int unitIntArraySz = 12;

        long bytes = 0;
        long unitLineSz = unitObjectSz +
                unitBooleanSz + // about_to_wrap
                unitReferenceSz + // attr
                unitIntSz + // backgroundColor
                unitReferenceSz + // buf
                unitIntSz + // capacity
                unitIntSz + // glyphId
                unitIntSz + // length
                unitBooleanSz // wrapped
                ;
        bytes += unitLineSz * nlines;

        bytes += unitCharArraySz * nlines;
        bytes += unitCharSz * charcapacity;

        bytes += unitIntArraySz * nalines;
        bytes += unitIntSz * attrcapacity;

        Term.indent(indented);
        System.out.println("       " + // NOI18N
                "  bytes " + bytes / 1024 + "K");         	// NOI18N

    }
}
