#include <windows.h>
#include <mmsystem.h>
#include "Pattern.h"



/*

  Changelog
  -

  27/05/05

    v017 made

*/



//--- DATA -------------------------------------------------------------------//

HINSTANCE hMainInstance;
HWND hMainWindow = NULL;

char szAppName[40] = "Lewpen's pattern generator";

  RECT rc;  //  client rect of screen

#define WINDOW_HEIGHT 400
#define WINDOW_WIDTH  500



//----- buffer for doing the 3d view

int the3dbuf[ WINDOW_WIDTH * WINDOW_HEIGHT ];




//---- Startup ---------------------------------------------------------------//

void Startup()
{
  Pattern_Startup();
}



//---- Display ---------------------------------------------------------------//

void Display(HDC dc, PATTERN_RGB *rgb)
{
  BITMAPINFO bmi;

  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  bmi.bmiHeader.biWidth = DIM;
  bmi.bmiHeader.biHeight = -DIM;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = 24;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biSizeImage = 0;
  bmi.bmiHeader.biXPelsPerMeter = 1000;
  bmi.bmiHeader.biYPelsPerMeter = 1000;
  bmi.bmiHeader.biClrUsed = 0;
  bmi.bmiHeader.biClrImportant = 0;

  int w = WINDOW_WIDTH, h = WINDOW_HEIGHT, x=0, y=0;

  //- did just tile it
/*
  for(y = 0; y < h; y += DIM)
    for(x = 0; x < w; x += DIM)

      StretchDIBits(
        dc,
        x, y, DIM, DIM,
        0, 0, DIM, DIM,
        (LPVOID)rgb->buf,
        (LPBITMAPINFO)&bmi,
        DIB_RGB_COLORS, SRCCOPY
      );
*/

  //- Now plots it in 3D

  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  bmi.bmiHeader.biWidth = WINDOW_WIDTH;
  bmi.bmiHeader.biHeight = -WINDOW_HEIGHT;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = 32;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biSizeImage = 0;
  bmi.bmiHeader.biXPelsPerMeter = 1000;
  bmi.bmiHeader.biYPelsPerMeter = 1000;
  bmi.bmiHeader.biClrUsed = 0;
  bmi.bmiHeader.biClrImportant = 0;

  int i, j, k;

  //  clear

  for( i=0; i<WINDOW_WIDTH * WINDOW_HEIGHT; i++ ) the3dbuf[i] = 0;

  int o, c, cc, v;

  //  draw from back forwards

  for( j=0; j<DIM; j++ )
  {
    for( i=0; i<DIM; i++ )
    {
      c = ( *(int*)rgb->buf[ i ][ j ] );
      the3dbuf[ i + j * WINDOW_WIDTH ] = c * 0x020202;
    }
  }

  for( j=4; j<DIM-4; j++ )
  {
    for( i=4; i<DIM-4; i++ )
    {
      x = WINDOW_WIDTH/2 + i*2 - j*2;
      y = WINDOW_HEIGHT/2 - DIM/2 + i + j;

      if( x >= 0 && x < WINDOW_WIDTH-3 && y >= 0 && y < WINDOW_HEIGHT )
      {
        o = x+y*WINDOW_WIDTH;
        c = ( *(int*)rgb->buf[ i ][ j ] ) & 0xFFFFFF;

        c += ( *(int*)rgb->buf[ i+1 ][ j ] ) & 0xFFFFFF;
        c += ( *(int*)rgb->buf[ i ][ j+1 ] ) & 0xFFFFFF;
        c += ( *(int*)rgb->buf[ i+1 ][ j+1 ] ) & 0xFFFFFF;

      c /= 4;

        v = c & 0xFFFFFF;

//        v /= 2;

        //  lighting

        cc  = ( *(int*)rgb->buf[ i+1 ][ j   ] ) & 0xFFFFFF;
        cc += ( *(int*)rgb->buf[ i+2 ][ j+1 ] ) & 0xFFFFFF;
        cc += ( *(int*)rgb->buf[ i+1 ][ j   ] ) & 0xFFFFFF;
        cc += ( *(int*)rgb->buf[ i+2 ][ j+1 ] ) & 0xFFFFFF;

        cc /= 4;

        cc = ((c - cc));

        if( cc < -255 ) cc = -255;
        if( cc > 255 ) cc = 255;

        c = v+cc;//(cc*v)/255;

        if ( c < 0 ) c = 0;
        if ( c > 255) c = 255;

        c = (c&0xFF) * 0x010101;


//        if( v > 255 ) v = 255;
        v *= 1;


//        if( v > 100 ) v = 100;

        for( k=0; k<v && o >= 0; k++ )
        {
          the3dbuf[ o     ] = c;
          the3dbuf[ o + 1 ] = c;
          the3dbuf[ o + 2 ] = c;
          the3dbuf[ o + 3 ] = c;
          o -= WINDOW_WIDTH;
        }
      }
    }
  }

  StretchDIBits(
    dc,
    0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
    0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
    (LPVOID)the3dbuf,
    (LPBITMAPINFO)&bmi,
    DIB_RGB_COLORS, SRCCOPY
  );

}



//---- Redraw ----------------------------------------------------------------//

void Redraw(HDC dc)
{
  Display( dc, Pattern_Generate() );
}



//---- WinProc ---------------------------------------------------------------//

int mouse_l=0;

LRESULT CALLBACK WinProc(HWND hwnd, UINT uiMsg, UINT wParam, LONG lParam)
{
  int mouse_x=0, mouse_y=0;

  HDC dc;
  PAINTSTRUCT ps;

  switch(uiMsg) {

  case WM_CREATE:
    Startup();
    SetTimer(hwnd, 1, 10, NULL);
    GetClientRect( hwnd, &rc );
    SetWindowPos( hwnd, NULL, 0, 0, WINDOW_WIDTH+WINDOW_WIDTH-rc.right, WINDOW_HEIGHT+WINDOW_HEIGHT-rc.bottom, SWP_NOMOVE );
    break;

  case WM_TIMER:
    dc = GetDC(hwnd);
    Redraw(dc);
    ReleaseDC(hwnd, dc);
    return 0L;

  case WM_PAINT:
    dc = BeginPaint(hwnd, &ps);
    Redraw(dc);
    EndPaint(hwnd, &ps);
    return 0L;

  //- WM_MOUSEMOVE

  case WM_MOUSEMOVE:
    mouse_x = LOWORD(lParam);
    mouse_y = HIWORD(lParam);

    if( !mouse_l ) MouseMove( mouse_x, mouse_y );

    //  TEMP: TODO: Make this a Pattern_MouseDrag function

    if( mouse_l ) drag(mouse_x, mouse_y);

    break;

  //- WM_LBUTTONDOWN

  case WM_LBUTTONDOWN:  //  todo: capture focus so that we know when the button is released
    mouse_x = LOWORD(lParam);
    mouse_y = HIWORD(lParam);
    mouse_l = 1;
    if( mouse_l ) drag(mouse_x, mouse_y);
    break;

  //- WM_LBUTTONUP

  case WM_LBUTTONUP:
    mouse_l = 0;
    break;


/*
//  full-window drag
  case WM_NCHITTEST:
    return HTCAPTION;
*/

  case WM_KEYDOWN:
    if( wParam == VK_ESCAPE ) PostMessage( hwnd, WM_DESTROY, 0, 0 );
    return 0L;

  case WM_DESTROY:
    KillTimer(hwnd, 1);
    PostQuitMessage(0);
    return 0L;

  }

  return DefWindowProc(hwnd, uiMsg, wParam, lParam);
}




//---- WinMain ---------------------------------------------------------------//

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASS wndclass;
  char cSwitch;
  MSG msg;
  RECT rc;

  hMainInstance = hInstance;

  if(hPrevInstance) return 1;

  //- Create window class

  wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc   = WinProc;
  wndclass.cbClsExtra    = 0;
  wndclass.cbWndExtra    = 0;
  wndclass.hInstance     = hInstance;
  wndclass.hIcon         = NULL;
  wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  wndclass.lpszMenuName  = NULL;
  wndclass.lpszClassName = szAppName;

  if(!RegisterClass(&wndclass)) return 1;

  //- Create main window

  hMainWindow = CreateWindowEx(
    0,
    szAppName,
    szAppName,
    WS_OVERLAPPEDWINDOW,//WS_OVERLAPPED,//WS_POPUP,
    50,
    50,
    WINDOW_WIDTH,
    WINDOW_HEIGHT,
    NULL,
    NULL,
    hInstance,
    NULL
  );

  if(!hMainWindow) return 1;

  ShowWindow(hMainWindow, SW_SHOW);

  //- Message loop

  while(TRUE) {
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
      if (msg.message == WM_QUIT) return TRUE;
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    HDC dc = GetDC(hMainWindow);
    Redraw(dc);
    ReleaseDC(hMainWindow, dc);
  }

  return 0;
}



//---- END OF FILE -----------------------------------------------------------//




