// Copyright 1997-2000 Omni Development, Inc.  All rights reserved.
//
// This software may only be used and reproduced according to the
// terms in the file OmniSourceLicense.html, which should be
// distributed with this project and can also be found at
// http://www.omnigroup.com/DeveloperResources/OmniSourceLicense.html.

#import "OHColorPalette.h"

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <OmniBase/OmniBase.h>
#import <OmniFoundation/OmniFoundation.h>
#import <OmniAppKit/OmniAppKit.h>

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/Support.subproj/OHColorPalette.m,v 1.10 2000/01/20 00:27:58 kc Exp $")

const OHColorPaletteIndex OHColorPaletteFirstIndex = OHColorPaletteBackgroundIndex;

@implementation OHColorPalette

static OHColorPalette *defaultColorPalette = nil;
static NSLock *defaultColorPaletteLock;
static unsigned int cacheChangeCount = NSNotFound;
static BOOL alwaysUsePreferenceColors = NO;

+ (void)initialize;
{
    static BOOL initialized = NO;

    [super initialize];
    if (initialized)
	return;
    initialized = YES;

    defaultColorPaletteLock = [[NSLock alloc] init];
}

+ (OHColorPalette *)defaultPalette;
{
    OHColorPalette *colorPalette;
    OFUserDefaults *defaults;

    defaults = [OFUserDefaults sharedUserDefaults];

    [defaultColorPaletteLock lock];
    if (!defaultColorPalette || cacheChangeCount == NSNotFound || cacheChangeCount != [defaults changeCount]) {
	[defaultColorPalette release];
    
	defaultColorPalette = [[OHColorPalette alloc] init];
	cacheChangeCount = [defaults changeCount];
        [defaultColorPalette setBackgroundColor:[defaults colorForKey:@"OHBackgroundColor"]];
        [defaultColorPalette setTextColor:[defaults colorForKey:@"OHTextColor"]];
        [defaultColorPalette setLinkColor:[defaults colorForKey:@"OHLinkColor"]];
        [defaultColorPalette setVisitedLinkColor:[defaults colorForKey:@"OHCachedLinkColor"]];
        [defaultColorPalette setActiveLinkColor:[defaults colorForKey:@"OHHighlightedAnchorColor"]];
	[self setAlwaysUsePreferenceColors:[defaults boolForKey:@"OHAlwaysUsePreferenceColors"]];
    }
    colorPalette = [[defaultColorPalette retain] autorelease];
    [defaultColorPaletteLock unlock];
    return colorPalette;
}

+ (void)setAlwaysUsePreferenceColors:(BOOL)shouldAlwaysUsePreferenceColors;
{
    alwaysUsePreferenceColors = shouldAlwaysUsePreferenceColors;
}

+ (NSColor *)colorForString:(NSString *)colorString;
{
    return [OAColorPalette colorForString:colorString gamma:[[OFUserDefaults sharedUserDefaults] floatForKey:@"OIGammaCorrection"]];
}

+ (NSString *)stringForColor:(NSColor *)color;
{
#warning +stringForColor: does not reverse the gamma correction applied in +colorForString:
    return [OAColorPalette stringForColor:color];
}

- init;
{
    NSColor *textColor;
    unsigned int colorIndex;

    if (!(self = [super init]))
	return nil;

    textColor = [NSColor textColor];
    for (colorIndex = OHColorPaletteFirstIndex; colorIndex < OHColorPaletteIndexCount; colorIndex++)
        colorArray[colorIndex] = [textColor retain];
    [self setBackgroundColor:[NSColor textBackgroundColor]];
    [self setActiveLinkColor:[NSColor controlShadowColor]];

    return self;
}

- initAsCopy:(OHColorPalette *)template;
{
    unsigned int colorIndex;
    NSColor * const *templateColorArray;

    if (![self init])
	return nil;

    templateColorArray = [template colorArray];
    for (colorIndex = OHColorPaletteFirstIndex; colorIndex < OHColorPaletteIndexCount; colorIndex++) {
        [colorArray[colorIndex] release];
	colorArray[colorIndex] = [templateColorArray[colorIndex] copy];
    }
    hasExtraColor = template->hasExtraColor;
    return self;
}

- (void)dealloc;
{
    unsigned int colorIndex;

    for (colorIndex = OHColorPaletteFirstIndex; colorIndex < OHColorPaletteIndexCount; colorIndex++)
	[colorArray[colorIndex] release];
    [super dealloc];
}

- (id)copy;
{
    return [[isa alloc] initAsCopy:self];
}

- (id)copyWithZone:(NSZone *)newZone
{
    return [[isa allocWithZone:newZone] initAsCopy:self];
}

- (NSColor *)backgroundColor;
{
    return colorArray[OHColorPaletteBackgroundIndex];
}

- (NSColor *)textColor;
{
    return colorArray[OHColorPaletteTextIndex];
}

- (NSColor *)linkColor;
{
    return colorArray[OHColorPaletteLinkIndex];
}

- (NSColor *)visitedLinkColor;
{
    return colorArray[OHColorPaletteVisitedLinkIndex];
}

- (NSColor *)activeLinkColor;
{
    return colorArray[OHColorPaletteActiveLinkIndex];
}

- (void)setBackgroundColor:(NSColor *)aColor;
{
    if (aColor == nil)
        return;
    [colorArray[OHColorPaletteBackgroundIndex] release];
    colorArray[OHColorPaletteBackgroundIndex] = [aColor copy];
}

- (void)setTextColor:(NSColor *)aColor;
{
    if (aColor == nil)
        return;
    [colorArray[OHColorPaletteTextIndex] release];
    colorArray[OHColorPaletteTextIndex] = [aColor copy];
}

- (void)setLinkColor:(NSColor *)aColor;
{
    if (aColor == nil)
        return;
    [colorArray[OHColorPaletteLinkIndex] release];
    colorArray[OHColorPaletteLinkIndex] = [aColor copy];
}

- (void)setVisitedLinkColor:(NSColor *)aColor;
{
    if (aColor == nil)
        return;
    [colorArray[OHColorPaletteVisitedLinkIndex] release];
    colorArray[OHColorPaletteVisitedLinkIndex] = [aColor copy];
}

- (void)setActiveLinkColor:(NSColor *)aColor;
{
    if (aColor == nil)
        return;
    [colorArray[OHColorPaletteActiveLinkIndex] release];
    colorArray[OHColorPaletteActiveLinkIndex] = [aColor copy];
}

- (void)setExtraColor:(NSColor *)aColor;
{
    if (aColor == nil) {
        return;
    }
    [colorArray[OHColorPaletteExtraIndex] release];
    colorArray[OHColorPaletteExtraIndex] = [aColor copy];
    hasExtraColor = YES;
}

- (void)unsetExtraColor;
{
    hasExtraColor = NO;
}

- (NSColor *)anchorColor;
{
    return [self textColor];
}

- (NSColor * const *)colorArray;
{
    return colorArray;
}

- (NSColor *)colorAtColorIndex:(OHColorPaletteIndex)colorIndex;
{
    return colorArray[colorIndex];
}

@end

#import <OWF/OWF.h>

@implementation OHColorPalette (ColorTag)

- (id)copyWithChangesFromTag:(OWSGMLTag *)tag bgColorAttributeIndex:(unsigned int)bgColorAttributeIndex textAttributeIndex:(unsigned int)textAttributeIndex linkAttributeIndex:(unsigned int)linkAttributeIndex vlinkAttributeIndex:(unsigned int)vlinkAttributeIndex alinkAttributeIndex:(unsigned int)alinkAttributeIndex;
{
    NSString *bgcolor, *text, *link, *vlink, *alink;
    OHColorPalette *newColorPalette;

    if (alwaysUsePreferenceColors)
	return [self retain];

    if (sgmlTagAttributePresentAtIndex(tag, bgColorAttributeIndex)) {
	bgcolor = sgmlTagValueForAttributeAtIndex(tag, bgColorAttributeIndex);
	if (!bgcolor)
	    bgcolor = @"#000000";
    } else
	bgcolor = nil;

    if (sgmlTagAttributePresentAtIndex(tag, textAttributeIndex)) {
	text = sgmlTagValueForAttributeAtIndex(tag, textAttributeIndex);
	if (!text)
	    text = @"#000000";
    } else
	text = nil;

    link = sgmlTagValueForAttributeAtIndex(tag, linkAttributeIndex);
    vlink = sgmlTagValueForAttributeAtIndex(tag, vlinkAttributeIndex);
    alink = sgmlTagValueForAttributeAtIndex(tag, alinkAttributeIndex);

    if (!(bgcolor || text || link || vlink || alink))
	return [self retain];

    newColorPalette = [self copy];

    if (bgcolor)
	[newColorPalette setBackgroundColor:[isa colorForString:bgcolor]];
    if (text)
	[newColorPalette setTextColor:[isa colorForString:text]];
    if (link)
	[newColorPalette setLinkColor:[isa colorForString:link]];
    if (vlink)
	[newColorPalette setVisitedLinkColor:[isa colorForString:vlink]];
    if (alink)
	[newColorPalette setActiveLinkColor:[isa colorForString:alink]];

    return newColorPalette;
}

@end
