String.java

/**
* Copyright 2010,2021 Nikolas S Boyd.
Permission is granted to copy this work provided this copyright statement is retained in all copies.

*/
package Hoot.Collections;

import Hoot.Runtime.Functions.*;
import Hoot.Runtime.Faces.*;
import Hoot.Runtime.Values.*;
import Hoot.Runtime.Blocks.*;
import Smalltalk.Core.*;
import Smalltalk.Blocks.*;
import Smalltalk.Magnitudes.*;
import Hoot.Behaviors.*;
import Hoot.Behaviors.Nil;
import Hoot.Behaviors.Object;
import Hoot.Behaviors.True;
import Hoot.Behaviors.False;
import Hoot.Behaviors.Boolean;
import Hoot.Magnitudes.*;
import Hoot.Magnitudes.Integer;
import Hoot.Magnitudes.Character;
import Hoot.Magnitudes.Float;
import Hoot.Magnitudes.Double;
import java.util.List;
import org.apache.commons.lang3.*;
import Hoot.Behaviors.*;
import Hoot.Behaviors.Boolean;
import Hoot.Behaviors.Object;
import Hoot.Magnitudes.Integer;
import Hoot.Magnitudes.SmallInteger;
import Hoot.Magnitudes.Character;
import Hoot.Streams.TextWriteStream;
import Hoot.Runtime.Names.Primitive;
import Smalltalk.Magnitudes.Code;
import Smalltalk.Magnitudes.Ordinal;
import Smalltalk.Collections.*;

public class String extends CharacterString implements MutableString
{

  public static Metaclass type() { return (Metaclass)Metaclass.$class; }
  @Override public Metaclass $class() { return (Metaclass)Metaclass.$class; }
  public static class Metaclass extends CharacterString.Metaclass implements MutableString.Metatype
  {
    static final String.Metaclass $class = new String.Metaclass();
    public Metaclass() {
      this(String.Metaclass.class);
    }

    public Metaclass(java.lang.Class aClass) {
      super(aClass);
    }

    @Override public java.lang.Class outerClass() { return String.class; }


    /**
     * @return 
     */
    @Override public   String $new()
    {
      java.lang.String exitID = "StringMetatype>>$new";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (String)f0.exit(exitID, this.$new(SmallInteger.from(10)));
      });
    }

    /**
     * @return 
     */
    @Override public   String $new(final Ordinal capacity)
    {
      java.lang.String exitID = "StringMetatype>>$new";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (String)f0.exit(exitID, new String(capacity));
      });
    }

    /**
     * @return 
     */
    public   TextWriteStream writeStream(final Integer capacity)
    {
      java.lang.String exitID = "StringMetatype>>writeStream";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (TextWriteStream)f0.exit(exitID, new String(capacity).writeStream());
      });
    }
  }


  private StringBuffer contents = new StringBuffer();

  /**
   * 
   */
  protected    String(final java.lang.String primitiveString)
  {
    java.lang.String exitID = "String>>String";
    Frame f0 = new Frame(exitID);
    contents.append(primitiveString);
  }

  /**
   * 
   */
  protected    String(final Ordinal capacity)
  {
    java.lang.String exitID = "String>>String";
    Frame f0 = new Frame(exitID);
     contents = new StringBuffer(capacity.intValue());
  }

  /**
   * @return 
   */
  public static   String emptyString()
  {
    java.lang.String exitID = "String>>$emptyString";
    Frame f0 = new Frame(exitID);
    return (String)String.type().$new();
  }

  /**
   * @return 
   */
  public static   String from(final ReadableString aString)
  {
    java.lang.String exitID = "String>>$from";
    Frame f0 = new Frame(exitID);
    return (String)(Boolean.primitiveValue((aString == null)) ? String.emptyString() : new String(aString.toString()));
  }

  /**
   * @return 
   */
  public static   String from(final java.lang.String aString)
  {
    java.lang.String exitID = "String>>$from";
    Frame f0 = new Frame(exitID);
    return (String)(Boolean.primitiveValue((aString == null)) ? String.emptyString() : new String(aString));
  }

  /**
   * @return 
   */
  public static   List<String> listFrom(final String ... textStrings)
  {
    java.lang.String exitID = "String>>$listFrom";
    Frame f0 = new Frame(exitID);
    return (List<String>)Utils.wrap(textStrings);
  }

  /**
   * @return 
   */
  public static   String join_with(final List<String> textStrings, final String joint)
  {
    java.lang.String exitID = "String>>$join_with";
    Frame f0 = new Frame(exitID);
    return (String)String.from(Utils.joinWith(joint.asPrimitive(), String.primitiveListFrom(textStrings)));
  }

  /**
   * @return 
   */
  public static   java.lang.String [] primitiveArrayFrom(final List<String> textStrings)
  {
    java.lang.String exitID = "String>>$primitiveArrayFrom";
    Frame f0 = new Frame(exitID);
    return (java.lang.String [])Utils.unwrap(String.primitiveListFrom(textStrings), Primitive.EmptyArray);
  }

  /**
   * @return 
   */
  public static   List<java.lang.String> primitiveListFrom(final List<String> textStrings)
  {
    java.lang.String exitID = "String>>$primitiveListFrom";
    Frame f0 = new Frame(exitID);
    return (List<java.lang.String>)Closure.with(f2 -> {
      List<java.lang.String> list = f2.getValue(0).value();
      String s = f2.getValue(1).value();
      list.add(s.asPrimitive());
    }, "list", "s").collectStringsFrom(textStrings);
  }

  /**
   * @return 
   */
  public static   List<String> listWith(final java.lang.String ... textStrings)
  {
    java.lang.String exitID = "String>>$listWith";
    Frame f0 = new Frame(exitID);
    return (List<String>)String.listWith(Utils.wrap(textStrings));
  }

  /**
   * @return 
   */
  public static   List<String> listWith(final List<java.lang.String> textStrings)
  {
    java.lang.String exitID = "String>>$listWith";
    Frame f0 = new Frame(exitID);
    return (List<String>)Closure.with(f2 -> {
      java.lang.String s = f2.getValue(0).value();
      return String.from(s);
    }, "s").evaluateEach(textStrings, String.type().outerClass());
  }

  /**
   * @return 
   */
  public static   List<String> listWithEach(final List<java.lang.Object> textStrings)
  {
    java.lang.String exitID = "String>>$listWithEach";
    Frame f0 = new Frame(exitID);
    return (List<String>)Closure.with(f2 -> {
      java.lang.Object s = f2.getValue(0).value();
      return String.from(s.toString());
    }, "s").evaluateEach(textStrings, String.type().outerClass());
  }

  /**
   * @return 
   */
  public   Integer toInteger()
  {
    java.lang.String exitID = "String>>toInteger";
    Frame f0 = new Frame(exitID);
    return (Integer)SmallInteger.from(java.lang.Integer.valueOf(this.asPrimitive()));
  }

  /**
   * @return 
   */
  @Override public   java.lang.String toString()
  {
    java.lang.String exitID = "String>>toString";
    Frame f0 = new Frame(exitID);
    return (java.lang.String)this.primitiveString();
  }

  /**
   * @return 
   */
  @Override public   java.lang.String primitiveString()
  {
    java.lang.String exitID = "String>>primitiveString";
    Frame f0 = new Frame(exitID);
    return (java.lang.String)contents.toString();
  }

  /**
   * @return 
   */
  @Override public   Integer size()
  {
    java.lang.String exitID = "String>>size";
    Frame f0 = new Frame(exitID);
    return (Integer)SmallInteger.from(contents.length());
  }

  /**
   * @return 
   */
  @Override protected   Character get(final int index)
  {
    java.lang.String exitID = "String>>get";
    Frame f0 = new Frame(exitID);
    return (Character)Character.from(contents.charAt(index));
  }

  /**
   * @return 
   */
  @Override public   Character at_ifAbsent(final Ordinal index, final NiladicValuable aBlock)
  {
    java.lang.String exitID = "String>>at_ifAbsent";
    Frame f0 = new Frame(exitID);
    int i = this.checkIndex_ifAbsent(index, aBlock);
    return (Character)Character.from(contents.charAt(i));
  }

  /**
   * @return 
   */
  public   Character at_put(final Ordinal index, final Object element)
  {
    java.lang.String exitID = "String>>at_put";
    Frame f0 = new Frame(exitID);
    Character c = ((Character)element);

    int i = this.checkGrows(index);
    if ((i < contents.length())) {
      contents.setCharAt(i, c.primitiveCharacter());
    }
    else {
      contents.append(c.primitiveCharacter());
    };
    return (Character)c;
  }

  /**
   * @return 
   */
  public   Integer indexOf_ifAbsent(final Object element, final NiladicValuable noneBlock)
  {
    java.lang.String exitID = "String>>indexOf_ifAbsent";
    Frame f0 = new Frame(exitID);
    return (Integer)this.indexOf_ifAbsent(((Character)element), noneBlock);
  }

  /**
   * @return 
   */
  public   Integer indexOf_ifAbsent(final Character element, final NiladicValuable noneBlock)
  {
    java.lang.String exitID = "String>>indexOf_ifAbsent";
    Frame f0 = new Frame(exitID);
    int index = contents.indexOf(element.toString());
    if (!((index < 0))) {
      return SmallInteger.from((index + 1));
    };
    return (Integer)noneBlock.value();
  }

  /**
   * @return 
   */
  protected   Object add_at(final Object element, final int index)
  {
    java.lang.String exitID = "String>>add_at";
    Frame f0 = new Frame(exitID);
    contents.insert(index, element);
    return (Object)element;
  }

  /**
   * @return 
   */
  public   Character add(final Subject element)
  {
    java.lang.String exitID = "String>>add";
    Frame f0 = new Frame(exitID);
    return (Character)this.add(((Character)element));
  }

  /**
   * @return 
   */
  public   Character add(final Character c)
  {
    java.lang.String exitID = "String>>add";
    Frame f0 = new Frame(exitID);
    contents.append(c.primitiveCharacter());
    return (Character)c;
  }

  /**
   * @return 
   */
  public   Character add_after(final Object element, final Object target)
  {
    java.lang.String exitID = "String>>add_after";
    Frame f0 = new Frame(exitID);
    return (Character)this.add_afterIndex(element, this.indexOf_ifAbsent(target, Closure.with(f2 -> {
      return this.elementNotFound();
    }, "")));
  }

  /**
   * @return 
   */
  public   Character add_afterIndex(final Object element, final Ordinal index)
  {
    java.lang.String exitID = "String>>add_afterIndex";
    Frame f0 = new Frame(exitID);
    int i = this.checkRange(((Ordinal)(index.plus(SmallInteger.from(1)))));

    Character c = ((Character)element);
    contents.insert(i, c.primitiveCharacter());
    return (Character)c;
  }

  /**
   * @return 
   */
  public   Character add_before(final Object element, final Object target)
  {
    java.lang.String exitID = "String>>add_before";
    Frame f0 = new Frame(exitID);
    return (Character)this.add_beforeIndex(element, this.indexOf_ifAbsent(target, Closure.with(f2 -> {
      return this.elementNotFound();
    }, "")));
  }

  /**
   * @return 
   */
  public   Character add_beforeIndex(final Object element, final Ordinal index)
  {
    java.lang.String exitID = "String>>add_beforeIndex";
    Frame f0 = new Frame(exitID);
    int i = this.checkRange(index);

    Character c = ((Character)element);
    contents.insert(i, c.primitiveCharacter());
    return (Character)c;
  }

  /**
   * @return 
   */
  public   CollectedReadably<Character> addAll_after(final CollectedReadably elements, final Object target)
  {
    java.lang.String exitID = "String>>addAll_after";
    Frame f0 = new Frame(exitID);
    return (CollectedReadably<Character>)this.addAll_afterIndex(elements, this.indexOf_ifAbsent(target, Closure.with(f2 -> {
      this.elementNotFound();
    }, "")));
  }

  /**
   * @return 
   */
  @Override public   CollectedReadably<Character> addAll_afterIndex(final CollectedReadably elements, final Ordinal index)
  {
    java.lang.String exitID = "String>>addAll_afterIndex";
    Frame f0 = new Frame(exitID);
    elements.inject_into(index, Closure.with(f2 -> {
      Ordinal i = f2.getValue(0).value();
      Character e = f2.getValue(1).value();
      this.add_afterIndex(e, i);
    return (i.plus(SmallInteger.from(1)));
    }, "i", "e"));
    return (CollectedReadably<Character>)elements;
  }

  /**
   * @return 
   */
  public   CollectedReadably<Character> addAll_before(final CollectedReadably elements, final Object target)
  {
    java.lang.String exitID = "String>>addAll_before";
    Frame f0 = new Frame(exitID);
    return (CollectedReadably<Character>)this.addAll_beforeIndex(elements, this.indexOf_ifAbsent(target, Closure.with(f2 -> {
      return this.elementNotFound();
    }, "")));
  }

  /**
   * @return 
   */
  @Override public   CollectedReadably<Character> addAll_beforeIndex(final CollectedReadably elements, final Ordinal index)
  {
    java.lang.String exitID = "String>>addAll_beforeIndex";
    Frame f0 = new Frame(exitID);
    elements.inject_into(index, Closure.with(f2 -> {
      Ordinal i = f2.getValue(0).value();
      Character e = f2.getValue(1).value();
      this.add_beforeIndex(e, i);
    return (i.plus(SmallInteger.from(1)));
    }, "i", "e"));
    return (CollectedReadably<Character>)elements;
  }

  /**
   * @return 
   */
  @Override public   Collected<Character> addAll(final Collected elements)
  {
    java.lang.String exitID = "String>>addAll";
    Frame f0 = new Frame(exitID);
    elements.$do(Closure.with(f2 -> {
      Character element = f2.getValue(0).value();
      return this.add(element);
    }, "element"));
    return (Collected<Character>)elements;
  }

  /**
   * @return 
   */
  @Override public   CollectedReadably<Character> addAllFirst(final CollectedReadably elements)
  {
    java.lang.String exitID = "String>>addAllFirst";
    Frame f0 = new Frame(exitID);
    elements.reverseDo(Closure.with(f2 -> {
      Character element = f2.getValue(0).value();
      return this.addFirst(element);
    }, "element"));
    return (CollectedReadably<Character>)elements;
  }

  /**
   * @return 
   */
  @Override public   CollectedReadably<Character> addAllLast(final CollectedReadably elements)
  {
    java.lang.String exitID = "String>>addAllLast";
    Frame f0 = new Frame(exitID);
    elements.$do(Closure.with(f2 -> {
      Character element = f2.getValue(0).value();
      return this.addLast(element);
    }, "element"));
    return (CollectedReadably<Character>)elements;
  }

  /**
   * @return 
   */
  public   Character addFirst(final Object element)
  {
    java.lang.String exitID = "String>>addFirst";
    Frame f0 = new Frame(exitID);
    Character c = ((Character)element);
    this.add_beforeIndex(c, SmallInteger.from(1));
    return (Character)c;
  }

  /**
   * @return 
   */
  public   Character addLast(final Object element)
  {
    java.lang.String exitID = "String>>addLast";
    Frame f0 = new Frame(exitID);
    return (Character)this.add(element);
  }

  /**
   * @return 
   */
  public   String trim()
  {
    java.lang.String exitID = "String>>trim";
    Frame f0 = new Frame(exitID);
    return (String)String.from(contents.toString().trim());
  }

  /**
   * @return 
   */
  public   String removeAll()
  {
    java.lang.String exitID = "String>>removeAll";
    Frame f0 = new Frame(exitID);
     contents = new StringBuffer();
    return (String)this;
  }

  /**
   * @return 
   */
  public   Character removeAtIndex(final Ordinal index)
  {
    java.lang.String exitID = "String>>removeAtIndex";
    Frame f0 = new Frame(exitID);
    return (Character)this.removeAtIndex_ifAbsent(index, Closure.with(f2 -> {
      this.indexRangeError();
    return Nil.literal();
    }, ""));
  }

  /**
   * @return 
   */
  public   Character removeAtIndex_ifAbsent(final Ordinal index, final NiladicValuable aBlock)
  {
    java.lang.String exitID = "String>>removeAtIndex_ifAbsent";
    Frame f0 = new Frame(exitID);
    int i = this.checkIndex_ifAbsent(index, aBlock);

    Character c = Character.from(contents.charAt(i));
    contents.deleteCharAt(i);
    return (Character)c;
  }

  /**
   * @return 
   */
  public   Character remove(final Object element)
  {
    java.lang.String exitID = "String>>remove";
    Frame f0 = new Frame(exitID);
    return (Character)this.remove_ifAbsent(element, Closure.with(f2 -> {
      this.elementNotFound();
    return Nil.literal();
    }, ""));
  }

  /**
   * @return 
   */
  public   Character remove_ifAbsent(final Object element, final NiladicValuable aBlock)
  {
    java.lang.String exitID = "String>>remove_ifAbsent";
    Frame f0 = new Frame(exitID);
    return (Character)this.removeAtIndex(this.indexOf_ifAbsent(element, aBlock));
  }

  /**
   * @return 
   */
  @Override public   Collected removeAll(final Collected elements)
  {
    java.lang.String exitID = "String>>removeAll";
    Frame f0 = new Frame(exitID);
    elements.$do(Closure.with(f2 -> {
      Character element = f2.getValue(0).value();
      return this.remove(element);
    }, "element"));
    return (Collected)elements;
  }

  /**
   * @return 
   */
  public   Character removeFirst()
  {
    java.lang.String exitID = "String>>removeFirst";
    Frame f0 = new Frame(exitID);
    this.emptyCheck();

    Character c = Character.from(contents.charAt(SmallInteger.from(0).asPrimitive()));
    contents.deleteCharAt(SmallInteger.from(0).asPrimitive());
    return (Character)c;
  }

  /**
   * @return 
   */
  public   Character removeLast()
  {
    java.lang.String exitID = "String>>removeLast";
    Frame f0 = new Frame(exitID);
    this.emptyCheck();

    int index = (contents.length() - 1);

    Character c = Character.from(contents.charAt(index));
    contents.deleteCharAt(index);
    return (Character)c;
  }

  /**
   * @return 
   */
  @Override public   String append(final CharacterString aString)
  {
    java.lang.String exitID = "String>>append";
    Frame f0 = new Frame(exitID);
    return (String)String.from((this.primitiveString() + aString.primitiveString()));
  }

  /**
   * @return 
   */
  public   TextWriteStream writeStream()
  {
    java.lang.String exitID = "String>>writeStream";
    Frame f0 = new Frame(exitID);
    return (TextWriteStream)TextWriteStream.type().with(this);
  }

  /**
   * @return 
   */
  @Override public   Boolean isLiteral()
  {
    java.lang.String exitID = "String>>isLiteral";
    Frame f0 = new Frame(exitID);
    return (Boolean)True.literal();
  }

  /**
   * @return 
   */
  @Override public   String printLine()
  {
    java.lang.String exitID = "String>>printLine";
    Frame f0 = new Frame(exitID);
    {
    String prime = this;
    prime.add(Character.type().cr()); 

    return prime.yourself();
    }
  }

  /**
   * @return 
   */
  @Override public   String printString()
  {
    java.lang.String exitID = "String>>printString";
    Frame f0 = new Frame(exitID);
    return (String)String.from(Primitive.quoteLiterally(this.primitiveString()));
  }

  /**
   * @return 
   */
  public   String rightPadded(final Integer count)
  {
    java.lang.String exitID = "String>>rightPadded";
    Frame f0 = new Frame(exitID);
    return (String)String.from(StringUtils.rightPad(this.asPrimitive(), count.intValue()));
  }

  /**
   * @return 
   */
  public   String formatWith(final String ... args)
  {
    java.lang.String exitID = "String>>formatWith";
    Frame f0 = new Frame(exitID);
    return (String)String.from(this.formatWith(Utils.wrap(args)));
  }

  /**
   * @return 
   */
  public   String formatWith(final List<String> args)
  {
    java.lang.String exitID = "String>>formatWith";
    Frame f0 = new Frame(exitID);
    return (String)this.formatWith(String.primitiveArrayFrom(args));
  }

  /**
   * @return 
   */
  public   String formatWith(final java.lang.String ... args)
  {
    java.lang.String exitID = "String>>formatWith";
    Frame f0 = new Frame(exitID);
    java.lang.Object [] vargs = args;
    return (String)String.from(java.lang.String.format(this.asPrimitive(), vargs));
  }
}