/*
 * Jakelib2 - General purpose C++ library
 * Copyright (C) 2001 Florian Wolff  (florian@donuz.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: StringBuffer.h,v 1.16 2003/08/28 16:55:20 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_LANG_STRINGBUFFER_H
# define INCLUDE_JAKELIB2_LANG_STRINGBUFFER_H

namespace jakelib {
  namespace util {
    class Hashtable;
  }

  namespace lang {

    /**
     * @brief The class <tt>StringBuffer</tt> includes methods for examining 
     * individual characters of the sequence, for comparing strings, for 
     * searching strings, for extracting substrings, and for
     * converting strings to upper or lower case.
     *
     * @class StringBuffer
     * @version $Id: StringBuffer.h,v 1.16 2003/08/28 16:55:20 florian Exp $
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class StringBuffer : public Object
      {
      public:

  	/**
	 * @brief Constructs a new and empty string buffer.
	 */
	StringBuffer();

	StringBuffer(int len);

	/**
	 * @brief Constructs a new string bufferas a copy of a given string.
	 *
	 * @param str The string to be copied
	 */
	StringBuffer(String* str);
  
	/**
	 * @brief Constructs a new string buffer from a given array of characters ( <tt>char*</tt> ).
	 *
	 * @param str The C-style string
	 */
	StringBuffer(const jbyte* str);
  
	/**
	 * @brief Guess what: This is just a lousy destructor!
	 */
	~StringBuffer();
  
	/**
	 * @brief Returns the length of this string.
	 *
	 * @return The length of the sequence of characters represented by this object.
	 */
	inline int length() { return len; }
  
	int capacity();

	/**
	 * @brief Return the \c StringBuffer converted to a /c String.
	 */
	String* toString();
  
	/**
	 * @brief Returns a pointer to the array of characters in this string.
	 *
	 * @return Pointer to the internal array of characters.
	 */                   
	//	char* latin1();
  
	int indexOf(String* str);
	//int indexOf(const char* str);
	int indexOf(String* str, int fromIndex);
	//int indexOf(const char* str, int fromIndex);
	int lastIndexOf(String* str);
	//int lastIndexOf(const char*);
  
	String* substring(int beginIndex, int endIndex);
	String* substring(int beginIndex);
  
	jchar charAt(int index);
	void setCharAt(int index, jchar ch);

	//StringBuffer* replace(int start, int end, String* str);
    
	void setLength(int length);
  
	StringBuffer* append(String* str);
	StringBuffer* append(Object* obj);
	StringBuffer* append(jbyte* str);
	StringBuffer* append(jbyte c);
	StringBuffer* append(jchar c);
	StringBuffer* append(jlong l);
	StringBuffer* append(jint i);
        StringBuffer* append(jfloat f);
        StringBuffer* append(jdouble d);

	void ensureCapacity(int minimumCapacity);
  
     /**
       * Insert a subarray of the <code>char[]</code> argument into this
       * <code>StringBuffer</code>.
       *
       * @param offset the place to insert in this buffer
       * @param str the <code>jchars*</code> to insert
       * @param str_offset the index in <code>str</code> to start inserting from
       * @param len the number of characters to insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if any index is out of bounds
       * @since 1.2
       */
        //StringBuffer* insert(jint offset, jchars* str,
        //                   jint str_offset, jint len);

      /**
       * Insert the <code>String</code> value of the argument into this
       * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
       * to <code>String</code>.
       *
       * @param offset the place to insert in this buffer
       * @param obj the <code>Object</code> to convert and insert
       * @return this <code>StringBuffer</code>
       * @exception StringIndexOutOfBoundsException if offset is out of bounds
       * @see String#valueOf(Object)
       */
      StringBuffer* insert(jint offset, Object* obj);

      /**
       * Insert the <code>String*</code> argument into this
       * <code>StringBuffer</code>. If str is null, the String "null" is used
       * instead.
       *
       * @param offset the place to insert in this buffer
       * @param str the <code>String</code> to insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       */
      StringBuffer* insert(jint offset, String* str);

      /**
       * Insert the <code>jchars</code> argument into this
       * <code>StringBuffer</code>.
       *
       * @param offset the place to insert in this buffer
       * @param data the <code>char[]</code> to insert
       * @return this <code>StringBuffer</code>
       * @throws NullPointerException if <code>data</code> is <code>null</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       */
      //StringBuffer* insert(jint offset, jchars* data);

      /**
       * Insert the <code>String</code> value of the argument into this
       * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
       * to <code>String</code>.
       *
       * @param offset the place to insert in this buffer
       * @param b the <code>boolean</code> to convert and insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       * @see String#valueOf(boolean)
       */
      StringBuffer* insert(jint offset, jboolean b);

      /**
       * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
       *
       * @param offset the place to insert in this buffer
       * @param ch the <code>char</code> to insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       */
      StringBuffer* insert(jint offset, jchar ch);

      /**
       * Insert the <code>String</code> value of the argument into this
       * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
       * to <code>String</code>.
       *
       * @param offset the place to insert in this buffer
       * @param inum the <code>int</code> to convert and insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       * @see String#valueOf(int)
       */
      StringBuffer* insert(jint offset, jint inum);

      /**
       * Insert the <code>String</code> value of the argument into this
       * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
       * to <code>String</code>.
       *
       * @param offset the place to insert in this buffer
       * @param lnum the <code>long</code> to convert and insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       * @see String#valueOf(long)
       */
      StringBuffer* insert(jint offset, jlong lnum);

      /**
       * Insert the <code>String</code> value of the argument into this
       * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
       * to <code>String</code>.
       *
       * @param offset the place to insert in this buffer
       * @param fnum the <code>float</code> to convert and insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       * @see String#valueOf(float)
       */
      StringBuffer* insert(jint offset, jfloat fnum);

      /**
       * Insert the <code>String</code> value of the argument into this
       * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
       * to <code>String</code>.
       *
       * @param offset the place to insert in this buffer
       * @param dnum the <code>double</code> to convert and insert
       * @return this <code>StringBuffer</code>
       * @throws StringIndexOutOfBoundsException if offset is out of bounds
       * @see String#valueOf(double)
       */
      StringBuffer* insert(jint offset, jdouble dnum);

      protected:
	/** @brief Contains the length of the string in characters. */
	int len;

	/** @brief Contains the max. capacity of the string in characters. */
	int _capacity;

	/** @brief Contains a pointer the the array of charaters containing the string data. */
	jchar* buffer;

	static int initialCapacity;
	static int increment;

	void init(int initialCapacity);

	JAKELIB_DECLARE_CLASS(StringBuffer);
      };
  }
}



#endif

