/*
 * Internet control panel applet: security propsheet
 *
 * Copyright 2011 Detlef Riekenberg
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */

#define COBJMACROS
#define CONST_VTABLE
#define NONAMELESSUNION

#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winuser.h>
#include <prsht.h>
#include "commctrl.h"

#include "ole2.h"
#include "urlmon.h"
#include "initguid.h"
#include "winreg.h"
#include "shlwapi.h"

#include "inetcpl.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);

typedef struct secdlg_data_s {
    HWND hsec;  /* security propsheet */
    HWND hlv;   /* listview */
    HWND htb;   /* trackbar */
    IInternetSecurityManager *sec_mgr;
    IInternetZoneManager *zone_mgr;
    DWORD zone_enumerator;
    DWORD num_zones;
    ZONEATTRIBUTES *zone_attr;
    DWORD *zones;
    DWORD *levels;
    HIMAGELIST himages;
    DWORD last_lv_index;
    DWORD last_level;
} secdlg_data;

#define NUM_TRACKBAR_POS 5

static DWORD url_templates[] = {URLTEMPLATE_CUSTOM,
                                URLTEMPLATE_LOW,
                                URLTEMPLATE_MEDLOW,
                                URLTEMPLATE_MEDIUM,
                                URLTEMPLATE_MEDHIGH,
                                URLTEMPLATE_HIGH};

/*********************************************************************
 * index_from_urltemplate [internal]
 *
 */
static DWORD index_from_urltemplate(URLTEMPLATE value)
{

    DWORD index = sizeof(url_templates) / sizeof(url_templates[0]);

    while((index > 0) && (url_templates[index-1] != value))
        index--;

    index--; /* table entries are 0 based */
    if (!index && value)
        FIXME("URLTEMPLATE 0x%x not supported\n", value);

    TRACE("URLTEMPLATE 0x%08x=> Level %d\n", value, index);
    return index;
}

/*********************************************************************
 * update_security_level [internal]
 *
 */
static void update_security_level(secdlg_data *sd, DWORD lv_index, DWORD tb_index)
{
    WCHAR name[512];
    DWORD current_index;

    TRACE("(%p, lv_index: %u, tb_index: %u)\n", sd, lv_index, tb_index);

    if ((sd->levels[lv_index] != sd->last_level) || (tb_index > 0)) {
        /* show or hide the trackbar */
        if (!sd->levels[lv_index] || !sd->last_level)
            ShowWindow(sd->htb, sd->levels[lv_index] ? SW_NORMAL : SW_HIDE);

        current_index = (tb_index > 0) ? tb_index : index_from_urltemplate(sd->levels[lv_index]);

        name[0] = 0;
        LoadStringW(hcpl, IDS_SEC_LEVEL0 + current_index, name, sizeof(name)/sizeof(name[0]));
        TRACE("new level #%d: %s\n", current_index, debugstr_w(name));
        SetWindowTextW(GetDlgItem(sd->hsec, IDC_SEC_LEVEL), name);

        name[0] = 0;
        LoadStringW(hcpl, IDS_SEC_LEVEL0_INFO + (current_index * 0x10), name, sizeof(name)/sizeof(name[0]));
        TRACE("new level info: %s\n", debugstr_w(name));
        SetWindowTextW(GetDlgItem(sd->hsec, IDC_SEC_LEVEL_INFO), name);

        if (current_index)
            SendMessageW(sd->htb, TBM_SETPOS, TRUE, NUM_TRACKBAR_POS - current_index);

        sd->last_level = sd->levels[lv_index];

    }
}

/*********************************************************************
 * update_zone_info [internal]
 *
 */
static void update_zone_info(secdlg_data *sd, DWORD lv_index)
{
    ZONEATTRIBUTES *za = &sd->zone_attr[lv_index];
    WCHAR name[MAX_PATH];
    DWORD len;

    SetWindowTextW(GetDlgItem(sd->hsec, IDC_SEC_ZONE_INFO), za->szDescription);

    LoadStringW(hcpl, IDS_SEC_SETTINGS, name, sizeof(name)/sizeof(*name));
    len = lstrlenW(name);
    lstrcpynW(&name[len], za->szDisplayName, sizeof(name)/sizeof(*name) - len - 1);

    TRACE("new title: %s\n", debugstr_w(name));
    SetWindowTextW(GetDlgItem(sd->hsec, IDC_SEC_GROUP), name);

    update_security_level(sd, lv_index, 0);
    sd->last_lv_index = lv_index;
}

/*********************************************************************
 * add_zone_to_listview [internal]
 *
 */
static void add_zone_to_listview(secdlg_data *sd, DWORD *pindex, DWORD zone)
{
    DWORD lv_index = *pindex;
    ZONEATTRIBUTES *za = &sd->zone_attr[lv_index];
    LVITEMW lvitem;
    HRESULT hr;
    INT iconid = 0;
    HMODULE hdll = NULL;
    WCHAR * ptr;
    HICON icon;

    TRACE("item %d (zone %d)\n", lv_index, zone);

    sd->zones[lv_index] = zone;

    memset(&lvitem, 0, sizeof(LVITEMW));
    memset(za, 0, sizeof(ZONEATTRIBUTES));
    za->cbSize = sizeof(ZONEATTRIBUTES);
    hr = IInternetZoneManager_GetZoneAttributes(sd->zone_mgr, zone, za);
    if (SUCCEEDED(hr)) {
        TRACE("displayname: %s\n", debugstr_w(za->szDisplayName));
        TRACE("description: %s\n", debugstr_w(za->szDescription));
        TRACE("minlevel: 0x%x, recommended: 0x%x, current: 0x%x (flags: 0x%x)\n", za->dwTemplateMinLevel,
             za->dwTemplateRecommended, za->dwTemplateCurrentLevel, za->dwFlags);

        if (za->dwFlags & ZAFLAGS_NO_UI ) {
            TRACE("item %d (zone %d): UI disabled for %s\n", lv_index, zone, debugstr_w(za->szDisplayName));
            return;
        }

        sd->levels[lv_index] = za->dwTemplateCurrentLevel;

        lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
        lvitem.iItem = lv_index;
        lvitem.iSubItem = 0;
        lvitem.pszText = za->szDisplayName;
        lvitem.lParam = (LPARAM) zone;

        /* format is "filename.ext#iconid" */
        ptr = StrChrW(za->szIconPath, '#');
        if (ptr) {
            *ptr = 0;
            ptr++;
            iconid = StrToIntW(ptr);
            hdll = LoadLibraryExW(za->szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
            TRACE("%p: icon #%d from %s\n", hdll, iconid, debugstr_w(za->szIconPath));

            icon = LoadImageW(hdll, MAKEINTRESOURCEW(iconid), IMAGE_ICON, GetSystemMetrics(SM_CXICON),
                              GetSystemMetrics(SM_CYICON), LR_SHARED);

            if (!icon) {
                FIXME("item %d (zone %d): missing icon #%d in %s\n", lv_index, zone, iconid, debugstr_w(za->szIconPath));
            }

            /* the failure result (NULL) from LoadImageW let ImageList_AddIcon fail
               with -1, which is reused in ListView_InsertItemW to disable the image */
            lvitem.iImage = ImageList_AddIcon(sd->himages, icon);
        }
        else
            FIXME("item %d (zone %d): malformed szIconPath %s\n", lv_index, zone, debugstr_w(za->szIconPath));

        if (ListView_InsertItemW(sd->hlv, &lvitem) >= 0) {
            /* activate first item in the listview */
            if (! lv_index) {
                lvitem.state = LVIS_FOCUSED | LVIS_SELECTED;
                lvitem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
                SendMessageW(sd->hlv, LVM_SETITEMSTATE, 0, (LPARAM) &lvitem);
                sd->last_level = ~0;
                update_zone_info(sd, lv_index);
            }
            (*pindex)++;
        }
        FreeLibrary(hdll);
    }
    else
        FIXME("item %d (zone %d): GetZoneAttributes failed with 0x%x\n", lv_index, zone, hr);
}

/*********************************************************************
 * security_cleanup_zones [internal]
 *
 */
static void security_cleanup_zones(secdlg_data *sd)
{
    if (sd->zone_enumerator) {
        IInternetZoneManager_DestroyZoneEnumerator(sd->zone_mgr, sd->zone_enumerator);
    }

    if (sd->zone_mgr) {
        IInternetZoneManager_Release(sd->zone_mgr);
    }

    if (sd->sec_mgr) {
        IInternetSecurityManager_Release(sd->sec_mgr);
    }
}

/*********************************************************************
 * security_enum_zones [internal]
 *
 */
static HRESULT security_enum_zones(secdlg_data * sd)
{
    HRESULT hr;

    hr = CoInternetCreateSecurityManager(NULL, &sd->sec_mgr, 0);
    if (SUCCEEDED(hr)) {
        hr = CoInternetCreateZoneManager(NULL, &sd->zone_mgr, 0);
        if (SUCCEEDED(hr)) {
            hr = IInternetZoneManager_CreateZoneEnumerator(sd->zone_mgr, &sd->zone_enumerator, &sd->num_zones, 0);
        }
    }
    return hr;
}

/*********************************************************************
 * security_on_destroy [internal]
 *
 * handle WM_NCDESTROY
 *
 */
static INT_PTR security_on_destroy(secdlg_data * sd)
{
    TRACE("(%p)\n", sd);

    heap_free(sd->zone_attr);
    heap_free(sd->zones);
    if (sd->himages) {
        SendMessageW(sd->hlv, LVM_SETIMAGELIST, LVSIL_NORMAL, 0);
        ImageList_Destroy(sd->himages);
    }

    security_cleanup_zones(sd);
    SetWindowLongPtrW(sd->hsec, DWLP_USER, 0);
    heap_free(sd);
    return TRUE;
}

/*********************************************************************
 * security_on_initdialog [internal]
 *
 * handle WM_INITDIALOG
 *
 */
static INT_PTR security_on_initdialog(HWND hsec)
{
    secdlg_data *sd;
    HRESULT hr;
    DWORD current_zone;
    DWORD lv_index = 0;
    DWORD i;

    sd = heap_alloc_zero(sizeof(secdlg_data));
    SetWindowLongPtrW(hsec, DWLP_USER, (LONG_PTR) sd);
    if (!sd) {
        return FALSE;
    }

    sd->hsec = hsec;
    sd->hlv = GetDlgItem(hsec, IDC_SEC_LISTVIEW);
    sd->htb = GetDlgItem(hsec, IDC_SEC_TRACKBAR);

    EnableWindow(sd->htb, FALSE); /* not changeable yet */

    TRACE("(%p)   (data: %p, listview: %p, trackbar: %p)\n", hsec, sd, sd->hlv, sd->htb);

    SendMessageW(sd->htb, TBM_SETRANGE, FALSE, MAKELONG(0, NUM_TRACKBAR_POS - 1));
    SendMessageW(sd->htb, TBM_SETTICFREQ, 1, 0 );

    /* Create the image lists for the listview */
    sd->himages = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32 | ILC_MASK, 1, 1);

    TRACE("using imagelist: %p\n", sd->himages);
    if (!sd->himages) {
        ERR("ImageList_Create failed!\n");
        return FALSE;
    }
    SendMessageW(sd->hlv, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)sd->himages);

    hr = security_enum_zones(sd);
    if (FAILED(hr)) {
        ERR("got 0x%x\n", hr);
        security_on_destroy(sd);
        return FALSE;
    }

    TRACE("found %d zones\n", sd->num_zones);

    /* remember ZONEATTRIBUTES for a listview entry */
    sd->zone_attr = heap_alloc(sizeof(ZONEATTRIBUTES) * sd->num_zones);
    if (!sd->zone_attr) {
        security_on_destroy(sd);
        return FALSE;
    }

    /* remember zone number and current security level for a listview entry */
    sd->zones = heap_alloc((sizeof(DWORD) + sizeof(DWORD)) * sd->num_zones);
    if (!sd->zones) {
        security_on_destroy(sd);
        return FALSE;
    }
    sd->levels = &sd->zones[sd->num_zones];

    /* use the same order as visible with native inetcpl.cpl */
    add_zone_to_listview(sd, &lv_index, URLZONE_INTERNET);
    add_zone_to_listview(sd, &lv_index, URLZONE_INTRANET);
    add_zone_to_listview(sd, &lv_index, URLZONE_TRUSTED);
    add_zone_to_listview(sd, &lv_index, URLZONE_UNTRUSTED);

    for (i = 0; i < sd->num_zones; i++)
    {
        hr = IInternetZoneManager_GetZoneAt(sd->zone_mgr, sd->zone_enumerator, i, &current_zone);
        if (SUCCEEDED(hr) && (current_zone != (DWORD)URLZONE_INVALID)) {
            if (!current_zone || (current_zone > URLZONE_UNTRUSTED)) {
                add_zone_to_listview(sd, &lv_index, current_zone);
            }
        }
    }
    return TRUE;
}

/*********************************************************************
 * security_on_notify [internal]
 *
 * handle WM_NOTIFY
 *
 */
static INT_PTR security_on_notify(secdlg_data *sd, WPARAM wparam, LPARAM lparam)
{
    NMLISTVIEW *nm;

    nm = (NMLISTVIEW *) lparam;
    switch (nm->hdr.code)
    {
        case LVN_ITEMCHANGED:
            TRACE("LVN_ITEMCHANGED (0x%lx, 0x%lx) from %p with code: %d (item: %d, uNewState: %u)\n",
                    wparam, lparam, nm->hdr.hwndFrom, nm->hdr.code, nm->iItem, nm->uNewState);
            if ((nm->uNewState & LVIS_SELECTED) == LVIS_SELECTED) {
                update_zone_info(sd, nm->iItem);
            }
            break;

        case PSN_APPLY:
            TRACE("PSN_APPLY (0x%lx, 0x%lx) from %p with code: %d\n", wparam, lparam,
                    nm->hdr.hwndFrom, nm->hdr.code);
            break;

        default:
            TRACE("WM_NOTIFY (0x%lx, 0x%lx) from %p with code: %d\n", wparam, lparam,
                    nm->hdr.hwndFrom, nm->hdr.code);

    }
    return FALSE;
}

/*********************************************************************
 * security_dlgproc [internal]
 *
 */
INT_PTR CALLBACK security_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    secdlg_data *sd;

    if (msg == WM_INITDIALOG) {
        return security_on_initdialog(hwnd);
    }

    sd = (secdlg_data *)GetWindowLongPtrW(hwnd, DWLP_USER);
    if (sd) {
        switch (msg)
        {
            case WM_NOTIFY:
                return security_on_notify(sd, wparam, lparam);

            case WM_NCDESTROY:
                return security_on_destroy(sd);

            default:
                /* do not flood the log */
                if ((msg == WM_SETCURSOR) || (msg == WM_NCHITTEST) ||
                    (msg == WM_MOUSEMOVE) || (msg == WM_MOUSEACTIVATE) || (msg == WM_PARENTNOTIFY))
                    return FALSE;

                TRACE("(%p, 0x%08x/%03d, 0x%08lx, 0x%08lx)\n", hwnd, msg, msg, wparam, lparam);
        }
    }
    return FALSE;
}
