OrderedCollection.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 Hoot.Magnitudes.Number;
import Hoot.Magnitudes.Integer;
import Hoot.Streams.ReadStream;
import Hoot.Streams.WriteStream;
import Smalltalk.Magnitudes.Ordinal;
import Smalltalk.Collections.*;
import Smalltalk.Core.Subject;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;

public class OrderedCollection<ElementType extends Object> extends ArrayedCollection<ElementType> implements CollectedOrdinally<ElementType>
{

  public static Metaclass type() { return (Metaclass)Metaclass.$class; }
  @Override public Metaclass $class() { return (Metaclass)Metaclass.$class; }
  public static class Metaclass extends ArrayedCollection.Metaclass implements CollectedOrdinally.Metatype
  {
    static final OrderedCollection.Metaclass $class = new OrderedCollection.Metaclass();
    public Metaclass() {
      this(OrderedCollection.Metaclass.class);
    }

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

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


    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> OrderedCollection with(final ElementType a)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, ((OrderedCollection)super.with(a)));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> OrderedCollection with_with(final ElementType a, final ElementType b)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>with_with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, ((OrderedCollection)this.withAll(((Object)a), ((Object)b))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> OrderedCollection with_with_with(final ElementType a, final ElementType b, final ElementType c)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>with_with_with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, ((OrderedCollection)this.withAll(((Object)a), ((Object)b), ((Object)c))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> OrderedCollection with_with_with_with(final ElementType a, final ElementType b, final ElementType c, final ElementType d)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>with_with_with_with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, ((OrderedCollection)this.withAll(((Object)a), ((Object)b), ((Object)c), ((Object)d))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> OrderedCollection withAll(final CollectedReadably<ElementType> elements)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>withAll";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, ((OrderedCollection)super.withAll(elements)));
      });
    }

    /**
     * @return 
     */
    public  <ElementType extends Object> OrderedCollection<ElementType> withAll(final ElementType ... elements)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>withAll";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection<ElementType>)f0.exit(exitID, new OrderedCollection(Arrays.asList(elements)));
      });
    }

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

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

    /**
     * @return 
     */
    public   OrderedCollection from(final java.util.List primitiveList)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>from";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, new OrderedCollection(primitiveList));
      });
    }

    /**
     * @return 
     */
    public   OrderedCollection synchronizedFrom(final java.util.List primitiveList)
    {
      java.lang.String exitID = "OrderedCollectionMetatype>>synchronizedFrom";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (OrderedCollection)f0.exit(exitID, new OrderedCollection(java.util.Collections.synchronizedList(primitiveList)));
      });
    }
  }


  protected java.util.List<ElementType> contents = new ArrayList();

  /**
   * 
   */
  protected    OrderedCollection()
  {
    java.lang.String exitID = "OrderedCollection>>OrderedCollection";
    Frame f0 = new Frame(exitID);
  }

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

  /**
   * 
   */
  protected    OrderedCollection(final java.util.List primitiveList)
  {
    java.lang.String exitID = "OrderedCollection>>OrderedCollection";
    Frame f0 = new Frame(exitID);
    contents.addAll(primitiveList);
  }

  /**
   * @return 
   */
  public   java.util.List primitiveContents()
  {
    java.lang.String exitID = "OrderedCollection>>primitiveContents";
    Frame f0 = new Frame(exitID);
    return (java.util.List)contents;
  }

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

  /**
   * @return 
   */
  @Override public   ElementType at_put(final Ordinal index, final ElementType element)
  {
    java.lang.String exitID = "OrderedCollection>>at_put";
    Frame f0 = new Frame(exitID);
    int i = this.checkGrows(index);
    if ((i < this.primitiveSize())) {
      contents.set(i, element);
    }
    else {
      contents.add(element);
    };
    return (ElementType)element;
  }

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

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

  /**
   * @return 
   */
  @Override public   List<ElementType> asList()
  {
    java.lang.String exitID = "OrderedCollection>>asList";
    Frame f0 = new Frame(exitID);
    return (List<ElementType>)new ArrayList(this.primitiveContents());
  }

  /**
   * @return 
   */
  @Override protected   ElementType add_at(final ElementType element, final int index)
  {
    java.lang.String exitID = "OrderedCollection>>add_at";
    Frame f0 = new Frame(exitID);
    Object.isNull(((Object)element)).ifFalse(Closure.with(f2 -> {
      this.registerType(((Object)element));
    contents.add(index, element);
    }, ""));
    return (ElementType)element;
  }

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

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

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

  /**
   * @return 
   */
  @Override public   ElementType add_afterIndex(final ElementType element, final Ordinal index)
  {
    java.lang.String exitID = "OrderedCollection>>add_afterIndex";
    Frame f0 = new Frame(exitID);
    return (ElementType)this.add_at(element, this.checkRange((SmallInteger.from(1).plus(index))));
  }

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

  /**
   * @return 
   */
  @Override public   ElementType add_beforeIndex(final ElementType element, final Ordinal index)
  {
    java.lang.String exitID = "OrderedCollection>>add_beforeIndex";
    Frame f0 = new Frame(exitID);
    return (ElementType)this.add_at(element, this.checkRange(index));
  }

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

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

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

  /**
   * @return 
   */
  @Override public   Boolean equals(final Collected aCollection)
  {
    java.lang.String exitID = "OrderedCollection>>equals";
    Frame f0 = new Frame(exitID);
    return (Boolean)(this.equals(aCollection.asOrderedCollection()));
  }

  /**
   * @return 
   */
  @Override public   Boolean equals(final CollectedReadably aCollection)
  {
    java.lang.String exitID = "OrderedCollection>>equals";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from(contents.equals(((OrderedCollection)aCollection).primitiveContents()));
  }

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

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

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

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

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

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

  /**
   * @return 
   */
  @Override public   OrderedCollection<ElementType> removeAllSuchThat(final MonadicPredicate criteria)
  {
    java.lang.String exitID = "OrderedCollection>>removeAllSuchThat";
    Frame f0 = new Frame(exitID);
    OrderedCollection<ElementType> results = OrderedCollection.type().$new();
    SmallInteger.from(1).to_do(this.size(), Closure.with(f2 -> {
      Ordinal index = f2.getValue(0).value();
      
    ElementType element = this.at(index);
    return criteria.value(element).ifTrue(Closure.with(f3 -> {
      results.add(element);
    return this.removeAtIndex(index);
    }, ""));
    }, "index"));
    return (OrderedCollection<ElementType>)results;
  }

  /**
   * @return 
   */
  public   ElementType removeFirst()
  {
    java.lang.String exitID = "OrderedCollection>>removeFirst";
    Frame f0 = new Frame(exitID);
    this.emptyCheck();
    return (ElementType)((ElementType)contents.remove(SmallInteger.from(0).asPrimitive()));
  }

  /**
   * @return 
   */
  public   ElementType removeLast()
  {
    java.lang.String exitID = "OrderedCollection>>removeLast";
    Frame f0 = new Frame(exitID);
    this.emptyCheck();
    return (ElementType)((ElementType)contents.remove((contents.size() - 1)));
  }

  /**
   * @return 
   */
  public   OrderedCollection<ElementType> removeFirst(final Ordinal count)
  {
    java.lang.String exitID = "OrderedCollection>>removeFirst";
    Frame f0 = new Frame(exitID);
    OrderedCollection<ElementType> results = OrderedCollection.type().$new(count);
    ((Integer)count).timesRepeat(Closure.with(f2 -> {
      return results.add(this.removeFirst());
    }, ""));
    return (OrderedCollection<ElementType>)results;
  }

  /**
   * @return 
   */
  public   OrderedCollection<ElementType> removeLast(final Ordinal count)
  {
    java.lang.String exitID = "OrderedCollection>>removeLast";
    Frame f0 = new Frame(exitID);
    OrderedCollection<ElementType> results = OrderedCollection.type().$new(count);
    ((Integer)count).timesRepeat(Closure.with(f2 -> {
      return results.add(this.removeLast());
    }, ""));
    return (OrderedCollection<ElementType>)results;
  }

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

  /**
   * @return 
   */
  @Override public   ReadStream readStream()
  {
    java.lang.String exitID = "OrderedCollection>>readStream";
    Frame f0 = new Frame(exitID);
    return (ReadStream)ReadStream.type().on(this);
  }
}