// Copyright 1998-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 "OHAbstractTextRow.h"

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

#import "OHHTMLView.h"
#import "OHWord.h"

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/View.subproj/OHAbstractTextRow.m,v 1.11 2000/01/20 00:28:03 kc Exp $")

@implementation OHAbstractTextRow

- (NSParagraphStyle *)paragraphStyleInHTMLView:(OHHTMLView *)htmlView;
{
    return [[htmlView textStorage] attribute:NSParagraphStyleAttributeName atIndex:((OHWord *)[[htmlView words] objectAtIndex:wordRange.location])->characterRange.location effectiveRange:NULL];
}

// Debugging

- (NSMutableDictionary *)debugDictionary;
{
    NSMutableDictionary *debugDictionary;

    debugDictionary = [super debugDictionary];
    [debugDictionary setObject:NSStringFromRange(wordRange) forKey:@"wordRange"];
    [debugDictionary setObject:NSStringFromRect(bounds) forKey:@"bounds"];
    [debugDictionary setObject:[NSString stringWithFormat:@"%0.1f", maxAscent] forKey:@"maxAscent"];
    return debugDictionary;
}

@end

@implementation OHAbstractTextRow (SubclassesOnly)

- (void)getLineHeightAndAscentForAttributes:(NSDictionary **)attributes attributesRange:(NSRange *)attributesRange inHTMLView:(OHHTMLView *)htmlView;
{
    OFStaticArray *words;
    NSTextStorage *textStorage;
    NSRange characterRange;
    OHWord *word;
    NSParagraphStyle *paragraphStyle;
    float maxDescent = 0;
    float minimumLineHeight;

    OBASSERT(wordRange.length > 0);

    words = [htmlView words];
    textStorage = [htmlView textStorage];

    bounds.size.height = 0;
    maxAscent = 0;
    
    characterRange.location = ((OHWord *)[words objectAtIndex:wordRange.location])->characterRange.location;
    // Don't include final return in ascent and descent calculations for paragraphs that are more than just a single return
    word = (OHWord *)[words objectAtIndex:NSMaxRange(wordRange) - 1];
    if (word->type == OHWordTypeReturn && wordRange.length > 1)
        word = (OHWord *)[words objectAtIndex:NSMaxRange(wordRange) - 2];
    characterRange.length = NSMaxRange(word->characterRange) - characterRange.location;


    while (NSMaxRange(*attributesRange) <= characterRange.location)
        *attributes = [textStorage attributesAtIndex:NSMaxRange(*attributesRange) effectiveRange:attributesRange];

    paragraphStyle = [*attributes objectForKey:NSParagraphStyleAttributeName];
    minimumLineHeight = [paragraphStyle minimumLineHeight];

    while (1) {
        NSNumber *baselineOffsetNumber;
        float baselineOffset = 0.0;
        OHBasicCell * attachmentCell;


        baselineOffsetNumber = [*attributes objectForKey:NSBaselineOffsetAttributeName];
        if (baselineOffsetNumber)
            baselineOffset = [baselineOffsetNumber floatValue];

        attachmentCell = (OHBasicCell *)[[*attributes objectForKey:NSAttachmentAttributeName] attachmentCell];
        if (attachmentCell) {
            [self getMaxAscent:&maxAscent andMaxDescent:&maxDescent forAttachmentCell:attachmentCell baselineOffset:baselineOffset attributes:*attributes];
        } else {
            NSFont *font;
            NSRect boundingBox;

            font = [*attributes objectForKey:NSFontAttributeName];
            boundingBox = NSIntegralRect([font boundingRectForFont]);

            maxAscent = MAX(maxAscent, NSMaxY(boundingBox) + baselineOffset);
            maxDescent = MIN(maxDescent, NSMinY(boundingBox) + baselineOffset);
        }

        if (NSMaxRange(*attributesRange) >= NSMaxRange(characterRange))
            break;

        *attributes = [textStorage attributesAtIndex:NSMaxRange(*attributesRange) effectiveRange:attributesRange];
    }

    maxAscent = MAX(minimumLineHeight - -maxDescent, maxAscent);

    bounds.size.height = maxAscent + -maxDescent;
}

- (void)getMaxAscent:(float *)ascent andMaxDescent:(float *)descent forAttachmentCell:(OHBasicCell *)attachmentCell baselineOffset:(float)baselineOffset attributes:(NSDictionary *)attributes;
{
    NSSize cellSize;
    NSPoint cellBaselineOffset;

    cellSize = [attachmentCell cellSize];
    cellBaselineOffset = [attachmentCell cellBaselineOffset];

    *ascent = MAX(*ascent, cellSize.height + cellBaselineOffset.y + baselineOffset);
    *descent = MIN(*descent, cellBaselineOffset.y + baselineOffset);
}

@end
