/* ====================================================================
 * FTD4Linux Software License, Version 1.0
 *
 * Copyright (c) 2000-2004 The FTD4Linux Development Team.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        FTD4Linux Development Team (http://www.ftd4linux.2y.net/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "FTD" and "FTD4Linux" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact alguno@ftd4linux.2y.net.
 *
 * 5. Products derived from this software may not be called "FTD4Linux",
 *    nor may "FTD4Linux" appear in their name, without prior written
 *    permission of the FTD4Linux Development Team.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE FTD4LINUX DEVELOPMENT TEAM OR
 * ITS 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 "ftd_gui_main.h"
#include "ftd_gui_pixbuf.h"
#ifdef WIN32
#include <windows.h>
#include "resource.h"
#else
#include "eggtrayicon.h"
#endif

#ifdef WIN32
static HWND systray_hwnd = NULL;
static NOTIFYICONDATA ftd_nid;
#else
static EggTrayIcon *docklet = NULL;
static GtkWidget *image = NULL;
gboolean reanimate = FALSE;
#endif

#ifdef WIN32
static void
ftd_gui_tray_clicked(void)
{
    g_assert(gui);

    gtk_window_present(GTK_WINDOW(gui->window));
    if (ftd_config_get()->startMaximized) {
        gtk_window_maximize(GTK_WINDOW(gui->window));
    }
}

static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
    static UINT taskbarRestartMsg;

	switch(msg) {
        case WM_CREATE:
            taskbarRestartMsg = RegisterWindowMessage(L"TaskbarCreated");
            break;
		case WM_TIMER:
		case WM_DESTROY:
            break;

        case WM_USER:
            if(lparam == WM_LBUTTONUP) {
                ftd_gui_tray_clicked();
            }

		    break;

	    default:
            if (msg == taskbarRestartMsg) {
		        /* explorer crashed and left us hanging...
		           This will put the systray icon back in it's place, when it restarts */
		        Shell_NotifyIcon(NIM_ADD,&ftd_nid);
            }
		    break;
    }

	return DefWindowProc(hwnd, msg, wparam, lparam);
}

/* Create hidden window to process systray messages */
static HWND systray_create_hiddenwin()
{
	WNDCLASSEX wcex;
	TCHAR wname[32];

	strcpy(wname, L"OpenFTD");

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style	        = 0;
	wcex.lpfnWndProc	= (WNDPROC)systray_mainmsg_handler;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= main_getinstance();
	wcex.hIcon		    = NULL;
	wcex.hCursor		= NULL,
	wcex.hbrBackground	= NULL;
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= wname;
	wcex.hIconSm		= NULL;

	RegisterClassEx(&wcex);

	/* Create the window */
	return (CreateWindow(wname, L"", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, main_getinstance(), 0));
}

void
ftd_gui_tray_destroy(void)
{
    DestroyWindow(systray_hwnd);
    Shell_NotifyIcon(NIM_DELETE,&ftd_nid);
    gui->trayIconActivated = FALSE;
}

gboolean
ftd_gui_tray_create(gpointer data)
{
	gui->trayIconActivated = TRUE;

	ZeroMemory(&ftd_nid, sizeof(ftd_nid));
	ftd_nid.cbSize = sizeof(NOTIFYICONDATA);
	ftd_nid.hWnd = systray_create_hiddenwin();
	ftd_nid.uID = 0;
	ftd_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
	ftd_nid.uCallbackMessage = WM_USER;
	ftd_nid.hIcon = (HICON)LoadImage(main_getinstance(), MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);

	return Shell_NotifyIcon(NIM_ADD, &ftd_nid);
}
#endif

#ifndef WIN32
#ifndef DARWIN

static void
ftd_gui_tray_embedded(GtkWidget *widget, void *data)
{
    g_assert(gui);
    gui->trayIconActivated = TRUE;
}

static void
ftd_gui_tray_destroyed(GtkWidget *widget, void *data)
{
    /* Tray icon is om een of andere reden destroyed, opnieuw aanmaken */
    if (reanimate) {
        g_idle_add(ftd_gui_tray_create, NULL);
    }
}

static void
ftd_gui_tray_clicked(GtkWidget *button, GdkEventButton *event, void *data)
{
    g_assert(gui);

    if (event->type != GDK_BUTTON_PRESS)
        return;

    if (gtk_window_is_active(GTK_WINDOW(gui->window))) {
        gtk_window_iconify(GTK_WINDOW(gui->window));
        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(gui->window), TRUE);
    } else {
        gtk_window_present(GTK_WINDOW(gui->window));
        if (ftd_config_get()->startMaximized) {
            gtk_window_maximize(GTK_WINDOW(gui->window));
        }
        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(gui->window), FALSE);
    }
}

void
ftd_gui_tray_destroy(void)
{
    g_assert(gui);

    if (!docklet) {
        return;
    }

    reanimate = FALSE;
    gtk_widget_destroy(GTK_WIDGET(docklet));

    docklet = NULL;

    gui->trayIconActivated = FALSE;
}

gboolean
ftd_gui_tray_create(gpointer data)
{
    GtkWidget *box;

    if (docklet) {
        ftd_gui_tray_destroy();
    }

    gui->trayIconActivated = FALSE;

    docklet = egg_tray_icon_new("OpenFTD");
    box = gtk_event_box_new();
    image = gtk_image_new_from_pixbuf(GDK_PIXBUF(ftd_gui_main_get_pixbuf("icon")));

    g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(ftd_gui_tray_embedded), NULL);
    g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(ftd_gui_tray_destroyed), NULL);
    g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(ftd_gui_tray_clicked), NULL);

    gtk_container_add(GTK_CONTAINER(box), image);
    gtk_container_add(GTK_CONTAINER(docklet), box);
    gtk_widget_show_all(GTK_WIDGET(docklet));

    reanimate = TRUE;

    return FALSE;
}

#endif
#endif
