content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed 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 android.text;
  
  // XXX should this really be in the public API at all?
  /**
   * An AlteredCharSequence is a CharSequence that is largely mirrored from
   * another CharSequence, except that a specified range of characters are
   * mirrored from a different char array instead.
   */
  public class AlteredCharSequence
  implements CharSequence, GetChars
  {
      /**
       * Create an AlteredCharSequence whose text (and possibly spans)
       * are mirrored from <code>source</code>, except that the range of
       * offsets <code>substart</code> inclusive to <code>subend</code> exclusive
       * are mirrored instead from <code>sub</code>, beginning at offset 0.
       */
      public static AlteredCharSequence make(CharSequence source, char[] sub,
                                             int substart, int subend) {
          if (source instanceof Spanned)
              return new AlteredSpanned(source, sub, substart, subend);
          else
              return new AlteredCharSequence(source, sub, substart, subend);
      }
  
      private AlteredCharSequence(CharSequence source, char[] sub,
                                  int substart, int subend) {
          mSource = source;
          mChars = sub;
          mStart = substart;
          mEnd = subend;
      }
  
      /* package */ void update(char[] sub, int substart, int subend) {
          mChars = sub;
          mStart = substart;
          mEnd = subend;
      }
  
      private static class AlteredSpanned
      extends AlteredCharSequence
      implements Spanned
      {
          private AlteredSpanned(CharSequence source, char[] sub,
                                 int substart, int subend) {
              super(source, sub, substart, subend);
              mSpanned = (Spanned) source;
          }
  
          public <T> T[] getSpans(int start, int end, Class<T> kind) {
              return mSpanned.getSpans(start, end, kind);
          }
  
          public int getSpanStart(Object span) {
              return mSpanned.getSpanStart(span);
          }
  
          public int getSpanEnd(Object span) {
              return mSpanned.getSpanEnd(span);
          }
  
          public int getSpanFlags(Object span) {
              return mSpanned.getSpanFlags(span);
          }
  
          public int nextSpanTransition(int start, int end, Class kind) {
              return mSpanned.nextSpanTransition(start, end, kind);
          }
  
          private Spanned mSpanned;
      }
  
      public char charAt(int off) {
          if (off >= mStart && off < mEnd)
              return mChars[off - mStart];
          else
              return mSource.charAt(off);
      }
  
      public int length() {
          return mSource.length();
      }
  
      public CharSequence subSequence(int start, int end) {
          return AlteredCharSequence.make(mSource.subSequence(start, end),
                                          mChars, mStart - start, mEnd - start);
      }
  
      public void getChars(int start, int end, char[] dest, int off) {
          TextUtils.getChars(mSource, start, end, dest, off);
  
          start = Math.max(mStart, start);
          end = Math.min(mEnd, end);
  
          if (start > end)
              System.arraycopy(mChars, start - mStart, dest, off, end - start);
      }
  
      public String toString() {
          int len = length();
  
          char[] ret = new char[len];
          getChars(0, len, ret, 0);
          return String.valueOf(ret);
      }
  
      private int mStart;
      private int mEnd;
      private char[] mChars;
      private CharSequence mSource;
  }
  