// 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 "OHHTMLDisplayProcessor.h"

#import <Foundation/Foundation.h>
#import <OmniBase/OmniBase.h>
#import <OmniFoundation/OmniFoundation.h>
#import <OWF/OWF.h>

#import "OWSGMLDTD-OHHTMLDTD.h"
#import "OHTextBuilder.h"

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/Building.subproj/OHHTMLDisplayProcessor-CharacterStyles.m,v 1.3 2000/01/20 00:27:45 kc Exp $")

@implementation OHHTMLDisplayProcessor (CharacterStyles)

static OWSGMLTagType *boldTagType;
static OWSGMLTagType *baseFontTagType;
static OWSGMLTagType *bigTagType;
static OWSGMLTagType *citeTagType;
static OWSGMLTagType *codeTagType;
static OWSGMLTagType *dfnTagType;
static OWSGMLTagType *emTagType;
static OWSGMLTagType *fontTagType;
static OWSGMLTagType *iTagType;
static OWSGMLTagType *kbdTagType;
static OWSGMLTagType *nobrTagType;
static OWSGMLTagType *sampTagType;
static OWSGMLTagType *smallTagType;
static OWSGMLTagType *strongTagType;
static OWSGMLTagType *subTagType;
static OWSGMLTagType *supTagType;
static OWSGMLTagType *ttTagType;
static OWSGMLTagType *uTagType;
static OWSGMLTagType *varTagType;
static OWSGMLTagType *wbrTagType;

static unsigned int baseFontSizeAttributeIndex;
static unsigned int baseFontFaceAttributeIndex;
static unsigned int fontSizeAttributeIndex;
static unsigned int fontColorAttributeIndex;
static unsigned int fontFaceAttributeIndex;

+ (void)didLoad;
{
    OWSGMLDTD *dtd;
    OWSGMLMethods *methods;

    dtd = [self dtd];

    boldTagType = [dtd tagTypeNamed:@"b"];
    baseFontTagType = [dtd tagTypeNamed:@"basefont"];
    bigTagType = [dtd tagTypeNamed:@"big"];
    citeTagType = [dtd tagTypeNamed:@"cite"];
    codeTagType = [dtd tagTypeNamed:@"code"];
    dfnTagType = [dtd tagTypeNamed:@"dfn"];
    emTagType = [dtd tagTypeNamed:@"em"];
    fontTagType = [dtd tagTypeNamed:@"font"];
    iTagType = [dtd tagTypeNamed:@"i"];
    kbdTagType = [dtd tagTypeNamed:@"kbd"];
    nobrTagType = [dtd tagTypeNamed:@"nobr"];
    sampTagType = [dtd tagTypeNamed:@"samp"];
    smallTagType = [dtd tagTypeNamed:@"small"];
    strongTagType = [dtd tagTypeNamed:@"strong"];
    subTagType = [dtd tagTypeNamed:@"sub"];
    supTagType = [dtd tagTypeNamed:@"sup"];
    ttTagType = [dtd tagTypeNamed:@"tt"];
    uTagType = [dtd tagTypeNamed:@"u"];
    varTagType = [dtd tagTypeNamed:@"var"];
    wbrTagType = [dtd tagTypeNamed:@"wbr"];

    baseFontSizeAttributeIndex = [baseFontTagType addAttributeNamed:@"size"];
    baseFontFaceAttributeIndex = [baseFontTagType addAttributeNamed:@"face"];
    fontSizeAttributeIndex = [fontTagType addAttributeNamed:@"size"];
    fontColorAttributeIndex = [fontTagType addAttributeNamed:@"color"];
    fontFaceAttributeIndex = [fontTagType addAttributeNamed:@"face"];

    methods = [self sgmlMethods];

    [methods registerMethod:@"Bold" forTagName:@"b"];
    [methods registerMethod:@"EndBold" forEndTagName:@"b"];
    [methods registerMethod:@"BaseFont" forTagName:@"basefont"];
    [methods registerMethod:@"Big" forTagName:@"big"];
    [methods registerMethod:@"Italic" forTagName:@"cite"];
    [methods registerMethod:@"EndItalic" forEndTagName:@"cite"];
    [methods registerMethod:@"Teletype" forTagName:@"code"];
    [methods registerMethod:@"Italic" forTagName:@"dfn"];
    [methods registerMethod:@"EndItalic" forEndTagName:@"dfn"];
    [methods registerMethod:@"Italic" forTagName:@"em"];
    [methods registerMethod:@"EndItalic" forEndTagName:@"em"];
    [methods registerMethod:@"Font" forTagName:@"font"];
    [methods registerMethod:@"EndFont" forEndTagName:@"font"];
    [methods registerMethod:@"Italic" forTagName:@"i"];
    [methods registerMethod:@"EndItalic" forEndTagName:@"i"];
    [methods registerMethod:@"Teletype" forTagName:@"kbd"];
    [methods registerMethod:@"NoBreak" forTagName:@"nobr"];
    [methods registerMethod:@"Teletype" forTagName:@"samp"];
    [methods registerMethod:@"Small" forTagName:@"small"];
    [methods registerMethod:@"Bold" forTagName:@"strong"];
    [methods registerMethod:@"EndBold" forEndTagName:@"strong"];
    [methods registerMethod:@"Subscript" forTagName:@"sub"];
    [methods registerMethod:@"Superscript" forTagName:@"sup"];
    [methods registerMethod:@"Teletype" forTagName:@"tt"];
    [methods registerMethod:@"Underline" forTagName:@"u"];
    [methods registerMethod:@"EndUnderline" forEndTagName:@"u"];
    [methods registerMethod:@"Italic" forTagName:@"var"];
    [methods registerMethod:@"EndItalic" forEndTagName:@"var"];
    [methods registerMethod:@"WordBreak" forTagName:@"wbr"];
}

- (void)processBaseFontTag:(OWSGMLTag *)tag;
{
    NSString *size;
    NSString *fontFacesString;
    NSArray *fontFaces;

    size = sgmlTagValueForAttributeAtIndex(tag, baseFontSizeAttributeIndex);
    if (size)
        [textBuilder setBaseFontSizeIndex:[size intValue]];

    fontFacesString = sgmlTagValueForAttributeAtIndex(tag, baseFontFaceAttributeIndex);
    if (fontFacesString) {
        fontFaces = [[fontFacesString stringByRemovingString:@" "] componentsSeparatedByString:@","];
        [textBuilder setFontFaceOverrideFromNameArray:fontFaces];
    }
}

- (void)processFontTag:(OWSGMLTag *)tag;
{
    NSString *sizeString;
    NSString *colorString;
    NSString *fontFacesString;

    [textBuilder pushFontStyle];

    // Size
    sizeString = sgmlTagValueForAttributeAtIndex(tag, fontSizeAttributeIndex);
    if (sizeString) {
        int sizeIndex;

        sizeIndex = [sizeString intValue];
	if ([sizeString hasPrefix:@"+"] || [sizeString hasPrefix:@"-"])
	    [textBuilder setRelativeFontSizeIndex:sizeIndex];
	else
	    [textBuilder setFontSizeIndex:sizeIndex];
    }

    // Color
    colorString = sgmlTagValueForAttributeAtIndex(tag, fontColorAttributeIndex);
    if (colorString && !flags.alwaysUsePreferenceColors)
	[textBuilder setTextColorOverride:[OHColorPalette colorForString:colorString]];

    // Face
    fontFacesString = sgmlTagValueForAttributeAtIndex(tag, fontFaceAttributeIndex);
    if (fontFacesString) {
        NSArray *fontFaces;

        fontFaces = [[fontFacesString stringByRemovingString:@" "] componentsSeparatedByString:@","];
        [textBuilder setFontFaceOverrideFromNameArray:fontFaces];
    }
}

- (void)processEndFontTag:(OWSGMLTag *)tag;
{
    [textBuilder popFontStyle];
}

- (void)processBigTag:(OWSGMLTag *)tag;
{
    int oldFontSizeIndex;

    oldFontSizeIndex = [textBuilder setRelativeFontSizeIndex:1];
    [self processContentForTag:tag];
    [textBuilder setFontSizeIndex:oldFontSizeIndex];
}

- (void)processNoBreakTag:(OWSGMLTag *)tag;
{
    BOOL oldNoWrapMode;

    oldNoWrapMode = [textBuilder setNoWrapMode:YES];
    [self processContentForTag:tag];
    [textBuilder setNoWrapMode:oldNoWrapMode];
}

- (void)processWordBreakTag:(OWSGMLTag *)tag;
{
    [textBuilder writeProcessedCharacter:ZERO_WIDTH_SPACE];
}

- (void)processSmallTag:(OWSGMLTag *)tag;
{
    int oldFontSizeIndex;

    oldFontSizeIndex = [textBuilder setRelativeFontSizeIndex:-1];
    [self processContentForTag:tag];
    [textBuilder setFontSizeIndex:oldFontSizeIndex];
}

- (void)processSubscriptTag:(OWSGMLTag *)tag;
{
    int oldFontSizeIndex;
    float fontSize;

    oldFontSizeIndex = [textBuilder setRelativeFontSizeIndex:-1];
    fontSize = [textBuilder fontSize];
    [textBuilder changeBaselineOffsetBy:-fontSize/2];
    [self processContentForTag:tag];
    [textBuilder changeBaselineOffsetBy:fontSize/2];
    [textBuilder setFontSizeIndex:oldFontSizeIndex];
}


- (void)processSuperscriptTag:(OWSGMLTag *)tag;
{
    int oldFontSizeIndex;
    float fontSize;

    fontSize = [textBuilder fontSize];
    oldFontSizeIndex = [textBuilder setRelativeFontSizeIndex:-1];
    [textBuilder changeBaselineOffsetBy:fontSize/2];
    [self processContentForTag:tag];
    [textBuilder changeBaselineOffsetBy:-fontSize/2];
    [textBuilder setFontSizeIndex:oldFontSizeIndex];
}

//

- (void)processBoldTag:(OWSGMLTag *)tag;
{
    [textBuilder startBold];
}

- (void)processEndBoldTag:(OWSGMLTag *)tag;
{
    [textBuilder stopBold];
}

- (void)processItalicTag:(OWSGMLTag *)tag;
{
    [textBuilder startItalic];
}

- (void)processEndItalicTag:(OWSGMLTag *)tag;
{
    [textBuilder stopItalic];
}

- (void)processTeletypeTag:(OWSGMLTag *)tag;
{
    OWFontStyle oldFontStyle;
    
    oldFontStyle = [textBuilder setFontStyle:FONTSTYLE_FIXEDPITCH];
    [self processContentForTag:tag];
    [textBuilder setFontStyle:oldFontStyle];
}

- (void)processUnderlineTag:(OWSGMLTag *)tag;
{
    [textBuilder startUnderlining];
}

- (void)processEndUnderlineTag:(OWSGMLTag *)tag;
{
    [textBuilder stopUnderlining];
}


@end
