/*
 *	Systray
 *
 *	Copyright 1999 Kai Morich	<kai.morich@bigfoot.de>
 *
 *  Manage the systray window. That it actually appears in the docking
 *  area of KDE or GNOME is delegated to windows/x11drv/wnd.c,
 *  X11DRV_WND_DockWindow.
 *
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include "heap.h"
#include "shellapi.h"
#include "shell32_main.h"
#include "windows.h"
#include "commctrl.h"
#include "debugtools.h"
#include "config.h"

DEFAULT_DEBUG_CHANNEL(shell)

typedef struct SystrayData {
  HWND                  hWnd;
  HWND                  hWndToolTip;
  NOTIFYICONDATAA       notifyIcon;
  int                   nitem; /* number of current element = tooltip id */
  struct SystrayData    *nextTrayItem;
} SystrayData;

typedef struct Systray {
  int              hasCritSection;
  CRITICAL_SECTION critSection;
  SystrayData      *systrayItemList;
} Systray;

static Systray systray;
static int nNumberTrayElements;


static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid);


/**************************************************************************
*  internal systray
*
*/

#define SMALL_ICON_SIZE GetSystemMetrics(SM_CXSMICON)

/* space between icons and frame */
#define IBORDER 3
#define OBORDER 2
#define TBORDER  (OBORDER+1+IBORDER)

static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;

  switch (message) {
  case WM_PAINT:
  {
    RECT rc;
    SystrayData  *ptrayItem = systray.systrayItemList;

    while (ptrayItem)
    {
      if (ptrayItem->hWnd == hWnd)
      {
        hdc = BeginPaint(hWnd, &ps);
        GetClientRect(hWnd, &rc);

        if (!DrawIconEx(hdc, rc.left, rc.top, ptrayItem->notifyIcon.hIcon,
                        SMALL_ICON_SIZE, SMALL_ICON_SIZE, 0, 0, DI_DEFAULTSIZE|DI_NORMAL))
          SYSTRAY_Delete(&ptrayItem->notifyIcon);
      }
      ptrayItem = ptrayItem->nextTrayItem;
    }
    EndPaint(hWnd, &ps);
  }
  break;

  case WM_MOUSEMOVE:
  case WM_LBUTTONDOWN:
  case WM_LBUTTONUP:
  case WM_RBUTTONDOWN:
  case WM_RBUTTONUP:
  case WM_MBUTTONDOWN:
  case WM_MBUTTONUP:
  {
    MSG msg;
    SystrayData *ptrayItem = systray.systrayItemList;

    while ( ptrayItem )
    {
      if (ptrayItem->hWnd == hWnd)
      {
        msg.hwnd=hWnd;
        msg.message=message;
        msg.wParam=wParam;
        msg.lParam=lParam;
        msg.time = GetMessageTime ();
        msg.pt.x = LOWORD(GetMessagePos ());
        msg.pt.y = HIWORD(GetMessagePos ());

        SendMessageA(ptrayItem->hWndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
      }
      ptrayItem = ptrayItem->nextTrayItem;
    }
  }

  case WM_LBUTTONDBLCLK:
  case WM_RBUTTONDBLCLK:
  case WM_MBUTTONDBLCLK:
  {
    int xPos;
    SystrayData *ptrayItem = systray.systrayItemList;

    while (ptrayItem)
    {
      if (ptrayItem->hWnd == hWnd)
      {
        xPos = LOWORD(lParam);
        if( (xPos >= TBORDER) &&
            (xPos < (TBORDER+SMALL_ICON_SIZE)) )
        {
          if (!PostMessageA(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
                            (WPARAM)ptrayItem->notifyIcon.uID, (LPARAM)message))
            SYSTRAY_Delete(&ptrayItem->notifyIcon);
          break;
        }
      }
      ptrayItem = ptrayItem->nextTrayItem;
    }
  }
  break;

  default:
    return (DefWindowProcA(hWnd, message, wParam, lParam));
  }
  return (0);

}

BOOL SYSTRAY_RegisterClass(void)
{
  WNDCLASSA  wc;

  wc.style         = CS_SAVEBITS;
  wc.lpfnWndProc   = (WNDPROC)SYSTRAY_WndProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = 0;
  wc.hIcon         = 0; /* LoadIcon (NULL, IDI_EXCLAMATION); */
  wc.hCursor       = LoadCursorA(0, IDC_ARROWA);
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
  wc.lpszMenuName  = NULL;
  wc.lpszClassName = "WineSystray";

  if (!RegisterClassA(&wc)) {
    ERR("RegisterClass(WineSystray) failed\n");
    return FALSE;
  }
  return TRUE;
}


BOOL SYSTRAY_Create(SystrayData *ptrayItem)
{
  RECT rect;

  /* Register the class if this is our first tray item. */
  if ( nNumberTrayElements == 1 )
  {
    if ( !SYSTRAY_RegisterClass() )
    {
      ERR( "RegisterClass(WineSystray) failed\n" );
      return FALSE;
    }
  }

  /* Initialize the window size. */
  rect.left   = 0;
  rect.top    = 0;
  rect.right  = SMALL_ICON_SIZE+2*TBORDER;
  rect.bottom = SMALL_ICON_SIZE+2*TBORDER;

  /* Create tray window for icon. */
  ptrayItem->hWnd = CreateWindowExA( WS_EX_TRAYWINDOW,
                                "WineSystray", "Wine-Systray",
                                WS_VISIBLE,
                                CW_USEDEFAULT, CW_USEDEFAULT,
                                rect.right-rect.left, rect.bottom-rect.top,
                                0, 0, 0, 0 );
  if ( !ptrayItem->hWnd )
  {
    ERR( "CreateWindow(WineSystray) failed\n" );
    return FALSE;
  }

  /* Create tooltip for icon. */
  ptrayItem->hWndToolTip = CreateWindowA( TOOLTIPS_CLASSA,NULL,TTS_ALWAYSTIP,
                                     CW_USEDEFAULT, CW_USEDEFAULT,
                                     CW_USEDEFAULT, CW_USEDEFAULT,
                                     ptrayItem->hWnd, 0, 0, 0 );
  if ( ptrayItem->hWndToolTip==0 )
  {
    ERR( "CreateWindow(TOOLTIP) failed\n" );
    return FALSE;
  }
  return TRUE;
}

static void SYSTRAY_RepaintAll(void)
{
  SystrayData  *ptrayItem = systray.systrayItemList;

  while(ptrayItem)
  {
    InvalidateRect(ptrayItem->hWnd, NULL, TRUE);
    ptrayItem = ptrayItem->nextTrayItem;
  }

}

static void SYSTRAY_RepaintItem(int nitem)
{

  SystrayData *ptrayItem = systray.systrayItemList;

  while(ptrayItem)
  {
    if (ptrayItem->nitem == nitem)
      InvalidateRect(ptrayItem->hWnd, NULL, TRUE);

    ptrayItem = ptrayItem->nextTrayItem;
  }
}

void SYSTRAY_InitItem(SystrayData *ptrayItem)
{
  ptrayItem->nitem = nNumberTrayElements++;
  SYSTRAY_Create(ptrayItem);
}

void SYSTRAY_SetIcon(SystrayData *ptrayItem, HICON hIcon)
{
  ptrayItem->notifyIcon.hIcon = hIcon;
}

void SYSTRAY_SetTip(SystrayData *ptrayItem, CHAR* szTip)
{
  TTTOOLINFOA ti;

  strncpy(ptrayItem->notifyIcon.szTip, szTip, sizeof(ptrayItem->notifyIcon.szTip));
  ptrayItem->notifyIcon.szTip[sizeof(ptrayItem->notifyIcon.szTip)-1]=0;

  ti.cbSize = sizeof(TTTOOLINFOA);
  ti.uFlags = 0;
  ti.hwnd = ptrayItem->hWnd;
  ti.hinst = 0;
  ti.uId = ptrayItem->nitem;
  ti.lpszText = ptrayItem->notifyIcon.szTip;
  ti.rect.left   = 0;
  ti.rect.top    = 0;
  ti.rect.right  = SMALL_ICON_SIZE+2*TBORDER;
  ti.rect.bottom = SMALL_ICON_SIZE+2*TBORDER;

  SendMessageA(ptrayItem->hWndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
}

static void SYSTRAY_ModifyTip(SystrayData *ptrayItem, CHAR* szTip)
{
  TTTOOLINFOA ti;

  strncpy(ptrayItem->notifyIcon.szTip, szTip, sizeof(ptrayItem->notifyIcon.szTip));
  ptrayItem->notifyIcon.szTip[sizeof(ptrayItem->notifyIcon.szTip)-1]=0;

  ti.cbSize = sizeof(TTTOOLINFOA);
  ti.uFlags = 0;
  ti.hwnd = ptrayItem->hWnd;
  ti.hinst = 0;
  ti.uId = ptrayItem->nitem;
  ti.lpszText = ptrayItem->notifyIcon.szTip;
  ti.rect.left   = 0;
  ti.rect.top    = 0;
  ti.rect.right  = SMALL_ICON_SIZE+2*TBORDER;
  ti.rect.bottom = SMALL_ICON_SIZE+2*TBORDER;

  SendMessageA(ptrayItem->hWndToolTip, TTM_UPDATETIPTEXTA, 0, (LPARAM)&ti);
}

static void SYSTRAY_TermItem(SystrayData *removeItem)
{
  int nitem;
  SystrayData **trayItem;
  TTTOOLINFOA ti;
  ti.cbSize = sizeof(TTTOOLINFOA);
  ti.uFlags = 0;
  ti.hinst = 0;

  /* delete all tooltips ...*/
  trayItem = &systray.systrayItemList;
  while (*trayItem) {
    ti.uId = (*trayItem)->nitem;
    ti.hwnd = (*trayItem)->hWnd;
    SendMessageA((*trayItem)->hWndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
    trayItem = &((*trayItem)->nextTrayItem);
  }
  /* ... and add them again, because uID may shift */
  nitem=0;
  trayItem = &systray.systrayItemList;
  while (*trayItem)
  {
    if (*trayItem != removeItem)
    {
      (*trayItem)->nitem = nitem;
      ti.uId = nitem;
      ti.hwnd = (*trayItem)->hWnd;
      ti.lpszText = (*trayItem)->notifyIcon.szTip;
      ti.rect.left   = 0;
      ti.rect.top    = 0;
      ti.rect.right  = SMALL_ICON_SIZE+2*TBORDER;
      ti.rect.bottom = SMALL_ICON_SIZE+2*TBORDER;
      SendMessageA((*trayItem)->hWndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
      nitem++;
    }
    trayItem = &((*trayItem)->nextTrayItem);
  }
  nNumberTrayElements--;
}


/**************************************************************************
*  helperfunctions
*
*/
void SYSTRAY_SetMessage(SystrayData *ptrayItem, UINT uCallbackMessage)
{
  ptrayItem->notifyIcon.uCallbackMessage = uCallbackMessage;
}

static BOOL SYSTRAY_IsEqual(PNOTIFYICONDATAA pnid1, PNOTIFYICONDATAA pnid2)
{
  if (pnid1->hWnd != pnid2->hWnd) return FALSE;
  if (pnid1->uID  != pnid2->uID)  return FALSE;
  return TRUE;
}

static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
{
  SystrayData **ptrayItem = &systray.systrayItemList;

  /* Find empty space for new element. */
  while( *ptrayItem )
  {
    if ( SYSTRAY_IsEqual(pnid, &(*ptrayItem)->notifyIcon) )
      return FALSE;
    ptrayItem = &((*ptrayItem)->nextTrayItem);
  }

  /* Allocate SystrayData for element and zero memory. */
  (*ptrayItem) = ( SystrayData *)malloc( sizeof(SystrayData) );
  ZeroMemory( (*ptrayItem), sizeof(SystrayData) );

  /* Copy notification data */
  memcpy( &(*ptrayItem)->notifyIcon, pnid, sizeof(NOTIFYICONDATAA) );

  /* Initialize and set data for the tray element. */
  SYSTRAY_InitItem( (*ptrayItem) );

  SYSTRAY_SetIcon   (*ptrayItem, (pnid->uFlags&NIF_ICON)   ?pnid->hIcon           :0);
  SYSTRAY_SetMessage(*ptrayItem, (pnid->uFlags&NIF_MESSAGE)?pnid->uCallbackMessage:0);
  SYSTRAY_SetTip    (*ptrayItem, (pnid->uFlags&NIF_TIP)    ?pnid->szTip           :"");

  (*ptrayItem)->nextTrayItem = NULL; /* may be overkill after the ZeroMemory call. */

  /* Repaint all system tray icons as we have added one. */
  SYSTRAY_RepaintAll();

  TRACE("%p: 0x%08x %d %s\n",  (*ptrayItem), (*ptrayItem)->notifyIcon.hWnd,
                               (*ptrayItem)->notifyIcon.uID,
                               (*ptrayItem)->notifyIcon.szTip);
  return TRUE;
}

static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
{
  SystrayData *ptrayItem = systray.systrayItemList;

  while ( ptrayItem )
  {
    if ( SYSTRAY_IsEqual(pnid, &ptrayItem->notifyIcon) )
    {
      if (pnid->uFlags & NIF_ICON)
      {
        SYSTRAY_SetIcon(ptrayItem, pnid->hIcon);
        SYSTRAY_RepaintItem(ptrayItem->nitem);
      }

      if (pnid->uFlags & NIF_MESSAGE)
        SYSTRAY_SetMessage(ptrayItem, pnid->uCallbackMessage);

      if (pnid->uFlags & NIF_TIP)
        SYSTRAY_ModifyTip(ptrayItem, pnid->szTip);

      TRACE("%p: 0x%08x %d %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd,
            ptrayItem->notifyIcon.uID, ptrayItem->notifyIcon.szTip);
      return TRUE;
    }
    ptrayItem = ptrayItem->nextTrayItem;
  }
  return FALSE; /* not found */
}

static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid)
{
  SystrayData **ptrayItem = &systray.systrayItemList;

  while (*ptrayItem)
  {
    if (SYSTRAY_IsEqual(pnid, &(*ptrayItem)->notifyIcon))
    {
      SystrayData *next = (*ptrayItem)->nextTrayItem;
      TRACE("%p: 0x%08x %d %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd,
            (*ptrayItem)->notifyIcon.uID, (*ptrayItem)->notifyIcon.szTip);
      SYSTRAY_TermItem(*ptrayItem);

      DestroyWindow((*ptrayItem)->hWndToolTip);
      DestroyWindow((*ptrayItem)->hWnd);

      free(*ptrayItem);
      *ptrayItem = next;

      SYSTRAY_RepaintAll();

      return TRUE;
    }
    ptrayItem = &((*ptrayItem)->nextTrayItem);
  }

  return FALSE; /* not found */
}

/*************************************************************************
 *
 */
BOOL SYSTRAY_Init(void)
{
  if (!systray.hasCritSection)
  {
    systray.hasCritSection=1;
    InitializeCriticalSection(&systray.critSection);
    MakeCriticalSectionGlobal(&systray.critSection);
    TRACE(" =%p\n", &systray.critSection);
  }
  return TRUE;
}


/*************************************************************************
 * Shell_NotifyIconA			[SHELL32.297]
 */
BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
{
  BOOL flag=FALSE;
  TRACE("wait %d %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
  /* must be serialized because all apps access same systray */
  EnterCriticalSection(&systray.critSection);
  TRACE("enter %d %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);


  switch(dwMessage) {
  case NIM_ADD:
    TRACE("Calling systray add\n");
    flag = SYSTRAY_Add(pnid);
    break;
  case NIM_MODIFY:
    flag = SYSTRAY_Modify(pnid);
    break;
  case NIM_DELETE:
    flag = SYSTRAY_Delete(pnid);
    break;
  }

  LeaveCriticalSection(&systray.critSection);
  TRACE("leave %d %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
  return flag;
}

/*************************************************************************
 * Shell_NotifyIconW			[SHELL32.297]
 */
BOOL WINAPI Shell_NotifyIconW (DWORD dwMessage, PNOTIFYICONDATAW pnid )
{
	BOOL ret;

	PNOTIFYICONDATAA p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAA));
	memcpy(p, pnid, sizeof(NOTIFYICONDATAA));
	if (*(pnid->szTip))
	  lstrcpynWtoA (p->szTip, pnid->szTip, 64 );

	ret = Shell_NotifyIconA(dwMessage, p );

	HeapFree(GetProcessHeap(),0,p);
	return ret;
}
/*************************************************************************
 * Shell_NotifyIcon			[SHELL32.296]
 */
BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATAA pnid)
{
  return Shell_NotifyIconA(dwMessage, pnid);
}
