// 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 "OHFormSelectPopup.h"
#import "OHFormSelectOption.h"

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

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

@implementation OHFormSelectPopup

static NSFont *typingFont;

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

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

    typingFont = [NSFont systemFontOfSize:12.0];
}

- (void)dealloc
{
    [popUpButton release];
    [super dealloc];
}

- (void)constructView;
{
    unsigned int optionIndex, optionCount;
    NSMutableArray *itemNames;
    NSMutableSet *usedItemNames;
    NSString *zeroWidthSpace;

    ASSERT_IN_MAIN_THREAD(@"AppKit calls must be from main thread!");

    popUpButton = [[NSPopUpButton alloc] init];
    [popUpButton setFont:typingFont];
    [popUpButton setAutoenablesItems:NO];

    optionCount = [options count];
    itemNames = [[NSMutableArray alloc] initWithCapacity:optionCount];
    usedItemNames = [[NSMutableSet alloc] initWithCapacity:optionCount+1];
    [usedItemNames addObject:@""];  /* disallow blank popup titles due to bug in MacOSX */
    zeroWidthSpace = nil;
    for (optionIndex = 0; optionIndex < optionCount; optionIndex++) {
        OHFormSelectOption *currentOption;
        NSString *itemName;

        currentOption = [options objectAtIndex:optionIndex];
        itemName = [currentOption text];

        /* Make sure that the items are unique by appending zero-width spaces as necessary */
        while([usedItemNames containsObject:itemName]) {
            if ([itemName length] < 3) {
                /* Due to yet another bug in NSPopUpButton, a title can't be actually zero-width or the Cell will raise. Also, cells containing thin spaces also produce the bug that cells with zero-length titles produce (the popup gets sized incorrectly). So, if we're uniquifying a short popup title, use normal ol' spaces. */
                itemName = [itemName stringByAppendingString:@" "];
            } else {
                if (!zeroWidthSpace)
                    zeroWidthSpace = [NSString stringWithCharacter:0x200B];
                itemName = [itemName stringByAppendingString:zeroWidthSpace];
            }
        }
        
        [itemNames addObject:itemName];
        [usedItemNames addObject:itemName];
    }
    [popUpButton addItemsWithTitles:itemNames];
    [itemNames release];
    [usedItemNames release];

    OBASSERT([[popUpButton itemArray] count] == optionCount);

    NS_DURING {
        /* NSCell will raise under certain circumstances, e.g. a zero-width title. */
        [popUpButton sizeToFit];
    } NS_HANDLER {
        [popUpButton removeAllItems];
        NSLog(@"Exception raised in NSPopUpButton: %@", localException);
    } NS_ENDHANDLER;
    [popUpButton setTarget:self];
    [popUpButton setAction:@selector(uiDidSelect:)];

    [self reset];
}

// PopUpButton action method

- (void)uiDidSelect:(id)sender
{
   unsigned int selectedIndex;
   OHFormSelectOption *option;

   selectedIndex = [popUpButton indexOfSelectedItem];
   [elementStateLock lock];
   option = [options objectAtIndex:selectedIndex];
   [selectedOptions removeAllObjects];
   [selectedOptions addObject:option];
   [elementStateLock unlock];

   [self userDidChangeSelection];
}

// OHViewCell subclass

- (void)setupContentView;
{
    [self constructView];
    [self setContentView:popUpButton];
}

// OHFormSelect subclass stuff

- (void)updateUI
{
    unsigned int selectedIndex;
    ASSERT_IN_MAIN_THREAD(@"AppKit calls must be from mail thread");

    [elementStateLock lock];
    if ([selectedOptions count] == 0) {
        if ([options count]) {
            [selectedOptions addObject:[options objectAtIndex:0]];
            selectedIndex = 0;
        } else {
            /* something's a little screwy here */
            [elementStateLock unlock];
            return;
        }
    } else {
        selectedIndex = [options indexOfObjectIdenticalTo:[selectedOptions objectAtIndex:0]];
        if (selectedIndex == NSNotFound) {
            /* something's REALLY screwed up */
            [elementStateLock unlock];
            return;
        }
        /* we can only have one option selected at a time */
        while([selectedOptions count] > 1)
            [selectedOptions removeLastObject];
    }
    [elementStateLock unlock];

    [popUpButton selectItemAtIndex:selectedIndex];
}

@end
