#!/usr/bin/env python

import sys
import win32con
from win32api import *
try:
     from winxpgui import *
except ImportError:
     from win32gui import *

from ctypes import windll
import struct
import window


class PyNOTIFYICONDATA:
     _struct_format = (
         "I" # DWORD cbSize;
         "I" # HWND hWnd;
         "I" # UINT uID;
         "I" # UINT uFlags;
         "I" # UINT uCallbackMessage;
         "I" # HICON hIcon;
         "128s" #    TCHAR szTip[128];
         "I" # DWORD dwState;
         "I" # DWORD dwStateMask;
         "256s" # TCHAR szInfo[256];
         "I" #     union {
             #    UINT  uTimeout;
             #    UINT  uVersion;
             #} DUMMYUNIONNAME;
         "64s" #    TCHAR szInfoTitle[64];
         "I" #  DWORD dwInfoFlags;
         #       GUID guidItem;
     )
     _struct = struct.Struct(_struct_format)

     hWnd = 0
     uID = 0
     uFlags = 0
     uCallbackMessage = 0
     hIcon = 0
     szTip = ''
     dwState = 0
     dwStateMask = 0
     szInfo = ''
     uTimeoutOrVersion = 0
     szInfoTitle = ''
     dwInfoFlags = 0

     def pack(self):
         return self._struct.pack(
             self._struct.size,
             self.hWnd,
             self.uID,
             self.uFlags,
             self.uCallbackMessage,
             self.hIcon,
             self.szTip,
             self.dwState,
             self.dwStateMask,
             self.szInfo,
             self.uTimeoutOrVersion,
             self.szInfoTitle,
             self.dwInfoFlags)

     def __setattr__(self, name, value):
         # avoid wrong field names
         if not hasattr(self, name):
             raise NameError, name
         self.__dict__[name] = value

from ctypes import windll
Shell_NotifyIcon = windll.shell32.Shell_NotifyIconA

def load_icon(name):
	icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
	hinst = GetModuleHandle(None)
	try:
		icon = LoadImage(hinst, name, win32con.IMAGE_ICON, 0, 0, icon_flags)
	except:
		try:
			icon = LoadIcon(0, win32con.IDI_APPLICATION)
		except:
			icon = 0

	return icon		

WM_TRAYICON = win32con.WM_USER + 20

class TrayIcon(window.Window):
	def __init__(self, icon_name):
		window.Window.__init__(self, {
				win32con.WM_DESTROY: self.on_destroy,
				WM_TRAYICON: self.on_taskbar_notify,
		})
		
		data = PyNOTIFYICONDATA()
		data.hWnd = self.hwnd
		data.uFlags = NIF_ICON | NIF_MESSAGE # | NIF_TIP # NIF_INFO
		#"Cellphone Calendar Sync"
		# Call the Windows function, not the wrapped one

		data.uCallbackMessage = WM_TRAYICON

		#data.szTip = ""
		data.hIcon = load_icon(icon_name)
		self.data = data

		# nid = (data.hWnd, 0, NIF_ICON | NIF_MESSAGE | NIF_TIP, win32con.WM_USER + 20, data.hIcon, "Balloontooltip demo")
		Shell_NotifyIcon(NIM_ADD, data.pack())

		#Shell_NotifyIcon(NIM_ADD, data.pack())

	def close(self):
		Shell_NotifyIcon(NIM_DELETE, self.data.pack()) # hwnd, 0

	def set_balloon_text(self, text, level = "info"):
		levels = {
			"info": NIIF_INFO,
			"warning": NIIF_WARNING,
			"error": NIIF_ERROR,
		}
		self.data.dwInfoFlags = levels.get(level) or NIIF_INFO #choice([NIIF_INFO, NIIF_WARNING, NIIF_ERROR])
		self.data.szInfoTitle = sys.argv[0]
		self.data.uFlags = NIF_INFO
		self.data.szInfo = text
		Shell_NotifyIcon(NIM_MODIFY, self.data.pack())

	def on_destroy(self, hwnd, msg, wparam, lparam):
		self.close()
		pass
		
	def on_taskbar_notify(self, hwnd, msg, wparam, lparam):
		pass

if __name__ == "__main__":
	icon_1 = TrayIcon(None)
	icon_1.set_balloon_text("hi")
	PumpMessages()
