// This is an old test program for safe indexes mode on a list, which is
// not currently supported.  Now it shows how indexes can be affected by
// remove.

#import "grid.h"
#import "GridTurtle.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id aZone, listType, aList, aTurtle, index, index2;
  int i;
  
  initModule( grid );

  aZone = [Zone create: globalZone];

  listType = [List customizeBegin: aZone];
  [listType setIndexFromMemberLoc: offsetof( GridTurtle_c, listMembership )];
  // [listType setSafeIndexes: 1];
  listType = [listType customizeEnd];

  aList = [listType create: aZone];

  printf( "count: %d\n", [aList count] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [aList addLast: aTurtle];
  }

  printf( "count: %d\n", [aList count] );

  index = [aList begin: aZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  [index drop];

  [aList addFirst: [aList removeLast]];
  [aList addFirst: [aList removeLast]];
  [aList addLast: [aList removeFirst]];

  index = [aList begin: aZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  [index drop];
  [aList addLast: [aList removeFirst]];

  printf( "count: %d\n", [aList count] );
  index = [aList createIndex: aZone fromMember: [aList atOffset: 8]];
  printf( "offset after createIndex:fromMember: %d\n", [index getOffset] );
  [index next];
  [index next];
  [index prev];
  printf( "offset after next to End then prev: %d\n", [index getOffset] );
  [index drop];

  index = [aList createIndex: aZone fromMember: [aList atOffset: 1]];
  [index setOffset: 1];
  index2 = [aList createIndex: aZone fromMember: [aList atOffset: 0]];
  [index remove];
  [index2 remove];
  printf( "offset after remove on both index and lesser index: %d\n",
          [index getOffset] );
  printf( "member after removed offsets 0 and 1:\n  " );
  [[index next] print];
  [index drop];
  [index2 drop];

  index = [aList createIndex: aZone fromMember: [aList atOffset: 0]];
  index2 = [aList createIndex: aZone fromMember: [aList atOffset: 1]];
  [index remove];
  [index2 remove];
  printf( "offset after remove on both index and greater index: %d\n",
          [index getOffset] );
  printf( "member after removed offsets 0 and 1:\n  " );
  [[index next] print];
  [index drop];
  [index2 drop];

  index = [aList createIndex: aZone fromMember: [aList atOffset: 1]];
  index2 = [aList createIndex: aZone fromMember: [aList atOffset: 0]];
  [index2 remove];
  printf( "offset after remove on lesser index: %d\n",
          [index getOffset] );
  printf( "member after removed offset 0 and original offset 1:\n  " );
  [[index next] print];
  [index drop];
  [index2 drop];

  index = [aList createIndex: aZone fromMember: [aList atOffset: 1]];
  index2 = [aList createIndex: aZone fromMember: [aList atOffset: 1]];
  [index2 remove];
  printf( "offset after remove on same index: %d\n",
          [index getOffset] );
  printf( "member after removed offset 1:\n  " );
  [[index next] print];
  [index drop];
  [index2 drop];

  index = [aList createIndex: aZone fromMember: [aList atOffset: 0]];
  index2 = [aList createIndex: aZone fromMember: [aList atOffset: 1]];
  [index2 remove];
  printf( "offset after remove on greater index: %d\n",
          [index getOffset] );
  printf( "member after original offset 0 and removed offset 1:\n  " );
  [[index next] print];
  [index drop];
  [index2 drop];

  index = [aList createIndex: aZone fromMember: [aList atOffset: 0]];
  [index setLoc: Start];
  index2 = [aList createIndex: aZone fromMember: [aList atOffset: 0]];
  [index2 remove];
  printf( "offset after move to Start and remove on other index: %d\n",
          [index getOffset] );
  printf( "member after removed offset 0:\n  " );
  [[index next] print];
  [index drop];
  [index2 drop];

  printf( "remaining members of list:\n" );
  index = [aList begin: aZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  printf( "location of index at End: %s\n", [[index getLoc] getName] );

  [index setOffset: 1];
  printf( "location of index at offset 1: %s\n", [[index getLoc] getName] );
  [index remove];
  printf( "location of index after remove: %s\n", [[index getLoc] getName] );
  [index prev];
  printf( "location of index after prev: %s\n", [[index getLoc] getName] );

  [index setOffset: 0];
  printf( "location of index at offset 0: %s\n", [[index getLoc] getName] );
  [index remove];
  printf( "location of index after remove: %s\n", [[index getLoc] getName] );
  [index next];
  printf( "location of index after next: %s\n", [[index getLoc] getName] );
  [index drop];

  return 0;
}
