/*
 * Tab control
 *
 * Copyright 1998 Anders Carlsson
 *
 * TODO:
 *  Image list support
 *  Multiline support
 *  Unicode support
 *  Updown control support
 *  Look and feel
 *  Messages to be added in commctrl.h
 *  ...
 */

#include "windows.h"
#include "commctrl.h"
#include "tab.h"
#include "heap.h"
#include "win.h"
#include "debug.h"


#define TAB_GetInfoPtr(wndPtr) ((TAB_INFO *)wndPtr->wExtra[0])

static BOOL32
TAB_SendSimpleNotify (WND *wndPtr, UINT32 code)
{
    NMHDR nmhdr;

    nmhdr.hwndFrom = wndPtr->hwndSelf;
    nmhdr.idFrom = wndPtr->wIDmenu;
    nmhdr.code = code;

    return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
				    (WPARAM32) nmhdr.idFrom, (LPARAM) &nmhdr);
}

static LRESULT
TAB_GetCurSel (WND *wndPtr)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
 
    return infoPtr->iSelected;
}

static LRESULT
TAB_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
    POINT32 pt;
    RECT32 rect;
    INT32 iCount;

    pt.x = (INT32)LOWORD(lParam);
    pt.y = (INT32)HIWORD(lParam);

    GetClientRect32 (wndPtr->hwndSelf, &rect);

    if (PtInRect32 (&rect, pt))
    {
	for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
	    rect = infoPtr->items[iCount].rect;
	    if (PtInRect32 (&rect, pt)) {
		TRACE(tab, "On Tab, item %d\n", iCount);
		
		if (infoPtr->iSelected != iCount) {
			infoPtr->iSelected = iCount;

			TAB_SendSimpleNotify(wndPtr, TCN_SELCHANGE);
		}
		
		return 0;
	    }
	}
    }

    return 0;
}

static void 
TAB_SetItemBounds (WND *wndPtr)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
    RECT32 rect;
    HFONT32 hFont, hOldFont;
    INT32 i, left;
    SIZE32 size;
    HDC32 hdc;

    /* FIXME: Is this needed? */
    GetClientRect32 (wndPtr->hwndSelf, &rect);
    
    hdc = GetDC32(wndPtr->hwndSelf); 
    
    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
    hOldFont = SelectObject32 (hdc, hFont);

    left = rect.left;
    
    for (i = 0; i < infoPtr->uNumItem; i++)
    {
	infoPtr->items[i].rect.left = left;
	infoPtr->items[i].rect.top = infoPtr->rect.top;

	GetTextExtentPoint32A(hdc, 
			     infoPtr->items[i].pszText, 
			     lstrlen32A(infoPtr->items[i].pszText), &size);
	infoPtr->items[i].rect.right = left + size.cx+2*5;
        infoPtr->items[i].rect.bottom = infoPtr->rect.top + 20;
	TRACE(tab, "TextSize: %i - ", size.cx);
	TRACE(tab, "Rect: T %i, L %i, B %i, R %i\n", 
	      infoPtr->items[i].rect.top,
	      infoPtr->items[i].rect.left,
	      infoPtr->items[i].rect.bottom,
	      infoPtr->items[i].rect.right);	
	left += (size.cx + 11);
    }

    SelectObject32 (hdc, hOldFont);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
				 
static void
TAB_DrawItem (WND *wndPtr, HDC32 hdc, INT32 iItem)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
    TAB_ITEM *pti = &infoPtr->items[iItem];
    RECT32 r;
    INT32 oldBkMode;
   
    HPEN32	hwPen = CreatePen32 (PS_SOLID, 1, RGB (255, 255, 255 ));
    HPEN32	hbPen = CreatePen32 (PS_SOLID, 1, GetSysColor32 (COLOR_BTNSHADOW));
    HPEN32	hsdPen = CreatePen32(PS_SOLID, 1, GetSysColor32 (COLOR_BTNTEXT));
    HPEN32	htmpPen = (HPEN32)NULL;

    CopyRect32(&r, &pti->rect);

    htmpPen = hwPen;
    htmpPen = SelectObject32 (hdc, htmpPen);
    MoveToEx32 (hdc, r.left, r.bottom, NULL);
    LineTo32 (hdc, r.left, r.top + 2);
    LineTo32 (hdc, r.left +2, r.top);

    LineTo32 (hdc, r.right -1, r.top);
    htmpPen = SelectObject32 (hdc, htmpPen);

    htmpPen = SelectObject32 (hdc, hbPen);
    MoveToEx32 (hdc, r.right-1, r.top, NULL);
    LineTo32 (hdc,r.right-1, r.bottom-1);
    hbPen = SelectObject32 (hdc, hsdPen);
    MoveToEx32 (hdc, r.right, r.top+1, NULL);
    LineTo32(hdc, r.right,r.bottom);
    hsdPen = SelectObject32(hdc,htmpPen); 
    DeleteObject32(hwPen);
    DeleteObject32(hbPen);
    DeleteObject32(hsdPen);

    oldBkMode = SetBkMode32(hdc, TRANSPARENT);
    r.left += 3;
    r.right -= 3;
    SetTextColor32 (hdc, COLOR_BTNTEXT);
    DrawText32A(hdc, pti->pszText, lstrlen32A(pti->pszText),
	&r, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
    if (oldBkMode != TRANSPARENT)
	SetBkMode32(hdc, oldBkMode);
}

static void
TAB_DrawBorder (WND *wndPtr, HDC32 hdc)
{
    HPEN32 htmPen;
    HPEN32 hwPen = GetStockObject32(WHITE_PEN);
    HPEN32 hbPen = GetStockObject32(BLACK_PEN);
    HPEN32 hShade = CreatePen32 ( PS_SOLID, 1, GetSysColor32 (COLOR_BTNSHADOW));
    RECT32 rect;

    htmPen = SelectObject32 (hdc, hwPen);
    GetClientRect32 (wndPtr->hwndSelf, &rect);

    MoveToEx32 (hdc, rect.left, rect.bottom, NULL);
    LineTo32 (hdc, rect.left, rect.top+20); 

    LineTo32 (hdc, rect.right, rect.top+20);

    hwPen = SelectObject32 (hdc, htmPen);
    LineTo32 (hdc, rect.right, rect.bottom );
    LineTo32 (hdc, rect.left, rect.bottom);
    hbPen = SelectObject32 (hdc, hShade );
    MoveToEx32 (hdc, rect.right-1, rect.top+20, NULL);
    LineTo32 (hdc, rect.right-1, rect.bottom-1);
    LineTo32 (hdc, rect.left, rect.bottom-1);
    hShade = SelectObject32(hdc, hShade);
    DeleteObject32 (hShade);
}

    
static void
TAB_Refresh (WND *wndPtr, HDC32 hdc)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
    HFONT32 hFont, hOldFont;
    RECT32 rect;
    HBRUSH32 hbrBk;
    INT32 i;

    TAB_DrawBorder (wndPtr, hdc);

    for (i = 0; i < infoPtr->uNumItem; i++) {
	TAB_DrawItem (wndPtr, hdc, i);
    }

}

static LRESULT
TAB_Paint (WND *wndPtr, WPARAM32 wParam)
{
    HDC32 hdc;
    PAINTSTRUCT32 ps;
    
    hdc = wParam== 0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
    TAB_Refresh (wndPtr, hdc);
    
    if(!wParam)
	EndPaint32 (wndPtr->hwndSelf, &ps);
    return 0;
}

static LRESULT
TAB_InsertItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
    TCITEM *pti;
    HDC32  hdc;
    INT32 iItem, len;

    pti = (TCITEM*)lParam;
    iItem = (INT32)wParam;

    if (iItem < 0) return -1;
    if (iItem > infoPtr->uNumItem)
	iItem = infoPtr->uNumItem;

    if (infoPtr->uNumItem == 0) {
	infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
				    sizeof (TAB_ITEM));
	infoPtr->uNumItem++;
    }
    else {
	TAB_ITEM *oldItems = infoPtr->items;

	infoPtr->uNumItem++;
	infoPtr->items = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
				    sizeof (TAB_ITEM) * infoPtr->uNumItem);
	
	/* pre insert copy */
	if (iItem > 0) {
	    memcpy (&infoPtr->items[0], &oldItems[0],
		    iItem * sizeof(TAB_ITEM));
	}

	/* post insert copy */
	if (iItem < infoPtr->uNumItem - 1) {
	    memcpy (&infoPtr->items[iItem+1], &oldItems[iItem],
		    (infoPtr->uNumItem - iItem - 1) * sizeof(TAB_ITEM));

	}
	
	HeapFree (GetProcessHeap (), 0, oldItems);
    }

    infoPtr->items[iItem].mask = pti->mask;
    if (pti->mask & TCIF_TEXT) {
	len = lstrlen32A (pti->pszText);
	infoPtr->items[iItem].pszText = 
	    HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
	lstrcpy32A (infoPtr->items[iItem].pszText, pti->pszText);
	infoPtr->items[iItem].cchTextMax = pti->cchTextMax;
    }

    

    if (pti->mask & TCIF_IMAGE)
	infoPtr->items[iItem].iImage = pti->iImage;

    if (pti->mask & TCIF_PARAM)
	infoPtr->items[iItem].lParam = pti->lParam;

    hdc = GetDC32 (wndPtr->hwndSelf);
    TAB_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    TRACE(tab, "[%04x]: added item %d '%s'\n",
		wndPtr->hwndSelf, iItem, infoPtr->items[iItem].pszText);

    TAB_SetItemBounds(wndPtr);
    return iItem;
}

static LRESULT 
TAB_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TAB_INFO *infoPtr;

    infoPtr = (TAB_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
				     sizeof(TAB_INFO));
    wndPtr->wExtra[0] = (DWORD)infoPtr;
   
    infoPtr->uNumItem = 0;
    infoPtr->hFont = 0;
    infoPtr->items = 0;
    infoPtr->hcurArrow = LoadCursor32A (0, IDC_ARROW32A);
    infoPtr->iSelected = -1;  
  
    TRACE(tab, "Created tab control, hwnd [%04x]\n", wndPtr->hwndSelf); 
    return 0;
}

static LRESULT
TAB_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
    INT32 iItem;

    if (infoPtr->items) {
	for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) {
	    if (infoPtr->items[iItem].pszText)
		HeapFree (GetProcessHeap (), 0, infoPtr->items[iItem].pszText);
	}
	HeapFree (GetProcessHeap (), 0, infoPtr->items);
    }

    HeapFree (GetProcessHeap (), 0, infoPtr);
 
    return 0;
}

LRESULT WINAPI
TAB_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
    WND *wndPtr = WIN_FindWndPtr(hwnd);

    switch (uMsg)
    {

	case TCM_GETCURSEL:
	   return TAB_GetCurSel (wndPtr);

	case TCM_INSERTITEM:
	   return TAB_InsertItem (wndPtr, wParam, lParam);

	case WM_CREATE:
	    return TAB_Create (wndPtr, wParam, lParam);

	case WM_DESTROY:
	    return TAB_Destroy (wndPtr, wParam, lParam);

	case WM_LBUTTONUP:
	    return TAB_LButtonUp (wndPtr, wParam, lParam);
	case WM_PAINT:
	    return TAB_Paint (wndPtr, wParam);
	
	
	default:
	    if (uMsg >= WM_USER)
		ERR (tab, "unknown msg %04x wp=%08x lp=%08lx\n",
		     uMsg, wParam, lParam);
	    return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
    }
    return 0;
}


VOID
TAB_Register (VOID)
{
    WNDCLASS32A wndClass;

    if (GlobalFindAtom32A (WC_TABCONTROL32A)) return;

    ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
    wndClass.lpfnWndProc   = (WNDPROC32)TAB_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(TAB_INFO *);
    wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
    wndClass.hbrBackground = 0;
    wndClass.lpszClassName = WC_TABCONTROL32A;
 
    RegisterClass32A (&wndClass);
}


VOID
TAB_Unregister (VOID)
{
    if (GlobalFindAtom32A (WC_TABCONTROL32A))
	UnregisterClass32A (WC_TABCONTROL32A, (HINSTANCE32)NULL);
}

