1//
2//  PXMagicWandTool.m
3//  Pixen-XCode
4//
5//  Created by Andy Matuschak on Sat Jun 12 2004.
6//  Copyright (c) 2004 Open Sword Group. All rights reserved.
7//
8
9#import "PXMagicWandTool.h"
10#import "PXCanvas.h"
11#import "PXCanvasController.h"
12#import "PXTool.h"
13#import "PXLayer.h"
14#import "PXImage.h"
15#import "PXToolSwitcher.h"
16#import "PXPoint.h"
17
18@implementation PXMagicWandTool
19
20- (NSString *)name
21{
22	return NSLocalizedString(@"MAGICWAND_NAME", @"Magic Wand Tool");
23}
24
25- (BOOL)shiftKeyDown
26{
27	isAdding = YES;
28	[switcher setIcon:[NSImage imageNamed:@"magicadd"] forTool:self];
29	return YES;
30}
31
32- (BOOL)shiftKeyUp
33{
34	isAdding = NO;
35	[switcher setIcon:[NSImage imageNamed:@"magic"] forTool:self];
36	return YES;
37}
38
39- (BOOL)optionKeyDown
40{
41	isSubtracting = YES;
42	[switcher setIcon:[NSImage imageNamed:@"magicsubtract"] forTool:self];
43	return YES;
44}
45
46- init
47{
48    [super init];
49	selectedPoints = [[NSMutableArray alloc] init];
50    return self;
51}
52
53- (void)dealloc
54{
55	[selectedPoints release];
56	[super dealloc];
57}
58
59- (BOOL)optionKeyUp
60{
61	isSubtracting = NO;
62	[switcher setIcon:[NSImage imageNamed:@"magic"] forTool:self];
63	return YES;
64}
65
66- actionName
67{
68    return NSLocalizedString(@"MAGICWAND_ACTION", @"Selection");
69}
70
71- movingActionName
72{
73	return NSLocalizedString(@"MOVE_ACTION", @"Moving");
74}
75
76- (void)startMovingCanvas:canvas
77{
78	[[self undoManager] setActionName:[self movingActionName]];
79	isMoving = YES;
80}
81
82- (void)stopMovingCanvas:canvas
83{
84	isMoving = NO;
85	selectedRect = lastSelectedRect;
86	[[canvas activeLayer] finalizeMotion];
87}
88
89- (BOOL)shouldAbandonFillingAtPoint:(NSPoint)aPoint fromCanvasController:controller
90{
91	return NO;
92}
93
94- (void)setLayers:layers fromLayers:oldLayers ofCanvas:canvas
95{
96	[[[self undoManager] prepareWithInvocationTarget:self] setLayers:oldLayers fromLayers:layers ofCanvas:canvas];
97	[canvas setLayers:layers];
98}
99
100- (void)mouseDownAt:(NSPoint)aPoint fromCanvasController:controller
101{
102	[[self undoManager] beginUndoGrouping];
103	[self setLayers:[[[controller canvas] layers] deepMutableCopy] fromLayers:[[controller canvas] layers] ofCanvas:[controller canvas]];
104
105    if([[controller canvas] pointIsSelected:aPoint] && !isSubtracting)
106	{
107		lastSelectedRect = [[controller canvas] selectedRect];
108		[self startMovingCanvas:[controller canvas]];
109	}
110    else
111	{
112		if (!isAdding && !isSubtracting)
113		{
114			oldLayerIndex = [[[controller canvas] layers] indexOfObject:[[controller canvas] activeLayer]];
115			oldLastLayerIndex = [[[controller canvas] layers] indexOfObject:[[controller canvas] lastActiveLayer]];
116			selectedRect = NSZeroRect;
117			if ([[controller canvas] hasSelection])
118			{
119				NSRect deselectRect = [[controller canvas] selectedRect];
120				[[controller canvas] deselect];
121				[[controller canvas] changedInRect:NSMakeRect(deselectRect.origin.x-2, deselectRect.origin.y-2, deselectRect.size.width+4, deselectRect.size.height+4)];
122			}
123		}
124		if (isAdding)
125		{
126			if (oldLastLayerIndex < [[[controller canvas] layers] count])
127			{
128				[[controller canvas] restoreActivateLayer:[[[controller canvas] layers] objectAtIndex:oldLayerIndex] lastActiveLayer:[[[controller canvas] layers] objectAtIndex:oldLastLayerIndex]];
129			}
130			else
131			{
132				[[controller canvas] restoreActivateLayer:[[[controller canvas] layers] objectAtIndex:oldLayerIndex] lastActiveLayer:nil];
133			}
134		}
135        [super mouseDownAt:aPoint fromCanvasController:controller];
136	}
137	[[self undoManager] endUndoGrouping];
138}
139
140- (void)mouseDraggedFrom:(NSPoint)initialPoint to:(NSPoint)finalPoint fromCanvasController:controller
141{
142	if(isMoving)
143	{
144		[[[controller canvas] activeLayer] translateXBy:(finalPoint.x - initialPoint.x) yBy:(finalPoint.y - initialPoint.y)];
145		[[controller canvas] changedInRect:NSMakeRect(0,0,[[controller canvas] size].width,[[controller canvas] size].height)];
146	}
147}
148
149- (void)mouseUpAt:(NSPoint)aPoint fromCanvasController:controller
150{
151	if(isMoving)
152	{
153		[self stopMovingCanvas:[controller canvas]];
154	}
155	else
156	{
157		NSEnumerator *enumerator = [selectedPoints objectEnumerator];
158		id current;
159		while  ( (current = [enumerator nextObject] ) )
160		{
161			if (isSubtracting)
162			{
163				NSPoint currentPoint = [current pointValue];
164				[[controller canvas] deselectPixelAtPoint:currentPoint];
165				if ([[controller canvas] pointIsSelected:currentPoint])
166				{
167					[[[controller canvas] lastActiveLayer] setColor:[[[[controller canvas] layers] lastObject] colorAtPoint:currentPoint] atPoint:currentPoint];
168				}
169				[[[[controller canvas] layers] lastObject] setColor:nil atPoint:currentPoint];
170			} else {
171				[[controller canvas] selectPixelAtPoint:[current pointValue]];
172			}
173		}
174		if (isSubtracting && NSEqualRects([[controller canvas] selectedRect], NSZeroRect))
175		{
176			[[controller canvas] deselect];
177		}
178		[[controller canvas] changedInRect:NSMakeRect(selectedRect.origin.x-2, selectedRect.origin.y-2, selectedRect.size.width+4, selectedRect.size.height+4)];
179		selectedRect = NSZeroRect;
180		[selectedPoints removeAllObjects];
181		[[controller canvas] finalizeSelection];
182	}
183}
184
185- (BOOL)point:(NSPoint)aPoint isUsefulForReplacing:oldColor inCanvas:aCanvas shouldCheckToTheLeft:(BOOL)check
186{
187    return  (([[NSUserDefaults standardUserDefaults] boolForKey:@"PXShouldTile"] ? YES : (aPoint.y < [aCanvas size].height)) &&
188			 ([[NSUserDefaults standardUserDefaults] boolForKey:@"PXShouldTile"] ? YES : (aPoint.y >= 0)) &&
189			 ([[aCanvas colorAtPoint:aPoint] isEqual:oldColor] &&
190			  (check ? ![[aCanvas colorAtPoint:NSMakePoint(aPoint.x-1, aPoint.y)] isEqual:oldColor] : YES)) &&
191			 (isSubtracting ? [aCanvas pointIsSelected:aPoint] : ![aCanvas pointIsSelected:aPoint]) &&
192			 ![selectedPoints containsObject:[PXPoint withNSPoint:aPoint]]);
193}
194
195- (void)activatePointWithOldColor:oldColor newColor:newColor atPoints:thisTimeFilled ofCanvas:aCanvas
196{
197    id enumerator = [thisTimeFilled objectEnumerator], current;
198	[selectedPoints addObjectsFromArray:thisTimeFilled];
199	while ( (current = [enumerator nextObject]) )
200    {
201		selectedRect = NSUnionRect(selectedRect, NSMakeRect([current pointValue].x, [current pointValue].y, 1, 1));
202		lastSelectedRect = selectedRect;
203    }
204}
205
206@end
207