/* 
   ArchiverClasses.m

   Copyright (C) 1995, 1996, 1997 Ovidiu Predescu and Mircea Oancea.
   All rights reserved.

   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>

   This file is part of libFoundation.

   Permission to use, copy, modify, and distribute this software and its
   documentation for any purpose and without fee is hereby granted, provided
   that the above copyright notice appear in all copies and that both that
   copyright notice and this permission notice appear in supporting
   documentation.

   We disclaim all warranties with regard to this software, including all
   implied warranties of merchantability and fitness, in no event shall
   we be liable for any special, indirect or consequential damages or any
   damages whatsoever resulting from loss of use, data or profits, whether in
   an action of contract, negligence or other tortious action, arising out of
   or in connection with the use or performance of this software.
*/

#include <config.h>

#if NeXT_foundation_LIBRARY
typedef void NXTypedStream;
#endif

#include <stdio.h>
#include <Foundation/NSString.h>
#include <Foundation/NSArchiver.h>
#include "ArchiverClasses.h"

@implementation ArchivedClass1
- obj1		{ return obj1; }
- obj2		{ return obj2; }
- cond		{ return cond; }
- replacement	{ return replacement; }
- (int)value	{ return value; }

- set_obj1:anObject
{
    obj1 = anObject;
    return self;
}

- set_obj2:anObject
{
    obj2 = anObject;
    return self;
}

- set_cond:anObject
{
    cond = anObject;
    return self;
}

- set_replacement:anObject
{
    replacement = anObject;
    return self;
}

- set_value:(int)aValue
{
    value = aValue;
    return self;
}

- (BOOL)isEqual:anotherObject
{
    if(!anotherObject)
	return NO;

    if(self == anotherObject)
	return YES;

    if(![anotherObject isKindOfClass:isa])
	return NO;

    if(obj1Visited) {
	if(obj1 == self)
	    return anotherObject == [anotherObject obj1];
	else return obj1 == obj1Tested;
    }
    else {
	obj1Visited = YES;
	obj1Tested = [anotherObject obj1];
	if(! ((!obj1 && ![anotherObject obj1])
	       || [obj1 isEqual:[anotherObject obj1]])) {
	    obj1Visited = NO;
	    return NO;
	}
    }
	    
    if(obj2Visited)
	if(obj2 == self)
	    return anotherObject == [anotherObject obj2];
	else return obj2 == obj2Tested;
    else {
	obj2Visited = YES;
	obj2Tested = [anotherObject obj2];
	if(! ((!obj2 && ![anotherObject obj2])
	       || [obj2 isEqual:[anotherObject obj2]])) {
	    obj2Visited = NO;
	    return NO;
	}
    }
	    
    if(condVisited)
	if(cond == self)
	    return anotherObject == [anotherObject cond];
	else return cond == condTested;
    else {
	condVisited = YES;
	condTested = [anotherObject cond];
	if(! ((!cond && ![anotherObject cond])
	       || [cond isEqual:[anotherObject cond]])) {
	    condVisited = NO;
	    return NO;
	}
    }

    if(value != [anotherObject value])
	return NO;

    obj1Visited = obj2Visited = condVisited = NO;
    return YES;
}

- (Class)classForCoder
{
    printf("%u classForCoder\n", (unsigned)self);
    return isa;
}

- (void)encodeWithCoder:(NSCoder*)coder
{
    printf("%u encodeWithCoder:\n", (unsigned)self);
    [coder encodeObject:obj1];
    [coder encodeConditionalObject:cond];
    [coder encodeObject:obj2];
    [coder encodeValueOfObjCType:@encode(typeof(value)) at:&value];
}

- replacementObjectForCoder:(NSCoder*)coder
{
    printf("%u replacementObjectForCoder:\n", (unsigned)self);
    return self;
}

- initWithCoder:(NSCoder*)decoder
{
    printf("%u initWithCoder:\n", (unsigned)self);
    obj1 = [decoder decodeObject];
    cond = [decoder decodeObject];
    obj2 = [decoder decodeObject];
    [decoder decodeValueOfObjCType:@encode(typeof(value)) at:&value];
    return self;
}

- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{
    printf("%u awakeAfterUsingCoder:\n", (unsigned)self);
    return self;
}
@end /* ArchivedClass1 */


@implementation ArchivedClass2
- obj		{ return obj; }
- replacement	{ return replacement; }
- (int)value	{ return value; }

- set_obj:anObject
{
    obj = anObject;
    return self;
}

- set_replacement:anObject
{
    replacement = anObject;
    return self;
}

- set_value:(int)aValue
{
    value = aValue;
    return self;
}

- (BOOL)isEqual:anotherObject
{
    if(!anotherObject)
	return NO;

    if(self == anotherObject)
	return YES;

    if(objVisited)
	if(obj == self)
	    return anotherObject == [anotherObject obj];
	else return obj == objTested;
    else {
	objVisited = YES;
	objTested = [anotherObject obj];
	if(! ((!obj && ![anotherObject obj])
	       || [obj isEqual:[anotherObject obj]])) {
	    objVisited = NO;
	    return NO;
	}
    }

    if(value != [anotherObject value])
	return NO;

    objVisited = NO;
    return YES;		
}

- (Class)classForCoder
{
    printf("%u classForCoder\n", (unsigned)self);
    return isa;
}

- (void)encodeWithCoder:(NSCoder*)coder
{
    printf("%u encodeWithCoder:\n", (unsigned)self);
    [coder encodeObject:obj];
    [coder encodeValueOfObjCType:@encode(typeof(value)) at:&value];
}

- replacementObjectForCoder:(NSCoder*)coder
{
    printf("%u replacementObjectForCoder:\n", (unsigned)self);
    return self;
}

- initWithCoder:(NSCoder*)decoder
{
    printf("%u initWithCoder:\n", (unsigned)self);
    obj = [decoder decodeObject];
    [decoder decodeValueOfObjCType:@encode(typeof(value)) at:&value];
    return self;
}

- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{
    printf("%u awakeAfterUsingCoder:\n", (unsigned)self);
    return self;
}
@end /* ArchivedClass2 */
