#import "draw.h"

@interface Inspector(PrivateMethods)

- reloadGraphic:(Graphic *)graphic;
- loadOrReloadGraphic:(Graphic *)graphic;

@end

@implementation Inspector

static void setTitle(Button *button, int row)
{
    [button setTitle:[[[[button target] itemList] cellAt:row :0] title]];
    [[[button target] itemList] selectCellAt:row :0];
}

- reloadGraphic:(Graphic *)graphic
/*
 * Loads up the size fields if they have changed since last time
 * we loaded up the panel with this graphic.  This is used since we
 * know that none of the things controlled by the InspectorPanel
 * except the size or the fill color can change from event to event
 * (we should probably not make that assumption, but it makes the
 * updating of this panel go much faster and since it has to happen
 * on every event, it seems a worthwhile optimization).
 */
{
    NXRect bounds;

    if (!graphic) return self;
    [graphic getBounds:&bounds];
    if (lastSize.width != bounds.size.width) {
	[width setFloatValue:bounds.size.width];
	lastSize.width = bounds.size.width;
    }
    if (lastSize.height != bounds.size.height) {
	[height setFloatValue:bounds.size.height];
	lastSize.height = bounds.size.height;
    }
    if ([graphic fill] != [[[filled target] itemList] selectedRow]) setTitle(filled, [graphic fill]);
    if (graphic && !NXEqualColor([fillColor color], [graphic fillColor])) [fillColor setColor:[graphic fillColor]];

    return self;
}

- loadOrReloadGraphic:(Graphic *)graphic
{
    if (selectedGraphic == graphic) 
        return [self reloadGraphic:graphic];
    else
        return [self loadGraphic:graphic];
}

- loadGraphic:(Graphic *)graphic
/*
 * Loads up the InspectorPanel with a new graphic's attributes.
 */
{
    NXRect bounds;

    selectedGraphic = graphic;
    if (!selectedGraphic) return self;

    [lineWidthField setFloatValue:[graphic lineWidth]];
    [lineWidthSlider setFloatValue:[graphic lineWidth]];
    [lineColor setColor:[graphic lineColor]];
    [fillColor setColor:[graphic fillColor]];
    [graphic getBounds:&bounds];
    [width setFloatValue:bounds.size.width];
    [height setFloatValue:bounds.size.height];
    lastSize = bounds.size;
    setTitle(filled, [graphicRVl]);
    setTitle(lineCap, [graphic lineCap]);
    setTitle(arrows, [graphic lineArrow]);
    setTitle(lineJoin, [graphic lineJoin]);
    [formEntry setIntValue:[graphic isFormEntry]];

    return self;
}

- load:(GraphicView *)view
/*
 * If the view has only one selected graphic, then the panel is loaded with it.
 */
{
    graphicView = view;
    [self loadOrReloadGraphic:[view selectedGraphic]];
    return self;
}

- initializeGraphic:(Graphic *)graphic
/*
 * Goes the opposite way of loadGraphic.  Gives the Graphic the attributes
 * which are in the InspectorPanel.
 */
{
    float value;
    const char *s;
    NXColor color;

    s = [lineWidthField stringValue];
    if (s && s[0] && (value = atof(s))) [graphic setLineWidth:&value];
    color = [lineColor color];
    [graphic setLineColor:&color];
    color = [fillColor color];
    [graphic setFillColor:&color];
    [graphic setFill:[[[filled target] itemList] selectedRow]];
    [graphic setLineCap:[[[lineCap target] itemList] selectedRow]];
    [graphic setLineArrow:[[[arrows target] itemList] selectedRow]];
    [graphic setLineJoin:[[[lineJoin target] itemList] selectedRow]];

    return self;
}

- preset
{
    [fillColor setColor:NX_COLORWHITE];
    [lineColor setColor:NX_COLORBLACK];
    return self;
}

/* Overridden from superclass */

- windowDidUpdate:(Window *)sender
/*
 * Called each time an event occurs.  Loads up the panel.
 */
{
    [self load:[[NXApp currentDocument] view]];
    return self;
}

- changeContinuous:sender
{
    [[NXColorPanel sharedInstance:NO] setContinuous:([sender intValue] ? YES : NO)];
    return self;
}

/* Target/Action methods */

- changeFormEntry:sender
{
    [graphicView takeFormEntryStatusFrom:formEntry];
    return self;
}

- changeFilled:sender
{
    [graphicView takeFillValueFrom:[[filled target] itemList]];
    return self;
}

- changeLineCap:sender
{
    [graphicView takeLineCapFrom:[[lineCap target] itemList]];
    return self;
}

- changeArrows:sender
{
    [graphicView takeLineArrowFrom:[[arrows target] itemList]];
    return self;
}

- changeLineJoin:sender
{
    [graphicView takeLineJoinFrom:[[lineJoin target] itemList]];
    [[graphicView window] makeKeyWindow];
    return self;
}

- changeLineWidth:sender
{
    float linewidth;

    linewidth = [sender floatValue];
    if (sender == lineWidthSlider) {
	iRVNXApp currentEvent]->type == NX_MOUSEDRAGGED) {
	    [[graphicView selectedGraphics] makeObjectsPerform:@selector(deselect)];
	} else {
	    [[graphicView selectedGraphics] makeObjectsPerform:@selector(select)];
	}
	[lineWidthField setFloatValue:linewidth];
    } else {
	if ([lineWidthSlider maxValue] < linewidth) {
	    [lineWidthSlider setMaxValue:linewidth];
	}
	[lineWidthSlider setFloatValue:linewidth];
	[[graphicView window] makeKeyWindow];
    }
    [graphicView takeLineWidthFrom:lineWidthField];
    return self;
}

- changeLineColor:sender
{
    [graphicView takeLineColorFrom:sender];
    return self;
}

- changeFillColor:sender
{
    [graphicView takeFillColorFrom:sender];
    if ([[[filled target] itemList] selectedRow] == 0)
        setTitle(filled, 2);
    return self;
}

- changeDimensions:sender
{
    NXSize size;
    id change;

    size.width = [width floatValue];
    size.height = [height floatValue];
    change = [[DimensionsGraphicsChange alloc] initGraphicView:graphicView];
    [change startChange];
	[graphicView graphicsPerform:@selector(sizeTo:) with:&size];
	[[[graphicView window] flushWindow] makeKeyWindow];
    [change endChange];

    return self;
}

- setFilled:anObject
{
    Matrix *matrix = [[anObject target] itemList];
    [matrix setTarget:self];
    [matrix setAction:@selector(changeFilled:)];
    [matrix selectCellAt:0 :0];
    filled = anObject;
    return self;
}

- setLineJoin:anObject
{
    Matrix *matrix = [[anObject target] itemList];
    [matrix setTarget:self];
    [matrix setAction:@selector(changeLineJoin:)];
    [matrix selectCellAt:0 :0];
    lineJoin = anObject;
    return self;
}

- setLineCap:anObject
{
    Matrix *matrix = [[anObject target] itemList];
    [matrix setTarget:self];
    [matrix setAction:@selector(changeLineCap:)];
    [matrix selectCellAt:0 :0];
    lineCap = anObject;
    return self;
}

- setArrows:anObject
{
    Matrix *matrix = [[anObject target] itemList];
    [matrix setTarget:self];
    [matrix setAction:@selector(changeArrows:)];
    [matrix selectCellAt:0 :0];
    arrows = anObject;
    return self;
}

@end
