/*
 * Desktop window class.
 *
 * Copyright 1994 Alexandre Julliard
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "win.h"
#include "desktop.h"
#include "directory.h"
#include "file.h"
#include "graphics.h"
#include "heap.h"


/***********************************************************************
 *           DESKTOP_LoadBitmap
 *
 * Load a bitmap from a file. Used by SetDeskWallPaper().
 */
static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
{
    BITMAPFILEHEADER *fileHeader;
    BITMAPINFO *bitmapInfo;
    HBITMAP hbitmap;
    HFILE file;
    LPSTR buffer;
    LONG size;

    /* Read all the file into memory */

    if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
    {
        UINT32 len = GetWindowsDirectory( NULL, 0 );
        if (!(buffer = HeapAlloc( SystemHeap, 0, len + strlen(filename) + 2 )))
            return 0;
        GetWindowsDirectory( buffer, len + 1 );
        strcat( buffer, "\\" );
        strcat( buffer, filename );
        file = _lopen( buffer, OF_READ );
        HeapFree( SystemHeap, 0, buffer );
    }
    if (file == HFILE_ERROR) return 0;
    size = _llseek( file, 0, 2 );
    if (!(buffer = HeapAlloc( SystemHeap, 0, size )))
    {
	_lclose( file );
	return 0;
    }
    _llseek( file, 0, 0 );
    size = FILE_Read( file, buffer, size );
    _lclose( file );
    fileHeader = (BITMAPFILEHEADER *)buffer;
    bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
    
      /* Check header content */
    if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
    {
	HeapFree( SystemHeap, 0, buffer );
	return 0;
    }
    hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
			      buffer + fileHeader->bfOffBits,
			      bitmapInfo, DIB_RGB_COLORS );
    HeapFree( SystemHeap, 0, buffer );
    return hbitmap;
}


/***********************************************************************
 *           DESKTOP_DoEraseBkgnd
 *
 * Handle the WM_ERASEBKGND message.
 */
static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
{
    RECT16 rect;
    GetClientRect16( hwnd, &rect );    

    /* Paint desktop pattern (only if wall paper does not cover everything) */

    if (!infoPtr->hbitmapWallPaper || 
	(!infoPtr->fTileWallPaper && ((infoPtr->bitmapSize.cx < rect.right) ||
	 (infoPtr->bitmapSize.cy < rect.bottom))))
    {
	  /* Set colors in case pattern is a monochrome bitmap */
	SetBkColor( hdc, RGB(0,0,0) );
	SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
	FillRect16( hdc, &rect, infoPtr->hbrushPattern );
    }

      /* Paint wall paper */

    if (infoPtr->hbitmapWallPaper)
    {
	int x, y;

	if (infoPtr->fTileWallPaper)
	{
	    for (y = 0; y < rect.bottom; y += infoPtr->bitmapSize.cy)
		for (x = 0; x < rect.right; x += infoPtr->bitmapSize.cx)
		    GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper,
				      x, y, 0, 0, 
				      infoPtr->bitmapSize.cx,
				      infoPtr->bitmapSize.cy );
	}
	else
	{
	    x = (rect.left + rect.right - infoPtr->bitmapSize.cx) / 2;
	    y = (rect.top + rect.bottom - infoPtr->bitmapSize.cy) / 2;
	    if (x < 0) x = 0;
	    if (y < 0) y = 0;
	    GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper, x, y, 0, 0, 
                              infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy );
	}
    }

    return 1;
}


/***********************************************************************
 *           DesktopWndProc
 *
 * Window procedure for the desktop window.
 */
LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
                        WPARAM32 wParam, LPARAM lParam )
{
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;

      /* Most messages are ignored (we DON'T call DefWindowProc) */

    switch(message)
    {
	/* Warning: this message is sent directly by                     */
	/* WIN_CreateDesktopWindow() and does not contain a valid lParam */
    case WM_NCCREATE:
	infoPtr->hbrushPattern = 0;
	infoPtr->hbitmapWallPaper = 0;
	SetDeskPattern();
	SetDeskWallPaper( (LPSTR)-1 );
	break;
	
    case WM_ERASEBKGND:
	if (rootWindow == DefaultRootWindow(display)) return 1;
	return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, infoPtr );

    case WM_SYSCOMMAND:
	if ((wParam & 0xfff0) != SC_CLOSE) return 0;
	ExitWindows( 0, 0 ); 

    case WM_SETCURSOR:
        return (LRESULT)SetCursor( LoadCursor( 0, IDC_ARROW ) );
    }
    
    return 0;
}


/***********************************************************************
 *           SetDeskPattern   (USER.279)
 */
BOOL SetDeskPattern(void)
{
    char buffer[100];
    GetProfileString( "desktop", "Pattern", "(None)", buffer, 100 );
    return DESKTOP_SetPattern( buffer );
}


/***********************************************************************
 *           SetDeskWallPaper   (USER.285)
 */
BOOL SetDeskWallPaper( LPCSTR filename )
{
    HBITMAP hbitmap;
    HDC hdc;
    char buffer[256];
    WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
    DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;

    if (filename == (LPSTR)-1)
    {
	GetProfileString( "desktop", "WallPaper", "(None)", buffer, 256 );
	filename = buffer;
    }
    hdc = GetDC( 0 );
    hbitmap = DESKTOP_LoadBitmap( hdc, filename );
    ReleaseDC( 0, hdc );
    if (infoPtr->hbitmapWallPaper) DeleteObject( infoPtr->hbitmapWallPaper );
    infoPtr->hbitmapWallPaper = hbitmap;
    infoPtr->fTileWallPaper = GetProfileInt( "desktop", "TileWallPaper", 0 );
    if (hbitmap)
    {
	BITMAP16 bmp;
	GetObject16( hbitmap, sizeof(bmp), &bmp );
	infoPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
	infoPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
    }
    return TRUE;
}


/***********************************************************************
 *           DESKTOP_SetPattern
 *
 * Set the desktop pattern.
 */
BOOL DESKTOP_SetPattern(char *pattern )
{
    WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
    DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
    int pat[8];

    if (infoPtr->hbrushPattern) DeleteObject( infoPtr->hbrushPattern );
    memset( pat, 0, sizeof(pat) );
    if (pattern && sscanf( pattern, " %d %d %d %d %d %d %d %d",
			   &pat[0], &pat[1], &pat[2], &pat[3],
			   &pat[4], &pat[5], &pat[6], &pat[7] ))
    {
	WORD pattern[8];
	HBITMAP hbitmap;
	int i;

	for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
	hbitmap = CreateBitmap( 8, 8, 1, 1, (LPSTR)pattern );
	infoPtr->hbrushPattern = CreatePatternBrush( hbitmap );
	DeleteObject( hbitmap );
    }
    else infoPtr->hbrushPattern = CreateSolidBrush( GetSysColor(COLOR_BACKGROUND) );
    return TRUE;
}

