/* 
 * Cria um novo StringBuffer baseado em uma string passada como
 * parâmetro.
 */
function StringBuffer(strval) 
{
    this.arrayContents = new Array();
    for (var i = 0; i < strval.length; i++)
        this.arrayContents[i] = strval.charAt(i);
    this.setCharAt = _setCharAt;
    this.getCharAt = _getCharAt;
    this.squeeze = _squeeze;
    this.toString = _toString;
    this.reverse = _reverse;
    this.append = _append;
    this.size = _size;
    this.copy = _copy;
    this.reset = _reset;
    this.trim = _trim;
}

/*
 * Retorna o tamanho do buffer
 */
function _size() 
{
    return this.arrayContents.length;
}

/*
 * Substitui o valor de arrayContents[intIndex] por charValue.
 */
function _setCharAt(intIndex, charValue) 
{
    if (intIndex >= 0)
        this.arrayContents[intIndex] = charValue;
    else
        throw "Índice menor do que zero.";
}

/*
 * Retorna o valor de arrayContens[intIndex].
 */
function _getCharAt(intIndex) 
{
    if (intIndex < 0 || intIndex > this.arrayContents.length)
        throw "Índice inválido.";
    else
        return this.arrayContents[intIndex];
}

/*
 * Reverte a ordem de caracteres do buffer.
 */
function _reverse() 
{
    this.arrayContents.reverse();
}
   
/*
 * Adiciona um charValue no final de arrayContents.
 */
function _append(aval) 
{
    if (aval.constructor == String) {
        var ilen1 = this.arrayContents.length;
        var ilen2 = aval.length + ilen1;
        for (var i = ilen1; i < ilen2; i++)
            this.arrayContents[i] = aval.charAt(i - ilen1);
    } else
        this.arrayContents[this.arrayContents.length] = aval;
}

/*
 * Retira todas as ocorrências de charValue em arrayContents.
 */
function _squeeze(charValue) 
{
    var arrtmp;
    var i, j;

    arrtmp = new Array();
    for (i = j = 0 ; i < this.arrayContents.length; i++) {
        if (this.arrayContents[i] == charValue)
            continue;
        arrtmp[j++] = this.arrayContents[i];
    }
    this.copy(arrtmp);
}

/*
 * Copia para o valor de um array passado como parâmetro.
 */
function _copy(arrsrc) 
{
    this.arrayContents = arrsrc;
}

/*
 * Esvazia o nosso buffer.
 */
function _reset() 
{
    this.arrayContents = new Array();
}

/*
 * Retorna a representação string do buffer.
 */
function _toString() 
{
    var strval;

    strval = new String();
    for (var i = 0; i < this.arrayContents.length; i++)
        if (this.arrayContents[i] != ",")
            strval += this.arrayContents[i];
    return strval;
}

/*
 * Retira todos os espaços do final e do começo
 * do array.
 */
function _trim() 
{
    var i, j, k;
    var arrtemp;

    for (i = 0; i < this.arrayContents.length; i++)
        if (this.arrayContents[i] != " ")
            break; 
    for (j = this.arrayContents.length; --j >= i; )
        if (this.arrayContents[j] != " ")
            break;
    arrtemp = new Array();
    for (k = 0; i <= j; i++)
        arrtemp[k++] = this.arrayContents[i];
    this.copy(arrtemp);
}

function StringBuffer_TEST() 
{
    var buffValue;
   
    buffValue = new StringBuffer("Teste");
    alert("CONSTRUTOR: " + buffValue);

    buffValue.append("abc");
    buffValue.append("abc");
    buffValue.append("abc");
    alert("APPEND: " + buffValue);
  
    buffValue.squeeze('a');
    buffValue.squeeze('b');
    buffValue.squeeze('c');
    alert("SQUEEZE: " + buffValue);

    alert("SIZE: " + buffValue.size());

    buffValue.reverse();
    alert("REVERSE: " + buffValue);

    try {
        for (var i = 0; i < buffValue.size(); i++)
	        alert("GETCHARAT(" + i + ")" + buffValue.getCharAt(i));
    } catch (e) {
        alert(e);
    }
    try {
        buffValue.setCharAt(0, 'T');
        buffValue.setCharAt(2, 't');
    } catch (e) {
        alert(e);
    }
    alert("SETCHARAT(): " + buffValue);

    buffValue.reset();
    alert("RESET: " + buffValue);

    buffValue.append("  TRIM  ");
    alert(buffValue);
    alert(buffValue.size());
    buffValue.trim();
    alert("TRIM: " + buffValue);
    alert(buffValue.size());
}
