/* The original version of this program can be found at http://damb.dk */
#include <windows.h>
#include <scrnsave.h>

BITMAPINFOHEADER CreateHeader(int aWidth, int aHeight, WORD aBitPixel)
{
   BITMAPINFOHEADER BitmapInfoHeader;
   BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
   BitmapInfoHeader.biWidth = aWidth;
   BitmapInfoHeader.biHeight = aHeight;
   BitmapInfoHeader.biPlanes = 1;
   BitmapInfoHeader.biBitCount = aBitPixel;
   BitmapInfoHeader.biCompression = BI_RGB;
   BitmapInfoHeader.biSizeImage = 0;
   BitmapInfoHeader.biXPelsPerMeter = 0;
   BitmapInfoHeader.biYPelsPerMeter = 0;
   BitmapInfoHeader.biClrUsed = 0;
   BitmapInfoHeader.biClrImportant = 0;

   return BitmapInfoHeader;
}

BITMAPINFOHEADER Header;
char *Buffer;
int Width, Height, BytesPixel;
unsigned int Idx;

void Draw(HDC dc)
{
   StretchDIBits(dc,
                 0, Idx, Width, Height - Idx,        // Dest
                 0, Idx, Width, Height - Idx,        // Src
                 Buffer,
                 (LPBITMAPINFO)&Header, DIB_RGB_COLORS, SRCCOPY);
   StretchDIBits(dc,
                 0, 0, Width, Idx,        // Dest
                 0, 0, Width, Idx,        // Src
                 Buffer,
                 (LPBITMAPINFO)&Header, DIB_RGB_COLORS, SRCCOPY);
}

LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   switch(message)
   {
   case WM_CREATE:
      {
         HDC dc = GetDC(0);
         Width = GetDeviceCaps(dc, HORZRES);
         Height = GetDeviceCaps(dc, VERTRES);
         HDC MemDc = CreateCompatibleDC(dc);
         HBITMAP BitMap = CreateCompatibleBitmap(dc, Width, Height);
         SelectObject(MemDc, BitMap);
         BitBlt(MemDc, 0, 0, Width, Height, dc, 0, 0, SRCCOPY);
         BITMAP Bm;
         GetObject(BitMap, sizeof(Bm), &Bm);
         Header = CreateHeader(Width, Height, Bm.bmBitsPixel);
         Buffer = new char [Width*Height*Bm.bmBitsPixel/8];
         BytesPixel = Bm.bmBitsPixel/8;
         GetDIBits(MemDc, BitMap, 0, Height, Buffer, (BITMAPINFO *)&Header, DIB_RGB_COLORS);
         ReleaseDC(0, dc);
         ReleaseDC(0, MemDc);
         DeleteObject(BitMap);
         SetTimer(hwnd, 1025, 100, 0);
      }
      break;
   case WM_DESTROY:
      delete Buffer;
      PostQuitMessage(0);
      break;
   case WM_TIMER:
      {
         HDC dc = GetDC(0);
         Idx = (Idx + 2)%Height;
         Draw(dc);
         ReleaseDC(0, dc);
      }
      break;
   case WM_PAINT:
      {
         PAINTSTRUCT ps;
         HDC dc = BeginPaint(hwnd, &ps);
         Draw(dc);
         EndPaint(hwnd, &ps);
      }
      break;
   default:
      return DefScreenSaverProc(hwnd, message, wParam, lParam);
   }
   return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
   return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
    return TRUE;
}