package com.stuffwithstuff.magpie.interpreter.builtin;

import com.stuffwithstuff.magpie.interpreter.Interpreter;
import com.stuffwithstuff.magpie.interpreter.Obj;

public class StringBuiltIns {
  @Signature("call(index Int -> String)")
  public static class Call implements BuiltInCallable {
    public Obj invoke(Interpreter interpreter, Obj thisObj, Obj arg) {
      int index = arg.asInt();
      String c = thisObj.asString().substring(index, index + 1);
      return interpreter.createString(c);
    }
  }
  
  // TODO(bob): May want to strongly-type arg at some point.
  @Signature("compareTo(other -> Int)")
  public static class CompareTo implements BuiltInCallable {
    public Obj invoke(Interpreter interpreter, Obj thisObj, Obj arg) {
      return interpreter.createInt(thisObj.asString().compareTo(arg.asString()));
    }
  }
  
  // TODO(bob): May want to strongly-type arg at some point.
  @Signature("concatenate(other -> String)")
  public static class Concatenate implements BuiltInCallable {
    public Obj invoke(Interpreter interpreter, Obj thisObj, Obj arg) {
      String left = thisObj.asString();
      String right = arg.asString();
      
      return interpreter.createString(left + right);
    }
  }
  
  @Getter("count Int")
  public static class Count implements BuiltInCallable {
    public Obj invoke(Interpreter interpreter, Obj thisObj, Obj arg) {
      return interpreter.createInt(thisObj.asString().length());
    }
  }
  
  @Signature("substring(arg -> String)")
  public static class Substring implements BuiltInCallable {
    public Obj invoke(Interpreter interpreter, Obj thisObj, Obj arg) {
      // TODO(bob): Hackish way to see if we have one or two arguments to this.
      if (arg.getTupleField(0) != null) {
        int startIndex = arg.getTupleField(0).asInt();
        int endIndex = arg.getTupleField(1).asInt();
        String substring = thisObj.asString().substring(startIndex, endIndex);
        return interpreter.createString(substring);
      } else {
        int startIndex = arg.asInt();
        String substring = thisObj.asString().substring(startIndex);
        return interpreter.createString(substring);
      }
    }
  }
}

@@ -49,16 +49,68 @@
 iltin;%0A%0A
+import java.util.ArrayList;%0Aimport java.util.List;%0A%0A
 import c
@@ -159,16 +159,16 @@
 preter;%0A
-
 import c
@@ -892,69 +892,8 @@
 %0A  %0A
-  // TODO(bob): May want to strongly-type arg at some point.%0A
   @S
@@ -920,16 +920,23 @@
 e(other 
+String 
 -%3E Strin
@@ -1442,35 +1442,963 @@
 h());%0A    %7D%0A  %7D%0A
-
   %0A
+  @Signature(%22split(delimiter String -%3E List(String))%22)%0A  public static class Split implements BuiltInCallable %7B%0A    public Obj invoke(Interpreter interpreter, Obj thisObj, Obj arg) %7B%0A      String string = thisObj.asString();%0A      String delimiter = arg.asString();%0A      %0A      // Note: We're not using String#split because we don't want to split on%0A      // a regex, just a literal delimiter.%0A      List%3CObj%3E substrings = new ArrayList%3CObj%3E();%0A      int start = 0;%0A      while (start != -1) %7B%0A        int end = string.indexOf(delimiter, start);%0A        String substring;%0A        if (end != -1) %7B%0A          substring = string.substring(start, end);%0A          start = end + delimiter.length();%0A        %7D else %7B%0A          substring = string.substring(start);%0A          start = -1;%0A        %7D%0A        substrings.add(interpreter.createString(substring));%0A      %7D%0A      %0A      return interpreter.createArray(substrings);%0A    %7D%0A  %7D%0A%0A
   @Signature(%22su

Add "split" method on String.