/*
 * @(#)$RCSfile: MConstText.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 com.ibm.textlayout.attributes.AttributeMap;
import java.text.CharacterIterator;
import java.awt.datatransfer.DataFlavor;

/**
 * MConstText is a base class for text with multiple character and
 * paragraph styles.  The text is a sequence of Unicode characters,
 * represented by <code>char</code>.  Character and paragraph
 * styles are represented by the <code>AttributeMap</code> class.
 * <p>
 * Characters in the text are accessed with an integer index using the
 * <code>at</code> method.
 * Valid indices are between 0 and (length-1), where length is the number
 * of characters in the text.  Additionally, the
 * characters in the text may be accessed through a
 * <code>java.text.CharacterIterator</code>.
 * <p>
 * Every character in the text has a character style associated with it,
 * represented by the <code>AttributeMap</code> class.  The character
 * style for a particular character can be obtained using the
 * <code>characterStyleAt</code> method.
 * <p>
 * Each character in the text is contained in a paragraph.  A paragraph
 * is a range of text including and terminated by a
 * paragraph separator (either <code>\n</code> or <code>U+2029</code>).
 * Every
 * paragraph has a paragraph style associated with it, represented
 * by the <code>AttributeMap</code> class.  Paragraph boundaries and
 * styles can be obtained from the MConstText.
 * <p>
 * This class does not have methods for modifying the text or styles.
 * However, subclasses may add this capability, so it is not safe to
 * assume that an MConstText instance is immutable.  In particular,
 * the MText class adds modification protocol to this class.  Clients
 * can detect whether an MConstText has changed by keeping track of its
 * timestamp.
 * <p>
 * A DataFlavor for clipboard content is defined in this class.  Using
 * this DataFlavor insures that all clients will recognize MConstText
 * content on the clipboard.
 * @see MText
 * @see AttributeMap
 * @see java.text.CharacterIterator
 * @see java.awt.datatransfer.DataFlavor
 */
public abstract class MConstText {

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
    /**
     * The DataFlavor for MConstText clipboard content.  Used to
     * indicate that clipboard data has an MConstText representation.
     */
    public static final DataFlavor styledTextFlavor =
                            new DataFlavor(MConstText.class, "Styled Text");

    protected MConstText() {
    }

//========================================================
// CHARACTER ACCESS
//========================================================
/**
* Return the character at offset <code>pos</code>.
* @param pos a valid offset into the text
* @returns the character at offset <code>pos</code>
*/
    public abstract char at(int pos);

/**
* Copy the characters in the range [<code>start</code>, <code>limit</code>)
* into the array <code>dst</code>, beginning at <code>dstStart</code>.
* @param start offset of first character which will be copied into the array
* @param limit offset immediately after the last character which will be copied into the array
* @param dst array in which to copy characters.  The length of <code>dst</code> must be at least
* (<code>dstStart + limit - start</code>).
*/
    public abstract void extractChars(int start, int limit, char[] dst, int dstStart);

/**
* Create an MConstText containing the characters and styles in the range
* [<code>start</code>, <code>limit</code>).
* @param start offset of first character in the new text
* @param limit offset immediately after the last character in the new text
* @return an MConstText object containing the characters and styles in the given range
*/
    public abstract MConstText extract(int start, int limit);

/**
* Create a <code>java.text.CharacterIterator</code> over all
* of the characters in the text.  Default implementation calls
* <code>createCharacterIterator(0, length())</code>
* @return a <code>java.text.CharacterIterator</code> over all
*      of the characters in the text
*/
    public CharacterIterator createCharacterIterator() {

        return createCharacterIterator(0, length());
    }

/**
* Create a <code>java.text.CharacterIterator</code> over the
* given range of characters in the text.
* @param start the first index in the iteration range
* @param limit the index after the last character in the iteration range
* @return a <code>java.text.CharacterIterator</code> over the
*     given range
*/
    public abstract CharacterIterator createCharacterIterator(int start,
                                                              int limit);


//========================================================
// SIZE/CAPACITY
//========================================================
/**
* Return the length of the MConstText object.  The length is the number of characters in the text.
* @return the length of the MConstText object
*/
    public abstract int length();

//========================================================
// Character styles
//========================================================

/**
* Return the index of the first character in the character style run
* containing pos.  All characters in a style run have the same character
* style.
* @returns the style at offset <code>pos</code>
*/
    public abstract int characterStyleStart(int pos);

/**
* Return the index after the last character in the character style run
* containing pos.  All characters in a style run have the same character
* style.
* @returns the style at offset <code>pos</code>
*/
    public abstract int characterStyleLimit(int pos);

/**
* Return the style applied to the character at offset <code>pos</code>.
* @param pos a valid offset into the text
* @returns the style at offset <code>pos</code>
*/
    public abstract AttributeMap characterStyleAt(int pos);

//========================================================
// PARAGRAPH BOUNDARIES
//========================================================
/**
* Return the start of the paragraph containing the character at offset <code>pos</code>.
* @param pos a valid offset into the text
* @returns the start of the paragraph containing the character at offset <code>pos</code>
*/
    public abstract int paragraphStart(int pos);

/**
* Return the limit of the paragraph containing the character at offset <code>pos</code>.
* @param pos a valid offset into the text
* @returns the limit of the paragraph containing the character at offset <code>pos</code>
*/
    public abstract int paragraphLimit(int pos);

/**
* Return the paragraph style applied to the paragraph containing offset <code>pos</code>.
* @param pos a valid offset into the text
* @returns the paragraph style in effect at <code>pos</code>
*/
    public abstract AttributeMap paragraphStyleAt(int pos);

/**
* Return the current time stamp.  The time stamp is
* incremented whenever the contents of the MConstText changes.
* @return the current paragraph style time stamp
*/
    public abstract int getTimeStamp();

/**
* Return the start of the damaged range.  If the start is not less
* than the the limit of the damaged range, then the damaged range
* is empty.
* @return the start of the damaged range
* @see #damagedRangeLimit
* @see MText#resetDamagedRange
*/
    public abstract int damagedRangeStart();

/**
* Return the limit of the damaged range.  If the start is not less
* than the the limit of the damaged range, then the damaged range
* is empty.
* @return the start of the damaged range
* @see #damagedRangeStart
* @see MText#resetDamagedRange
*/
    public abstract int damagedRangeLimit();

//========================================================
// Equality and hashCode
//========================================================
/**
* Compare this to another Object for equality.  This is
* equal to rhs if rhs is an MConstText which is equal
* to this.
* @param rhs Object to compare to
* @return true if this equals <code>rhs</code>
*/
    public final boolean equals(Object rhs) {

        MConstText otherText;

        try {
            otherText = (MConstText) rhs;
        }
        catch(ClassCastException e) {
            return false;
        }

        return equals(otherText);
    }

/**
* Compare this to another MConstText for equality.  This is
* equal to rhs if the characters and styles in rhs are the
* same as this.  Subclasses may override this implementation
* for efficiency, but they should preserve these semantics.
* Determining that two MConstText instances are equal may be
* an expensive operation, since every character and style must
* be compared.
* @param rhs Object to compare to
* @return true if this equals <code>rhs</code>
*/
    public boolean equals(MConstText rhs) {

        if (rhs == null) {
            return false;
        }

        if (rhs == this) {
            return true;
        }

        if (hashCode() != rhs.hashCode()) {
            return false;
        }

        int length = length();
        if (length != rhs.length()) {
            return false;
        }

        for (int i=0; i < length; i++) {
            if (i < length && at(i) != rhs.at(i)) {
                return false;
            }
        }

        for (int start = 0; start < length;) {
            if (!characterStyleAt(start).equals(rhs.characterStyleAt(start))) {
                return false;
            }
            int limit = characterStyleLimit(start);
            if (limit != rhs.characterStyleLimit(start)) {
                return false;
            }
            start = limit;
        }

        for (int start = 0; start < length;) {

            if (!paragraphStyleAt(start).equals(rhs.paragraphStyleAt(start))) {
                return false;
            }
            start = paragraphLimit(start);
        }

        return paragraphStyleAt(length).equals(rhs.paragraphStyleAt(length));
    }

    /**
     * Return the hashCode for this MConstText.  An empty MConstText
     * has hashCode 0;  a nonempty MConstText's hashCode is
     * <blockquote><pre>
     *       at(0) +
     *       at(length/2)*31^1 +
     *       at(length-1)*31^2 +
     *       characterStyleAt(0).hashCode()*31^3 +
     *       paragraphStyleAt(length-1).hashCode()*31^4
     * </pre></blockquote>
     * where <code>^</code> is exponentiation (not bitwise XOR).
     */
    public final int hashCode() {

        int hashCode = 0;
        int length = length();

        if (length > 0) {
            hashCode = paragraphStyleAt(length-1).hashCode();
            hashCode = hashCode*31 + characterStyleAt(0).hashCode();
            hashCode = hashCode*31 + at(length-1);
            hashCode = hashCode*31 + at(length/2);
            hashCode = hashCode*31 + at(0);
        }

        return hashCode;
    }
}