/***************************************************************************
 * CLASS:		MiscIconWell
 *
 *	See the header file for more information.
 *
 * This object is included in the MiscKit by permission from the author
 * and its use is governed by the MiscKit license, found in the file
 * "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
 * for a list of all applicable permissions and restrictions.
 ***************************************************************************/

#import <misckit/MiscString.h>
#import <misckit/MiscIconWell.h>

 
@implementation MiscIconWell
 
- initFrame: (const NXRect *)frameRect
{
  const char *const types[] = {NXFilenamePboardType};
  
  	[super initFrame: frameRect];
	[self registerForDraggedTypes: (const char *const *)&types count: 1];
	
	filename = [ [MiscString alloc] init];
	[self setAllowDoubleClickLaunch: YES];
	
	return self;
}



- awake
{ 
  const char *const types[] = {NXFilenamePboardType};
  
	[super awake];	
	[self registerForDraggedTypes: (const char *const *)&types count: 1];
	
	return self;
}



- free
{
	[filename free];
	return [super free];
}


// Return the filename associated with the image. Kind of a hack to return
// nil if no filename set, I suppose.

- (char *)filename
{   
 	if (strcmp([filename stringValue], "") == 0)
		return NULL;
	else
  		return ((char *)[filename stringValue]);
}



// Overridden from MiscDragView so the icon representation of the file
// is fetched instead of the image itself (likely the filename is not
// an image). It also has a small hack that if there are more than one
// filename that it steals that multiple.tiff from Librarian.app. 

- setImageByFilename: (char *)aFilename
{
	[filename setStringValue: aFilename];
		
	if ([filename numWords] > 1)
		[super setImageByFilename: "/NextApps/Librarian.app/multiple.tiff"];
	else	
		[self setImage: [ [Application workspace] getIconForFile: aFilename] ];
	
	return self;
}



// Add additional options that only apply to MiscIconWell.

- setAllowDoubleClickLaunch: (BOOL)aBool
{
	allowDoubleClickLaunch = aBool;
	return self;
}



- (BOOL)allowDoubleClickLaunch
{
	return allowDoubleClickLaunch;
}



// Override mouseDown to check if the icon was double clicked. If so, then
// launch it from workspace, else let super handle it.

- mouseDown: (NXEvent *)theEvent
{
	if ([self allowDoubleClickLaunch] && theEvent->data.mouse.click > 1 && 
			filename)
		[ [Application workspace] openFile: [filename stringValue] ];
	else
		[super mouseDown: theEvent];
	return self;
}



// Make the dragPoint be the middle of the image, so it looks nice.

- calculateDragPoint: (NXPoint *)dragPoint andOffset: (NXPoint *)offset
{
	dragPoint->x -= imageSize.width/2.0;
    dragPoint->y -= imageSize.width/2.0;

	return self;
}


	
// Put the data on the pasteboard when a source drag takes place, and
// also choose the image to drag. 

- (BOOL)setupForSourceDrag
{
  id  dragPB = [Pasteboard newName: NXDragPboard];
  
	if (filename != nil)
	{
		[dragPB declareTypes:&NXFilenamePboardType num:1 owner:self];

 		[dragPB writeType: NXFilenamePboard data: [filename stringValue]
		 			length: [filename length] ];
		dragImage = theImage;
		 
		return YES;
	 }

	return NO;
}




// Check if an incoming dragged icon is using the NXFilenamePboardType. If
// not, then don't accept the drag.

- (BOOL)performDragOperation: sender
{
  id  dragPB = [Pasteboard newName: NXDragPboard];
  char  *pbData;
  int  pbLength;

	if ([dragPB readType: NXFilenamePboardType data: &pbData 
			length: &pbLength] == nil)
		return NO;	
	 
	return YES;
}


// Take the data from the pasteboard and set the new image.

- concludeDragOperation: sender
{
  id  dragPB = [Pasteboard newName: NXDragPboard];
  char  *pbData;
  int  pbLength;
  
	[dragPB readType: NXFilenamePboardType data: &pbData 
			length: &pbLength];

	[self setImageByFilename: pbData];
			
	[dragPB deallocatePasteboardData: pbData length: pbLength];
	
	[super concludeDragOperation: sender];
	
    return self;
}



// Archiving methods

- read: (NXTypedStream *)stream
{
	[super read: stream];
	filename = NXReadObject (stream);
	NXReadTypes (stream, "c", &allowDoubleClickLaunch);
	return self;
}



- write: (NXTypedStream *)stream
{
	[super write: stream];
	NXWriteObject (stream, filename);
	NXWriteTypes (stream, "c", &allowDoubleClickLaunch);
	return self;
}

@end