/*
 * @(#)$RCSfile: CharBuffer.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.
 */
/** An implementation of MCharBuffer that stores chars in an array with an insertion gap. */
/*
    Change history
    072396 jf   - fixed a bug in replace(int, int, char[], int, int) so that it correctly
                inserted into the middle of the buffer.
    080296 jf   - added timestamp.  This is strictly a debugging device to help catch
                stale iterators.

    082296 jbr  added check for 0-length iterator in replace
*/

package com.ibm.richtext.styledtext;

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

import java.text.CharacterIterator;

final class CharBuffer
    extends MCharBuffer implements Externalizable
{

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
  private static final int kGrowSize = 0x80; // small size for testing
  private static final int CURRENT_VERSION = 1; // version code for streaming
  private static final long serialVersionUID = 563174;

  transient Validation fValidation = null;
  private char[] fArray;
  transient private int fArraySize;
  transient private int fGap;

  /** Create an empty char buffer. */
  public CharBuffer()
  {
  }

  /** Create a char buffer that can hold at least capacity chars. */

  public CharBuffer(int capacity)
  {
    fArray = allocate(capacity);
  }

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

    if (in.readInt() != CURRENT_VERSION) {
        throw new IOException("Invalid version of CharBuffer");
    }

    fArray = (char[]) in.readObject();
    if (fArray != null) {
        fArraySize = fArray.length;
        fGap = fArraySize;
    }
    else {
        fArraySize = 0;
        fGap = 0;
    }
  }

  public void writeExternal(ObjectOutput out) throws IOException {

    compress();
    out.writeInt(CURRENT_VERSION);
    out.writeObject(fArray);
  }

  private void invalidate() {

    if (fValidation != null) {
        fValidation.invalidate();
        fValidation = null;
    }
  }

  // not ThreadSafe - could end up with two Validations
  // being generated
  private Validation getValidation() {

    if (fValidation == null) {
        fValidation = new Validation();
    }
    return fValidation;
  }

  /** Replace the chars from start to limit with the chars from srcStart to srcLimit in srcBuffer. */

  /** Replace the chars from start to limit with the chars from srcStart to srcLimit in srcChars.
  * This is the core routine for manipulating the buffer.
  */
  public void replace(int start, int limit, char[] srcChars, int srcStart, int srcLimit)
  {
    invalidate();
    int dstLength = limit - start;
    int srcLength = srcLimit - srcStart;

    if (dstLength < 0 || srcLength < 0) {
        throw new IllegalArgumentException("replace(int start, int limit, char[] srcChars, int srcStart, int srcLimit)");
    }

    int gapAlloc = 0;
    if (srcChars == null) {
        gapAlloc = srcLength;
        srcLength = 0;
    }

    int newSize = fArraySize - dstLength + srcLength;

    if (fArray == null) {
        if (start != 0 || limit != 0) {
            throw new IllegalArgumentException("replace(int start, int limit, char[] srcChars, int srcStart, int srcLimit)");
        }
        if (newSize + gapAlloc > 0) {
            fArray = allocate(newSize + gapAlloc);
            if (srcLength > 0) {
                System.arraycopy(srcChars, srcStart, fArray, 0, srcLength);
                fArraySize = srcLength;
                fGap = srcLength;
            }
        }
    } else {
        int newGap = start + srcLength;
        int gapLimit = fArray.length - fArraySize + fGap;

        if (newSize + gapAlloc > fArray.length) {
            char[] temp = allocate(newSize + gapAlloc);

            //move stuff at beginning that we aren't writing over
            if (start > 0) {
                at(0, start, temp, 0);
            }
            //move stuff from src array that we are copying
            if (srcLength > 0) {
                System.arraycopy(srcChars, srcStart, temp, start, srcLength);
            }
            //move stuff at end that we aren't copying over
            if (limit < fArraySize) {
                at(limit, fArraySize, temp, temp.length - newSize + newGap);
            //change 7-23-96
            //    at(limit, fArraySize - limit, temp, temp.length - newSize + newGap);
            }

            fArray = temp;
        } else {
            if (start > fGap) {
                System.arraycopy(fArray, gapLimit, fArray, fGap, start - fGap);
            }
            if (limit < fGap) {
                System.arraycopy(fArray, limit, fArray, fArray.length - newSize + newGap, fGap - limit);
            }
            if (srcLength > 0) {
                System.arraycopy(srcChars, srcStart, fArray, start, srcLength);
            }
        }

        fArraySize = newSize;
        fGap = newGap;
    }
  }

  /** Replace the chars from start to limit with the chars from srcStart to srcLimit in srcString. */

  /* This implements optimizations for null text or inserting text that fits at the gap,
     and defaults to call the core replace routine if these optimizations fail. */

  public void replace(int start, int limit, String srcString, int srcStart, int srcLimit)
  {
    invalidate();
    int length = limit - start;
    int srcLength = srcLimit - srcStart;

    if (fArray == null) {
        if (start != 0 || limit != 0) {
            throw new IllegalArgumentException("replace(int start, int limit, String srcString, int srcStart, int srcLimit)");
        }
        if (srcLength > 0) {
            fArray = allocate(srcLength);
            srcString.getChars(srcStart, srcLimit, fArray, 0);
            fArraySize = srcLength;
            fGap = srcLength;
        }
    } else {
        if (start == fGap && fArray.length >= fArraySize - length + srcLength) {
            if (srcLimit > 0) {
                srcString.getChars(srcStart, srcLimit, fArray, fGap);
                fGap += srcLength;
            }
            fArraySize += srcLength - length;
        } else {
            replace(start, limit, srcString != null ? srcString.toCharArray() : null, srcStart, srcLimit);
        }
    }
  }

  public void replace(int start, int limit, MConstText srcText, int srcStart, int srcLimit)
  {
    invalidate();
    int length = limit - start;
    int srcLength = srcLimit - srcStart;

    if (fArray == null) {
        if (start != 0 || limit != 0) {
            throw new IllegalArgumentException("replace(int start, int limit, String srcString, int srcStart, int srcLimit)");
        }
        if (srcLength > 0) {
            fArray = allocate(srcLength);
            srcText.extractChars(srcStart, srcLimit, fArray, 0);
            fArraySize = srcLength;
            fGap = srcLength;
        }
    } else {
        if (start == fGap && fArray.length >= fArraySize - length + srcLength) {
            if (srcLimit > 0) {
                srcText.extractChars(srcStart, srcLimit, fArray, fGap);
                fGap += srcLength;
            }
            fArraySize += srcLength - length;
        } else {
            char[] temp = srcLength == 0? null : new char[srcLength];
            if (temp != null) {
                srcText.extractChars(srcStart, srcLimit, temp, 0);
            }
            replace(start, limit, temp, 0, srcLimit - srcStart);
        }
    }
  }

  /** Replace the chars from start to limit with srcChar. */

  /* This implements optimizations for null text or replacing a character that fits into the gap,
     and defaults to call the core replace routine if these optimizations fail. */

  public void replace(int start, int limit, char srcChar)
  {
    invalidate();
    if (fArray == null) {
        if (start != 0 || limit != 0) {
            throw new IllegalArgumentException("replace(int start, int limit, char srcChar)");
        }
        fArray = allocate(1);
        fArray[0] = srcChar;
        fArraySize = 1;
        fGap = 1;
    } else {
        int length = limit - start;
        if (start == fGap && fArray.length > fArraySize - length) {
            fArray[fGap] = srcChar;
            fGap += 1;
            fArraySize += 1 - length;
        } else {
            replace(start, limit, new char[] { srcChar} , 0, 1);
        }
    }
  }

  /** Return the char at pos. */

  public char at(int pos)
  {
    if (pos < 0 || pos >= fArraySize) {
      throw new IllegalArgumentException();
    }
    return pos < fGap ? fArray[pos] : fArray[fArray.length - fArraySize + pos];
  }

  /** Copy the chars from start to limit to dst starting at dstStart. */

  public void at(int start, int limit, char[] dst, int dstStart)
  {
    int length = limit - start;

    if (start < 0 || limit < start || limit > fArraySize) {
        throw new IllegalArgumentException();
    }

    if (limit <= fGap) {
        System.arraycopy(fArray, start, dst, dstStart, length);
    } else if (start >= fGap) {
        System.arraycopy(fArray, fArray.length - fArraySize + start, dst, dstStart, length);
    } else {
        System.arraycopy(fArray, start, dst, dstStart, fGap - start);
        System.arraycopy(fArray, fArray.length - fArraySize + fGap, dst, dstStart + fGap - start, limit - fGap);
    }
  }

  /** Return the number of chars in the buffer. */

  public final int length()
  {
    return fArraySize;
  }

  /** Return the number of chars the buffer can hold before it must reallocate. */

  public final int capacity()
  {
    return fArray != null ? fArray.length : 0;
  }

  /** Reserve capacity chars at start. Utility to optimize a sequence of operations at start. */

  public void reserveCapacity(int start, int capacity)
  {
    replace(start, start, (char[])null, 0, capacity);
  }

  /** Minimize the storage used by the buffer. */

  public void compress()
  {
    invalidate();
    if (fArraySize == 0) {
        fArray = null;
        fGap = 0;
    } else if (fArraySize != fArray.length) {
        char[] temp = new char[fArraySize];
        at(0, fArraySize, temp, 0);
        fArray = temp;
        fGap = fArraySize;
    }
  }

  /** Display the buffer. */

  public String toString()
  {
    if (fArray != null) {
        return new StringBuffer()
        .append("limit: ").append(fArray.length)
        .append(", size: ").append(fArraySize)
        .append(", gap: ").append(fGap)
        .append(", ").append(fArray, 0, fGap)
        .append(fArray, fArray.length - fArraySize + fGap, fArraySize - fGap)
        .toString();
    } else {
        return new String("The buffer is empty.");
    }
  }

  public CharacterIterator createCharacterIterator(int start, int limit) {

    Validation val = getValidation();
    return new CharBufferIterator(start, limit, fArray, fArraySize, fGap, val);
  }

  /** The resizing algorithm. Return a value >= minSize. */

  protected int allocation(int minSize)
  {
    //    return (minSize + kGrowSize) & ~(kGrowSize - 1);
    return minSize < kGrowSize ? kGrowSize : (minSize * 2 + kGrowSize) & ~(kGrowSize - 1);
  }

  /** Allocate a new character array of limit >= minSize. */

  protected char[] allocate(int minSize)
  {
    return new char[allocation(minSize)];
  }
}
