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

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

#import "OWAddress-OHImage.h"
#import "OHDownloader.h"

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/Support.subproj/OWAddress-OHPasteboard.m,v 1.3 2000/01/20 00:28:00 kc Exp $")

@interface OWAddress (PasteboardPrivate)
+ (void)setupPasteboardTypes;
@end

@implementation OWAddress (Pasteboard)

static BOOL OWAddressPasteboardTypesSetup = NO;

static NSString *W3URI11PboardType = @"WebStep Universal Resource Identifier 1.1";
static NSString *W3URI10PboardType = @"WebStep Universal Resource Identifier 1.0";
static NSString *W3URI11TitlePboardType = @"WebStep URI Descriptive Title 1.1";
static NSString *W3URI10TitlePboardType = @"WebStep URI Descriptive Title 1.0";
static NSString *OWNewWindowURIType = @"OmniWeb URI Pasteboard only for new windows 1.0";

static NSMutableArray *recognizedPasteboardTypes = nil;
static NSMutableArray *basicExportedPasteboardTypes = nil;

+ (void)setupPasteboardTypes;
{
    if (OWAddressPasteboardTypesSetup)
	return;

    recognizedPasteboardTypes = [[NSMutableArray alloc] initWithCapacity:3];
    [recognizedPasteboardTypes addObject:W3URI11PboardType];
    [recognizedPasteboardTypes addObject:NSStringPboardType];
    [recognizedPasteboardTypes addObject:NSFilenamesPboardType];
    [recognizedPasteboardTypes addObject:W3URI10PboardType];

    // Note: These should be declared in order of preference (i.e., the ones that best represent us should come first in the array)
    basicExportedPasteboardTypes = [[NSMutableArray alloc] initWithCapacity:2];
    [basicExportedPasteboardTypes addObject:W3URI11PboardType];
    [basicExportedPasteboardTypes addObject:W3URI10PboardType];
    [basicExportedPasteboardTypes addObject:NSStringPboardType];
    [basicExportedPasteboardTypes addObject:W3URI11TitlePboardType];
    [basicExportedPasteboardTypes addObject:W3URI10TitlePboardType];

    OWAddressPasteboardTypesSetup = YES;
}

+ (NSArray *)recognizedPasteboardTypes;
{
    if (!OWAddressPasteboardTypesSetup)
	[self setupPasteboardTypes];
    return recognizedPasteboardTypes;
}

+ (NSString *)OWNewWindowURIType;
{
    return OWNewWindowURIType;
}

//

+ (OWAddress *)addressFromPasteboard:(NSPasteboard *)pasteboard;
{
    NSString *type;
    id propertyList;

    if (!OWAddressPasteboardTypesSetup)
	[self setupPasteboardTypes];
    
    type = [pasteboard availableTypeFromArray:recognizedPasteboardTypes];
    
    if ([type isEqualToString:W3URI10PboardType]) {
        propertyList = [NSString stringWithData:[pasteboard dataForType:type] encoding:[NSString defaultCStringEncoding]];
    } else {
        propertyList = [pasteboard propertyListForType:type];
    }

    if (!propertyList)
	return nil;
    return [self entryFromPropertyList:propertyList ofType:type];
}

// These are convenience methods for classes that implement the OAOutlineDragSupport protocol.  These are never called directly by OAOutlineView, but lots of the classes it calls call some of these

+ (NSArray *)acceptedPasteboardTypes;
{
    if (!OWAddressPasteboardTypesSetup)
	[self setupPasteboardTypes];
    return recognizedPasteboardTypes;
}

+ (id)entryFromPropertyList:propertyList ofType:(NSString *)type;
{
    if ([type isEqualToString:W3URI10PboardType] || [type isEqualToString:W3URI11PboardType] || [type isEqualToString:NSStringPboardType]) {
        return [self addressForDirtyString:propertyList];

    } else if ([type isEqualToString:NSFilenamesPboardType]) {
        if (![propertyList count])
            return nil;
        return [self addressWithFilename:[propertyList objectAtIndex:0]];
    } else
	return nil;
}

+ (NSImage *)dragImageForEntry:(id)anEntry;
{
    return [anEntry dragImage];
}

+ (void)declareTypesForEntry:(id)anEntry pasteboardHelper:(OAPasteboardHelper *)pasteboardHelper;
{
    if (!OWAddressPasteboardTypesSetup)
	[self setupPasteboardTypes];
    [pasteboardHelper declareTypes:basicExportedPasteboardTypes owner:anEntry];
}

+ (void)addTypesForEntry:(id)anEntry pasteboardHelper:(OAPasteboardHelper *)pasteboardHelper;
{
    if (!OWAddressPasteboardTypesSetup)
	[self setupPasteboardTypes];
    [pasteboardHelper addTypes:basicExportedPasteboardTypes owner:anEntry];
}

- (void)pasteboard:(NSPasteboard *)pasteboard provideDataForType:(NSString *)type;
{
    if ([type isEqualToString:W3URI11PboardType] || [type isEqualToString:NSStringPboardType] || [type isEqualToString:OWNewWindowURIType]) {
        [pasteboard setString:[self addressString] forType:type];
    } else if ([type isEqualToString:W3URI10PboardType]) {
        [pasteboard setData:[[self addressString] dataUsingEncoding:[NSString defaultCStringEncoding]] forType:type];
    } else if ([type isEqualToString:W3URI11TitlePboardType] || [type isEqualToString:W3URI10TitlePboardType]) {
        NSString *title;

        title = [OWDocumentTitle titleForAddress:self];
        if (!title)
            title = [self addressString];
        if ([type isEqualToString:W3URI11TitlePboardType])
            [pasteboard setString:title forType:type];
        else
            [pasteboard setData:[title dataUsingEncoding:[NSString defaultCStringEncoding]] forType:type];
    } else if ([type isEqualToString:NSFilenamesPboardType]) {
        if (!pasteboardFilename) {
	    OHDownloader *downloader;

            downloader = [OHDownloader downloaderDownloadingAddressNoPresent:self];
            [downloader blockUntilDownloadComplete];
	    pasteboardFilename = [[downloader filename] retain];
	}
	if (pasteboardFilename) {
            [pasteboard setPropertyList:[NSArray arrayWithObject:pasteboardFilename] forType:type];
        } else {
            [pasteboard setPropertyList:[NSArray arrayWithObject:@"/tmp/unloaded-file"] forType:type];
	}
    }
}

//

- (void)copyToGeneralPasteboard;
{
    OAPasteboardHelper *helper;
    NSPasteboard *pasteboard;
    NSEnumerator *enumerator;
    NSString *type;

    pasteboard = [NSPasteboard pasteboardWithName:NSGeneralPboard];
    helper = [[OAPasteboardHelper alloc] initWithPasteboard:pasteboard];

    [isa declareTypesForEntry:self pasteboardHelper:helper];
    // now force all the data onto the pasteboard since OpenStep/Windows 4.2pr2 has a major bug with changing the owner of the NSGeneralPboard, causing us to break otherwise
    enumerator = [[pasteboard types] objectEnumerator];
    while ((type = [enumerator nextObject]))
        [self pasteboard:pasteboard provideDataForType:type];

    [helper release];
}

@end
