/*
 * @(#)$RCSfile: ParagraphBuffer.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:45:10 $
 *
 * (C) Copyright IBM Corp. 1998-1999.  All Rights Reserved.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */
package com.ibm.richtext.styledtext;

import java.io.Externalizable;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.IOException;

import com.ibm.textlayout.attributes.AttributeMap;

/*
    Right now, you have to construct this class with a charBuffer.  That's pretty ugly... */

/*
    8/8/96
        Added replace method, which reads styles from a ParagraphIterator.
        Also, added a constructor which takes a ParagraphIterator.
        These methods are for copy/paste support.

    8/22/96
        Replace method (which takes an iterator as an argument) tests for a
        0-length iterator.

    9/30/96
        {jbr} modified paragraphLimit();

    10/23/96
        This class now maintains paragraph styles.  Also has a timestamp.

    10/25/96
        Holds on to Style instead of Style.

    7/31/98 Switched to AttributeMap

*/

/**
* This class stores offsets where paragraph breaks occur, and the style applied to
* each paragraph.
*
* The offsets where paragraph breaks occur are stored in a RunArray object.  This is
* not strictly necessary, but it makes scanning the text for paragraph breaks unnecessary.
* However, it makes determining where paragraphs start a little confusing.  If there is a
* paragraph break at offset p, then there will be a paragraph start at offset p+1.
* If the last character in the text is a paragraph break, there will be a run array entry
* for that character (and also a paragraph style for that paragraph, even though the
* style does not apply to any text).
*
* The style of the first paragraph in the text is in the fFirstStyle member.  Other
* paragraph styles are stored in the fStyleTable array, in the following manner:  the
* paragraph with begins at offset fRunArray.fRunStart[i]+1 has style fStyleTable[i].
* The style table's "gap range" is kept in sync with the RunArray.
*
* This class propogates paragraph styles in the "Microsoft Word" fashion:  styles
* propogate backward from paragraph breaks.
*
* This class maintains a time stamp, which changes every time extra formatting (formatting
* on a range other than the current selection) is needed;  for example, when a paragraph
* break is removed.
*/


final class ParagraphBuffer extends MParagraphBuffer implements Externalizable {

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
    private static final int kInitialSize = 10;
    private static final int CURRENT_VERSION = 1;
    private static final long serialVersionUID = 22356934;

    private RunArray fRunArray;
    private AttributeMap[] fStyleTable;
    private AttributeMap fFirstStyle;

    private static final boolean isParagraphBreak(char c) {

        return c =='\u2029' || c == '\n';
    }

/**
* Construct a new paragraph buffer from the characters in <tt>charBuffer</tt>.
*/
    ParagraphBuffer(MCharBuffer charBuffer) {

        this(charBuffer.length());

        // scan text for paragraph boundaries

        int textLength = fRunArray.getCurTextLength();

        for (int pos=0; pos < textLength; pos++) {

            if (isParagraphBreak(charBuffer.at(pos))) {
                if (fRunArray.fPosEnd+1 >= fRunArray.fNegStart)
                    expandStyleTable();
                fRunArray.fRunStart[++fRunArray.fPosEnd] = pos;
                fStyleTable[fRunArray.fPosEnd] = fFirstStyle;
            }
        }

    }

/**
* Private constructor.
*/
    private ParagraphBuffer(int initialLength) {

        fRunArray = new RunArray(kInitialSize, initialLength);
        fStyleTable = new AttributeMap[fRunArray.getArrayLength()];

        fFirstStyle = AttributeMap.EMPTY_ATTRIBUTE_MAP;
    }

    /**
     * Note: this constructor is ONLY for use by the Serialization
     * mechanism.  It does not leave this object in a valid state!
     */
    public ParagraphBuffer() {
    }

    public void writeExternal(ObjectOutput out) throws IOException {

        compress();
        out.writeInt(CURRENT_VERSION);
        out.writeObject(fRunArray);
        out.writeObject(fStyleTable);
        out.writeObject(fFirstStyle);
    }

    public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {

        if (in.readInt() != CURRENT_VERSION) {
            throw new IOException("Invalid version of ParagraphBuffer");
        }
        fRunArray = (RunArray) in.readObject();
        fStyleTable = (AttributeMap[]) in.readObject();
        fFirstStyle = (AttributeMap) in.readObject();
    }

/**
* Shift table such that the last positive run starts before pos.
*/
    private void shiftTableTo(int pos) {

        int oldNegStart = fRunArray.fNegStart;
        int oldPosEnd = fRunArray.fPosEnd;

        fRunArray.shiftTableTo(pos);

        if (oldPosEnd > fRunArray.fPosEnd)
            System.arraycopy(fStyleTable, fRunArray.fPosEnd+1,
                             fStyleTable, fRunArray.fNegStart,
                             oldPosEnd-fRunArray.fPosEnd);
        else if (oldNegStart < fRunArray.fNegStart)
            System.arraycopy(fStyleTable, oldNegStart,
                             fStyleTable, oldPosEnd+1,
                             fRunArray.fNegStart-oldNegStart);
    }

/**
* Update the style table to reflect a change in the RunArray's size.
*/
    private void handleArrayResize(int oldNegStart) {

        AttributeMap newStyleTable[] = new AttributeMap[fRunArray.getArrayLength()];
        System.arraycopy(fStyleTable, 0, newStyleTable, 0, fRunArray.fPosEnd+1);
        System.arraycopy(fStyleTable, oldNegStart, newStyleTable, fRunArray.fNegStart, (fRunArray.getArrayLength()-fRunArray.fNegStart));
        fStyleTable = newStyleTable;
    }

    void compress() {

        int oldNegStart = fRunArray.fNegStart;
        fRunArray.compress();
        if (fRunArray.fNegStart != oldNegStart) {
            handleArrayResize(oldNegStart);
        }
    }

/**
* Make more room in run/style tables.
*/
    private void expandStyleTable() {

        int oldNegStart = fRunArray.fNegStart;
        fRunArray.expandRunTable();
        handleArrayResize(oldNegStart);
    }

/**
* Process a character insertion at offset <tt>start</tt>.
* If a paragraph break was inserted, propogate paragraph style at
* <tt>start</tt> to new paragraph.
*/
    public void insertText(int start, char insertedChar) {

        shiftTableTo(start);
        if (isParagraphBreak(insertedChar)) {
            if (fRunArray.fPosEnd+1 >= fRunArray.fNegStart)
                expandStyleTable();
            fRunArray.fRunStart[++fRunArray.fPosEnd] = start;
            fStyleTable[fRunArray.fPosEnd] =
                (fRunArray.fPosEnd == 0)? fFirstStyle : fStyleTable[fRunArray.fPosEnd-1];
            fRunArray.runStartsChanged();
        }

        //fRunArray.fCurTextLength++;
        fRunArray.addToCurTextLength(1);
    }

/**
* Process character insertion at offset <tt>start</tt>.
* Each new paragraph gets paragraph style at
* <tt>start</tt>.
*/
    public void insertText(int start, char srcChars[], int srcStart, int srcLimit) {

        shiftTableTo(start);

        int adjust = start - srcStart;

        for (int i=srcStart;  i < srcLimit; i++)
            if (isParagraphBreak(srcChars[i])) {
                if (fRunArray.fPosEnd+1 >= fRunArray.fNegStart)
                    expandStyleTable();
                fRunArray.fRunStart[++fRunArray.fPosEnd] = adjust + i;
                fStyleTable[fRunArray.fPosEnd] =
                    (fRunArray.fPosEnd == 0)? fFirstStyle : fStyleTable[fRunArray.fPosEnd-1];
                fRunArray.runStartsChanged();
            }

        //fRunArray.fCurTextLength += (srcLimit-srcStart);
        fRunArray.addToCurTextLength(srcLimit-srcStart);
    }

/**
* Process deletion by removing paragraph breaks contained in
* deleted range.  Propogate paragraph styles backward, if necessary.
*/
    public void deleteText(int start, int limit, int[] damagedRange) {

        int length = limit - start;
        if (length < 0) {
            throw new IllegalArgumentException("Invalid range");
        }

        shiftTableTo(limit);

        int newEnd = fRunArray.findRunContaining(start-1);

        if (newEnd != fRunArray.fPosEnd) {

            AttributeMap propStyle = fStyleTable[fRunArray.fPosEnd];
            boolean propogated;

            if (newEnd == -1) {
                propogated = !propStyle.equals(fFirstStyle);
                fFirstStyle = propStyle;
            }
            else {
                propogated = !propStyle.equals(fStyleTable[newEnd]);
                fStyleTable[newEnd] = propStyle;
            }

            if (propogated) {
                int pStart = (newEnd==-1)? 0 : fRunArray.fRunStart[newEnd] + 1;
                damagedRange[0] = Math.min(damagedRange[0], pStart);
            }

            fRunArray.fPosEnd = newEnd;
        }

        fRunArray.addToCurTextLength(-length);

        fRunArray.runStartsChanged();
    }

/**
* Returns the start of the paragraph containing offset <tt>pos</tt>.
*/
    public int paragraphStart(int pos) {

        int run = fRunArray.findRunContaining(pos-1);
        if (run == -1) {
            return 0;
        }
        else {
            return fRunArray.getLogicalRunStart(run) + 1;
        }
    }

/**
* Returns the limit of the paragraph containing offset <tt>pos</tt>.
*/
    public int paragraphLimit(int pos) {

        int run = fRunArray.findRunContaining(pos-1);

        if (run == fRunArray.fPosEnd)
            run = fRunArray.fNegStart;
        else
            run++;

        if (run == fRunArray.getArrayLength()) {
            return fRunArray.getCurTextLength();
        }

        int start = fRunArray.getLogicalRunStart(run);

        return start+1;
    }

/**
* Returns the style of the paragraph containing offset <tt>pos</tt>.
*/
    public AttributeMap paragraphStyleAt(int offset) {

        int run = fRunArray.findRunContaining(offset-1);
        if (run < 0)
            return fFirstStyle;
        else
            return fStyleTable[run];
    }

/**
* Create paragraph iterator.
*/
/*
    public MParagraphIterator createParagraphIterator(int start, int limit) {

        return new ParagraphIterator(start, limit);
    }
*/

/**
* Called by iterator to get run info.
*/
    private void setIterator(int pos, ParagraphIterator iter) {

        if ((pos < 0) || (pos >= fRunArray.getCurTextLength())) {
            iter.set(0, 0, kNoRun, null);
            return;
        }

        int run;

        if (pos > 0)
            run = fRunArray.findRunContaining(pos-1);
        else
            run = -1;

        setIteratorUsingRun(run, iter);
    }

/**
* Called by iterator to get run info.
*/
    private void setIteratorUsingRun(int run, ParagraphIterator iter) {

        int lastValidRun = fRunArray.lastRun();

        if (run < -1 || run > lastValidRun) {
            iter.set(0, 0, kNoRun, null);
            return;
        }

        if (run == fRunArray.fPosEnd+1)
            run = fRunArray.fNegStart;
        else if (run == fRunArray.fNegStart-1)
            run = fRunArray.fPosEnd;

        int runStart;
        AttributeMap style;

        if (run < 0) {
            runStart = 0;
            style = fFirstStyle;
        }
        else {
            runStart = fRunArray.fRunStart[run];
            style = fStyleTable[run];
            if (runStart < 0)
                runStart += fRunArray.getCurTextLength();
            runStart++;
        }

        int nextRun;

        if (run == fRunArray.fPosEnd)
            nextRun = fRunArray.fNegStart;
        else
            nextRun = run + 1;

        int runLimit;

        if (nextRun >= fRunArray.getArrayLength())
            runLimit = fRunArray.getCurTextLength();
        else {
            runLimit = fRunArray.fRunStart[nextRun];
            if (runLimit < 0)
                runLimit += fRunArray.getCurTextLength();
            runLimit++;
            }

        iter.set(runStart, runLimit, run, style);
    }

/**
* Replace paragraph breaks/styles between start and length with paragraph breaks/styles
* from <tt>srcText</tt>.
* @param start an offset into the text
* @param limit the index after the last character to replace
* @param srcText the text from which new paragraphs are taken
* @param srcStart the start of the range in <code>srcText</code> to copy
* @param srcLimit the first index after the range in <code>srcText</code> to copy
*/
    public void replace(int start,
                        int limit,
                        MConstText srcText,
                        int srcStart,
                        int srcLimit,
                        int[] damagedRange) {

        final int insLength = srcLimit - srcStart;
        if (insLength < 0) {
            throw new Error("invalid range");
        }
        final int origLength = fRunArray.getCurTextLength();
        deleteText(start, limit, damagedRange);

        if (insLength == 0)
            return;

        final int oldPosEnd = fRunArray.fPosEnd;
        AttributeMap origStyle;
        if (limit < origLength) {
            origStyle = (fRunArray.fPosEnd>=0)? fStyleTable[fRunArray.fPosEnd] : fFirstStyle;
        }
        else {
            origStyle = srcText.paragraphStyleAt(srcLimit);
        }

        int paragraphStart = srcStart;
        int lastPLimit = srcText.paragraphStart(srcLimit);
        boolean separatorAtEnd = lastPLimit > srcStart && isParagraphBreak(srcText.at(lastPLimit-1));

        if (limit == origLength && lastPLimit == paragraphStart) {
            if (fRunArray.fPosEnd > 0) {
                fStyleTable[fRunArray.fPosEnd] = origStyle;
            }
            else {
                fFirstStyle = origStyle;
            }
        }
        else {
            boolean firstPass = true;
            while (paragraphStart < lastPLimit) {

                AttributeMap style = srcText.paragraphStyleAt(paragraphStart);
                int paragraphLimit = srcText.paragraphLimit(paragraphStart);

                if (fRunArray.fPosEnd+1 >= fRunArray.fNegStart)
                    expandStyleTable();

                if (fRunArray.fPosEnd >= 0) {
                    if (!style.equals(fStyleTable[fRunArray.fPosEnd])) {
                        fStyleTable[fRunArray.fPosEnd] = style;
                        if (firstPass) {
                            int pStart = fRunArray.fRunStart[fRunArray.fPosEnd]+1;
                            damagedRange[0] = Math.min(damagedRange[0], pStart);
                        }
                    }
                }
                else if (!style.equals(fFirstStyle)) {
                    fFirstStyle = style;
                    damagedRange[0] = 0;
                }

                firstPass = false;

                if (paragraphLimit < lastPLimit || separatorAtEnd) {
                    fRunArray.fRunStart[++fRunArray.fPosEnd] = paragraphLimit - 1 + start - srcStart;
                }
                paragraphStart = paragraphLimit;
            }
            if (fRunArray.fPosEnd != oldPosEnd) {
                fStyleTable[fRunArray.fPosEnd] = origStyle;
            }
        }

        fRunArray.addToCurTextLength(insLength);
    }

/**
* Modify the style of all paragraphs containing offsets in the range [start, limit) to
* <tt>style</tt>.
*/
    public boolean modifyParagraphStyles(int start,
                                         int limit,
                                         StyleModifier modifier,
                                         int[] damagedRange)  {

        int run = fRunArray.findRunContaining(start-1);
        int currentPStart;
        if (run == -1) {
            currentPStart = 0;
        }
        else {
            currentPStart = fRunArray.getLogicalRunStart(run) + 1;
        }

        boolean modifiedAnywhere = false;

        for (;;) {

            boolean modified = false;

            if (run < 0) {

                AttributeMap newStyle = modifier.modifyStyle(fFirstStyle);

                if (!newStyle.equals(fFirstStyle)) {
                    fFirstStyle = newStyle;
                    modified = true;
                }
            }
            else {

                AttributeMap newStyle = modifier.modifyStyle(fStyleTable[run]);

                if (!fStyleTable[run].equals(newStyle)) {
                    fStyleTable[run] = newStyle;
                    modified = true;
                }
            }

            if (run == fRunArray.fPosEnd) {
                run = fRunArray.fNegStart;
            }
            else {
                run++;
            }

            int nextPStart;
            if (run == fRunArray.getArrayLength()) {
                nextPStart = fRunArray.getCurTextLength();
            }
            else {
                nextPStart = fRunArray.getLogicalRunStart(run) + 1;
            }

            if (modified) {
                modifiedAnywhere = true;
                damagedRange[0] = Math.min(damagedRange[0], currentPStart);
                damagedRange[1] = Math.max(damagedRange[1], nextPStart);
            }

            if (limit <= nextPStart) {
                break;
            }
            else {
                currentPStart = nextPStart;
            }
        }

        return modifiedAnywhere;
    }

    private static void dumpParagraphStarts(ParagraphBuffer st) {

        System.out.println("fRunArray.fPosEnd="+st.fRunArray.fPosEnd+", fRunArray.fNegStart="+st.fRunArray.fNegStart+
                            ", fRunArray.getArrayLength()="+st.fRunArray.getArrayLength()+", fRunArray.getCurTextLength()="+st.fRunArray.getCurTextLength());

        int i;
        System.out.print("Positives: ");
        for (i=0; i<=st.fRunArray.fPosEnd; i++)
            System.out.print(st.fRunArray.fRunStart[i]+" ");

        System.out.print("   Negatives: ");
        for (i=st.fRunArray.fNegStart; i<st.fRunArray.getArrayLength(); i++)
            System.out.print(st.fRunArray.fRunStart[i]+" ");

        System.out.println(" ");
    }

    private static final int kNoRun = -42; // iterator use

    private final class ParagraphIterator /*implements MParagraphIterator*/
    {
        ParagraphIterator(int start, int limit)
        {
            reset(start, limit, start);
        }

        public void reset(int start, int limit, int pos)
        {
            fStart = start;
            fLimit = limit;
            setIterator(fStart, this);
        }

        public boolean isValid()
        {
            return fCurrentRun != kNoRun;
        }

        public void next()
        {
            if (fRunLimit < fLimit) {
                fCurrentRun++;
                setIteratorUsingRun(fCurrentRun, this);
            }
            else
                set(0, 0, kNoRun, null);
        }

        public void prev()
        {
            if (fRunStart > fStart) {
                fCurrentRun--;
                setIteratorUsingRun(fCurrentRun, this);
            }
            else
                set(0, 0, kNoRun, null);
        }

        public void set(int pos)
        {
            if (pos >= fStart && pos < fLimit) {
                setIterator(pos, this);
            } else {
                set(0, 0, kNoRun, null);
            }
        }

        // ParagraphBuffer calls back on this to set iterators
        void set(int start, int limit, int currentRun, AttributeMap style)
        {
            fRunStart = start < fStart ? fStart : start;
            fRunLimit = limit > fLimit ? fLimit : limit;
            fCurrentRun = currentRun;
            fStyle = style;
        }

        public void reset(int start, int limit)
        {
            reset(start, limit, start);
        }

        public void first()
        {
            set(fStart);
        }

        public void last()
        {
            set(fLimit - 1);
        }

        public int rangeStart()
        {
            return fStart;
        }

        public int rangeLimit()
        {
            return fLimit;
        }

        public int rangeLength()
        {
            return fLimit - fStart;
        }

        public int runStart()
        {
            return fRunStart;
        }

        public int runLimit()
        {
            return fRunLimit;
        }

        public int runLength()
        {
            return fRunLimit - fRunStart;
        }

        public AttributeMap style() {

            return fStyle;
        }

        private int fStart;
        private int fLimit;
        private int fRunStart;
        private int fRunLimit;
        private int fCurrentRun;
        private AttributeMap fStyle;
    }
}
