// 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 "OHImageMapHolder.h"

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

#import "OHColorPalette.h"
#import "OHHTMLAnchor.h"
#import "OHHTMLDocument.h"
#import "OHHTMLPageView.h"
#import "OHImageMapSet.h"
#import "OHImageMapShape.h"
#import "OHInlineImageCell.h"

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/Cells.subproj/OHImageMapHolder.m,v 1.9 2000/01/20 00:27:48 kc Exp $")

@interface OHImageMapHolder (Private)
- (void)mainThreadPipeline:(OWPipeline *)aPipeline hasContent:(id <OWContent>)someContent;
- (void)selectAnchorAtCachedPoint;
- (void)followAnchorAtCachedPoint;
@end

@implementation OHImageMapHolder

// Init and dealloc

- initWithImageMapAddress:(OWAddress  *)anAddress inlineImage:(OHInlineImageCell *)inlineImage;
{
    OWWebPipeline *pipeline;

    OBPRECONDITION(anAddress != nil);
    OBPRECONDITION(inlineImage != nil);

    [super init];

    imageMapAddress = [anAddress retain];
    [self setInlineImage:inlineImage];

    pipeline = [[OWWebPipeline alloc] initWithContent:imageMapAddress target:self];
    [pipeline release];

    if ([[OFUserDefaults sharedUserDefaults] boolForKey:@"OHAutoFetchInlineImages"])
        [self fetch];

    return self;
}

- (void)dealloc;
{
    [OWPipeline cancelTarget:self];
    [imageMapAddress release];
    [shapes release];
    [super dealloc];
}


// API

- (void)setInlineImage:(OHInlineImageCell *)anInlineImage;
{
    nonretainedInlineImage = anInlineImage;
}

- (void)fetch;
{
    if (flags.pipelineIsFetching)
        return;

    flags.pipelineIsFetching = YES;
    [[OWPipeline currentPipelineForTarget:self] fetch];
}

- (void)selectAnchorAtPoint:(NSPoint)point;
{
    pointClicked = point;

    if (shapes) {
        [self selectAnchorAtCachedPoint];
    } else {
        actionWhenFetched = OHImageMap_selecting;
        [self fetch];
    }

}

- (void)followAnchorAtPoint:(NSPoint)point;
{
    pointClicked = point;

    if (shapes) {
        [self followAnchorAtCachedPoint];
    } else {
        actionWhenFetched = OHImageMap_following;
        [self fetch];
    }
}

- (void)startDragForAnchorAtPoint:(NSPoint)point fromView:(OHHTMLView *)aView event:(NSEvent *)event;
{
    if (shapes) {
        OWAddress *address;

        address = [[self shapeAtPoint:point] address];
        [aView dragAddress:address event:event];
    }
}

- (OHImageMapShape *)shapeAtPoint:(NSPoint)point
{
    unsigned int shapeIndex, shapeCount;

    shapeCount = [shapes count];
    for (shapeIndex = 0; shapeIndex < shapeCount; shapeIndex++) {
        OHImageMapShape *shape;

        shape = [shapes objectAtIndex:shapeIndex];
        if ([shape containsPoint:point])
            return shape;
    }
    return nil;
}

// OWTarget protocol

- (OWContentType *)targetContentType;
{
    return [OHImageMapSet contentType];
}

- (OWTargetContentDisposition)pipeline:(OWPipeline *)aPipeline hasContent:(id <OWContent>)someContent;
{
    OBPRECONDITION([someContent isKindOfClass:[OHImageMapSet class]]);

    [self mainThreadPerformSelector:@selector(mainThreadPipeline:hasContent:) withObject:aPipeline withObject:someContent];
    return OWTargetContentDisposition_ContentAccepted;
}

- (NSString *)targetTypeFormatString;
{
    return @"%@";
}

- (OWContentInfo *)parentContentInfo;
{
    return [nonretainedInlineImage parentContentInfo];
}


// OWOptionalContent protocol

- (NSString *)expectedContentTypeString;
{
    return @"Image map";
}

@end


@implementation OHImageMapHolder (Private)

- (void)mainThreadPipeline:(OWPipeline *)aPipeline hasContent:(id <OWContent>)someContent;
{
    shapes = [[(OHImageMapSet *)someContent mapNamed:[[imageMapAddress url] fragment]] retain];

    flags.pipelineIsFetching = NO;
    
    if (!shapes) {
        actionWhenFetched = OHImageMap_nothing;
        return;
    }

    if (actionWhenFetched == OHImageMap_selecting)
        [self selectAnchorAtCachedPoint];
    else if (actionWhenFetched == OHImageMap_following)
        [self followAnchorAtCachedPoint];

}

- (void)selectAnchorAtCachedPoint;
{
    OHHTMLAnchor *anchor;

    // Display the url that would have been triggered by a normal click
    anchor = [[OHHTMLAnchor alloc] initWithColorPalette:[OHColorPalette defaultPalette]];
    [anchor setAddress:[[self shapeAtPoint:pointClicked] address]];
    [[[nonretainedInlineImage htmlDocument] htmlPageView] selectAnchor:anchor];
    [anchor release];

    actionWhenFetched = OHImageMap_nothing;
}

- (void)followAnchorAtCachedPoint;
{
    [[[nonretainedInlineImage htmlDocument] htmlPageView] displayDocumentAtAddress:[[self shapeAtPoint:pointClicked] address]];

    actionWhenFetched = OHImageMap_nothing;
}

@end
