/*
 * Interface code to SCROLLBAR widget
 *
 * Copyright  Martin Ayotte, 1993
 *
 */

/*
#define DEBUG_SCROLL
*/

static char Copyright[] = "Copyright Martin Ayotte, 1993";

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include "windows.h"
#include "scroll.h"
#include "heap.h"
#include "win.h"
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr);
LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd);
void StdDrawScrollBar(HWND hwnd);
int CreateScrollBarStruct(HWND hwnd);


/***********************************************************************
 *           WIDGETS_ScrollBarWndProc
 */
LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
{    
    WORD	wRet;
    short	x, y;
    WND  	*wndPtr;
    LPHEADSCROLL lphs;
    RECT rect;
    static RECT rectsel;
    switch(message)
    {
    case WM_CREATE:
	CreateScrollBarStruct(hwnd);
#ifdef DEBUG_SCROLL
        printf("ScrollBar Creation up=%X down=%X!\n", lphs->hWndUp, lphs->hWndDown);
#endif
	return 0;
    case WM_DESTROY:
	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
	if (lphs == 0) return 0;
#ifdef DEBUG_SCROLL
        printf("ScrollBar WM_DESTROY %lX !\n", lphs);
#endif
	DestroyWindow(lphs->hWndUp);
	DestroyWindow(lphs->hWndDown);
	free(lphs);
	*((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
	return 0;
	
    case WM_COMMAND:
#ifdef DEBUG_SCROLL
        printf("ScrollBar WM_COMMAND wParam=%X lParam=%lX !\n", wParam, lParam);
#endif
	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
	if (HIWORD(lParam) != BN_CLICKED) return 0;
        if (LOWORD(lParam) == lphs->hWndUp)
            SendMessage(wndPtr->hwndParent, lphs->Direction, 
            	SB_LINEUP, MAKELONG(0, hwnd));
        if (LOWORD(lParam) == lphs->hWndDown)
            SendMessage(wndPtr->hwndParent, lphs->Direction, 
            	SB_LINEDOWN, MAKELONG(0, hwnd));
/*
	SetFocus(hwnd);
*/
	return 0;

    case WM_LBUTTONDOWN:
	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
/*
	SetFocus(hwnd);
*/
	SetCapture(hwnd);
	GetClientRect(hwnd, &rect);
	if (lphs->Direction == WM_VSCROLL) {
	    y = HIWORD(lParam);
#ifdef DEBUG_SCROLL
	    printf("WM_LBUTTONDOWN y=%d cur+right=%d %d\n", 
	    	y, lphs->CurPix + rect.right, lphs->CurPix + (rect.right << 1));
#endif
	    if (y < (lphs->CurPix + rect.right)) 
	        SendMessage(wndPtr->hwndParent, lphs->Direction, 
	        	SB_PAGEUP, MAKELONG(0, hwnd));
	    if (y > (lphs->CurPix + (rect.right << 1))) 
	        SendMessage(wndPtr->hwndParent, lphs->Direction, 
	        	SB_PAGEDOWN, MAKELONG(0, hwnd));
	    if ((y > (lphs->CurPix + rect.right)) &&
	        (y < (lphs->CurPix + (rect.right << 1)))) {
	        lphs->ThumbActive = TRUE;
#ifdef DEBUG_SCROLL
	        printf("THUMB DOWN !\n");
#endif
	        }
	    }
	else {
	    x = LOWORD(lParam);
#ifdef DEBUG_SCROLL
	    printf("WM_LBUTTONDOWN x=%d Cur+bottom=%d %d\n",
	    	 x, lphs->CurPix + rect.bottom, lphs->CurPix + (rect.bottom << 1));
#endif
	    if (x < (lphs->CurPix + rect.bottom))
	        SendMessage(wndPtr->hwndParent, lphs->Direction, 
	        	SB_PAGEUP, MAKELONG(0, hwnd));
	    if (x > (lphs->CurPix + (rect.bottom << 1)))
	        SendMessage(wndPtr->hwndParent, lphs->Direction, 
	        	SB_PAGEDOWN, MAKELONG(0, hwnd));
	    if ((x > (lphs->CurPix + rect.bottom)) &&
		(x < (lphs->CurPix + (rect.bottom << 1)))) {
	        lphs->ThumbActive = TRUE;
#ifdef DEBUG_SCROLL
	        printf("THUMB DOWN !\n");
#endif
		}
	    }
	break;
    case WM_LBUTTONUP:
	lphs = ScrollBarGetStorageHeader(hwnd);
        lphs->ThumbActive = FALSE;
	ReleaseCapture();
	break;

    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_CHAR:
	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
	return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));

    case WM_PAINT:
	StdDrawScrollBar(hwnd);
	break;
    case WM_MOUSEMOVE:
        if ((wParam & MK_LBUTTON) != 0) {
	    lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
	    if (lphs->ThumbActive == 0) break;
	    GetClientRect(hwnd, &rect);
	    if (lphs->Direction == WM_VSCROLL)
		y = HIWORD(lParam) - rect.right - (rect.right >> 1);
	    else
		y = LOWORD(lParam) - rect.bottom - (rect.bottom >> 1);
	    x = (y * (lphs->MaxVal - lphs->MinVal) / 
	    		lphs->MaxPix) + lphs->MinVal;
#ifdef DEBUG_SCROLL
	    printf("WM_MOUSEMOVE val=%d pix=%d\n", x, y);
#endif
            SendMessage(wndPtr->hwndParent, lphs->Direction, 
            		SB_THUMBTRACK, MAKELONG(x, hwnd));
	    }
	break;
    default:
	return DefWindowProc( hwnd, message, wParam, lParam );
    }
return(0);
}



LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr)
{
    WND  *Ptr;
    LPHEADSCROLL lphs;
    *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
    if (Ptr == 0) {
    	printf("Bad Window handle on ScrollBar !\n");
    	return 0;
    	}
    lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]);
    return lphs;
}


LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd)
{
    WND  *wndPtr;
    LPHEADSCROLL lphs;
    wndPtr = WIN_FindWndPtr(hwnd);
    if (wndPtr == 0) {
    	printf("Bad Window handle on ScrollBar !\n");
    	return 0;
    	}
    lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]);
    return lphs;
}


void StdDrawScrollBar(HWND hwnd)
{
    LPHEADSCROLL lphs;
    PAINTSTRUCT ps;
    HBRUSH hBrush;
    HDC hdc;
    RECT rect;
    UINT  i, w, h, siz;
    char	C[128];
    hdc = BeginPaint( hwnd, &ps );
    if (!IsWindowVisible(hwnd)) {
	EndPaint( hwnd, &ps );
	return;
	}
    hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc,
			MAKELONG(hwnd, CTLCOLOR_SCROLLBAR));
    if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(LTGRAY_BRUSH);
    lphs = ScrollBarGetStorageHeader(hwnd);
    if (lphs == NULL) goto EndOfPaint;
    GetClientRect(hwnd, &rect);
    w = rect.right - rect.left;
    h = rect.bottom - rect.top;
    if (lphs->Direction == WM_VSCROLL) {
	rect.top += w;
	rect.bottom -= w;
	}
    else {
	rect.left += h;
	rect.right -= h;
	}
    FillRect(hdc, &rect, hBrush);
    if (lphs->Direction == WM_VSCROLL)
	SetRect(&rect, 0, lphs->CurPix + w, w, lphs->CurPix + (w << 1));
    else
	SetRect(&rect, lphs->CurPix + h, 0, lphs->CurPix + (h << 1), h);
    FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
    InflateRect(&rect, -1, -1);
    FillRect(hdc, &rect, GetStockObject(LTGRAY_BRUSH));
    DrawReliefRect(hdc, rect, 2, 0);
    InflateRect(&rect, -3, -3);
    DrawReliefRect(hdc, rect, 1, 1);
    if (!lphs->ThumbActive) {
	InvalidateRect(lphs->hWndUp, NULL, TRUE);
	UpdateWindow(lphs->hWndUp);
	InvalidateRect(lphs->hWndDown, NULL, TRUE);
	UpdateWindow(lphs->hWndDown);
	}
EndOfPaint:
    EndPaint( hwnd, &ps );
}



int CreateScrollBarStruct(HWND hwnd)
{
    RECT	rect;
    int		width, height;
    WND  *wndPtr;
    LPHEADSCROLL lphs;
    wndPtr = WIN_FindWndPtr(hwnd);
    lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
    if (lphs == 0) {
    	printf("Bad Memory Alloc on ScrollBar !\n");
    	return 0;
    	}

#ifdef DEBUG_SCROLL
        printf("CreateScrollBarStruct %lX !\n", lphs);
#endif
    *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs;
    lphs->ThumbActive = FALSE;
    lphs->MinVal = 0;
    lphs->MaxVal = 100;
    lphs->CurVal = 0;
    lphs->CurPix = 0;
    width = wndPtr->rectClient.right - wndPtr->rectClient.left;
    height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
    if (width <= height)
	{
	lphs->MaxPix = height - 3 * width;
	lphs->Direction = WM_VSCROLL;
	lphs->hWndUp = CreateWindow("BUTTON", "", 
        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        	0, 0, width, width, hwnd, 1, wndPtr->hInstance, 0L);
	lphs->hWndDown = CreateWindow("BUTTON", "", 
        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        	0, height - width, width, width, hwnd, 2,
        	wndPtr->hInstance, 0L);
	}
    else
	{
	lphs->MaxPix = width - 3 * height;
	lphs->Direction = WM_HSCROLL;
	lphs->hWndUp = CreateWindow("BUTTON", "", 
        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        	0, 0, height, height, hwnd, 0, wndPtr->hInstance, 0L);
	lphs->hWndDown = CreateWindow("BUTTON", "", 
        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        	width - height, 0, height, height, hwnd, 0,
        	wndPtr->hInstance, 0L);
	}
    if (lphs->MaxPix < 1)  lphs->MaxPix = 1;
    if (wndPtr->hCursor == (HCURSOR)NULL)
	wndPtr->hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
    return TRUE;
}


/*************************************************************************
 *			GetScrollWindowHandle
 */
HWND GetScrollWindowHandle(HWND hWnd, int nBar)
{
    WND *wndPtr;
    if (nBar != SB_CTL) {
    wndPtr = WIN_FindWndPtr(hWnd);
    	if (nBar == SB_VERT) return wndPtr->hWndVScroll;
    	if (nBar == SB_HORZ) return wndPtr->hWndHScroll;
    	return (HWND)NULL;
	}
    return hWnd;
}


/*************************************************************************
 *			SetScrollPos [USER.62]
 */
int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw)
{
    int nRet;
    LPHEADSCROLL lphs;
    hwnd = GetScrollWindowHandle(hwnd, nBar);
    lphs = ScrollBarGetStorageHeader(hwnd);
    if (lphs == NULL) return 0;
    nRet = lphs->CurVal;
    lphs->CurVal = (short)nPos;
    if (lphs->MaxVal != lphs->MinVal)
	lphs->CurPix = lphs->MaxPix * (abs((short)nPos) - abs(lphs->MinVal)) / 
    		(abs(lphs->MaxVal) - abs(lphs->MinVal));
    if (lphs->CurPix > lphs->MaxPix)  lphs->CurPix = lphs->MaxPix;
#ifdef DEBUG_SCROLL
    printf("SetScrollPos val=%d pixval=%d pixmax%d\n",
	    (short)nPos, lphs->CurPix, lphs->MaxPix);
    printf("SetScrollPos min=%d max=%d\n", 
	    lphs->MinVal, lphs->MaxVal);
#endif
    if ((bRedraw) && (IsWindowVisible(hwnd))) {
        InvalidateRect(hwnd, NULL, TRUE);
        UpdateWindow(hwnd);
        }
    return nRet;
}



/*************************************************************************
 *			GetScrollPos [USER.63]
 */
int GetScrollPos(HWND hwnd, int nBar)
{
    LPHEADSCROLL lphs;
    hwnd = GetScrollWindowHandle(hwnd, nBar);
    lphs = ScrollBarGetStorageHeader(hwnd);
    if (lphs == NULL) return 0;
    return lphs->CurVal;
}



/*************************************************************************
 *			SetScrollRange [USER.64]
 */
void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw)
{
    LPHEADSCROLL lphs;
    hwnd = GetScrollWindowHandle(hwnd, nBar);
    lphs = ScrollBarGetStorageHeader(hwnd);
    if (lphs == NULL) return;
    lphs->MinVal = (short)MinPos;
    lphs->MaxVal = (short)MaxPos;
    if (lphs->MaxVal != lphs->MinVal)
	lphs->CurPix = abs(lphs->MaxVal) * 
		(abs(lphs->CurVal) - abs(lphs->MinVal)) / 
    		(abs(lphs->MaxVal) - abs(lphs->MinVal));
    if (lphs->CurPix > lphs->MaxPix)  lphs->CurPix = lphs->MaxPix;
#ifdef DEBUG_SCROLL
    printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal);
#endif
    if ((bRedraw) && (IsWindowVisible(hwnd))) {
        InvalidateRect(hwnd, NULL, TRUE);
        UpdateWindow(hwnd);
        }
}



/*************************************************************************
 *			GetScrollRange [USER.65]
 */
void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax)
{
    LPHEADSCROLL lphs;
    hwnd = GetScrollWindowHandle(hwnd, nBar);
    lphs = ScrollBarGetStorageHeader(hwnd);
    if (lphs == NULL) return;
    *lpMin = lphs->MinVal;
    *lpMax = lphs->MaxVal;
}



/*************************************************************************
 *			ShowScrollBar [USER.267]
 */
void ShowScrollBar(HWND hWnd, WORD wBar, BOOL bFlag)
{
    WND  *wndPtr;
#ifdef DEBUG_SCROLL
    printf("ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n", hWnd, wBar, bFlag);
#endif
    if (wBar == SB_CTL) {
    	if (bFlag)
	    ShowWindow(hWnd, SW_SHOW);
	else
	    ShowWindow(hWnd, SW_HIDE);
	return;
	}
    wndPtr = WIN_FindWndPtr(hWnd);
    if ((wBar == SB_VERT) || (wBar == SB_BOTH)) {
    	if (bFlag)
	    ShowWindow(wndPtr->hWndVScroll, SW_SHOW);
	else
	    ShowWindow(wndPtr->hWndVScroll, SW_HIDE);
	}
    if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) {
    	if (bFlag)
	    ShowWindow(wndPtr->hWndHScroll, SW_SHOW);
	else
	    ShowWindow(wndPtr->hWndHScroll, SW_HIDE);
	}
}


