/*

		Taskbar Notification Area (a.k.a. "system tray") interaction
		
		Development of this "API Classic" system tray implementation was
		expedited enormously by the "tray42" sample code developed by
		Michael Smith:  http://www.chebucto.ns.ca/~aa529/tray42.html
	 
*/

#include "netfone.h"

#ifdef TRAY

static BOOL	blinkIcon = FALSE;					//	Should icon blink ?
static int whichIcon = 0;						//	Which icon is presently shown ?

/*	UPDATETRAYTOOLTIPTEXT  --  Update ToolTip text to indicate status.  It's
							   safe to call this when no tray icon is displayed.  */

void updateTrayToolTipText(void)
{
	if (trayIconWindow != NULL) {
		NOTIFYICONDATA nid;
		
		if (openConnections == 0) {
			strcpy(nid.szTip, rstring(IDS_T_TOOLTIP_IDLE));
		} else {
			wsprintf(nid.szTip, Format(88), openConnections);
		}
		nid.cbSize = sizeof(NOTIFYICONDATA);
		nid.hWnd = trayIconWindow;
		nid.uID = 1;
		nid.uFlags = NIF_TIP;				// Only nid.szTip and nid.uID are valid; change tip
		Shell_NotifyIcon(NIM_MODIFY, &nid);	// Modify tooltip
	}
}

/*	BLINKTRAYICON  --  Enable or disable tray icon blinking.  It's safe to call this
					   when no tray icon is displayed.  */

void blinkTrayIcon(BOOL blink)
{
	NOTIFYICONDATA nid;
	
	if ((trayIconWindow != NULL) && (blink != blinkIcon)) {
		blinkIcon = blink;
		if (blinkIcon) {
			whichIcon = 0;
			SetTimer(trayIconWindow, TRAY_TIMER_ID, 500, NULL);	// Start timer to blink icon
		} else {
			KillTimer(trayIconWindow, TRAY_TIMER_ID);
			//	Ensure the regular icon is displayed when we're done blinking
			nid.cbSize = sizeof(NOTIFYICONDATA);
			nid.hWnd = trayIconWindow;
			nid.uID = 1;
			nid.uFlags = NIF_ICON;
			nid.hIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_FRAME), IMAGE_ICON,
								GetSystemMetrics(SM_CXSMICON),
								GetSystemMetrics(SM_CYSMICON), LR_SHARED);

			Shell_NotifyIcon(NIM_MODIFY, &nid);				
		}
	}
}
  
//	TRAYWNDPROC  --  Window procedure for processing tray messages

static LRESULT CALLBACK trayWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	POINT pt;
	HMENU hmenu, hpopup;
	NOTIFYICONDATA nid;
	int mid;

	switch (message) {

		case WM_TIMER:
			if (blinkIcon) {
				nid.cbSize = sizeof(NOTIFYICONDATA);
				nid.hWnd = hwnd;
				nid.uID = 1;
				nid.uFlags = NIF_ICON;
				nid.hIcon = LoadImage(hInst, whichIcon ? MAKEINTRESOURCE(IDI_FRAME) : MAKEINTRESOURCE(IDI_PHONE_BLINK), IMAGE_ICON,
									GetSystemMetrics(SM_CXSMICON),
									GetSystemMetrics(SM_CYSMICON), LR_SHARED);

				Shell_NotifyIcon(NIM_MODIFY, &nid);				
				whichIcon = !whichIcon;
			}
			return TRUE;

		case WM_DESTROY:
			nid.cbSize = sizeof(NOTIFYICONDATA);
			nid.hWnd = hwnd;
			nid.uID = 1;
			nid.uFlags = NIF_TIP;
			Shell_NotifyIcon(NIM_DELETE, &nid);		// Remove icon from the taskbar
			if (blinkIcon) {
				KillTimer(hwnd, TRAY_TIMER_ID);
			}
			return TRUE;

		case WM_TRAY_NOTIFY:			// We are being notified of mouse activity over the icon
			switch (lParam) {
			
				case WM_RBUTTONUP:		// Pop up the menu and wait for a selection
					GetCursorPos(&pt);
					hmenu = LoadMenu(hInst, MAKEINTRESOURCE(IDM_TRAY_POPUP));
					hpopup = GetSubMenu(hmenu, 0);
					
					EnableMenuItem(hpopup, ID_TRAY_ANSWER, MF_BYCOMMAND |
						((hDlgAnswer == 0) ? MF_ENABLED : MF_GRAYED));

					/* SetForegroundWindow and the ensuing null PostMessage is a
						workaround for a Windows 95 bug (see MSKB article Q135788,
						http://www.microsoft.com/kb/articles/q135/7/88.htm, I think).
						In typical Microsoft style this bug is listed as "by design".
						SetForegroundWindow also causes our MessageBox to pop up in front
						of any other application's windows. */
						
					SetForegroundWindow(hwnd);
					
					/*	We specifiy TPM_RETURNCMD, so TrackPopupMenu returns the menu
						selection instead of returning immediately and our getting a
						WM_COMMAND with the selection. You don't have to do it this way. */
						
					mid = TrackPopupMenu(hpopup,				// Popup menu to track
											TPM_RETURNCMD |		// Return menu code
											TPM_RIGHTBUTTON,	// Track right mouse button?
											pt.x, pt.y,			// screen coordinates
											0,					// reserved
											hwnd,				// owner
											NULL);				// LPRECT user can click in without dismissing menu

					PostMessage(hwnd, 0, 0, 0);					// see above
					DestroyMenu(hmenu);							// Delete loaded menu and reclaim its resources

					switch (mid) {
						case ID_TRAY_EXIT:
							PostMessage(hwndMDIFrame, WM_CLOSE, 0, 0L);
							break;
					
						case ID_TRAY_OPEN:
							goto openit;
							
						case ID_TRAY_ANSWER:
							PostMessage(hwndMDIFrame, WM_COMMAND, IDM_CO_REPONDEUR, 0);
							goto openit;
					}
					break;

				case WM_LBUTTONUP:				// Open and activate the main window
openit:				if (IsIconic(hwndMDIFrame)) {
						ShowWindow(hwndMDIFrame, SW_SHOWNORMAL);
					}
					SetForegroundWindow(hwndMDIFrame);
					break;

				}
				return TRUE;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}

//	CREATETRAYICON  --  Create tray icon and window to handle its messages

HWND createTrayIcon(void)
{
	HWND hwnd;
	WNDCLASSEX wc;
	NOTIFYICONDATA nid;
	char trayClassname[64];
	
	/*	Create a window class for the window that receives notifications
		from the system tray icon.  This window exists solely to receive
		messages and is never itself displayed.  */

	strcpy(trayClassname, rstring(IDS_T_TRAY_ICON_CLASS));
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = trayWndProc;
	wc.cbClsExtra = wc.cbWndExtra = 0;
	wc.hInstance = hInst;
	wc.hIcon = LoadIcon(hInst, IDI_FRAME);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = trayClassname;
	wc.hIconSm = LoadImage(hInst, IDI_FRAME, IMAGE_ICON,
						   GetSystemMetrics(SM_CXSMICON),
						   GetSystemMetrics(SM_CYSMICON), LR_SHARED);
	RegisterClassEx(&wc);
	
	// Create window.  Note that WS_VISIBLE is not used, so the window is never shown.
	
	hwnd = CreateWindowEx(0, trayClassname, trayClassname, WS_POPUP, CW_USEDEFAULT, 0,
						  CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);

	//	Initialise NOTIFYICONDATA structure
	
	nid.cbSize = sizeof(NOTIFYICONDATA);		// size
	nid.hWnd = hwnd;							// window to receive notifications
	nid.uID = 1;								// application-defined ID for icon (can be any UINT value)
	nid.uFlags = NIF_MESSAGE |					// nid.uCallbackMessage is valid, use it
				NIF_ICON |						// nid.hIcon is valid, use it
				NIF_TIP;						// nid.szTip is valid, use it
	nid.uCallbackMessage = WM_TRAY_NOTIFY;		// message sent to nid.hWnd
	nid.hIcon = LoadImage(hInst, IDI_FRAME, IMAGE_ICON,
						GetSystemMetrics(SM_CXSMICON),
						GetSystemMetrics(SM_CYSMICON), LR_SHARED);
						
	strcpy(nid.szTip, rstring(IDS_T_APP_TITLE_NORM));	// Default ToolTip to application name

	//	Add the icon to the system tray
	
	Shell_NotifyIcon(NIM_ADD, &nid);
	
	return hwnd;
}
#endif