/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "ContextMenu.h"

#if ENABLE(CONTEXT_MENUS)

namespace WebCore {

ContextMenu::ContextMenu()
{
    NSMutableArray* array = [[NSMutableArray alloc] init];
    m_platformDescription = array;
    [array release];
}

ContextMenu::ContextMenu(const PlatformMenuDescription menu)
    : m_platformDescription(menu)
{
}

ContextMenu::~ContextMenu()
{
}

void ContextMenu::appendItem(ContextMenuItem& item)
{
    NSMenuItem* platformItem = item.releasePlatformDescription();

    [m_platformDescription.get() addObject:platformItem];
    [platformItem release];
}

void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
{
    NSMenuItem* platformItem = item.releasePlatformDescription();

    [m_platformDescription.get() insertObject:platformItem atIndex:position];
    [platformItem release];
}

unsigned ContextMenu::itemCount() const
{
    return [m_platformDescription.get() count];
}

void ContextMenu::setPlatformDescription(NSMutableArray* menu)
{
    if (m_platformDescription.get() != menu)
        m_platformDescription = menu;
}

NSMutableArray* ContextMenu::platformDescription() const
{
    return m_platformDescription.get();
}

NSMutableArray* ContextMenu::releasePlatformDescription()
{
    return m_platformDescription.leakRef();
}

Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription menu)
{
    Vector<ContextMenuItem> items;
    unsigned count = [menu count];
    if (menu)
        items.reserveCapacity(count);
    
    for (unsigned i = 0; i < count; ++i)
        items.append(ContextMenuItem([menu objectAtIndex:i]));
    
    return items;
}

PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>& menuItemVector)
{
    PlatformMenuDescription platformMenu = [[NSMutableArray alloc] initWithCapacity:menuItemVector.size()];
    for (unsigned i = 0; i < menuItemVector.size(); ++i) {
        PlatformMenuItemDescription platformItem = menuItemVector[i].releasePlatformDescription();
        [platformMenu addObject:platformItem];
        [platformItem release];
    }
    
    return [platformMenu autorelease];
}

} // namespace WebCore

#endif // ENABLE(CONTEXT_MENUS)
