// ////////////////////////////////////////////////////////
// Copyright (1994) Columbia University
// Department of Biochemistry and Molecular Biophysics
//
// Author: Weider Chang, Ph.D
// ///////////////////////////////////////////////////////

#include "llistobj.h"
#include "iterator.h"
#include "starasso.h"

@implementation WDCLListOfObject

#include "llistcom.m"
#include "itering.m"

- free
{
}

- getContent
{
  return _object;
}

- getContentNamed:(char*)aName
{
  id tempId, iter;
  if ([[self getContent] respondsTo:@selector(getName)])
    {
      iter=[[WDCListIterator alloc] initFrom:self];
      while ([iter goNext])
	{
	  tempId=[[iter getCurrentObject] getContent];
	  if (!strcmp(aName, [tempId getName])) break;
	}
      [iter free];
    }
  else
    [self error:"%s doesn't responds to getName method", 
     [[self getContent] name]];
  return tempId;
}

- selectedDeepCopy
{
  id temp=[WDCLListOfObject alloc];
  [temp setContent:[[self getContent] selectedDeepCopy]];
  // only copy the first branch, since all the branches are the same.
  return temp;
}

- setContent: object
{
  _object=object;
  return self;
}

- addContent: object
{
  if (![self getContent]) [self setContent: object];
  else 
    {
      if (![self nextLink])
	{
	  [self setNextLink:[[[[self class] alloc] 
			    setContent:object] setPrevLink:self]];
	}
      else [_next addContent:object];
    }
  return self;
}

- merge: aList
{
  // The default behavior will remove the aList after merge operation.
  // 
  // ******* IMPORTANT **************
  // use this operation cautiously, it merges any type of list regardless
  // the type of its content.
  
  id iter, current;

  if (aList)
    {
      iter=[[WDCListIterator alloc] initFrom:aList];
      while ([iter goNext]){
	current=[[iter getCurrentObject] getContent];
	if (![self isExist:current]) [self addContent:current];
      }
      [iter free];
      [aList free];
    }
  return self;
}

- joint: aList
{
  id iter;
  if (aList)
    {
      iter=[[WDCListIterator alloc] initFrom:aList];
      while ([iter goNext])
	[self addContent:[[iter getCurrentObject] getContent]];
      [iter free];
      [aList free];
    }
  return self;
}


- (BOOL)isExist:object
{
  id tempObject;
  id temp=[[WDCListIterator alloc] initFrom: self];
  /*, temp=self;*/
  BOOL result=NO;
  SEL aSel=0;
  if ([object respondsTo:@selector(compare:)])
    aSel=@selector(compare:);
  else if ([object respondsTo:@selector(compareObject:)])
    aSel=@selector(compareObject:);
  if (aSel)
    {
      while ([temp goNext])
	{
	  if ((tempObject=[[temp getCurrentObject] getContent])
	      && ![tempObject perform:aSel with:object])
	    {
	      result=YES;
	      break;
	    }
	}
    }
  [temp free];
  return result;
}

- forward:(SEL)aSel :(arglist_t)argFrame
{
  id currentid, iter;
  if ([[self getContent] respondsTo:aSel])
    {
      iter=[[WDCListIterator alloc] initFrom:self];
      while ([iter goNext]) 
	[[[iter getCurrentObject] getContent] performv:aSel :argFrame];
      [iter free];
    }
  else
    [self error:"Content does not responds to forwarding message"];
  return self;
}
  

- printForDebugger
{
  printf("(%s\n", [self name]);
  printf(" _object:");
  [_object printForDebugger];
  printf(")\n");
  if (_next) [_next printForDebugger];
  return self;
}

@end
