/*
 * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#import "KWQAssertions.h"

#import "DrawViewPrivate.h"
#import "DrawCanvasItem.h"
#import "DrawDocumentPrivate.h"

#import <kcanvas/KCanvas.h>
#import <kcanvas/KCanvasContainer.h>
#import <kcanvas/device/quartz/KCanvasViewQuartz.h>
#import <kcanvas/device/quartz/KRenderingDeviceQuartz.h>

// This should go in the Prefix header eventually.
#define foreacharray(__variable, __container) \
for (int __variable##__i=0, __variable##__n=[__container count];  \
     __variable##__i < __variable##__n && (__variable = [__container objectAtIndex:__variable##__i]);  \
     ++__variable##__i)

#define NSDifferencePoint(a,b) (NSMakePoint(a.x-b.x, a.y-b.y))
#define NSSumPoint(a,b) (NSMakePoint(a.x+b.x, a.y+b.y))

// editing knobs.
#define KNOB_SIZE 6
#define KNOB_HALF_SIZE 3

typedef enum {
    DragActionNone = 0,
    DragActionPan,
    DragActionResize,
    DragActionMove,
    DragActionSelection
} DrawDragAction;

// this is sorta a hack
@interface DrawDocument (InternalCanvasMethod)
- (KCanvas *)canvas;
@end


@interface DrawViewPrivate : NSObject {
    @public
    NSArray *selectedItems;
    
    DrawView *drawView; // pointer to "owner"
    DrawDocument *document;
    
    NSColor *backgroundColor;
    
    int dragControlPointIndex;
    NSPoint dragStartPoint;
    NSPoint lastDragPoint;
    NSPoint canvasDragAnchorPoint; // used mostly for group resize.
    NSPoint canvasDragOriginOffset;
    
    int trackingRectTag;
    DrawDragAction currentDragAction;
    NSRect selectionRect;
    
    NSSize _maxSize;
    
    // temporary hack, will eventually be stored in scrollview/view
    float canvasZoom;
    NSPoint canvasvisibleOrigin;
    
    KCanvasViewQuartz *canvasView;
    KRenderingDeviceContextQuartz *quartzContext;
}
@end 

@implementation DrawViewPrivate

- (id)initWithDrawView:(DrawView *)view
{
    if ((self = [super init])) {
        drawView = view;
        quartzContext = new KRenderingDeviceContextQuartz();
        canvasView = new KCanvasViewQuartz();
        canvasView->setView(drawView);
        canvasView->setContext(quartzContext);
    }
    return self;
}

- (DrawDocument *)document
{
    return document;
}

- (void)setDocument:(DrawDocument *)doc
{
    if (doc != document) {
        [document unregisterView:drawView];
        [document release];
        document = [doc retain];
        
        delete canvasView;
        canvasView = NULL;
        if (document) {
            canvasView = new KCanvasViewQuartz();
            canvasView->init([document canvas], NULL);
            canvasView->setView(drawView);
            canvasView->setContext(quartzContext);
        }
		[document registerView:drawView];
    }
}

// c++ enabled drawing code.
- (void)drawRect:(NSRect)dirtyViewRect
{
    if (![document canvas] || ![document canvas]->rootContainer() || !canvasView)
        return;
    
    // push the drawing context
    KRenderingDevice *renderingDevice = [document canvas]->renderingDevice();
	ASSERT(renderingDevice);
    
    // Apply the top-level "world transform" for zoom/pan
    CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
    quartzContext->setCGContext(context); // should probably just be set once...
    renderingDevice->pushContext(quartzContext);
    CGContextSaveGState(context);
    CGContextConcatCTM(context, CGAffineTransformInvert([drawView transformFromViewToCanvas]));
    
    // do the draw
    //[document drawRect:[drawView mapViewRectToCanvas:dirtyViewRect] inCGContext:context];
    [document canvas]->rootContainer()->draw(QRect([drawView mapViewRectToCanvas:dirtyViewRect]));
    
    // restore drawing state
    CGContextRestoreGState(context);
    renderingDevice->popContext();
    quartzContext->setCGContext(NULL);
}

- (void)dealloc
{
    // If we go away, make sure we clear the view pointer.
    [document unregisterView:drawView];
    delete canvasView;
    delete quartzContext;
    [super dealloc];
}
@end

NSArray *DrawViewDragTypes;

@interface DrawView (InternalMethods)
- (void)drawKnobsForRect:(NSRect)rect;
- (void)updateCanvasScale;
- (void)enableMouseMovedEventsIfNeeded;
@end

@implementation DrawView

+ (void)initialize
{
    //DrawViewDragTypes = [[NSArray arrayWithObject:NSFilenamesPboardType] retain];
    [self setKeys:[NSArray arrayWithObject:@"toolMode"] triggerChangeNotificationsForDependentKey:@"selectedCanvasItems"];
}

+ (void)setFilterSupportEnabled:(BOOL)enabled
{
    KRenderingDeviceQuartz::setFiltersEnabled(enabled);
}

+ (BOOL)isFilterSupportEnabled
{
    return KRenderingDeviceQuartz::filtersEnabled();
}

+ (void)setHardwareFilterSupportEnabled:(BOOL)enabled
{
    KRenderingDeviceQuartz::setHardwareRenderingEnabled(enabled);
}

+ (BOOL)isHardwareFilterSupportEnabled
{
    return KRenderingDeviceQuartz::hardwareRenderingEnabled();
}

- (id)initWithFrame:(NSRect)frameRect
{
    if ((self = [super initWithFrame:frameRect]) != nil) {
        _private = [[DrawViewPrivate alloc] initWithDrawView:self];
    }
    return self;
}

- (void)dealloc
{
    [_private release];
    [super dealloc];
}

// Used when the document dellocs
// to avoid recursion.
- (void)_clearDocument
{
	_private->document = nil;
	delete _private->canvasView;
	_private->canvasView = NULL;
}

- (NSRect)selectionCanvasBoundingBox
{
    NSRect selectionBoundingBox = NSZeroRect;
    DrawCanvasItem *item = nil;
    NSArray *selectedItems = [self selectedCanvasItems];
    foreacharray(item, selectedItems) {
        selectionBoundingBox = NSUnionRect(selectionBoundingBox,[item boundingBox]);
    }
    return selectionBoundingBox;
}

- (void)_clearAndDrawBackground:(NSRect)dirtyRect
{
    [[NSColor lightGrayColor] set];
    NSRectFill(dirtyRect);
    
    [[self backgroundColor] set];
    NSSize canvasSize = [[self document] canvasSize];
    NSRect canvasRect = NSMakeRect(0,0, canvasSize.width, canvasSize.height);
    NSRectFill([self mapCanvasRectToView:canvasRect]);
}

- (void)_drawSelectionKnobs
{
    if ((_toolMode == DrawViewToolArrow) && [[self selectedCanvasItems] count]) {
        NSRect viewSelectionBoundingBox = [self mapCanvasRectToView:[self selectionCanvasBoundingBox]];
        [self drawKnobsForRect:viewSelectionBoundingBox];
    }
    
    if (_private->currentDragAction == DragActionSelection) {
        [[NSColor lightGrayColor] set];
        NSFrameRect(_private->selectionRect);
    }
}

- (void)drawRect:(NSRect)dirtyRect
{
    [self _clearAndDrawBackground:dirtyRect];
    [_private drawRect:dirtyRect];
    [self _drawSelectionKnobs];
}

- (void)setBackgroundColor:(NSColor *)color
{
    id oldColor = _private->backgroundColor ;
    _private->backgroundColor = [color retain];
    [oldColor release];
}

- (NSColor *)backgroundColor
{
    if (!_private->backgroundColor)
        _private->backgroundColor = [[NSColor whiteColor] retain];
    return _private->backgroundColor;
}

- (BOOL)isOpaque
{
    return ![_private->backgroundColor isEqual:[NSColor clearColor]];
}

- (BOOL)isFlipped
{
    return YES;
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}

- (BOOL)acceptsFirstMouse:(NSEvent *)event
{
    return ((_toolMode == DrawViewToolBrowse) || (_toolMode == DrawViewToolArrow));
}

- (NSImageScaling)imageScaling
{
    return _scaleRule;
}

- (void)setImageScaling:(NSImageScaling)scaling
{
    _scaleRule = scaling;
    [self updateCanvasScale];
}

- (void)setFrame:(NSRect)newFrame
{
    [self removeTrackingRect:_private->trackingRectTag];
    [self setFrameOrigin:newFrame.origin];
    [self setFrameSize:newFrame.size];
    _private->trackingRectTag =
        [self addTrackingRect:[self frame]
                        owner:self userData:NULL
                 assumeInside:[self mouse:[NSEvent mouseLocation] inRect:[self bounds]]];
}

- (void)setFrameSize:(NSSize)newSize
{
    [super setFrameSize:newSize];
    [self updateCanvasScale];
}

- (void)setDocument:(DrawDocument *)document
{
    if ([_private document] != document) {
        [_private setDocument:document];
        [self updateCanvasScale];
        [self setNeedsDisplay:YES];
    }
}

- (DrawDocument *)document
{
    return [_private document];
}

- (KCanvasViewQuartz *)canvasView
{
    return _private->canvasView;
}

#pragma mark -
#pragma mark Editing support

- (void)setEditable:(BOOL)editable
{
    [self unregisterDraggedTypes];
    _isEditable = editable;
    if (_isEditable)
        [self registerForDraggedTypes:DrawViewDragTypes];
}

- (BOOL)isEditable
{
    return _isEditable;
}

- (NSRect)boundsForCanvasItem:(DrawCanvasItem *)canvasItem
{
    NSRect itemBBoxInCanvas = [canvasItem boundingBox];
    NSRect itemBBoxInView = [self mapCanvasRectToView:itemBBoxInCanvas];
    return NSInsetRect(itemBBoxInView, -KNOB_HALF_SIZE, -KNOB_HALF_SIZE);
}

- (NSArray *)selectedCanvasItems
{
    // selection only "exists" when using the arrow tool.
    // but we sill remember selection between uses.
    return _private->selectedItems;
}

- (void)setSelectedCanvasItems:(NSArray *)selectedItems
{
    DrawCanvasItem *newSelectedItem = nil;
    NSMutableArray *newSelectedItems = [[NSMutableArray alloc] init];
    foreacharray(newSelectedItem, selectedItems) {
        [newSelectedItems addObject:newSelectedItem];
    }
    [_private->selectedItems release];
    if ([newSelectedItems count])
        _private->selectedItems = newSelectedItems;
    else
        _private->selectedItems = nil;
    [self setNeedsDisplay:YES]; // FIXME: just invalidate the whole view for now.
}

- (IBAction)moveSelectionForward:(id)sender
{
    DrawCanvasItem *item = nil;
    NSArray *selectedItems = [self selectedCanvasItems];
    foreacharray(item, selectedItems) {
        [item raise];
    }
}

- (IBAction)moveSelectionBackward:(id)sender
{
    DrawCanvasItem *item = nil;
    NSArray *selectedItems = [self selectedCanvasItems];
    foreacharray(item, selectedItems) {
        [item lower];
    }
}

- (NSArray *)canvasControlPointsForSelection
{
    NSArray *selectedItems = [self selectedCanvasItems];
    if ([selectedItems count] == 1)
        return [[selectedItems objectAtIndex:0] controlPoints];
    else if ([selectedItems count] > 1)
        return [DrawCanvasItem controlPointsForRect:[self selectionCanvasBoundingBox]];
    
    return nil;
}

- (NSPoint)canvasDragAnchorPointForControlPointIndex:(int)controlPointIndex
{
    NSArray *selectedItems = [self selectedCanvasItems];
    if ([selectedItems count] == 1) {
        return [[selectedItems objectAtIndex:0] dragAnchorPointForControlPointIndex:controlPointIndex];
    } else if ([selectedItems count] > 1) {
        NSArray *controlPoints = [DrawCanvasItem controlPointsForRect:[self selectionCanvasBoundingBox]];
        return [DrawCanvasItem dragAnchorPointForControlPointIndex:controlPointIndex fromRectControlPoints:controlPoints];
    }
    NSLog(@"Error, no selection, you shouldn't ask for drag anchor point!");
    return NSZeroPoint;
}

- (int)controlPointIndexForCanvasHitPoint:(NSPoint)canvasPoint
{
    NSValue *controlPointValue = nil;
    NSArray *controlPoints = [self canvasControlPointsForSelection];
    
    NSSize canvasKnobSize = [self mapViewSizeToCanvas:NSMakeSize(KNOB_SIZE, KNOB_SIZE)];
    
    NSRect controlRect = NSZeroRect;
    controlRect.size = canvasKnobSize;
    NSSize halfCanvasKnobSize = NSMakeSize(canvasKnobSize.width/2.f, canvasKnobSize.height/2.f);
    int index = 0;
    
    foreacharray (controlPointValue, controlPoints) {
        NSPoint controlPoint = [controlPointValue pointValue];
        controlRect.origin.x = controlPoint.x - halfCanvasKnobSize.width;
        controlRect.origin.y = controlPoint.y - halfCanvasKnobSize.height;
        
        if (NSPointInRect(canvasPoint, controlRect))
            return index;
        index++;
    }
    return NSNotFound;
}

- (BOOL)createCanvasItemAtPoint:(NSPoint)mousePoint
{
    // first map to canvas coords.
    mousePoint = [self mapViewPointToCanvas:mousePoint];
    
    DrawCanvasItem *newItem = [[_private document] createItemForTool:_toolMode atPoint:mousePoint];
    if (newItem) {
        [self setSelectedCanvasItems:[NSArray arrayWithObject:newItem]];
        return YES;
    }
    return NO;
}

- (IBAction)deleteSelection:(id)sender
{
    NSArray *oldItems = [[self selectedCanvasItems] retain];
    [self setSelectedCanvasItems:nil];
    DrawCanvasItem *oldItem = nil;
    foreacharray(oldItem, oldItems) {
        [[_private document] removeItemFromDOM:oldItem];
    }
    [oldItems release];
}

- (int)toolMode
{
    return _toolMode;
}

- (void)setToolMode:(int)newToolMode
{
    _toolMode = (DrawViewTool)newToolMode;
    //[[self window] invalidateCursorRectsForView:self];
    // Not getting called until the view becomes key...
    [[self window] resetCursorRects]; // HACK?
    if ([self mouse:[NSEvent mouseLocation] inRect:[self bounds]])
        [self enableMouseMovedEventsIfNeeded];
}

- (void)resetCursorRects
{
    [super resetCursorRects];
    
    NSCursor *toolCursor = nil;
    switch (_toolMode) {
        case DrawViewToolBrowse:
            toolCursor = [NSCursor pointingHandCursor];
            break;            
	case DrawViewToolPan:
            toolCursor = [NSCursor openHandCursor];
            break;
	case DrawViewToolZoom:
            toolCursor = [NSCursor closedHandCursor]; // for now...
            break;
	case DrawViewToolLine:
	case DrawViewToolElipse:
	case DrawViewToolRectangle:
	case DrawViewToolPolyLine:
	case DrawViewToolArc:
            toolCursor = [NSCursor crosshairCursor];
            break;
	default:
            break;
    }
    if (toolCursor)
        [self addCursorRect:[self frame] cursor:toolCursor];
}

- (void)drawKnobsForRect:(NSRect)rect
{
    [[NSColor blackColor] set];
    [NSBezierPath fillRect:NSMakeRect(rect.origin.x - KNOB_HALF_SIZE, rect.origin.y - KNOB_HALF_SIZE, KNOB_SIZE, KNOB_SIZE)];
    [NSBezierPath fillRect:NSMakeRect(NSMaxX(rect) - KNOB_HALF_SIZE, rect.origin.y - KNOB_HALF_SIZE, KNOB_SIZE, KNOB_SIZE)];
    [NSBezierPath fillRect:NSMakeRect(rect.origin.x - KNOB_HALF_SIZE, NSMaxY(rect) - KNOB_HALF_SIZE, KNOB_SIZE, KNOB_SIZE)];
    [NSBezierPath fillRect:NSMakeRect(NSMaxX(rect) - KNOB_HALF_SIZE, NSMaxY(rect) - KNOB_HALF_SIZE, KNOB_SIZE, KNOB_SIZE)];
}


#pragma mark -
#pragma mark Event support

- (void)mouseDown:(NSEvent *)theEvent
{
    NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    NSPoint canvasPoint = [self mapViewPointToCanvas:mousePoint];
    _private->dragStartPoint = mousePoint;
    _private->lastDragPoint = mousePoint;
    
    switch (_toolMode) {
	case DrawViewToolBrowse:
	{
            // send mouse down events to DOM
            if (![[_private document] documentListensForMouseDownEvents])
                return;
            [[_private document] propagateMouseDownEvent:theEvent fromView:self];
            break;
	}
	case DrawViewToolArrow:
	{
            if ( (_private->dragControlPointIndex = [self controlPointIndexForCanvasHitPoint:canvasPoint]) != NSNotFound) {
                _private->canvasDragAnchorPoint = [self canvasDragAnchorPointForControlPointIndex:_private->dragControlPointIndex];
                NSLog(@"resize -- dragStartPoint: %@ canvasPoint: %@ controlIndex: %i canvasDragAnchorPoint: %@",
                      NSStringFromPoint(mousePoint), NSStringFromPoint(canvasPoint),
                      _private->dragControlPointIndex, NSStringFromPoint(_private->canvasDragAnchorPoint));
                _private->currentDragAction = DragActionResize;
            } else {
                // FIXME: we really should select SVGElements, not canvas items...
                DrawCanvasItem *hitItem = [[_private document] canvasItemAtPoint:canvasPoint];			
                //NSLog(@"move -- dragStartPoint: %@ canvasPoint: %@", NSStringFromPoint(mousePoint), NSStringFromPoint(canvasPoint));
                if (hitItem) {
                    NSArray *hitItems = [NSArray arrayWithObject:hitItem];
                    [self setSelectedCanvasItems:hitItems];
                    _private->currentDragAction = DragActionMove;
                    NSPoint hitOrigin = [hitItem boundingBox].origin;
                    _private->canvasDragOriginOffset = NSDifferencePoint(hitOrigin, canvasPoint);
                } else {
                    [self setSelectedCanvasItems:nil];
                    _private->currentDragAction = DragActionSelection;
                }
            }
            break;
	}
	case DrawViewToolPan:
            [[NSCursor closedHandCursor] push];
            _private->currentDragAction = DragActionPan;
            //NSLog(@"mouseDown: %@", NSStringFromPoint(_private->lastDragPoint));
            break;
            // creation tools:
	case DrawViewToolLine:
	case DrawViewToolElipse:
	case DrawViewToolTriangle:
	case DrawViewToolRectangle:
	case DrawViewToolPolyLine:
	case DrawViewToolArc:
	{
            if ([self createCanvasItemAtPoint:mousePoint]) {
                _private->currentDragAction = DragActionResize;
                _private->canvasDragAnchorPoint = canvasPoint;
                _private->dragControlPointIndex = 0;
            }
            break;
	}
	default:
            break;
    }
}

- (void)mouseDragged:(NSEvent *)theEvent
{
    NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    
    switch (_toolMode) {
	case DrawViewToolBrowse:
	{
            // send mouse dragged events to DOM.
            break;
	}
	case DrawViewToolArrow:
	{
            // move shapes here.
            if (_private->currentDragAction == DragActionMove) {
                NSSize dragOffset = NSMakeSize(mousePoint.x - _private->lastDragPoint.x, mousePoint.y - _private->lastDragPoint.y);
                NSSize canvasDragOffset = [self mapViewSizeToCanvas:dragOffset];
                NSLog(@"move: translating selection by: %@", NSStringFromSize(canvasDragOffset));
                DrawCanvasItem *item = nil;
                NSArray *selectedItems = [self selectedCanvasItems];
                foreacharray(item, selectedItems) {
                    [self setNeedsDisplayInRect:[self boundsForCanvasItem:item]];
                    [item translateByOffset:canvasDragOffset];
                    [self setNeedsDisplayInRect:[self boundsForCanvasItem:item]];
                }
            } else if (_private->currentDragAction == DragActionSelection) {
                [self setNeedsDisplayInRect:_private->selectionRect];
                _private->selectionRect = NSMakeRect(_private->dragStartPoint.x,
                                                     _private->dragStartPoint.y,
                                                     mousePoint.x - _private->dragStartPoint.x,
                                                     mousePoint.y - _private->dragStartPoint.y);
                [self setNeedsDisplayInRect:_private->selectionRect];
            }
            // fall through for resize code.
	}
	case DrawViewToolLine:
	case DrawViewToolElipse:
	case DrawViewToolTriangle:
	case DrawViewToolRectangle:
	case DrawViewToolPolyLine:
	case DrawViewToolArc:
	{
            if (_private->currentDragAction == DragActionResize) {
                NSPoint canvasPoint = [self mapViewPointToCanvas:mousePoint];
                DrawCanvasItem *item = nil;
                NSArray *selectedItems = [self selectedCanvasItems];
                foreacharray(item, selectedItems) {
                    [self setNeedsDisplayInRect:[self boundsForCanvasItem:item]];
                    [item resizeWithPoint:canvasPoint usingControlPoint:_private->dragControlPointIndex dragAnchorPoint:_private->canvasDragAnchorPoint];
                    [self setNeedsDisplayInRect:[self boundsForCanvasItem:item]];
                }
            }
            break;
	}
            
	case DrawViewToolPan:
	{
            NSPoint diff = NSDifferencePoint(mousePoint, _private->lastDragPoint);
            NSPoint canvasOrigin = [self canvasVisibleOrigin];
            NSPoint newOrigin = NSDifferencePoint(canvasOrigin, diff);
            [self setCanvasVisibleOrigin:newOrigin];
            //		NSLog(@"mouseDragged: %@  diff: %@ old origin: %@ newOrigin: %@",
            //			NSStringFromPoint(_private->lastDragPoint), 
            //			NSStringFromPoint(diff), NSStringFromPoint(canvasOrigin), NSStringFromPoint(newOrigin));
            break;
	}
            
	default:
            break;
    }
    
    // record the last drag point.
    _private->lastDragPoint = mousePoint;
}


- (void)mouseUp:(NSEvent *)theEvent
{
    //NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    
    switch (_toolMode) {
	case DrawViewToolBrowse:
	{
            if (![[_private document] documentListensForMouseUpEvents])
                return;
            [[_private document] propagateMouseUpEvent:theEvent fromView:self];
	}
	case DrawViewToolPan:
            [NSCursor pop];
            break;
	case DrawViewToolArrow:
            if (_private->currentDragAction == DragActionSelection) {
                [self setNeedsDisplayInRect:_private->selectionRect];
                // figure out what all was in that rect...
                _private->selectionRect = NSZeroRect;
            }
            break;
	default:
            break;
    }
    _private->currentDragAction = DragActionNone;
}

- (void)disableMouseMovedEvents
{
    if ([[self window] acceptsMouseMovedEvents])
        NSLog(@"Mouse move events now OFF");
    [[self window] setAcceptsMouseMovedEvents:NO];
}

- (void)enableMouseMovedEventsIfNeeded
{
    // FIXME:  This could still be more efficient
    BOOL needsMouseMoved = (_toolMode == DrawViewToolBrowse)
    && [[_private document] documentListensForMouseMovedEvents];
    if (needsMouseMoved != [[self window] acceptsMouseMovedEvents])
        NSLog(@"Mouse move events now %@", needsMouseMoved ? @"ON" : @"OFF");
    if (needsMouseMoved) {
        [[self window] setAcceptsMouseMovedEvents:needsMouseMoved];
    }
}

- (void)mouseEntered:(NSEvent *)theEvent
{
    [self enableMouseMovedEventsIfNeeded];
}

- (void)mouseExited:(NSEvent *)theEvent
{
    [self disableMouseMovedEvents];
}

- (void)mouseMoved:(NSEvent *)theEvent
{
    //NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    
    switch (_toolMode) {
	case DrawViewToolBrowse:
	{
            if (![[_private document] documentListensForMouseMovedEvents])
                return;
            
            NSCursor *cursor = [[_private document] cursorAfterPropagatingMouseMovedEvent:theEvent fromView:self];
            if (cursor && (cursor != [NSCursor currentCursor])) NSLog(@"Changing cursor: %@ name: %@", cursor, [[cursor image] name]);
            [cursor set];
	}
	default:
            break;
    }
}

- (void)keyDown:(NSEvent *)theEvent
{
    if (_toolMode == DrawViewToolArrow) {
        unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
        int flags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
        if (([theEvent keyCode] == NSDeleteFunctionKey) || ((key == NSDeleteCharacter) && (flags == 0)) ) {
            [self deleteSelection:nil];
        }
    } else if (_toolMode == DrawViewToolBrowse) {
        // Propagate the key event up through the DOM
    }
}

#pragma mark -
#pragma mark Zoom/Pan support

- (IBAction)zoomToFit:(id)sender
{
    NSSize canvasSize = [[_private document] canvasSize];
    float widthScale = canvasSize.width / [self bounds].size.width;
    float heightScale = canvasSize.height / [self bounds].size.height;
    
    float minScale = MAX(widthScale, heightScale);
    [self setCanvasZoom:minScale];
}

- (void)updateCanvasScale
{
    if (_scaleRule == NSScaleProportionally) {
        [self zoomToFit:nil];
    } else if (_scaleRule == NSScaleToFit) {
        // Not yet supported!
    } else if (_scaleRule == NSScaleNone) {
        [self setCanvasZoom:1.0];
    }
}

- (void)sizeToFitCanvas
{
    NSSize canvasSize = [[_private document] canvasSize];
    if ((canvasSize.width == 0) || (canvasSize.height == 0))
        return; // avoid disappearing.
    [self setFrameSize:canvasSize];
}

- (void)sizeToFitViewBox
{
    // FIXME: this is broken!
    [self sizeToFitCanvas];
}

- (IBAction)zoomIn:(id)sender
{
    NSPoint center = [self canvasvisibleCenterPoint];
    [self setCanvasZoom:([self canvasZoom] * 0.9)];
    [self panToCanvasCenterPoint:center];
}

- (IBAction)zoomOut:(id)sender
{
    NSPoint center = [self canvasvisibleCenterPoint];
    [self setCanvasZoom:([self canvasZoom] * 1.1)];
    [self panToCanvasCenterPoint:center];
}

- (IBAction)zoomOriginal:(id)sender
{
    // do these need to call into the canvas or document instead?
    [self setCanvasZoom:1.0];
    [self setCanvasVisibleOrigin:NSMakePoint(0,0)];
}

- (CGAffineTransform)transformFromViewToCanvas
{
    float zoom = [self canvasZoom];
    CGAffineTransform transform = CGAffineTransformMakeScale(zoom, zoom);
    NSPoint origin = [self canvasVisibleOrigin];
    return CGAffineTransformTranslate(transform,origin.x,origin.y);
}

- (NSPoint)mapViewPointToCanvas:(NSPoint)viewPoint
{
    CGPoint canvasPoint = CGPointApplyAffineTransform(*(CGPoint *)&viewPoint, [self transformFromViewToCanvas]);
    return (*(NSPoint *)&canvasPoint);
}
- (NSRect)mapViewRectToCanvas:(NSRect)viewRect
{
    CGRect canvasRect = CGRectApplyAffineTransform(*(CGRect *)&viewRect, [self transformFromViewToCanvas]);
    return (*(NSRect *)&canvasRect);
}
- (NSSize)mapViewSizeToCanvas:(NSSize)viewSize
{
    CGSize canvasSize = CGSizeApplyAffineTransform(*(CGSize *)&viewSize, [self transformFromViewToCanvas]);
    return (*(NSSize *)&canvasSize);
}

- (NSPoint)mapCanvasPointToView:(NSPoint)canvasPoint
{
    CGPoint viewPoint = CGPointApplyAffineTransform(*(CGPoint *)&canvasPoint, CGAffineTransformInvert([self transformFromViewToCanvas]));
    return (*(NSPoint *)&viewPoint);
}
- (NSRect)mapCanvasRectToView:(NSRect)canvasRect
{
    CGRect viewRect = CGRectApplyAffineTransform(*(CGRect *)&canvasRect, CGAffineTransformInvert([self transformFromViewToCanvas]));
    return (*(NSRect *)&viewRect);
}
- (NSSize)mapCanvasSizeToView:(NSSize)canavsSize
{
    CGSize viewSize = CGSizeApplyAffineTransform(*(CGSize *)&canavsSize, CGAffineTransformInvert([self transformFromViewToCanvas]));
    return (*(NSSize *)&viewSize);
}
#pragma mark -
#pragma mark Canvas Zoom/Pan (Hack!)

- (NSPoint)canvasVisibleOrigin
{
    return _private->canvasvisibleOrigin;
}

- (void)setCanvasVisibleOrigin:(NSPoint)newOrigin
{
    // will eventually move into NSScrollView I figure.
    _private->canvasvisibleOrigin = newOrigin;
    [self setNeedsDisplay:YES];
}

- (NSPoint)canvasvisibleCenterPoint
{
    NSPoint centerPoint = [self canvasVisibleOrigin];
    NSSize canvasVisibleSize = [self mapViewSizeToCanvas:[self bounds].size];
    centerPoint.x += canvasVisibleSize.width/2.f;
    centerPoint.y += canvasVisibleSize.height/2.f;
    //	NSPoint cvo = [self canvasVisibleOrigin];
    //	NSLog(@"Visible center: %@  visible origin: %@  visible size: %@  farPoint: %@",
    //		NSStringFromPoint(centerPoint), NSStringFromPoint(cvo),
    //		NSStringFromSize(canvasVisibleSize), NSStringFromPoint(NSMakePoint(cvo.x + canvasVisibleSize.width, cvo.y + canvasVisibleSize.height)));
    return centerPoint;
}

- (void)panToCanvasCenterPoint:(NSPoint)newCenter
{
    NSPoint newVisibleOrigin = newCenter;
    NSSize canvasVisibleSize = [self mapViewSizeToCanvas:[self bounds].size];
    newVisibleOrigin.x -= canvasVisibleSize.width/2.f;
    newVisibleOrigin.y -= canvasVisibleSize.height/2.f;
    //	NSLog(@"setting new origin: %@  visible size: %@", NSStringFromPoint(newVisibleOrigin), NSStringFromSize(canvasVisibleSize));
    [self setCanvasVisibleOrigin:newVisibleOrigin];
} 

- (float)canvasZoom
{
    return _private->canvasZoom;
    //return [self scale].width;
}

- (void)setCanvasZoom:(float)newZoom
{
    if (_private->canvasZoom != newZoom) {
        _private->canvasZoom = newZoom;
        //[self setScale:NSMakeSize(newZoom, newZoom)];
        [self setNeedsDisplay:YES];
    }
}

@end

