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

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

RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniHTML/ImageMap.subproj/OHImageMapPolygon.m,v 1.5 2000/01/20 00:27:54 kc Exp $")

@implementation OHImageMapPolygon

+ (void)didLoad
{
    [self registerClass:self forShapeName:@"poly"];
    [self registerClass:self forShapeName:@"polygon"];
}

- (void)dealloc;
{
    if (points)
	NSZoneFree(NSZoneFromPointer(points), points);
    [super dealloc];
}

- (void)setCoordinates:(NSArray *)pointsArray;
{
    unsigned int pointIndex;

    boundingRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
    pointCount = [pointsArray count] / 2;
    if (pointCount < 3)
	return;

    points = NSZoneMalloc([self zone], pointCount * 2 * sizeof(NSPoint));
    for (pointIndex = 0; pointIndex < pointCount; pointIndex++) {
	points[pointIndex].x = [[pointsArray objectAtIndex:pointIndex * 2]
				intValue];
	points[pointIndex].y = [[pointsArray objectAtIndex:pointIndex * 2 + 1]
				intValue];
	if (pointIndex == 0) {
	    boundingRect = NSMakeRect(points[pointIndex].x, points[pointIndex].y, 1.0, 1.0);
	} else {
	    NSRect		newRect;
	    
	    newRect = NSMakeRect(points[pointIndex].x, points[pointIndex].y, 1.0, 1.0);
	    boundingRect = NSUnionRect(newRect, boundingRect);
	}
    }
}

#warning Polygon image map code has not been tested
// TODO: see if this actually works (wim)
- (BOOL)containsPoint:(NSPoint)point;
{
    BOOL inside;
    unsigned int pointIndex;
    NSPoint a, b;
    
    if (!NSPointInRect(point, boundingRect)) {
	return NO;
    }
    
    // Calculate containment by odd-winding rule. TODO: Check whether we have to do nonzero-winding-rule or something.
    
    inside = NO;    
    
    for(pointIndex = 0; pointIndex < pointCount; pointIndex ++) {
        a = points[pointIndex];
	if (pointIndex == pointCount-1)
	    b = points[0];
	else
	    b = points[pointIndex+1];
	
	// take care of the edge cases
	if (a.y > b.y) {
	    NSPoint t = a;
	    a = b;
	    b = t;
	} else if (a.y == b.y) {
	    continue;
	}
	
	if (a.y <= point.y && b.y > point.y) {
            if ((point.x-b.x) * (a.y-b.y) >= (a.x-b.x) * (point.y-b.y))
	    	inside = !inside;
	}
    }
    
    return inside;
}

@end
