/*
**
*    Application.cpp
**
*/

#include "Application.h"

#include <cstdio>


//
// Initialise attributs
//

WINTYPE       Application::g_Types[MAX_WINTYPE] = {0,0,0};
HIMAGELIST Application::g_hImageList         = NULL;
UINT       Application::g_nbrTypes           = 0;
int        Application::g_nSelectItem         = -1;
HFONT      Application::g_fontList           = NULL;
IconEdit*  Application::g_edNewType             = NULL;
IconEdit*  Application::g_edNewIntegral         = NULL;
IconEdit*  Application::g_edNewInfo          = NULL;


//
// OnInitDialog()
//

void Application::OnInitDialog(HINSTANCE hInst, HWND hDlg)
{
    // Icones
    HICON hicon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MYICON));
    SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hicon);
    SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hicon);

    // ImageList
    g_hImageList = ImageList_LoadImage(hInst, MAKEINTRESOURCE(IDB_IMGLIST), CX_BITMAP, 1,
                                       RGB(0,255,0), IMAGE_BITMAP, LR_DEFAULTCOLOR);
    
    // Fonte pour liste
    g_fontList = CreateFont(15, 0, 0, 0, FW_MEDIUM, 0, 0, 0, ANSI_CHARSET,
                           OUT_DEFAULT_PRECIS,
                           CLIP_DEFAULT_PRECIS,
                           NONANTIALIASED_QUALITY,
                           DEFAULT_PITCH,
                           "Times New Roman");

    // Limite le texte des edit
    SendDlgItemMessage(hDlg, IDC_EDITNEWTYPEDEF, EM_LIMITTEXT, (WPARAM)64, 0);
    SendDlgItemMessage(hDlg, IDC_EDITNEWINTEGRAL, EM_LIMITTEXT, (WPARAM)64, 0);
    SendDlgItemMessage(hDlg, IDC_EDITNEWINFOS, EM_LIMITTEXT, (WPARAM)192, 0);

    // Rempli combo
    const TCHAR* szType[11] = {"VARIANT","CHAR","INT","REAL","STRING","BOOL",
                               "STRUCT","MODIFICATEUR","POINTEUR","FUNCTION PTR","HANDLE"};
    for(int i=0; i<11; i++)
    {
        SendDlgItemMessage(hDlg, IDC_COMBOINDICE, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szType[i]);
    }
    SendDlgItemMessage(hDlg, IDC_COMBOINDICE, CB_SETCURSEL, (WPARAM)0, 0);

    // Les iconEdit
    g_edNewType = new IconEdit(hDlg, IDC_EDITNEWTYPEDEF);
    g_edNewType->setIcon(IDI_MYICON);
    
    g_edNewIntegral = new IconEdit(hDlg, IDC_EDITNEWINTEGRAL);
    g_edNewIntegral->setIcon(IDI_MYICON);

    g_edNewInfo = new IconEdit(hDlg, IDC_EDITNEWINFOS);
    g_edNewInfo->setIcon(IDI_ICONTEST, 16);

    // Donn閑s de l'app
    if( LoadData(hDlg) )
    {
        InitListe(hDlg);
    }
}

//
// OnCleanUp()
//

void Application::OnCleanUp()
{
    if( g_hImageList ) 
        ImageList_Destroy(g_hImageList);
    if( g_fontList )
        DeleteObject(g_fontList);

    if( g_edNewType ) 
        delete g_edNewType;
    if( g_edNewIntegral ) 
        delete g_edNewIntegral;
    if( g_edNewInfo )
        delete g_edNewInfo;
}

//
// LoadData
//

bool Application::LoadData(HWND hDlg)
{
    g_nbrTypes = 0;

    const char sep[] = ";\r\n";
    char bufLigne[512];
    char bufError[128];
    FILE* file;
    
    if( (file = fopen(USER_FILE, "rt")) == NULL ) 
        goto ERROR_HANDLER;

    while( fgets(bufLigne, 512, file) != NULL )
    {
        int numChamp = 0;
        char *token;

        token = strtok(bufLigne, sep);
        while( token != NULL )
        {
            switch( numChamp )
            {
            case 0:
                strcpy(g_Types[g_nbrTypes].szTypedef, token);
                break;
            case 1:
                strcpy(g_Types[g_nbrTypes].szTypeIntegral, token);
                break;
            case 2:
                g_Types[g_nbrTypes].nImage = atoi(token);
                break;
            case 3:
                strcpy(g_Types[g_nbrTypes].szInfos, token);
                break;
            }

            token = strtok(NULL, sep);
            numChamp++;
        }

        if( numChamp != 4 )
            goto ERROR_HANDLER;

        if( g_nbrTypes++ >= MAX_WINTYPE ) 
            break;
    }

    fclose(file);
    return true;

ERROR_HANDLER:
    sprintf(bufError, "Erreur sur le fichier de donn閑s : %s", USER_FILE);
    MessageBox(hDlg, bufError, "Erreur", MB_OK | MB_ICONERROR);
    return false;
}

//
// InitListe    
//

void Application::InitListe(HWND hDlg)
{
    SendDlgItemMessage(hDlg, IDC_LIST1, LB_RESETCONTENT, 0, 0);
    SendDlgItemMessage(hDlg, IDC_LIST1, WM_SETREDRAW, FALSE, 0);
    
    for(UINT i=0; i<g_nbrTypes; i++)
    {
        SendDlgItemMessage(hDlg, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)g_Types[i].szTypedef);
        SendDlgItemMessage(hDlg, IDC_LIST1, LB_SETITEMDATA, i, (LPARAM)g_Types[i].nImage);
    }

    SendDlgItemMessage(hDlg, IDC_LIST1, WM_SETREDRAW, TRUE, 0);
    SendDlgItemMessage(hDlg, IDC_LIST1, LB_SETCURSEL, 0, 0);
    g_nSelectItem = 0;

    OnSelChange(hDlg);
}

//
// OnSelChange
//

void Application::OnSelChange(HWND hDlg)
{
    if( g_nSelectItem != -1 )
    {
        SendDlgItemMessage(hDlg, IDC_EDIT_INTEGRAL, WM_SETTEXT, 0,
                           (LPARAM)g_Types[g_nSelectItem].szTypeIntegral);
        SendDlgItemMessage(hDlg, IDC_LABEL_INFO, WM_SETTEXT, 0,
                           (LPARAM)g_Types[g_nSelectItem].szInfos);
    }
}

//
// OnDrawListItem
//

BOOL Application::OnDrawListItem(LPDRAWITEMSTRUCT lpItem)
{
    TCHAR  szBuf[256];
    RECT   rect;
    DWORD  crText, crBack;
    HBRUSH hbrBack;
    HFONT  oldFont;

    if( lpItem->itemID == -1 )
        return FALSE;

    switch( lpItem->itemAction ) 
    {
    case ODA_SELECT: 
    case ODA_DRAWENTIRE: 
        if( lpItem->itemState & ODS_SELECTED ) 
        {
            crBack = GetSysColor(COLOR_HIGHLIGHT);
            crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
            
            if( (hbrBack = CreateSolidBrush(crBack)) != NULL ) 
            {
                FillRect(lpItem->hDC, &lpItem->rcItem, hbrBack);
                DeleteObject(hbrBack);
            }
        }
        else
        {
            crBack = GetSysColor(COLOR_WINDOW);
            crText = GetSysColor(COLOR_WINDOWTEXT);

            if( (hbrBack = CreateSolidBrush(crBack)) != NULL ) 
            {
                FillRect(lpItem->hDC, &lpItem->rcItem, hbrBack);
                DeleteObject(hbrBack);
            }
        }
    
        ImageList_Draw(g_hImageList, (int)lpItem->itemData,
                       lpItem->hDC,
                       lpItem->rcItem.left + 2,
                       lpItem->rcItem.top,
                       ILD_NORMAL);

        SendMessage(lpItem->hwndItem, LB_GETTEXT, lpItem->itemID, (LPARAM)(LPCTSTR)szBuf);
        rect.left   = lpItem->rcItem.left + CX_BITMAP + 10; 
        rect.top    = lpItem->rcItem.top;
        rect.right  = lpItem->rcItem.right;
        rect.bottom = lpItem->rcItem.bottom;
        SetBkMode(lpItem->hDC, TRANSPARENT);
        SetTextColor(lpItem->hDC, crText);
        if( g_fontList ) oldFont = (HFONT)SelectObject(lpItem->hDC, g_fontList);
        DrawText(lpItem->hDC, szBuf, lstrlen(szBuf), &rect, DT_SINGLELINE | DT_VCENTER);
        if( oldFont ) SelectObject(lpItem->hDC, oldFont);
        return TRUE;

    case ODA_FOCUS:
        DrawFocusRect(lpItem->hDC, &lpItem->rcItem);
        return TRUE;
    }

    return FALSE;
}

//
// OnCtlColorStatic()
//

HBRUSH Application::OnCtlColorStatic(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
    if( (HWND)lParam == GetDlgItem(hDlg, IDC_LABEL_INFO) )
    {
        SetBkMode((HDC)wParam, TRANSPARENT);
        SetBkColor((HDC)wParam, (COLORREF)GetSysColor(COLOR_3DFACE));
        SetTextColor((HDC)wParam, RGB(130,40,0));
        return GetSysColorBrush(COLOR_3DFACE);
    }
    else if( (HWND)lParam == GetDlgItem(hDlg, IDC_EDIT_INTEGRAL) )
    {
        SetBkMode((HDC)wParam, TRANSPARENT);
        SetBkColor((HDC)wParam, (COLORREF)GetSysColor(COLOR_WINDOW));
        SetTextColor((HDC)wParam, RGB(0,0,210));
        return GetSysColorBrush(COLOR_WINDOW);
    }

    return (HBRUSH)0;
}

//
// OnCtlColorEdit
//

HBRUSH Application::OnCtlColorEdit(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
    return (HBRUSH)0;
}

//
// OnAddNewTypedef
//

void Application::OnAddNewTypedef(HWND hDlg)
{
    char szErr[128] = "";
    char szTypedef[64];
    char szTypeIntegral[64];
    char szInfos[192];
    char szNumImg[4];
    int  numImage = 0;

    numImage = SendDlgItemMessage(hDlg, IDC_COMBOINDICE, CB_GETCURSEL, 0, 0);
    if( numImage == CB_ERR )
    {
        strcpy(szErr, "Vous devez choisir un type pour l'image de la liste");
        goto ERROR_HANDLER;
    }
    else itoa(numImage, szNumImg, 10);
    
    GetWindowText(g_edNewType->getSafeHwnd(), szTypedef, 63);
    GetWindowText(g_edNewIntegral->getSafeHwnd(), szTypeIntegral, 63);
    GetWindowText(g_edNewInfo->getSafeHwnd(), szInfos, 191);

    if( strlen(szTypedef) < 1 || strlen(szTypeIntegral) < 1 || strlen(szInfos) < 1 )
    {
        strcpy(szErr, "Vous devez remplir tous les champs demand閟");
        goto ERROR_HANDLER;
    }

    // Ecrit la nouvelle entr閑
    FILE* file;
    
    if( (file = fopen(USER_FILE, "a")) == NULL )
    {
        strcpy(szErr, "Probl鑝e avec le ficher de donn閑s TYPEDEF.dat");
        goto ERROR_HANDLER;
    }

    fprintf(file, "\r\n%s;%s;%s;%s", szTypedef, szTypeIntegral, szNumImg, szInfos);
    fclose(file);

    // R閍juste donn閑s de l'app
    if( LoadData(hDlg) )
    {
        InitListe(hDlg);
    }

    SendDlgItemMessage(hDlg, IDC_LIST1, LB_SETCURSEL, (WPARAM)g_nbrTypes-1, 0);
    g_nSelectItem = g_nbrTypes-1;
    OnSelChange(hDlg);

    MessageBox(hDlg, "Une nouvelle entr閑 a bien 閠?ajout閑...", "Info", MB_OK|MB_ICONINFORMATION);
    return;

ERROR_HANDLER:
    MessageBox(hDlg, szErr, "Erreur", MB_OK | MB_ICONERROR);
    SetFocus(g_edNewType->getSafeHwnd());
}