/****************************************************************************
 *   Copyright (C) 2004 by Arboretum Systems, Inc.                          *
 *   Technical administrator: Alain Mazy, hav@mazy.be                       *
 *   Lead program designer: Georges Jaroslaw, gjaro@arboretum.com           *
 *                                                                          *
 *   HyperEngine-AV is a video, audio and text editor that can be used to   *
 *   record, import, edit, process and arrange together video, sound and    *
 *   text. These are all achieved in the program's free-form document       *
 *   window, with no limitations to the number of tracks.                   *
 *   The purpose of this program is to provide to users at all levels of    *
 *   expertise a readily accessible tool enabling them to create movies,    *
 *   slide shows or presentations.                                          *
 *                                                                          *
 *   HyperEngine-AV itself is free software. However, plug-ins that can be  *
 *   used as add-ons to HyperEngine-AV may or may not be free software, at  *
 *   the discretion of each plug-in developer and as specified by these     *
 *   plug-ins' respective licenses.                                         *
 *   You can redistribute HyperEngine-AV itself and/or modify it under the  *
 *   terms of the GNU General Public License as published by the Free       *
 *   Software Foundation; either version 2 of the License, or (at your      *
 *   option) any later version.                                             *
 *                                                                          *
 *   HyperEngine-AV is distributed in the hope that it will be useful, but  *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *   GNU General Public License for all applicable details.                 *
 *                                                                          *
 *   You should have received a copy of the GNU General Public License      *
 *   along with this program; if not, write to:                             *
 *   Free Software Foundation, Inc.,                                        *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
 ****************************************************************************/
#import "MIOverview.h"
#import "MIOverviewController.h"
#import "MIApplicationController.h"
#import "MIMainViewController.h"
#import "MIObject.h"
#import "MIObjectRep.h"
#import "MITopLevelContainerRep.h"
#import "MIOverviewTrackers.h"
#import "MICreateWSObjsFromFilesCommand.h";
#import "MIMontageDocument.h"
#import "MIPreferences.h"

#ifndef LibraryToggle_h
#include "LibraryToggle.h"
#endif //LibraryToggle_h

#import "MILibraryElement.h"

#if USE_LIBRARY
#import "MICreateClipsFromLibraryElementsCommand.h"
#endif //#if USE_LIBRARY

const int		kResizeHandleHalfSize = 3;

@implementation MIOverview

- (id)initWithFrame:(NSRect)frame
{
	self = [super initWithFrame:frame];
	{
		fCachedImage = nil;
        [self registerForDraggedTypes:[[MIApplicationController sharedApplicationController] pasteboardTypes]];
	}
	return self;
}

- (float)getHRatio
{
	return fHRatio;
}

- (float)getVRatio
{
	return fVRatio;
}

- (void)drawRect:(NSRect)aRect
{
	if ( !fCachedImage )
		[self refreshCachedImage];
		
	[self refreshRatios];
	// display the cached image
	[fCachedImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
	// draw the markers, locators, ...
	[self drawLocators:aRect];
	[self drawMarkers];
	// draw the rectangle
	[self drawVisibleRectangle:aRect];
	[self drawFutureVisibleRectangle:aRect];
	
	[fMouseTracker draw:aRect];
}

- (void)refreshRatios
{
	NSRect		visibleRect;
	NSRect		tlcBounds;
	NSRect		myBounds;

	if ( ![NSApp mainWindow] )
		return;
		
	visibleRect = [[[NSApp mainViewController] topLevelContainerView] visibleRect];
	tlcBounds = [[[NSApp mainViewController] topLevelContainerView] bounds];
	myBounds = [self bounds];

	fHRatio = NSWidth(myBounds)/NSWidth(tlcBounds);
	fVRatio = NSHeight(myBounds)/NSHeight(tlcBounds);


	
}

- (void)drawLocators:(NSRect)aRect
{
	MITopLevelContainerRep		*tlc;
	float						pos;
	NSRect						myBounds;
	
	myBounds = [self bounds];
	tlc = [[NSApp mainViewController] topLevelContainerView];
	
	pos = [tlc getCurrentPlayBarPosition];
	pos *= fHRatio;
	[[NSColor blueColor] set];
	[NSBezierPath strokeLineFromPoint:NSMakePoint(pos-0.5, NSMinY(myBounds)) toPoint:NSMakePoint(pos-0.5, NSMaxY(myBounds))];

	pos = [tlc getLeftLocatorPosition];
	pos *= fHRatio;
	[[NSColor greenColor] set];
	[NSBezierPath strokeLineFromPoint:NSMakePoint(pos-0.5, NSMinY(myBounds)) toPoint:NSMakePoint(pos-0.5, NSMaxY(myBounds))];

	pos = [tlc getRightLocatorPosition];
	pos *= fHRatio;
	[[NSColor redColor] set];
	[NSBezierPath strokeLineFromPoint:NSMakePoint(pos-0.5, NSMinY(myBounds)) toPoint:NSMakePoint(pos-0.5, NSMaxY(myBounds))];
}

- (void)drawMarkers
{
	MIMainViewController *controller = [NSApp mainViewController];
    MIMontageDocument *document = [controller document];
	MITopLevelContainerRep *tlc = [controller topLevelContainerView];
    unsigned i;
    float position;
    NSRect visibleRect = [self visibleRect];

    [[NSColor colorWithCalibratedRed:0.5 green:0.5 blue:0.5 alpha:1.0] set];

    for ( i = 0 ; i < [document getMarkerCount] ; i++ )
	{
        position = [tlc armeTimeToPixel:[document getMarker:i]];
		position *= fHRatio;
        [NSBezierPath strokeLineFromPoint:NSMakePoint((int)position - 0.5, NSMinY(visibleRect))
                                  toPoint:NSMakePoint((int)position - 0.5, NSMaxY(visibleRect))];
	}
}


- (void)drawFutureVisibleRectangle:(NSRect)aRect
{
	int			newH = [fOverviewController futureHZoomIndex];
	int			newV = [fOverviewController futureVZoomIndex];
	NSRect		vRect = [self getVisibleRect];
	NSRect		newRect;
	double ol, ne;
	
	if ( newH == -1 && newV == -1 )
		return;
	
	newRect = vRect;

	if ( newH != -1 )
	{
		ol = (double)[MIMainViewController getHZoomPNValueFromIndex:[[NSApp mainViewController] hZoomIndex]];
		ne = (double)[MIMainViewController getHZoomPNValueFromIndex:newH];
		if ( ol < 0 )
			ol = -1/ol;
		if ( ne < 0 )
			ne = -1/ne;
			
		newRect.size.width /= ol/ne;
	}

	if ( newV == -1 )
		newV = [[NSApp mainViewController] vZoomIndex];
		
	if ( newV != -1 )
	{
		ol = (double)[MIMainViewController getVZoomPNValueFromIndex:[[NSApp mainViewController] vZoomIndex]];
		ne = (double)[MIMainViewController getVZoomPNValueFromIndex:newV];
		if ( ol < 0 )
			ol = -1/ol;
		if ( ne < 0 )
			ne = -1/ne;
		newRect.size.height /= ol/ne;
	
		newRect.origin.y = NSMaxY(vRect) - NSHeight(newRect);
	}
	
	
	/// center the new rectangle on the playbar
	float pos = fHRatio * [[[NSApp mainViewController] topLevelContainerView] getCurrentPlayBarPosition];
	float delta = pos - NSMidX(newRect);
	
	if ( -delta > NSMinX(newRect) )
		delta = -NSMinX(newRect);
	
	newRect.origin.x += delta;
	
	[[NSColor redColor] set];
	[NSBezierPath strokeRect:newRect];
	
}

- (void)drawVisibleRectangle:(NSRect)aRect
{
	NSRect		visibleRect;
	
	visibleRect = [self getVisibleRect];
	
	visibleRect.origin.x -= 0.5;
	visibleRect.origin.y -= 0.5;
	
//	[[NSColor blackColor] set];
	[[NSColor colorWithCalibratedRed:0.259 green:0.388 blue:0.647 alpha:1] set];

	[NSBezierPath strokeRect:visibleRect];
	
	[NSBezierPath fillRect:[self getHandleRect:0]];
/*
	[NSBezierPath fillRect:[self getHandleRect:MIMaxXEdge]];
	[NSBezierPath fillRect:[self getHandleRect:MIMinXEdge]];
	[NSBezierPath fillRect:[self getHandleRect:MIMaxYEdge]];
	[NSBezierPath fillRect:[self getHandleRect:MIMinYEdge]];

	[NSBezierPath fillRect:[self getHandleRect:(MIMaxXEdge|MIMaxYEdge)]];
	[NSBezierPath fillRect:[self getHandleRect:(MIMinXEdge|MIMinYEdge)]];
	[NSBezierPath fillRect:[self getHandleRect:(MIMaxYEdge|MIMinXEdge)]];
	[NSBezierPath fillRect:[self getHandleRect:(MIMinYEdge|MIMaxXEdge)]];
*/	
}

- (NSRect)getVisibleRect
{
	NSRect		visibleRect;
	NSRect		tlcBounds;
	NSRect		myBounds;
	
	visibleRect = [[[NSApp mainViewController] topLevelContainerView] visibleRect];
	tlcBounds = [[[NSApp mainViewController] topLevelContainerView] bounds];
	myBounds = [self bounds];

	visibleRect.origin.x = (NSMinX(visibleRect)*NSWidth(myBounds))/NSWidth(tlcBounds);
	visibleRect.origin.y = (NSMinY(visibleRect)*NSHeight(myBounds))/NSHeight(tlcBounds);
	visibleRect.size.width = (NSWidth(visibleRect)*NSWidth(myBounds))/NSWidth(tlcBounds);
	visibleRect.size.height = (NSHeight(visibleRect)*NSHeight(myBounds))/NSHeight(tlcBounds);
	
//	visibleRect = ScaleNSRect(visibleRect, fHRatio, fVRatio);
/*
	visibleRect.origin.x = (int)visibleRect.origin.x;
	visibleRect.origin.y = (int)visibleRect.origin.y;
	visibleRect.size.width = (int)visibleRect.size.width;
	visibleRect.size.height = (int)visibleRect.size.height;
*/
	
	return visibleRect;
}

- (void)setCachedImageNeedsRefreshing
{
	[fCachedImage release];
	fCachedImage = nil;
}

- (void)refreshCachedImage
{
    MITopLevelContainerRep	*theTLC;

    if ( !fCachedImage )
    {
        fCachedImage = [[NSImage alloc] initWithSize:[self bounds].size];
    }
    else if ( !NSEqualSizes([self bounds].size, [fCachedImage size]) )
    {
        [fCachedImage release];
        fCachedImage = [[NSImage alloc] initWithSize:[self bounds].size];
    }

    theTLC = [[NSApp mainViewController] topLevelContainerView];
    if (theTLC)
    {
        [self refreshRatios];

        [fCachedImage lockFocus];
        [[NSColor whiteColor] set];
        [NSBezierPath fillRect:NSMakeRect(0,0,[fCachedImage size].width, [fCachedImage size].height)];
        [self drawObjectChildren:[theTLC representedObject] withHRate:fHRatio VRate:fVRatio offset:NSZeroPoint];
        [fCachedImage unlockFocus];
    }
}

- (void)drawObjectChildren:(MIObject*)anObject withHRate:(float)hRate VRate:(float)vRate offset:(NSPoint)parentOrigin
{
	MITopLevelContainerRep		*theTLC;
	MIObject					*aChild;
	MIObjectRep					*aRep;
	NSRect						childFrame;
	NSRect						drawFrame;
	
//	NSLog([NSString stringWithFormat:@"Drawing Childrens of %@", [anObject title]]);
	
	theTLC = [[NSApp mainViewController] topLevelContainerView];
	//childEnum = [[anObject getChildren] objectEnumerator];
	for(UInt32 childEnumIndex = 0; childEnumIndex < [[anObject getChildren] count]; childEnumIndex++)
//	while ( aChild = [childEnum nextObject] )
	{
		aChild = [[anObject getChildren] objectAtIndex:childEnumIndex];
//		NSLog([NSString stringWithFormat:@"aChild:%@", [aChild title]]);
		
		aRep = [aChild findRepresentationInTLC:theTLC];
		childFrame = [aRep frame];
		drawFrame = ScaleNSRect(childFrame, hRate, vRate);
		drawFrame.origin = TranslateNSPoint(drawFrame.origin, parentOrigin);

/*		
		[[NSColor blackColor] set];
		[NSBezierPath strokeRect:drawFrame];
		[[aRep backgroundColor] set];
		[NSBezierPath fillRect:NSInsetRect(drawFrame,1,1)];
*/		
		[[aRep backgroundColor] set];
		[NSBezierPath fillRect:drawFrame];
		[[NSColor blackColor] set];
		[NSBezierPath strokeRect:drawFrame];

		if ( [[aChild getChildren] count] && ![aChild isCollapsed])
			[self drawObjectChildren:aChild withHRate:hRate VRate:vRate offset:drawFrame.origin];
	}
}

-(BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
	// this function is used to tell that the view receives the first 'mousedown' event
	return YES;
}


- (void)mouseDragged:(NSEvent *)theEvent
{
	NSPoint	mouseLoc;
	
	mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
	
	[fMouseTracker mouseMoved:mouseLoc withModifiers:[theEvent modifierFlags]];
}

- (void)mouseUp:(NSEvent *)theEvent
{
	NSPoint	mouseLoc;
	
	mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];

	[fMouseTracker moved:[self convertPoint:[theEvent locationInWindow] fromView:nil] withModifiers:[theEvent modifierFlags]];
	[fMouseTracker stop:[self convertPoint:[theEvent locationInWindow] fromView:nil] withModifiers:[theEvent modifierFlags]];
	[fMouseTracker release];
	fMouseTracker = nil;
}

- (NSPoint)convertPointToTLCCoords:(NSPoint)point
{
	point.x /= [self getHRatio];
	point.y /= [self getVRatio];
	
	return point;
}

- (NSPoint)convertPointFromTLCCoords:(NSPoint)point
{
	point.x *= [self getHRatio];
	point.y *= [self getVRatio];
	
	return point;
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////  Dragging
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

/*
As the image is dragged into the destination's boundaries, the destination is sent a draggingEntered: message.
¥  While the image remains within the destination, a series of draggingUpdated: messages are sent.
¥  If the image is dragged out of the destination, draggingExited: is sent and the sequence of NSDraggingDestination messages stops. If it re-enters, the sequence begins again (with a new draggingEntered: message).
¥  When the image is released, it either slides back to its source (and breaks the sequence) or a prepareForDragOperation: message is sent to the destination, depending on the value returned by the most recent invocation of draggingEntered: or draggingUpdated:.
¥  If the prepareForDragOperation: message returned YES, a performDragOperation: message is sent.
¥  Finally, if performDragOperation: returned YES, concludeDragOperation: is sent.
*/

// The clipsheetwindowView is already registered as a dragging recipient on initialization of the clipSheetController

- (void)importWithObjectsFromDictionary:(NSMutableDictionary*)dict {
	id files = [[dict objectForKey:@"files"] retain];
	[dict removeObjectForKey:@"files"];
	[[NSApp mainViewController] importFilesUsingImportPanelIfNeeded:[files autorelease] importSelector:@selector(importSelectedFiles:contextDictionary:) importTarget:self contextDictionary:dict];
}

- (void)importSelectedFiles:(NSArray*)files contextDictionary:(NSMutableDictionary*)dict
{
	MICreateWSObjsFromFilesCommand	*createClipsCommand = [[MICreateWSObjsFromFilesCommand alloc] initWithFiles:files controller:[NSApp mainViewController]];
	MIPoint position;

	[[dict objectForKey:@"position"] getValue:&position];
	[createClipsCommand setFirstPosition:position];
	[createClipsCommand setParent:[dict objectForKey:@"parent"]];

	[[[NSApp mainViewController] document] doCmd:createClipsCommand];

	if ( [[MIPreferences sharedPrefs] gridShowMask] & kPrefsGridShowVObjLines ||
		 [[MIPreferences sharedPrefs] gridShowMask] & kPrefsGridShowHObjLines )
		[[MIApplicationController sharedApplicationController] redrawAllMainWindows];

	[createClipsCommand release];
	[[MIApplicationController sharedApplicationController] modelChangedForDocument:[[NSApp mainViewController] document]];
}

- (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
{
    NSPasteboard	*pboard;
    NSArray			*fileNames;
    NSString		*name;
    unsigned int	returnVal;
    unsigned int	i, n;
	NSPoint			mouseLoc;
	unsigned int	modifiers;	
    
    returnVal = NSDragOperationNone;
    pboard = [sender draggingPasteboard];
    
    if ([[pboard types] containsObject:NSFilenamesPboardType])
    {
        fileNames = [pboard propertyListForType:NSFilenamesPboardType];
        n = [fileNames count];
        for ( i = 0; i < n && returnVal == NSDragOperationNone; i++ )
        {
            name = [fileNames objectAtIndex:i];
            if ([[[NSApp mainViewController] topLevelContainerView] canFileBeImported:name])
                returnVal = NSDragOperationCopy;
        }
    }
	else if ( [[pboard types] containsObject:MILibraryElementsPboardType])
	{
#if USE_LIBRARY
		returnVal = NSDragOperationCopy;
#endif //#if USE_LIBRARY
	}
    
    fLastDraggingAnswer = returnVal;
	
	mouseLoc = [self convertPoint:[sender draggingLocation] fromView:nil];
	modifiers = 0;
    
	fMouseTracker = [[MIDragThingsFromOutsideInOverviewTracker alloc] initWithView:self atPos:mouseLoc withModifiers:modifiers];
	[fMouseTracker start:mouseLoc withModifiers:modifiers];
	
    return returnVal;
}

- (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender
{
	NSPoint			mouseLoc;
	unsigned int	modifiers;	

	mouseLoc = [self convertPoint:[sender draggingLocation] fromView:nil];
	modifiers = 0;

	[fMouseTracker mouseMoved:mouseLoc withModifiers:modifiers];

	return fLastDraggingAnswer;
}

- (void)draggingExited:(id <NSDraggingInfo>)sender
{
	NSPoint			mouseLoc;
	unsigned int	modifiers;	

	mouseLoc = [self convertPoint:[sender draggingLocation] fromView:nil];
	modifiers = 0;

	[fMouseTracker stop:mouseLoc withModifiers:modifiers];
	[fMouseTracker release];
	fMouseTracker = nil;
	
    fLastDraggingAnswer = NSDragOperationNone;
}

- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
	return TRUE;
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
	return TRUE;
}

- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
	NSPasteboard					*pboard;
    NSArray							*fileNames;
    NSPoint							pixelPosition;
	MIObject						*parent;
	NSPoint							mouseLoc;
	unsigned int					modifiers = 0;
//	NSMutableArray					*libElems;
	
	// get new parent from the mouseTracker and release it.
	parent = [[fMouseTracker destination] representedObject];
	mouseLoc = [self convertPoint:[sender draggingLocation] fromView:nil];

	[fMouseTracker stop:mouseLoc withModifiers:modifiers];
	[fMouseTracker release];
	fMouseTracker = nil;
	
    pboard = [sender draggingPasteboard];
    
	// check if the information contains filenames
	if ([[pboard types] containsObject:NSFilenamesPboardType])
    {
        fileNames = [pboard propertyListForType:NSFilenamesPboardType];
		
		// calculate new position
		pixelPosition = [self convertPointToTLCCoords:[self convertPoint:[sender draggingLocation] fromView:nil]];
		pixelPosition.y -=
#ifdef SMALL_TITLEBAR
			GET_VALUE(kDefaultClipRepresentationHeight) ;
#else
			kDefaultClipRepresentationHeight ;
#endif
		
		
		MIPoint position = [[NSApp mainViewController] NSPointToMIPoint:pixelPosition];

		NSMutableDictionary *dict = [NSMutableDictionary dictionary];
		[dict setObject:[[[NSApp mainViewController] topLevelContainerView] representedObject] forKey:@"parent"];
		[dict setObject:[NSValue valueWithBytes:&position objCType:@encode(MIPoint)] forKey:@"position"];
		[dict setObject:[[[NSApp mainViewController] topLevelContainerView] discardUnsupportedFiles:fileNames] forKey:@"files"];

		// call importWithObjectsFromDictionary: in .2 secs to do the real work
		[self performSelector:@selector(importWithObjectsFromDictionary:) withObject:dict afterDelay:.2 inModes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
		
    }
	else if ( [[pboard types] containsObject:MILibraryElementsPboardType])
	{
	#if USE_LIBRARY
		NSData	*d;
		MICreateClipsFromLibraryElementsCommand *cmd;
		
		d = [pboard dataForType:MILibraryElementsPboardType];
		libElems = [NSUnarchiver unarchiveObjectWithData:d];

		// calculate new position
		pixelPosition = [self convertPointToTLCCoords:[self convertPoint:[sender draggingLocation] fromView:nil]];
		MIPoint position = [[NSApp mainViewController] NSPointToMIPoint:pixelPosition];

		cmd = [[[MICreateClipsFromLibraryElementsCommand alloc] initWithElements:libElems] autorelease];
		[cmd setMainViewController:[NSApp mainViewController]];
		[cmd setGlobalFirstPosition:position];
		[cmd setParent:[[[NSApp mainViewController] topLevelContainerView] representedObject]];
			
		[[[NSDocumentController sharedDocumentController] currentDocument] doCmd:cmd];

		if ( [[MIPreferences sharedPrefs] gridShowMask] & kPrefsGridShowVObjLines ||
			[[MIPreferences sharedPrefs] gridShowMask] & kPrefsGridShowHObjLines )
			[[MIApplicationController sharedApplicationController] redrawAllMainWindows];
	
	#else //#if USE_LIBRARY
		ZzAssert(0);
	#endif //#if USE_LIBRARY
	}
}

- (NSRect)getHandleRect:(int)edge
{
	NSRect handleRect = NSZeroRect;
	NSRect visibleRect;

	visibleRect = [self getVisibleRect];

//	visibleRect.origin.x -= 0.5;
//	visibleRect.origin.y -= 0.5;
	
/* handle sticking out */
	handleRect.origin.x = NSMaxX(visibleRect) - 2*kResizeHandleHalfSize;
	handleRect.origin.y = NSMinY(visibleRect);

	handleRect.size.width = 2.0*kResizeHandleHalfSize;
	handleRect.size.height = 2.0*kResizeHandleHalfSize;


/* handle not sticking out 
	handleRect.origin.x = max(NSMinX(visibleRect), NSMaxX(visibleRect) - 2*kResizeHandleHalfSize);
	handleRect.origin.y = NSMinY(visibleRect);

	handleRect.size.width = min( NSWidth(visibleRect), (float)(2.0*kResizeHandleHalfSize));
	handleRect.size.height = min( NSHeight(visibleRect), (float)(2.0*kResizeHandleHalfSize));
*/

/*	
	handleRect.origin.x = NSMidX(visibleRect);
	handleRect.origin.y = NSMidY(visibleRect);

	if ( edge & MIMinXEdge )
		handleRect.origin.x = NSMinX(visibleRect);

	if ( edge & MIMinYEdge )
		handleRect.origin.y = NSMinY(visibleRect);

	if ( edge & MIMaxXEdge )
		handleRect.origin.x = NSMaxX(visibleRect);

	if ( edge & MIMaxYEdge )
		handleRect.origin.y = NSMaxY(visibleRect);

	handleRect = NSInsetRect(handleRect,-kResizeHandleHalfSize,-kResizeHandleHalfSize);
*/	
		
/*		
	switch( edge )
	{
		case NSMinYEdge:
			handleRect = NSMakeRect(NSMidX(visibleRect),NSMinY(visibleRect),0,0);
			handleRect = NSInsetRect(handleRect,-kResizeHandleHalfSize,-kResizeHandleHalfSize);
			break;
		case NSMaxYEdge:
			handleRect = NSMakeRect(NSMidX(visibleRect),NSMaxY(visibleRect),0,0);
			handleRect = NSInsetRect(handleRect,-kResizeHandleHalfSize,-kResizeHandleHalfSize);
			break;
		case NSMaxXEdge:
			handleRect = NSMakeRect(NSMaxX(visibleRect),NSMidY(visibleRect),0,0);
			handleRect = NSInsetRect(handleRect,-kResizeHandleHalfSize,-kResizeHandleHalfSize);
			break;
		case NSMinXEdge:
			handleRect = NSMakeRect(NSMinX(visibleRect),NSMidY(visibleRect),0,0);
			handleRect = NSInsetRect(handleRect,-kResizeHandleHalfSize,-kResizeHandleHalfSize);
			break;
	}
*/
	
	return handleRect;
}

- (void)mouseDown:(NSEvent*)theEvent;
{
	NSPoint			mouseLoc;
	unsigned int 	theModifier;
	
	mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
	theModifier = [theEvent modifierFlags];
/*
	for ( i = 0 ; i < 4; i++ )
	{
		switch( i )
		{
			case 0:		theEdge = MIMaxXEdge; break;
			case 1:		theEdge = MIMaxYEdge; break;
			case 2:		theEdge = MIMinXEdge; break;
			case 3:		theEdge = MIMinYEdge; break;
			case 4:		theEdge = MIMinYEdge|MIMinXEdge; break;
			case 5:		theEdge = MIMinYEdge|MIMaxXEdge; break;
			case 6:		theEdge = MIMaxYEdge|MIMinXEdge; break;
			case 7:		theEdge = MIMaxYEdge|MIMaxXEdge; break;
		}
		if ( NSPointInRect(mouseLoc, [self getHandleRect:theEdge]) )
		{
			fMouseTracker = [[MIResizeVisibleRectTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
			[(MIResizeVisibleRectTracker*)fMouseTracker setEdge:(MIRectEdge)theEdge];
			break;
		}
	}
*/
/*
 by Georges on Thu Sep 26th 2002 - 13:03 Here are the new kb modifiers:

- with no modifier : moves the visible window to that location
- with COMMAND : create a new OV Frame
- with COMMAND+ SHIFT: initiates a selection rectangle in the overview
- with SHIFT : move the current selection
- with ALTERNATE : allows to move the locators
*/	
	theModifier &= (NSHelpKeyMask| NSControlKeyMask| NSShiftKeyMask| NSCommandKeyMask| NSAlternateKeyMask);

	if ( theModifier ^ NSCommandKeyMask && NSPointInRect(mouseLoc, NSInsetRect([self getHandleRect:0], -1, -1)) )
	{
		fMouseTracker = [[MIResizeVisibleRectTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
		[(MIResizeVisibleRectTracker*)fMouseTracker setEdge:(MIRectEdge)(MIMinYEdge|MIMaxXEdge)];
	}
	
	if ( !fMouseTracker )
	{
		if ( theModifier & NSCommandKeyMask && theModifier & NSShiftKeyMask )
		{
			fMouseTracker = [[MIOverviewSelectionTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
		}
		else if ( theModifier & NSCommandKeyMask )
		{
			fMouseTracker = [[MICreateNewVisibleRectTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
		}
		else if ( theModifier & NSShiftKeyMask )
		{
			if ( [[[NSApp mainViewController] selection] count] > 0 )
			{
				fMouseTracker = [[MIOverviewMoveSelectionTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
			}
		}
		else if ( theModifier & NSAlternateKeyMask )
		{
			MITopLevelContainerRep		*tlc;
			float						pos;
			NSRect						myBounds;
			
			myBounds = [self bounds];
			tlc = [[NSApp mainViewController] topLevelContainerView];
			
			pos = [tlc getCurrentPlayBarPosition];
			pos *= fHRatio;
			if ( fabs(mouseLoc.x - pos) < 15 )
			{
				fMouseTracker = [[MIOverviewMoveLocatorTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
				[(MIOverviewMoveLocatorTracker*)fMouseTracker setLocator:MIPlayBarLocator];
			}
			
			if ( !fMouseTracker ) 
			{
				pos = [tlc getLeftLocatorPosition];
				pos *= fHRatio;
				if ( fabs(mouseLoc.x - pos) < 15 )
				{
					fMouseTracker = [[MIOverviewMoveLocatorTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
					[(MIOverviewMoveLocatorTracker*)fMouseTracker setLocator:MILeftLocator];
				}
			}
		
			if ( !fMouseTracker ) 
			{
				pos = [tlc getRightLocatorPosition];
				pos *= fHRatio;
				if ( fabs(mouseLoc.x - pos) < 15 )
				{
					fMouseTracker = [[MIOverviewMoveLocatorTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];
					[(MIOverviewMoveLocatorTracker*)fMouseTracker setLocator:MIRightLocator];
				}
			}
		}
	}
	
	
	if ( !fMouseTracker && !theModifier)
		fMouseTracker = [[MIMoveVisibleRectTracker alloc] initWithView:self atPos:mouseLoc withModifiers:theModifier];

	// start the mouse tracker
	[fMouseTracker start:mouseLoc withModifiers:theModifier];
		
}

@end
