/*   Copyright 2004 The Apache Software Foundation
 *
 *   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 org.apache.xmlbeans.impl.store;

//import org.apache.xmlbeans.impl.store.Root.WriteContext;
//import org.apache.xmlbeans.impl.store.Root.ReadContext;
import org.apache.xmlbeans.XmlBeans;

import java.io.IOException;

public final class Text
{
    char[] _buf;
    int    _gap;    // Where the gap starts
    int    _gapLen; // The length of the gap

    int length ( )
    {
        return bufLen() - _gapLen;
    }

    private int bufLen ( )
    {
        return _buf == null ? 0 : _buf.length;
    }

    private void copy ( char[] newBuf )
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( _buf != null && newBuf.length >= length() );
        
        System.arraycopy( _buf, 0, newBuf, 0, _gap );

        int lenAfterGap = _buf.length - _gap - _gapLen;

        System.arraycopy(
            _buf, _gap + _gapLen,
            newBuf, newBuf.length - (lenAfterGap), lenAfterGap );
    }

    void resize ( int cch )
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( cch > _gapLen );
        
        int newSize = length() + cch;
        int newLen = _buf == null ? 1024 : _buf.length * 2;

        while ( newLen < newSize )
            newLen *= 2;

        char[] newBuf = new char [ newLen ];

        if (_buf != null)
        {
            copy( newBuf );
            _gapLen += newBuf.length - _buf.length;
        }
        else
            _gapLen += newBuf.length;

        _buf = newBuf;
    }

    void trim ( )
    {
        if (_buf != null && _gapLen != 0)
        {
            char[] newBuf = new char [ length() ];

            copy( newBuf );

            _buf = newBuf;
            _gap = 0;
            _gapLen = 0;
        }
    }

    void move ( int pos, Text src, int srcPos, int cch )
    {
        insert( pos, src, srcPos, cch );

        if (src == this && srcPos >= pos)
            srcPos += cch;

        src.remove( srcPos, cch );
    }

    void insert ( int pos, Object txt, int off, int cch )
    {
        if (txt != null)
        {
            if (txt instanceof String)
                insert( pos, (String) txt, off, cch );
            else if (txt instanceof Text)
                insert( pos, (Text) txt, off, cch );
            else
            {
                if (XmlBeans.ASSERTS)
                    XmlBeans.assertTrue( txt instanceof char[] );
                insert( pos, (char[]) txt, off, cch );
            }
        }
    }
    
    void insert ( int pos, Text src, int srcPos, int cch )
    {
        //
        // This can deal with copying from itself
        //

        if (cch > 0)
        {
            if (cch > _gapLen)
                resize( cch );
            
            moveGap( pos );

            if (srcPos + cch < src._gap)
                System.arraycopy( src._buf, srcPos, _buf, _gap, cch );
            else if (srcPos >= src._gap)
            {
                System.arraycopy(
                    src._buf, srcPos + src._gapLen, _buf, _gap, cch );
            }
            else
            {
                int leftLen = src._gap - srcPos;
            
                System.arraycopy( src._buf, srcPos, _buf, _gap, leftLen );
            
                System.arraycopy(
                    src._buf, src._gap + src._gapLen,
                    _buf, _gap + leftLen, cch - leftLen );
            }

            _gap += cch;
            _gapLen -= cch;
        }
    }
    
    void insert ( int pos, char[] chars, int off, int cch )
    {
        if (XmlBeans.ASSERTS)
        {
            XmlBeans.assertTrue( chars != _buf );
            XmlBeans.assertTrue( pos >= 0 && pos <= length() );
        }

        if (cch > 0)
        {
            if (cch > _gapLen)
                resize( cch );

            moveGap( pos );

            System.arraycopy( chars, off, _buf, _gap, cch );

            _gap += cch;
            _gapLen -= cch;
        }
    }

    void insert ( int pos, String s )
    {
        insert( pos, s, 0, s.length() );
    }
    
    void insert ( int pos, String s, int off, int cch )
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( pos >= 0 && pos <= length() );
        
        if (cch > 0)
        {
            if (XmlBeans.ASSERTS)
            {
                XmlBeans.assertTrue( off >= 0 && off < s.length() );
                XmlBeans.assertTrue( cch <= s.length() - off );
            }

            if (cch > _gapLen)
                resize( cch );
            
            moveGap( pos );

            s.getChars( off, off + cch, _buf, _gap );

            _gap += cch;
            _gapLen -= cch;
        }
    }

    void remove ( int pos, int cch )
    {
        remove( pos, cch, null, 0 );
    }
    
    void remove ( int pos, int cch, char[] retBuf, int off )
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( pos >= 0 && pos + cch <= length() );

        moveGap( pos );

        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( retBuf == null || retBuf.length - off >= cch );

        if (cch > 0 && retBuf != null)
            System.arraycopy( _buf, _gap + _gapLen, retBuf, off, cch );
        
        _gapLen += cch;
    }

    void moveGap( int pos )
    {
        if (pos < _gap)
            System.arraycopy( _buf, pos, _buf, pos + _gapLen, _gap - pos );
        else if (pos > _gap)
            System.arraycopy( _buf, _gap + _gapLen, _buf, _gap, pos - _gap);

        _gap = pos;
    }

    int unObscure ( int pos, int cch )
    {
        if (XmlBeans.ASSERTS)
        {
            XmlBeans.assertTrue( cch >= 0 );
            XmlBeans.assertTrue( pos >= 0 && pos + cch <= length() );
        }

        if (cch > 0 && (pos < _gap && pos + cch > _gap))
            moveGap( pos + cch );

        return pos < _gap ? pos : pos + _gapLen;
    }

    void fetch ( StringBuffer sb, int pos, int cch )
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( pos >= 0 && pos + cch <= length() );

        if (cch == 0)
            return;

        if (pos + cch <= _gap)
        {
            sb.append( _buf, pos, cch );
        }
        else
        {
            if (pos >= _gap)
            {
                sb.append( _buf, pos + _gapLen, cch );
            }
            else
            {
                sb.append( _buf, pos, _gap - pos );
                sb.append( _buf, _gap + _gapLen, cch - _gap + pos );
            }
        }
    }

    String fetch ( int pos, int cch )
    {
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue( pos >= 0 && pos + cch <= length() );

        if (cch == 0)
            return "";

        if (pos + cch <= _gap)
            return new String( _buf, pos, cch );

        if (pos >= _gap)
            return new String( _buf, pos + _gapLen, cch );

        StringBuffer sb = new StringBuffer();

        sb.append( _buf, pos, _gap - pos );
        sb.append( _buf, _gap + _gapLen, cch - _gap + pos );

        return sb.toString();
    }

    void fetch ( char[] buf, int off, int pos, int cch )
    {
        if (XmlBeans.ASSERTS)
        {
            XmlBeans.assertTrue( off >= 0 );
            XmlBeans.assertTrue( pos >= 0 && pos + cch <= length() );
            XmlBeans.assertTrue( buf.length - off >= cch );
        }

        if (cch == 0)
            return;
        
        if (pos + cch <= _gap)
            System.arraycopy( _buf, pos, buf, off, cch );
        else if (pos >= _gap)
            System.arraycopy( _buf, pos + _gapLen, buf, off, cch );
        else
        {
            int chunk = _gap - pos;
            
            System.arraycopy( _buf, pos, buf, off, chunk );
            
            System.arraycopy(
                _buf, _gap + _gapLen, buf, off + chunk, cch - chunk );
        }
    }

    public String toString ( )
    {
        return fetch( 0, length() );
    }
}
