// Copyright 1997-2000 Omni Development, Inc.  All rights reserved.
//
// This software may only be used and reproduced according to the
// terms in the file OmniSourceLicense.html, which should be
// distributed with this project and can also be found at
// http://www.omnigroup.com/DeveloperResources/OmniSourceLicense.html.

#import "OHFormArchive.h"

#import <Foundation/Foundation.h>
#import <OmniBase/OmniBase.h>
#import <OmniFoundation/OmniFoundation.h>
#import <OWF/OWF.h>

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/Forms.subproj/OHFormArchive.m,v 1.3 2000/01/20 00:27:50 kc Exp $")

#import "OHForm.h"
#import "OHFormElementArchive.h"

@interface OHFormArchive (Private)
- (void)archiveElementsInForm:(OHForm *)form;
@end

@implementation OHFormArchive

+ (NSArray *)formArchivesForForms:(NSArray *)forms;
{
    NSMutableArray *formArchives;
    unsigned int formsIndex, formsCount;

    formsCount = [forms count];
    formArchives = [NSMutableArray arrayWithCapacity:formsCount];

    for (formsIndex = 0; formsIndex < formsCount; formsIndex++) {
        OHFormArchive *formArchive;

        formArchive = [[self alloc] initWithForm:[forms objectAtIndex:formsIndex]];
        [formArchives addObject:formArchive];
        [formArchive release];
    }
    
    return formArchives;
}

+ (void)resetForms:(NSArray *)forms fromFormArchives:(NSArray *)formArchives;
{
    unsigned int formsIndex, formsCount;
    unsigned int formArchivesCount;

    formsCount = [forms count];
    formArchivesCount = [formArchives count];

    for (formsIndex = 0; formsIndex < formsCount && formsIndex < formArchivesCount; formsIndex++) {
        OHForm *form;
        OHFormArchive *formArchive;

        form = [forms objectAtIndex:formsIndex];
        formArchive = [formArchives objectAtIndex:formsIndex];

        [formArchive resetForm:form];
    }
}

// Init and dealloc

- initWithForm:(OHForm *)form;
{
    [super init];

    name = [[form name] copy];
    address = [[form address] retain];
    archivedElements = [[NSMutableArray alloc] init];

    [self archiveElementsInForm:form];

    return self;
}

- initWithPropertyList:plist;
{
    NSDictionary *dictionary;
    unsigned int archivedElementIndex, archivedElementCount;
    NSMutableArray *archivedElementPlists;
    
    [super init];

    dictionary = plist;

    name = [[dictionary objectForKey:@"name"] copy];
    address = [[OWAddress addressForString:[dictionary objectForKey:@"address"]] retain];

    // Reconstitute archivedElements array
    archivedElementPlists = [dictionary objectForKey:@"elements"];
    archivedElementCount = [archivedElementPlists count];
    archivedElements = [[NSMutableArray alloc] initWithCapacity:archivedElementCount];
    
    for (archivedElementIndex = 0; archivedElementIndex < archivedElementCount; archivedElementIndex++) {
        OHFormElementArchive *elementArchive;

        elementArchive = [[OHFormElementArchive alloc] initWithPropertyList:[archivedElementPlists objectAtIndex:archivedElementIndex]];
        [(NSMutableArray *)archivedElements addObject:elementArchive];
        [elementArchive release];
    }
    
    return self;
}

- (void)dealloc;
{
    [name release];
    [address release];
    [archivedElements release];
    [super dealloc];
}

// API

- (void)resetForm:(OHForm *)form;
{
    NSArray *elements;
    unsigned int archivedElementCount;
    unsigned int elementIndex, elementCount;

    // Bail if we're not the same form
    if (name) {
        if (![name isEqualToString:[form name]])
            return;
    } else if ([form name])
        return;

    if (address) {
        if (![address isEqual:[form address]])
            return;
    } else if ([form address])
        return;
    
    // Unpack the elements
    archivedElementCount = [archivedElements count];
    
    elements = [form elements];
    elementCount = [elements count];
    for (elementIndex = 0; elementIndex < elementCount && elementIndex < archivedElementCount; elementIndex++) {
        id <OHFormElement> element;
        OHFormElementArchive *elementArchive;

        element = [elements objectAtIndex:elementIndex];
        elementArchive = [archivedElements objectAtIndex:elementIndex];

        [elementArchive resetFormElement:element];
    }
}

- propertyList;
{
    NSMutableDictionary *dictionary;
    unsigned int archivedElementIndex, archivedElementCount;
    NSMutableArray *archivedElementPlists;

    dictionary = [NSMutableDictionary dictionary];

    if (name && [name length])
        [dictionary setObject:name forKey:@"name"];

    if (address)
        [dictionary setObject:[address addressString] forKey:@"address"];
    
    archivedElementCount = [archivedElements count];
    archivedElementPlists = [[NSMutableArray alloc] initWithCapacity:archivedElementCount];
    for (archivedElementIndex = 0; archivedElementIndex < archivedElementCount; archivedElementIndex++) {
        OHFormElementArchive *elementArchive;

        elementArchive = [archivedElements objectAtIndex:archivedElementIndex];
        [archivedElementPlists addObject:[elementArchive propertyList]];
    }
    [dictionary setObject:archivedElementPlists forKey:@"elements"];
    [archivedElementPlists release];

    return dictionary;
}

@end


@implementation OHFormArchive (Private)

- (void)archiveElementsInForm:(OHForm *)form;
{
    NSArray *elements;
    unsigned int elementIndex, elementCount;

    // For each element, add to archive
    elements = [form elements];
    elementCount = [elements count];
    for (elementIndex = 0; elementIndex < elementCount; elementIndex++) {
        id <OHFormElement> element;
        OHFormElementArchive *elementArchive;

        element = [elements objectAtIndex:elementIndex];
        elementArchive = [[OHFormElementArchive alloc] initWithFormElement:element];
        
        [archivedElements addObject:elementArchive];
        [elementArchive release];
    }
}

- (NSMutableDictionary *)debugDictionary;
{
    NSMutableDictionary *debugDictionary;

    debugDictionary = [super debugDictionary];
    [debugDictionary addEntriesFromDictionary:[self propertyList]];
    return debugDictionary;
}

@end

