#include "trayhotkey.h"

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpReserved)
{
    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_HOTKEY :
            if (hotKeyID == wParam && keyCode == lParam)
            {
                updatehWnds();
                (wincount == 1) ? onSingleWin() : onHotKey();
            }
            else if (transID == wParam && transKC == lParam)
            {
                updatehWnds();
                onTrans();
            }
            break;
        case WM_TRAYMESSAGE :
            switch (lParam)
            {
                case WM_LBUTTONUP :
                    updatehWnds();
                    (wincount == 1 || singleMode) ? onSingleWin()
                                                  : initPopupMenu(lParam);
                    break;
                case WM_MBUTTONUP :
                    quitApp();
                    break;
                case WM_RBUTTONUP :
                    initPopupMenu(lParam);
                    break;
            }
            break;
        case WM_COMMAND :
            if (wParam == 0xFFFF)
                quitApp();
            else if (win[(int)wParam].hWnd)
                onTray((int)wParam);
            break;
        case WM_CLOSE :
            if (hotKeyState)
                UnregisterHotKey(msghWnd, hotKeyID);
            if (trayState)
            {
                if (icoPath[0] && hIcon)
                    DestroyIcon(hIcon);
                Shell_NotifyIcon(NIM_DELETE, &nid);
                trayState = FALSE;
            }
            DestroyWindow(msghWnd);
            UnregisterClass(L"TrayHotKey", GetModuleHandle(NULL));
            break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

void onSingleWin(void)
{
    if (!singlehWnd) return;
    int i = winIndex(singlehWnd);
    if (i == 0xFFFF) return;
    if (win[i].hidden)
    {
        ShowWindow(win[i].hWnd, SW_SHOW);
        win[i].hidden = FALSE;
        if (IsIconic(win[i].hWnd))
            ShowWindow(win[i].hWnd, SW_RESTORE);
        foreground ? SetForegroundWindow(win[i].hWnd)
                   :  BringWindowToTop(win[i].hWnd);
        if (!alawysShowTray)
        {
            Shell_NotifyIcon(NIM_DELETE, &nid);
            trayState = FALSE;
        }
        windowState = TRUE;
    }
    else
    {
        ShowWindow(win[i].hWnd, SW_HIDE);
        win[i].hidden = TRUE;
        windowState = FALSE;
    }
}

void onHotKey(void)
{
    if (singleMode)
        return onSingleWin();
    switch (windowState)
    {
        case TRUE :
            windowState = FALSE;
            for (int i = 0; i < WINMAX; ++i)
            {
                if (win[i].hWnd && !win[i].hidden)
                {
                    ShowWindow(win[i].hWnd, SW_HIDE);
                    win[i].hidden = TRUE;
                }
            }
            break;
        case FALSE :
            windowState = TRUE;
            for (int i = 0; i < WINMAX; ++i)
            {
                if (win[i].hWnd && win[i].hidden)
                {
                    ShowWindow(win[i].hWnd, SW_SHOW);
                    win[i].hidden = FALSE;
                    if (IsIconic(win[i].hWnd))
                        ShowWindow(win[i].hWnd, SW_RESTORE);
                    foreground ? SetForegroundWindow(win[i].hWnd)
                               :  BringWindowToTop(win[i].hWnd);
                }
            }
            break;
    }
}

void onTrans(void)
{
    if (!windowState)
        return;
    switch (transStatus)
    {
        case TRUE :
            transStatus = FALSE;
            for (int i = WINMAX-1; i >= 0; --i)
            {
                if (win[i].occupied)
                {
                    if (singleMode && singlehWnd != win[i].hWnd)
                        continue;
                    LONG dwExStyle = GetWindowLong(win[i].hWnd, GWL_EXSTYLE);
                    dwExStyle &= ~WS_EX_TRANSPARENT;
                    if (!win[i].hidden)
                    {
                        foreground ? SetForegroundWindow(win[i].hWnd)
                                   : BringWindowToTop(win[i].hWnd);
                        SetLayeredWindowAttributes(win[i].hWnd, 0, opacityValue,
                                LWA_ALPHA);
                    }
                    SetWindowLong(win[i].hWnd, GWL_EXSTYLE, dwExStyle);
                }
            }
            break;
        case FALSE :
            transStatus = TRUE;
            for (int i = 0; i < WINMAX; ++i)
            {
                if (win[i].occupied)
                {
                    if (singleMode && singlehWnd != win[i].hWnd)
                        continue;
                    LONG dwExStyle = GetWindowLong(win[i].hWnd, GWL_EXSTYLE);
                    dwExStyle |= WS_EX_TRANSPARENT;
                    SetLayeredWindowAttributes(win[i].hWnd, 0, transValue,
                            LWA_ALPHA);
                    SetWindowLong(win[i].hWnd, GWL_EXSTYLE, dwExStyle);
                }
            }
            break;
    }
}

void onTray(int i)
{
    if (win[i].hidden)
    {
        ShowWindow(win[i].hWnd, SW_SHOW);
        if (IsIconic(win[i].hWnd))
            ShowWindow(win[i].hWnd, SW_RESTORE);
        foreground ? SetForegroundWindow(win[i].hWnd)
                   : BringWindowToTop(win[i].hWnd);
        win[i].hidden = FALSE;
        BOOL hwin = TRUE;
        for (int i = 0; i < WINMAX; i++)
        {
            if (win[i].occupied && win[i].hidden)
            {
                hwin = FALSE;
                break;
            }
        }
        if (hwin && !alawysShowTray)
        {
            Shell_NotifyIcon(NIM_DELETE, &nid);
            trayState = FALSE;
        }
    }
    else
    {
        ShowWindow(win[i].hWnd, SW_HIDE);
        win[i].hidden = TRUE;
    }
}

void initPopupMenu(LPARAM lParam)
{
    POINT point;
    HMENU hPopupMenu;
    if (!GetCursorPos(&point))
    {
        point.x = point.y = 0;
    }
    hPopupMenu = CreatePopupMenu();
    for (int i = 0; i < WINMAX; ++i)
    {
        if (singleMode && singlehWnd != win[i].hWnd)
            continue;
        if (win[i].occupied)
        {
            int j, max;
            j = win[i].hidden ? 1 : 2;
            max = _tcslen(trayStr[j]) > TITLEMAX ? TITLEMAX
                                                 : _tcslen(trayStr[j]);
            _tcsncpy(winTitle[i], trayStr[j], max);
            winTitle[i][max] = _T('\0');

            max = TITLEMAX - max + 1;
            TCHAR title[TITLEMAX] = {_T('\0')};
            BOOL tmp = GetWindowText(win[i].hWnd, title, max);
            if (!tmp) {
                static const TCHAR t[] = _T("No Title");
                _tcsncpy(title, t, _tcslen(t) > max ? max : _tcslen(t));
            }
            _tcsncat(winTitle[i], title, max);
            winTitle[i][TITLEMAX] = _T(' ');
            winTitle[i][TITLEMAX+1] = winTitle[i][TITLEMAX+2] =
                winTitle[i][TITLEMAX+3] = _T('.');
            winTitle[i][TITLEMAX+4] = _T('\0');
            AppendMenu(hPopupMenu, MF_STRING, i, winTitle[i]);
        }
    }
    if (lParam == WM_RBUTTONUP)
    {
        AppendMenu(hPopupMenu, MF_SEPARATOR, 0xFFFE, NULL);
        AppendMenu(hPopupMenu, MF_STRING, 0xFFFF, trayStr[0]);
    }
    SetForegroundWindow(msghWnd);
    TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN, point.x, point.y,
            0, msghWnd, NULL);
    DestroyMenu(hPopupMenu);
}

void EXPORT init(void)
{
    hotKeyState = trayState = FALSE;
    hotKeyChecked = opacityChecked = transChecked = FALSE;
    alawysShowTray = minimizeToTray = closeToTray = FALSE;
    foreground = TRUE;
    wincount = 0;
    opacityValue = transValue = 255;
    lpSubClassFun = (LONG)SubClassFunc;

    wndclass.style         = 0;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = NULL;
    wndclass.hIcon         = NULL;
    wndclass.hCursor       = NULL;
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = L"TrayHotKey";
    RegisterClass(&wndclass);

    msghWnd = CreateWindowEx(
            0, wndclass.lpszClassName, L"MessageOnlyWindow4THK", 0,
            0, 0, 0, 0,
            HWND_MESSAGE, NULL, NULL, NULL
            );
}

/* －－－－－－－－－－－－－－－－－－－－－－－－－ *
 * 函数名：trayHotKey
 * 参数值：
 *  @_icoPath_       ： 自定义托盘图标路径
 *  @_sTip_          ： 托盘相关文字
 *  @_trayChecked_   ： 是否总是显示托盘
 *  @_hotKeyChecked_ ： 是否使用系统热键功能
 *  @_keyCode_       ： 热键的键盘代码值
 *  @_foreground_    ： 当显示窗口时，是否显示在前台
 * 返回值：
 *  TRUE    系统热键注册成功
 *  FALSE   系统热键注册失败（当前热键已被占用）
 * －－－－－－－－－－－－－－－－－－－－－－－－－ *
 */
BOOL EXPORT
    trayHotKey(TCHAR _icoPath_[], TCHAR _sTip_[][PATHMAX], BYTE _trayChecked_,
        BOOL _hotKeyChecked_, DWORD _keyCode_)
{
    hotKeyChecked = _hotKeyChecked_;
    keyCode     = _keyCode_;
    WORD vkCode = HIWORD(_keyCode_);
    WORD fsModi = LOWORD(_keyCode_);
    alawysShowTray = (BOOL)(_trayChecked_ & 0x01);
    minimizeToTray = (BOOL)(_trayChecked_ & 0x02);
    closeToTray    = (BOOL)(_trayChecked_ & 0x04);
    foreground     = (BOOL)(_trayChecked_ & 0x08);
    windTop        = (BOOL)(_trayChecked_ & 0x10);
    singleMode     = (BOOL)(_trayChecked_ & 0x20);
    minimizeToFm   = (BOOL)(_trayChecked_ & 0x40);
    for (int i = 0; i < 6; ++i)
    {
        _tcsncpy(trayStr[i], _sTip_[i], PATHMAX);
    }
    //MessageBox(NULL, trayStr[4], _T("DEBUG"), MB_OK);

    _tcsncpy(icoPath, _icoPath_, PATHMAX);
    if (icoPath[0] != L'\0')
    {
        hIcon = LoadImage(
                NULL, (LPCTSTR)icoPath, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
    }
    else
    {
        HMODULE hinst;
        hinst = GetModuleHandle(NULL);
        hIcon = LoadIcon(hinst, (LPCTSTR)32512);
    }

    nid.cbSize           = sizeof(NOTIFYICONDATA);
    nid.hWnd             = msghWnd;
    nid.uID              = 8;
    nid.uFlags           = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    nid.uCallbackMessage = WM_TRAYMESSAGE;
    nid.hIcon            = hIcon;
    trayStr[3][PATHMAX-1] = L'\0';
    _tcsncpy(nid.szTip, trayStr[3], sizeof(nid.szTip)/sizeof(TCHAR));
    nid.dwState        = 0;
    nid.dwStateMask    = 0;
    nid.szInfo[0]      = L'\0';
    nid.szInfoTitle[0] = L'\0';
    nid.dwInfoFlags    = NIIF_NONE;

    if (alawysShowTray)
        trayState = Shell_NotifyIcon(NIM_ADD, &nid);
    LPCTSTR ATOMSTR = L"A8B88113-DF09-4FCB-BF04-C70FB355CCFB";
    hotKeyID = GlobalAddAtom(ATOMSTR) - 0xC000;
    if (_hotKeyChecked_)
        hotKeyState = RegisterHotKey(msghWnd, hotKeyID, fsModi, vkCode);
    return hotKeyState;
}

void updatehWnds(void)
{
    DWORD id = GetCurrentProcessId();
    const TCHAR wClass[] = L"MozillaWindowClass";
    static DWORD wndId;
    HWND mainhWnd = FindWindow(wClass, NULL);
    for (int i = 0; i < WINMAX; ++i)
        win[i].occupied = FALSE;
    wincount = 0;
    const TCHAR *TitleFlags[] = {
        _T("Mozilla Firefox"),
        _T("Aurora"),
        _T("Nightly"),
        _T("Mozilla Thunderbird")
    };
    TCHAR title[1024] = {_T('\0')};
    TCHAR * lpTitle;
    BOOL hWndflags = FALSE;
    while (mainhWnd) {
        GetWindowThreadProcessId(mainhWnd, &wndId);
        if (wndId == id) {
            GetWindowText(mainhWnd, title, 1023);
            for (int i = 0; i < sizeof(TitleFlags) / sizeof(TCHAR *); i++)
            {
                lpTitle = _tcsstr(title, TitleFlags[i]);
                if (lpTitle != NULL) break;
            }
            if (lpTitle == NULL && trayStr[4][0] != _T('\0'))
                hWndflags = _strcmp(title);
            if (lpTitle != NULL || hWndflags) {
                    win[wincount].hWnd = mainhWnd;
                    win[wincount].hidden = (GetWindowLong(mainhWnd, GWL_STYLE)
                            & WS_VISIBLE) ? FALSE : TRUE;
                    win[wincount].occupied = TRUE;
                    win[wincount].subclassed = 
                        (GetWindowLong(mainhWnd, GWL_WNDPROC) == lpSubClassFun)
                            ? TRUE : FALSE;
                    ++wincount;
            }
        }
        mainhWnd = FindWindowEx(NULL, mainhWnd, wClass, NULL);
    }
}
void closeWin(HWND hWnd)
{
    int i = winIndex(hWnd);
    if (i == 0xFFFF) return;
    win[i].hWnd = 0;
    win[i].hidden = FALSE;
    win[i].occupied = FALSE;
    win[i].subclassed = FALSE;
    --wincount;
    //DestroyWindow(hWnd);
    if (!wincount)
    {
        PostMessage(msghWnd, WM_CLOSE, 0, 0);
        return;
    }
    if (singlehWnd == hWnd)
    {
        updatehWnds();
        singlehWnd = win[0].hWnd;
    }
}

LRESULT CALLBACK
    SubClassFunc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    /*
    TCHAR a[256] = {_T('\0')};
    _stprintf(a, _T("%lld"), hSysMenu);
    */
    switch (uMsg)
    {
        case WM_INITMENUPOPUP :
            /* 兼容 NT6.0 以上的操作系统 only fx4 */
            //if (windTop && !(BOOL)HIWORD(lParam) && 
            //        (HMENU)wParam == GetSystemMenu(hWnd, FALSE))
                //addMenu(hWnd, (HMENU)wParam);
            //else
                updataTopChecked(hWnd);
            break;
        case WM_SIZE :
            if (wParam == SIZE_MINIMIZED)
            {
                if (minimizeToTray) 
                    if (!singleMode || singlehWnd == hWnd)
                        ToTray(hWnd);
                if (windTop) fixMinimizeWinTop(hWnd);
                if (minimizeToFm)
                {
                    SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
                }
                return TRUE;
            }
            break;
        case WM_CLOSE :
            if (closeToTray && (!singleMode || singlehWnd == hWnd))
            {
                ToTray(hWnd);
                return TRUE;
            }
            /*
            else
            {
                closeWin(hWnd);
            }
            return TRUE;
            */
            break;
        case WM_DESTROY :
            closeWin(hWnd);
            break;
        case WM_SYSCOMMAND :
            if (wParam == IDM_SYS_TOP)
            {
                setWinTop(hWnd);
                return TRUE;
            }
            break;
    }
    return CallWindowProc(lpfnOldWndProc, hWnd, uMsg, wParam, lParam);
}

void ToTray(HWND hWnd)
{
    int i = winIndex(hWnd);
    if (i == 0xFFFF) return;
    if (trayState == FALSE)
        trayState = Shell_NotifyIcon(NIM_ADD, &nid);
    win[i].hidden = TRUE;
    ShowWindow(hWnd, SW_HIDE);
}

void quitApp(void)
{
    PostMessage(msghWnd, WM_CLOSE, 0, 0);
    for (int i = 0; i < WINMAX; ++i)
    {
        if (win[i].hWnd)
            DestroyWindow(win[i].hWnd);
        --wincount;
    }
}

void addMenu(HWND hWnd, HMENU hSysMenu)
{
    if (!hWnd || !hSysMenu) return;
    BOOL hWndChecked = GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST;
    UINT uFlags = hWndChecked ? (MF_STRING | MF_CHECKED) : MF_STRING;
    InsertMenu(hSysMenu, SC_RESTORE, uFlags, IDM_SYS_TOP, trayStr[5]);
}

void setWinTop(HWND hWnd)
{
    HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
    if (hSysMenu)
    {
        if (GetMenuState(hSysMenu, IDM_SYS_TOP, MF_BYCOMMAND) & MF_CHECKED)
        {
            SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
                    SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
            CheckMenuItem(hSysMenu, IDM_SYS_TOP, MF_BYCOMMAND | MF_UNCHECKED);
        }
        else
        {
            SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, 
                    SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
            CheckMenuItem(hSysMenu, IDM_SYS_TOP, MF_BYCOMMAND | MF_CHECKED);
        }
    }
}

void fixMinimizeWinTop(HWND hWnd)
{
    int i = winIndex(hWnd);
    if (i == 0xFFFF) return;
    HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
    if (GetMenuState(hSysMenu, IDM_SYS_TOP, MF_BYCOMMAND) & MF_CHECKED)
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, 
                    SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
}

void updataTopChecked(HWND hWnd)
{
    BOOL isTopMost = GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST;
    UINT isChecked = isTopMost ? MF_CHECKED : MF_UNCHECKED;
    HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
    CheckMenuItem(hSysMenu, IDM_SYS_TOP, MF_BYCOMMAND | isChecked);
}

void winSubClass(void)
{
    if (win[0].hWnd == 0)
        return;
    for (int i = 0; i < WINMAX; ++i)
    {
        if (win[i].occupied && !win[i].subclassed)
        {
            if (windTop)
                addMenu(win[i].hWnd, GetSystemMenu(win[i].hWnd, FALSE));
            if (!lpfnOldWndProc)
            {
                lpfnOldWndProc = (WNDPROC)GetWindowLong(
                        win[0].hWnd, GWL_WNDPROC);
            }
            SetWindowLong(win[i].hWnd, GWL_WNDPROC, (LONG)SubClassFunc);
            win[i].subclassed = TRUE;
        }
    }
}

void EXPORT initWin(void)
{
    updatehWnds();
    if (!singlehWnd && win[0].occupied)
        singlehWnd = win[0].hWnd;
    winSubClass();
}

BOOL EXPORT
initOpacity(BOOL _opacityChecked_, WORD _opacity_, BOOL _transChecked_,
        DWORD _transKC_)
{
    opacityChecked = _opacityChecked_;
    transChecked = _transChecked_;
    opacityValue = HIBYTE(_opacity_);
    transValue = LOBYTE(_opacity_);
    BYTE tmp = _opacityChecked_ ? opacityValue : 255;
    for (int i = 0; i < WINMAX; ++i)
    {
        if (win[i].occupied)
        {
            LONG dwExStyle = GetWindowLong(win[i].hWnd, GWL_EXSTYLE);
            SetWindowLong(win[i].hWnd, GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED);
            SetLayeredWindowAttributes(win[i].hWnd, 0, tmp, LWA_ALPHA);
        }
    }
    transKC = _transKC_;
    WORD vkCode = HIWORD(_transKC_);
    WORD fsModi = LOWORD(_transKC_);
    LPCTSTR ATOMSTR = _T("7B46B87C-3C57-424B-AA84-CC167C98991B");
    transID = GlobalAddAtom(ATOMSTR) - 0xC000;
    if (_transChecked_ && _opacityChecked_ && !transState)
        transState = RegisterHotKey(msghWnd, transID, fsModi, vkCode);
    return transState;
}

BOOL EXPORT setHotKey(BYTE flags, DWORD kc)
{
    if (flags & 0x01)
    {
        if (hotKeyState) {
            UnregisterHotKey(msghWnd, hotKeyID);
            hotKeyState = FALSE;
        }
        if (flags & 0x02)
            keyCode = kc;
        else
            hotKeyChecked = (BOOL)kc;
        if (!hotKeyChecked)
            return FALSE;
        kc = keyCode;
        hotKeyState = RegisterHotKey(msghWnd, hotKeyID, LOWORD(kc), HIWORD(kc));
        return hotKeyState;
    }
    else
    {
        if (transState)
        {
            UnregisterHotKey(msghWnd, transID);
            transState = FALSE;
        }
        if (flags & 0x02)
            transKC = kc;
        else if (flags != 0xFC)
            transChecked = (BOOL)kc;
        if (opacityChecked && transChecked)
        {
            kc = transKC;
            transState = RegisterHotKey(
                    msghWnd, transID, LOWORD(kc), HIWORD(kc)
            );
            return transState;
        }
        return FALSE;
    }
}
void EXPORT setOpacity(BOOL ot, BYTE value, BOOL option)
{
    if (option)
    {
        BYTE tmp = ot ? opacityValue : 255;
        opacityChecked = ot;
        for (int i = 0; i < WINMAX; ++i)
        {
            if (win[i].occupied)
            {
                if (singleMode && singlehWnd != win[i].hWnd)
                    continue;
                SetLayeredWindowAttributes(win[i].hWnd, 0, tmp, LWA_ALPHA);
            }
        }
    }
    else
    {
        if (ot)
        {
            opacityValue = value;
            if (!opacityChecked)
                return;
            for (int i = 0; i < WINMAX; ++i)
            {
                if (win[i].occupied)
                {
                    if (singleMode && singlehWnd != win[i].hWnd)
                        continue;
                    SetLayeredWindowAttributes(win[i].hWnd, 0, value,
                            LWA_ALPHA);
                }
            }
        }
        else
        {
            transValue = value;
        }
    }
}
void EXPORT setTray(BYTE tray, BOOL state)
{
    switch (tray)
    {
        case 0x01 :
            if (state)
            {
                trayState = Shell_NotifyIcon(NIM_ADD, &nid);
                alawysShowTray = TRUE;
            }
            else
            {
                trayState = FALSE;
                Shell_NotifyIcon(NIM_DELETE, &nid);
                alawysShowTray = FALSE;
            }
            break;
        case 0x02 :
            minimizeToTray = state;
            break;
        case 0x04 :
            closeToTray = state;
            break;
        case 0x08 :
            foreground = state;
            break;
    }
}

void EXPORT quit(void)
{
    PostMessage(msghWnd, WM_CLOSE, 0, 0);
}

BOOL _strcmp(TCHAR * title)
{
    TCHAR tempStr[PATHMAX] = {_T('\0')};
    BOOL stflags = FALSE;
    BYTE start, end;
    start = end = 0;
    for (int i = 0; i < PATHMAX; ++i)
    {
        TCHAR c = trayStr[4][i];
        if (!stflags && c != _T(' ') && c != _T('|') && c != _T('\0'))
        {
            stflags = TRUE;
            start = i;
        }
        if (stflags && (c == _T('|') || c == _T('\0') || i == PATHMAX-1))
        {
            stflags = FALSE;
            end = i;
            while (--end > start)
                if (trayStr[4][end] != _T(' '))
                    break;
            if (end == start)
                continue;
            _tcsncpy(tempStr, &trayStr[4][start], end - start + 1);
            tempStr[end-start+1] = _T('\0');
            TCHAR * result;
            result = _tcsstr(title, tempStr);
            if (result)
                return TRUE;
            //_tprintf(_T("|%s|\n"), tempStr);
            if (i == PATHMAX-1 || c == _T('\0'))
                return FALSE;
        }
    }
    return FALSE;
}

int winIndex(HWND hWnd)
{
    if (!hWnd) return 0xFFFF;
    for (int i = 0; i < WINMAX; ++i)
        if (win[i].hWnd == hWnd)
            return i;
    return 0xFFFF;
}

BOOL EXPORT onWinTop(TCHAR title[])
{
    if (title[0] == _T('\0')) return FALSE;
    TCHAR lpClassName[] = _T("MozillaWindowClass");
    HWND hWnd = FindWindow(lpClassName, title);
    if (!hWnd) return FALSE;
    BOOL isTopMost = GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST;
    HWND hia = isTopMost ? HWND_NOTOPMOST : HWND_TOPMOST;
    SetWindowPos(hWnd, hia, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
    return !isTopMost;
}

void EXPORT setMinimizeToFm(BOOL value)
{
    minimizeToFm = (BOOL)value;
}
