#import "drawundo.h"

/*
 * Please refer to external documentation about Draw
 * with Undo for information about what GraphicsChange 
 * is and where it fits in.
 */

@interface GraphicsChange(PrivateMethods)

- undoDetails;
- redoDetails;

@end

@implementation GraphicsChange

- initGraphicView:aGraphicView
{
    [super init];
    graphicView = aGraphicView;
    graphics = nil;
    changeDetails = nil;

    return self;
}

- free
{
    [graphics free];
    if (changeDetails != nil) {
	[changeDetails freeObjects];
	[changeDetails free];
    }

    return [super free];
}

- saveBeforeChange
{
    List *selectedGraphics;
    int i, count;
    id changeDetailClass, changeDetail;
    BOOL changeExpected = NO;

    selectedGraphics = [graphicView selectedGraphics];
    count = [selectedGraphics count];
    if (count == 0) {
        [self disable];
    } else {
	changeDetailClass = [self changeDetailClass];
	if (changeDetailClass != nil)
	    changeDetails = [[List alloc] init];
	else
	    changeExpected = YES;
	graphics = [[List alloc] init];
	for (i = 0; i < count; i++) {
	    [graphics addObject:[selectedGraphics objectAt:i]];
	    if (changeDetailClass != nil) {
		changeDetail = [[changeDetailClass alloc] initGraphic:[selectedGraphics objectAt:i] change:self];
		changeExpected = changeExpected || [changeDetail changeExpected];
		[changeDetails addObject:changeDetail];
	    }
	}
    }
    
    if (!changeExpected)
        [self disable];
	
    return self;
}

- undoChange
{
    $phicView redrawGraphics:graphics afterChangeAgent:self performs:@selector(undoDetails)];
    [[graphicView window] flushWindow];
    [[[NXApp inspectorPanel] delegate] loadGraphic:[graphicView selectedGraphic]]; 

    return [super undoChange];
}

- redoChange
{
    [graphicView redrawGraphics:graphics afterChangeAgent:self performs:@selector(redoDetails)];
    [[graphicView window] flushWindow];
    [[[NXApp inspectorPanel] delegate] loadGraphic:[graphicView selectedGraphic]]; 

    return [super redoChange];
}

- changeDetailClass
/*
 * To be overridden 
 */
{
    return [ChangeDetail class];
}

- undoDetails
/*
 * To be overridden 
 */
{
    return self;
}

- redoDetails
/*
 * To be overridden 
 */
{
    return self;
}

@end
