/*
**
**    IconEdit.cpp
**
*/

#include "IconEdit.h"


//
// Construction dynamique
//

IconEdit::IconEdit(HWND hParent, LPRECT pCoord, UINT uUniqueID) 
         : m_hWndParent(hParent)
{
    SetRect(&m_rcCoord, pCoord->left, pCoord->top, pCoord->right, pCoord->bottom);
    m_hWndStatic     = NULL;
    m_hIcon             = NULL;
    m_pOldProcEdit   = NULL;
    m_bEditDyn       = false;

    m_hWndEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL,
                                WS_CHILD | WS_VISIBLE |
                                ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL, 
                                pCoord->left, pCoord->top,
                                pCoord->right-pCoord->left, pCoord->bottom-pCoord->top,
                                hParent, (HMENU)uUniqueID,
                                (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE), NULL);

    if( m_hWndEdit )
    {
        m_bEditDyn = true;
        subClassEdit();
    }
}

//
// Construction avec ID ressource
//

IconEdit::IconEdit(HWND hParent, UINT nIDEdit)
         : m_hWndParent(hParent)
{
    m_hWndStatic     = NULL;
    m_hIcon             = NULL;
    m_pOldProcEdit   = NULL;
    m_bEditDyn       = false;

    m_hWndEdit = GetDlgItem(hParent, nIDEdit);

    if( m_hWndEdit )
    {
        GetClientRect(m_hWndEdit, &m_rcCoord);
        subClassEdit();
    }
}

//
// Destruction
//

IconEdit::~IconEdit()
{
    if( m_hIcon )
        DestroyIcon(m_hIcon);
    if( m_hWndStatic )
        DestroyWindow(m_hWndStatic);
    if( m_hWndEdit )
    {
//        SetWindowLongPtr(m_hWndEdit, GWL_WNDPROC, (LONG_PTR)m_pOldProcEdit);
        SetWindowLong(m_hWndEdit, GWL_WNDPROC, (LONG)m_pOldProcEdit);
        if( m_bEditDyn  ) DestroyWindow(m_hWndEdit);
    }
}

//
// subClassEdit
// Sousclasse & stocke le Ptr sur this
// + cré–‘ le static enfant de l'edit
//

VOID IconEdit::subClassEdit()
{
    prepareWnd();
        
//    m_pOldProcEdit = (WNDPROC)SetWindowLongPtr(m_hWndEdit, GWL_WNDPROC,
//                     (LONG_PTR)IconEdit::Global_EditProc);
    m_pOldProcEdit = (WNDPROC)SetWindowLong(m_hWndEdit, GWL_WNDPROC,
                     (LONG)IconEdit::Global_EditProc);
    
//    SetWindowLongPtr(m_hWndEdit, GWL_USERDATA, (LONG_PTR)this);
    SetWindowLong(m_hWndEdit, GWL_USERDATA, (LONG)this);
    
    createEmbededStatic();
}

//
// setIcon
// Format n'est pas pour la taille mais pour quel format d'icone ?
// Le format 32/32 sera affich?en 16/16
//

VOID IconEdit::setIcon(UINT nIDIcon, int format)
{
    if( m_hIcon ) DestroyIcon(m_hIcon);

    m_hIcon = (HICON)LoadImage((HINSTANCE)GetWindowLong(m_hWndParent, GWL_HINSTANCE),
                               MAKEINTRESOURCE(nIDIcon), IMAGE_ICON, format, format,
                               LR_DEFAULTCOLOR);

    RedrawWindow(m_hWndStatic, NULL, NULL,
                 RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
}

//
// setIcon
//

VOID IconEdit::setIcon(HICON hIcon)
{
    if( hIcon )
    {
        if( m_hIcon ) DestroyIcon(m_hIcon);
        m_hIcon = hIcon;
        RedrawWindow(m_hWndStatic, NULL, NULL,
                     RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
    }
}

//
// prepareWnd
//

VOID IconEdit::prepareWnd()
{
    RECT rc;
    int width = GetSystemMetrics(SM_CXSMICON);
    SendMessage(m_hWndEdit, EM_GETRECT, 0, (LPARAM)&rc);
    rc.left += width + 6;
    SendMessage(m_hWndEdit, EM_SETRECTNP, 0, (LPARAM)&rc);
}

//
// createEmbededStatic
//

void IconEdit::createEmbededStatic()
{
    if( m_hWndEdit && !m_hWndStatic )
    {
        RECT editRect;
        SendMessage(m_hWndEdit, EM_GETRECT, 0, (LPARAM)&editRect);

        RECT iconRect = {1, 0, editRect.left-2, m_rcCoord.bottom-m_rcCoord.top};
        
        m_hWndStatic = CreateWindow("STATIC", NULL, 
                                    WS_CHILD | WS_VISIBLE | SS_OWNERDRAW,
                                    iconRect.left, iconRect.top,
                                    iconRect.right, iconRect.bottom,
                                    m_hWndEdit, NULL, GetModuleHandle(NULL), NULL);
    }
}

//
// WNDPROC Global_EditProc
//

LRESULT __stdcall IconEdit::Global_EditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    IconEdit* pThis = NULL;

    if( msg != WM_CREATE )
    {
//        pThis = (IconEdit*)GetWindowLongPtr(hWnd, GWL_USERDATA);
        pThis = (IconEdit*)GetWindowLong(hWnd, GWL_USERDATA);

        if( !pThis )
            return FALSE;
        else
            return pThis->EditProc(hWnd, msg, wParam, lParam);
    }
    else return FALSE;
}

//
// WNDPROC EditProc
//

LRESULT __stdcall IconEdit::EditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {
    case WM_SETFONT:
    case WM_SIZE:
        CallWindowProc(m_pOldProcEdit, hWnd, msg, wParam, lParam);
        prepareWnd();
        return 0;

    case WM_DRAWITEM:
    {
        RECT rect;
        LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
        if( lpdis->hwndItem == m_hWndStatic )
        {
            GetClientRect(lpdis->hwndItem, &rect);
            FillRect(lpdis->hDC, &rect, GetSysColorBrush(COLOR_WINDOW));
            int width  = GetSystemMetrics(SM_CXSMICON);
            int height = GetSystemMetrics(SM_CYSMICON);
            if( m_hIcon )
                DrawIconEx(lpdis->hDC, 1, 1, m_hIcon, width, height, 0, NULL, DI_NORMAL);
            return 1;
        }
    }   break;

    default:
        break;
    }

    return CallWindowProc(m_pOldProcEdit, hWnd, msg, wParam, lParam);
}