/* $Id: Array,v 1.1.1.1 2008/11/28 17:57:26 kiesling Exp $ -*-c-*-*/

/*
  This file is part of ctalk.
  Copyright  2005 - 2008  Robert Kiesling, ctalk@ctalklang.org.
  Permission is granted to copy this software provided that this copyright
  notice is included in all source code modules.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

/*
 *    Array class.  
 */

/*
 *  If you change these definitions, make sure they match the
 *  definitions in the file, "ctalklib."
 */

#ifndef MAXMSG
#define MAXMSG 8192
#endif

#ifndef MAXLABEL
#define MAXLABEL 256
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE (!(FALSE))
#endif

#ifndef NULL
#define NULL ((void *)0)
#endif

Collection class Array;

Array instanceMethod atPut (int __array_index, OBJECT *__elem_object) {
  self super atPut __array_index, __elem_object;
  methodReturnSelf
}

/*
 *    at (int index)
 *    Return the object at index.
 *    
 */

Array instanceMethod at (int __array_index) {
  return self super at __array_index;
}

/*
 *  Here we need to traverse the array list.  The method can't evaluate
 *  each element, in case one of them evaluates to False.
 */
Array instanceMethod size (void) {
  OBJECT *self_val, *t;
  int i;
  self_val = self value;
  for (i = 0, t = self_val -> next; t; t = t -> next, ++i)
    ;
  methodReturnInteger(i)
}

Array instanceMethod = set_value (Array a) {

  Integer new argSize;
  Integer new i;

  argSize = a size;

  for (i = 0; i < argSize; i = i + 1) {
    self atPut i, (a at i);
  }
  
  return __ctalk_self_internal ();
}

Array instanceMethod map (OBJECT *(*methodfn)()) {

  OBJECT *array_elem, *rcvr_obj, *(*fn)();
  METHOD *self_method, *arg_method;
  Integer new selfArraySize;
  Integer new i;

  fn = (OBJECT *(*)())__ctalkRtGetMethodFn ();
  rcvr_obj = __ctalkRtReceiverObject ();

  if (((self_method = __ctalkFindInstanceMethodByFn (&rcvr_obj, fn, 0))
      == NULL) &&
      ((self_method = __ctalkFindClassMethodByFn (&rcvr_obj, fn, 0))
       == NULL)) {
    __ctalkCriticalExceptionInternal (NULL, undefined_method_x, 
				      "from map (Class Array)");
    return NULL;
  }

  if (((arg_method = __ctalkFindInstanceMethodByName (&rcvr_obj, 
			      self_method->args[0] -> __o_name, 0))
      == NULL) &&
      ((arg_method = __ctalkFindClassMethodByName (&rcvr_obj, 
				 self_method->args[0]->__o_name, 0))
       == NULL)) {
    __ctalkCriticalExceptionInternal (NULL, undefined_method_x, 
				      "from map (Class Array)");
    return NULL;
  }

  selfArraySize = self size;

  for (i = 0; i < selfArraySize; i = i + 1) {
    array_elem = self at i;
    __ctalkInlineMethod (array_elem, arg_method);
  }

  return NULL;
}
