/*
 * 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);


#define CHECK_SYSTRAY_TIMER         1
#define CHECK_SYSTRAY_INTERVAL_MS   2000


/* 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);


/***********************************************************************
 *              check_icons
 *
 * Timer procedure for periodically checking that the systray icons are
 * still valid (their owning windows still exist).
 */
static VOID CALLBACK check_icons(HWND hwnd, UINT msg, UINT_PTR timer, DWORD time)
{
    struct tray_icon *icon, *next;

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


/***********************************************************************
 *              setup_check_icons_timer
 *
 * Set up a window with a timer to check that tray icons are still valid
 * (their owning windows still exist).
 */
static void setup_check_icons_timer(void)
{
    static BOOL done;

    if (!done)
    {
        static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
        HWND timer_window;

        /* Whether we succeed or not, don't try again. */
        done = TRUE;

        timer_window = CreateWindowW(messageW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
                                     NULL, NULL, NULL);
        if (!timer_window)
        {
            WARN("Could not create systray checking message window\n");
            return;
        }

        if (!SetTimer(timer_window, CHECK_SYSTRAY_TIMER, CHECK_SYSTRAY_INTERVAL_MS, check_icons))
            WARN("Could not create systray checking timer\n");
    }
}


/***********************************************************************
 *              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;
    }

    setup_check_icons_timer();

    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;
    default:
        FIXME("unhandled tray message: %u\n", msg);
        break;
    }
    return ret;
}


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

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

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

            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;
            }

            if (event->status_item_clicked.count == 1)
            {
                down = WM_LBUTTONDOWN;
                TRACE("posting WM_LBUTTONDOWN to hwnd %p id 0x%x\n", icon->owner, icon->id);
            }
            else
            {
                down = WM_LBUTTONDBLCLK;
                TRACE("posting WM_LBUTTONDBLCLK to hwnd %p id 0x%x\n", icon->owner, icon->id);
            }

            if (!PostMessageW(icon->owner, icon->callback_message, icon->id, down) &&
                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 WM_LBUTTONUP to hwnd %p id 0x%x\n", icon->owner, icon->id);
            if (!PostMessageW(icon->owner, icon->callback_message, icon->id, WM_LBUTTONUP) &&
                GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
            {
                WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id);
                delete_icon(icon);
            }

            break;
        }
    }
}
