// Copyright 1994 Scott Hess.  Permission to use, copy, modify,
// and distribute this software and its documentation for any
// purpose and without fee is hereby granted, provided that this
// copyright notice appear in all copies.
// 
// Scott Hess makes no representations about the suitability of
// this software for any purpose.  It is provided "as is" without
// express or implied warranty.
//
#import "TimeMonColors.h"
#import "AppDefaults.h"
#import "TimeMonWraps.h"

@interface TextFieldCell (TimeMonTextFieldCell)
- setColor:(NXColor)color;
@end
@implementation TimeMonColors
    // Have to set up the cells and stuff manually since we're a
    // custom view.
- initFrame:(const NXRect *)frameRect
{
    self=[super initFrame:frameRect mode:0 cellClass:[TextFieldCell class] numRows:1 numCols:4];
    if( self) {
	NXSize size={ 1, frameRect->size.height};
	[self setIntercell:&size];
	size.width=((int)frameRect->size.width-3)/4;
	[self setCellSize:&size];
	[self setAutosizeCells:YES];
	[self setFlipped:NO];
    }
    return self;
}
static const char *titles[]={
    "Idle", "Nice", "User", "System",
};
    // Read the colors for each field and stuff them into it.
- readColors
{
    char buf[ 32];
    int i;
    BOOL shouldDrawColor=[self shouldDrawColor];
    for( i=0; i<4; i++) {
	TextFieldCell *tCell=[self cellAt:0 :i];
	[tCell setStringValue:titles[ i]];
	    // If self is in a color window, then load color
	    // information.
	if( shouldDrawColor) {
	    sprintf( buf, "%sColor", titles[ i]);
	    [tCell setColor:[NXApp defaultAsColor:buf]];
	    
	    // Otherwise, load grayscale information.
	} else {
	    sprintf( buf, "%sGray", titles[ i]);
	    [tCell setColor:NXConvertGrayAlphaToColor( [NXApp defaultAsFloat:buf], 1.0)];
	}
	[tCell setBezeled:YES];
	[tCell setAlignment:NX_CENTERED];
    }
    return self;
}
    // Accept color drops, redraw the field it was dropped over,
    // save the new color setting, and kick the icon view to
    // redisplay.
- acceptColor:(NXColor)color atPoint:(NXPoint *)aPoint
{
    char buf[ 32];
    int row, col;
    NXPoint loc=*aPoint;
    TextFieldCell *tCell;
    
	// Find the cell for the point.
    [self convertPoint:&loc fromView:nil];
    [self getRow:&row andCol:&col forPoint:&loc];
    tCell=[self cellAt:row :col];
    
	// Set the color for the cell and redraw it.
    [tCell setColor:color];
    [self lockFocus];
    [self drawCellInside:tCell];
    [window flushWindow];
    [self unlockFocus];
    
	// If self is in a color window, save color information.
    if( [self shouldDrawColor]) {
	sprintf( buf, "%sColor", titles[ col]);
	[NXApp default:buf asColor:color];
	
	// Otherwise, save grayscale information.
    } else {
	float gray, alpha;
	NXConvertColorToGrayAlpha( color, &gray, &alpha);
	sprintf( buf, "%sGray", titles[ col]);
	[NXApp default:buf asFloat:gray];
    }
    
	// Redraw the application icon.
    [[NXApp delegate] display];
    return self;
}
    // Intercept the mousedown and cause it to drag a color.  If
    // double-click, pull up the color panel.
- mouseDown:(NXEvent *)e
{
    NXPoint loc=e->location;
    int row, col;
    NXColor color;
    
	// Find the color of the cell the click is in.
    [self convertPoint:&loc fromView:nil];
    [self getRow:&row andCol:&col forPoint:&loc];
    color=[[self cellAt:row :col] backgroundColor];
    
	// If it's a double-click, load the color into the color
	// panel and bring that panel up.
    if( e->data.mouse.click>1) {
	[[[NXColorPanel new] setColor:color] orderFront:nil];
    } else {
	NXEvent theEvent=*e;
	int mask=[window addToEventMask:(NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK)];
	    // Get the next mouse up or dragged event.
	e=[NXApp getNextEvent:(NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK)];
	[window setEventMask:mask];
	
	    // If it was a drag, initiate the color drag from
	    // ourselves.
	if( e && e->type==NX_MOUSEDRAGGED) {
	    [NXColorPanel dragColor:color withEvent:&theEvent fromView:self];
	}
    }
    return self;
}
@end
@implementation TextFieldCell (TimeMonTextFieldCell)
    // Set the colors for the field.  Adjust the foreground color
    // so that it's visible against the background.
- setColor:(NXColor)color
{
    float gray;
    float r, g, b;
	// Remove any alpha component.
    color=NXChangeAlphaComponent( color, NX_NOALPHA);
    
	// Get the grayscale version.
    gray=NXGrayComponent( color);
    
	// Set the text to be visible.
    [self setTextGray:gray<0.33 ? NX_WHITE : NX_BLACK];
    
	// Set the color and gray for the field.
    [self setBackgroundColor:color];
    [self setBackgroundGray:gray];
    
	// Tell the windowserver code that we want to use this
	// color for drawing the appropriate element.  [Note that
	// stringValue should be one of "Idle", "Nice", "User", or
	// "System".]
    NXConvertColorToRGBA( color, &r, &g, &b, NULL);
    setColor( (char *)[self stringValue], r, g, b);
    return self;
}
@end
