!7

concept TheList {
  S name;
  new L<S> entries;
  
  void add(S entry) {
    entries.add(entry);
    change();
  }
}

concept Selection {
  TheList list;
}

static TheList list;

p {
  dbIndexing(TheList, 'name);
  list = uniq(Selection).list;
  if (list == null) selectList("cool things");
  if (isMainProgram()) botSleep();
}

synchronized answer {
  if "select *" {
    selectList($1);
    ret "OK, has " + n(theList().entries, "entry");
  }
  
  if "which" {
    ret list.name;
  }
  
  if "add *" {
    theList().add($1);
    theList().change();
    ret "OK, has position " + l(theList().entries);
  }
  
  if "add * at *" {
    int i = parseInt($2)-1;
    theList().entries.add(i, $1);
    theList().change();
    ret "OK";
  }
  
  if "remove *" {
    int i = theList().entries.indexOf($1);
    if (i < 0) ret "Not in list";
    else {
      theList().entries.remove(i);
      theList().change();
    }
    ret "OK, removed from position " + (i+1);
  }
  
  if "length"
    ret lstr(theList().entries);
    
  if "entry *" {
    S entry = get(theList().entries, parseInt($1)-1);
    ret entry == null ? "Nuttn" : "Entry: " + quote(entry);
  }
  
  if "fix lol" {
    fixLOL();
    ret "OK";
  }
}

static TheList theList() {
  ret list;
}

svoid selectList(S name) {
  if (!hasConcept(TheList, +name)) {
    lol().add(name);
    lol().change();
  }
  list = uniq(TheList, +name);
  cset(uniq(Selection), +list);
}

// the "list of lists"
static TheList lol() {
  ret uniq(TheList, name := "lol");
}

svoid fixLOL {
  lol().entries = collect(list(TheList), 'name);
  lol().change();
}