/* 
 * tdcPasteboard - pasteboard functions for the ToDoController
 *
 * You may freely copy, distribute and reuse the code in this example.
 * This code is provided AS IS without warranty of any kind, expressed 
 * or implied, as to its fitness for any particular use.
 *
 * Copyright 1995 Ralph Zazula (zazula@next.com).  All Rights Reserved.
 *
 */

#import "ToDoController.h"
#import "ToDoItem.h"

const char *ToDoListPBoardType = "ToDoList v1.0 Item Pasteboard";
extern BOOL IncludesType(const NXAtom *types, NXAtom type);

@implementation ToDoController(Pasteboard)

- copy:sender
{
	if(![self copyToPasteboard:[Pasteboard new]]) {
		NXBeep();
		return nil;
	}
	return self;
}

- paste:sender
{
	if(![self pasteFromPasteboard:[Pasteboard new]]) {
		NXBeep();
		return nil;
	}
	return self;
}

- cut:sender
{
	if([self copy:self]) {
		[self delete:self];
	}
	return self;
}

- delete:sender
{
	[self remove:self];
	return self;
}

/*** utility methods used by cut/copy/paste and services ***/

- copyToPasteboard:(Pasteboard *)pboard
{
	const char *myTypes[3] = {NXAsciiPboardType, ToDoListPBoardType, NULL};
	NXStream *stream;
	BOOL failed = NO;
	id itemList = [self selectedItems];
	
	ToDoListPBoardType = NXUniqueStringNoCopy(ToDoListPBoardType);

	if(itemList && [itemList count]) {
		int i;
		char *buf;
		int len;
		
		/* declare the two types */
		[pboard declareTypes:myTypes num:2 owner:NULL];

		/* write the ASCII representation */
		NX_DURING
		stream = NXOpenMemory(NULL, 0, NX_READWRITE);
		for(i=0; i<[itemList count]; i++) {
			[[itemList objectAt:i] writeToStream:stream];
			NXPrintf(stream, "\n");
		}
		[pboard writeType:NXAsciiPboardType fromStream:stream];
		NXCloseMemory(stream, NX_FREEBUFFER);
		NX_HANDLER
		failed = YES;
		NX_ENDHANDLER
		
		/* write the internal representation */
		buf = NXWriteRootObjectToBuffer(itemList, &len);
		[pboard writeType:ToDoListPBoardType data:buf length:len];
		NXFreeObjectBuffer(buf, len);
		
		/* return status */
		return failed ? nil : self;
	}
		
	return nil;	
}

- pasteFromPasteboard:(Pasteboard *)pboard
{
   const char * const *types;
	char *data;
	int len;
	id pasteList;
	
	ToDoListPBoardType = NXUniqueStringNoCopy(ToDoListPBoardType);

	types = [pboard types];
	if(IncludesType(types, ToDoListPBoardType)) {
		if([pboard readType:ToDoListPBoardType data:&data length:&len]) {
			pasteList = NXReadObjectFromBuffer(data, len);
			[todoList appendList:pasteList];
			[pboard deallocatePasteboardData:data length:len];
			[self dirty:nil];
			[self update];
			[self selectItem:[pasteList objectAt:0]];
			pasteList = [pasteList free];
		}
	} else {
		/* check for ASCII or RTF data on pboard */
		NXStream *s = NULL;
		if(IncludesType(types, NXRTFPboardType)) {
			s = [pboard readTypeToStream:NXRTFPboardType];
		} else if(IncludesType(types, NXAsciiPboardType)) {
			s = [pboard readTypeToStream:NXAsciiPboardType];
		}
		if(s) {
			id item = [[ToDoItem alloc] init];
			[item setSubject:"<Pasteboard>"];
			[item setDataFromStream:s];
			NXCloseMemory(s, NX_FREEBUFFER);			
			[todoList addObject:item];
			[self dirty:nil];
			[self update];
			[self selectItem:item];
		}
	}			
	return self;
}

@end
