/*
 * 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

#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);

    len = LoadStringW(hcpl, IDS_SEC_SETTINGS, name, sizeof(name)/sizeof(*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;
}
