/*
 * Mac driver system tray management
 *
 * Copyright (C) 2004 Mike Hearn, for CodeWeavers
 * Copyright (C) 2005 Robert Shearman
 * Copyright (C) 2008 Alexandre Julliard
 * Copyright (C) 2012, 2013 Ken Thomases for CodeWeavers Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include "macdrv.h"

#include "windef.h"
#include "winuser.h"
#include "shellapi.h"

#include "wine/list.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(systray);


/* an individual systray icon */
struct tray_icon
{
    struct list         entry;
    HWND                owner;              /* the HWND passed in to the Shell_NotifyIcon call */
    UINT                id;                 /* the unique id given by the app */
    UINT                callback_message;
    HICON               image;              /* the image to render */
    WCHAR               tiptext[128];       /* tooltip text */
    DWORD               state;              /* state flags */
    macdrv_status_item  status_item;
};

static struct list icon_list = LIST_INIT(icon_list);


static BOOL delete_icon(struct tray_icon *icon);


/***********************************************************************
 *              cleanup_icons
 *
 * Delete all systray icons owned by a given window.
 */
static void cleanup_icons(HWND hwnd)
{
    struct tray_icon *icon, *next;

    LIST_FOR_EACH_ENTRY_SAFE(icon, next, &icon_list, struct tray_icon, entry)
        if (icon->owner == hwnd) delete_icon(icon);
}


/***********************************************************************
 *              get_icon
 *
 * Retrieves an icon record by owner window and ID.
 */
static struct tray_icon *get_icon(HWND owner, UINT id)
{
    struct tray_icon *this;

    LIST_FOR_EACH_ENTRY(this, &icon_list, struct tray_icon, entry)
        if ((this->id == id) && (this->owner == owner)) return this;
    return NULL;
}


/***********************************************************************
 *              modify_icon
 *
 * Modifies an existing tray icon and updates its status item as needed.
 */
static BOOL modify_icon(struct tray_icon *icon, NOTIFYICONDATAW *nid)
{
    BOOL update_image = FALSE, update_tooltip = FALSE;

    TRACE("hwnd %p id 0x%x flags %x\n", nid->hWnd, nid->uID, nid->uFlags);

    if (nid->uFlags & NIF_STATE)
    {
        DWORD changed = (icon->state ^ nid->dwState) & nid->dwStateMask;
        icon->state = (icon->state & ~nid->dwStateMask) | (nid->dwState & nid->dwStateMask);
        if (changed & NIS_HIDDEN)
        {
            if (icon->state & NIS_HIDDEN)
            {
                if (icon->status_item)
                {
                    TRACE("destroying status item %p\n", icon->status_item);
                    macdrv_destroy_status_item(icon->status_item);
                    icon->status_item = NULL;
                }
            }
            else
            {
                if (!icon->status_item)
                {
                    struct macdrv_thread_data *thread_data = macdrv_init_thread_data();

                    icon->status_item = macdrv_create_status_item(thread_data->queue);
                    if (icon->status_item)
                    {
                        TRACE("created status item %p\n", icon->status_item);

                        if (icon->image)
                            update_image = TRUE;
                        if (lstrlenW(icon->tiptext))
                            update_tooltip = TRUE;
                    }
                    else
                        WARN("failed to create status item\n");
                }
            }
        }
    }

    if (nid->uFlags & NIF_ICON)
    {
        if (icon->image) DestroyIcon(icon->image);
        icon->image = CopyIcon(nid->hIcon);
        if (icon->status_item)
            update_image = TRUE;
    }

    if (nid->uFlags & NIF_MESSAGE)
    {
        icon->callback_message = nid->uCallbackMessage;
    }
    if (nid->uFlags & NIF_TIP)
    {
        lstrcpynW(icon->tiptext, nid->szTip, sizeof(icon->tiptext)/sizeof(WCHAR));
        if (icon->status_item)
            update_tooltip = TRUE;
    }

    if (update_image)
    {
        CGImageRef cgimage = NULL;
        if (icon->image)
            cgimage = create_cgimage_from_icon(icon->image, 0, 0);
        macdrv_set_status_item_image(icon->status_item, cgimage);
        CGImageRelease(cgimage);
    }

    if (update_tooltip)
    {
        CFStringRef s;

        TRACE("setting tooltip text for status item %p to %s\n", icon->status_item,
              debugstr_w(icon->tiptext));
        s = CFStringCreateWithCharacters(NULL, (UniChar*)icon->tiptext,
                                         lstrlenW(icon->tiptext));
        macdrv_set_status_item_tooltip(icon->status_item, s);
        CFRelease(s);
    }

    return TRUE;
}


/***********************************************************************
 *              add_icon
 *
 * Creates a new tray icon structure and adds it to the list.
 */
static BOOL add_icon(NOTIFYICONDATAW *nid)
{
    NOTIFYICONDATAW new_nid;
    struct tray_icon *icon;

    TRACE("hwnd %p id 0x%x\n", nid->hWnd, nid->uID);

    if ((icon = get_icon(nid->hWnd, nid->uID)))
    {
        WARN("duplicate tray icon add, buggy app?\n");
        return FALSE;
    }

    if (!(icon = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*icon))))
    {
        ERR("out of memory\n");
        return FALSE;
    }

    icon->id     = nid->uID;
    icon->owner  = nid->hWnd;
    icon->state  = NIS_HIDDEN;

    list_add_tail(&icon_list, &icon->entry);

    if (!(nid->uFlags & NIF_STATE) || !(nid->dwStateMask & NIS_HIDDEN))
    {
        new_nid = *nid;
        new_nid.uFlags |= NIF_STATE;
        new_nid.dwState     &= ~NIS_HIDDEN;
        new_nid.dwStateMask |= NIS_HIDDEN;
        nid = &new_nid;
    }
    return modify_icon(icon, nid);
}


/***********************************************************************
 *              delete_icon
 *
 * Destroy tray icon status item and delete structure.
 */
static BOOL delete_icon(struct tray_icon *icon)
{
    TRACE("hwnd %p id 0x%x\n", icon->owner, icon->id);

    if (icon->status_item)
    {
        TRACE("destroying status item %p\n", icon->status_item);
        macdrv_destroy_status_item(icon->status_item);
    }
    list_remove(&icon->entry);
    DestroyIcon(icon->image);
    HeapFree(GetProcessHeap(), 0, icon);
    return TRUE;
}


/***********************************************************************
 *              wine_notify_icon   (MACDRV.@)
 *
 * Driver-side implementation of Shell_NotifyIcon.
 */
int CDECL wine_notify_icon(DWORD msg, NOTIFYICONDATAW *data)
{
    BOOL ret = FALSE;
    struct tray_icon *icon;

    switch (msg)
    {
    case NIM_ADD:
        ret = add_icon(data);
        break;
    case NIM_DELETE:
        if ((icon = get_icon(data->hWnd, data->uID))) ret = delete_icon(icon);
        break;
    case NIM_MODIFY:
        if ((icon = get_icon(data->hWnd, data->uID))) ret = modify_icon(icon, data);
        break;
    case 0xdead:  /* Wine extension: owner window has died */
        cleanup_icons(data->hWnd);
        break;
    default:
        FIXME("unhandled tray message: %u\n", msg);
        break;
    }
    return ret;
}


/***********************************************************************
 *              macdrv_status_item_mouse_button
 *
 * Handle STATUS_ITEM_MOUSE_BUTTON events.
 */
void macdrv_status_item_mouse_button(const macdrv_event *event)
{
    struct tray_icon *icon;

    TRACE("item %p button %d down %d count %d\n", event->status_item_mouse_button.item,
          event->status_item_mouse_button.button, event->status_item_mouse_button.down,
          event->status_item_mouse_button.count);

    LIST_FOR_EACH_ENTRY(icon, &icon_list, struct tray_icon, entry)
    {
        if (icon->status_item == event->status_item_mouse_button.item)
        {
            UINT msg;

            switch (event->status_item_mouse_button.button)
            {
                case 0: msg = WM_LBUTTONDOWN; break;
                case 1: msg = WM_RBUTTONDOWN; break;
                case 2: msg = WM_MBUTTONDOWN; break;
                default:
                    TRACE("ignoring button beyond the third\n");
                    return;
            }

            if (!event->status_item_mouse_button.down)
                msg += WM_LBUTTONUP - WM_LBUTTONDOWN;
            else if (event->status_item_mouse_button.count % 2 == 0)
                msg += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;

            if (!SendMessageW(icon->owner, WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS, 0, 0) &&
                GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
            {
                WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id);
                delete_icon(icon);
                return;
            }

            TRACE("posting msg 0x%04x to hwnd %p id 0x%x\n", msg, icon->owner, icon->id);
            if (!PostMessageW(icon->owner, icon->callback_message, icon->id, msg) &&
                GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
            {
                WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id);
                delete_icon(icon);
                return;
            }

            break;
        }
    }
}


/***********************************************************************
 *              macdrv_status_item_mouse_move
 *
 * Handle STATUS_ITEM_MOUSE_MOVE events.
 */
void macdrv_status_item_mouse_move(const macdrv_event *event)
{
    struct tray_icon *icon;

    TRACE("item %p\n", event->status_item_mouse_move.item);

    LIST_FOR_EACH_ENTRY(icon, &icon_list, struct tray_icon, entry)
    {
        if (icon->status_item == event->status_item_mouse_move.item)
        {
            if (!PostMessageW(icon->owner, icon->callback_message, icon->id, WM_MOUSEMOVE) &&
                GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
            {
                WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id);
                delete_icon(icon);
                return;
            }

            break;
        }
    }
}
