#include <windows.h>
#include <tchar.h>
#include "Files.h"

#define MAIN_WINDOW_WIDTH  768
#define MAIN_WINDOW_HEIGHT 512

#define MAX_FILENAME_LENGTH 256


LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProc( HWND, UINT, WPARAM, LPARAM);


HINSTANCE hGlobalInstance;
BYTE bGlobPat = 0;
int codLength;
char codText[256];


VOID RawCycle( LPBYTE lpRaw, DWORD iSize)
      {
       int i, ii;
	   char c;

        for( i = 0; i < iSize; i++)
         lpRaw[i] = (lpRaw[i] ^ bGlobPat);


        for( i = 0, ii = (iSize-1); i < (iSize/2); i++)
         {
           c = (lpRaw[i] ^ codText[i % codLength]);
           lpRaw[i] = (lpRaw[ii] ^ codText[i % codLength]);
           lpRaw[ii] = c;
           ii--;
          }

       return;
       }

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
 {
  WNDCLASSEX wc;
  HWND hwnd;
  MSG uMsg;
  int xPos, yPos;

     hGlobalInstance = hInstance;

     wc.cbSize = sizeof(WNDCLASSEX);
     wc.lpszClassName = _T("FilesWinClass");
     wc.lpfnWndProc = MainWndProc;
     wc.style = CS_VREDRAW | CS_HREDRAW;
     wc.hInstance = hInstance;
     wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
     wc.hIconSm = wc.hIcon;
     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
     wc.lpszMenuName = "FilesMenu";
     wc.cbClsExtra = 0;
     wc.cbWndExtra = 0;

    if(!RegisterClassEx( &wc))
       return 1;

     xPos = GetSystemMetrics(SM_CXSCREEN);
     xPos = ( xPos - MAIN_WINDOW_WIDTH) >> 1;                                            // or ( xPos - MAIN_WINDOW_WIDTH) / 2;
                                                                                         // Compute central position for the main window
     yPos = GetSystemMetrics(SM_CYSCREEN);
     yPos = ( yPos - MAIN_WINDOW_HEIGHT) >> 1;

     hwnd = CreateWindowEx( 0,_T("FilesWinClass"), _T(">>"),
                            WS_OVERLAPPEDWINDOW, xPos,yPos,
                            MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT, NULL, NULL,
                            hInstance, NULL);
    if(!hwnd)
        return 1;

     ShowWindow( hwnd, SW_SHOWNORMAL);
     UpdateWindow( hwnd);

    while (GetMessage( &uMsg, NULL, 0, 0))
      {
        TranslateMessage( &uMsg);
        DispatchMessage( &uMsg);
       }

    return uMsg.wParam;
 }

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
  RECT rc;
  static OPENFILENAME strOpenFile = {0};
  static HWND hEdit, hEditFile;
  static char cFileName[MAX_FILENAME_LENGTH];
  static char cClearFileName[MAX_FILENAME_LENGTH];
  static HLOCAL hGlobMem;
  static LPVOID lpGlobMem;
  static DWORD iTextLimit;

   switch(uMsg)
    {
     case WM_CREATE:
      GetClientRect( hwnd, &rc);
      hEdit = CreateWindowEx( WS_EX_CLIENTEDGE, _T( "EDIT"), 0,                          // Use predefined control class EDIT
                    WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL |                    // Create a multiline edit control
                    ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
                    WS_BORDER, 0, 0, rc.right, rc.bottom, hwnd,
                    (HMENU)IDE_EDIT, ((LPCREATESTRUCT)lParam)->hInstance, NULL);



      strOpenFile.lStructSize = sizeof(OPENFILENAME);                                    // Fill in the OPENFILENAME structure
      strOpenFile.hwndOwner = hwnd;                                                      // before calling GetOpenFileName() and
      strOpenFile.lpstrFilter = "Bilogic files\0*.ff6;\0All\0*.*;\0";                       // GetSaveFileName() functions
      strOpenFile.nFilterIndex = 1;
      strOpenFile.lpstrFile = cFileName;
      strOpenFile.nMaxFile = MAX_FILENAME_LENGTH;
      strOpenFile.lpstrFileTitle = cClearFileName;
      strOpenFile.nMaxFileTitle = MAX_FILENAME_LENGTH;
      strOpenFile.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST |
                          OFN_LONGNAMES | OFN_FILEMUSTEXIST;
      strOpenFile.lpstrDefExt = "ff6";
      hEditFile = 0;

      wsprintf( cFileName, "%ld%s", iTextLimit,"-no-white");
      SetWindowText( hwnd, cFileName);

   //   hGlobMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, iTextLimit);                // Allocate memory
   //   lpGlobMem = GlobalLock( hGlobMem);

     return 0;

     case WM_SETFOCUS:
         SetFocus(hEdit);
     return 0;

     case WM_SIZE:
      MoveWindow( hEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
     return 0;

     case WM_COMMAND:
      switch(LOWORD(wParam))
       {
        case IDM_OPEN:
         {
          int iRet;

           iRet = GetOpenFileName( &strOpenFile);                                        // Create a Open dialog box
           if( iRet != 0)                                                                // If the filename was specified
            {
             DWORD dwBytesRead;


             hEditFile = CreateFile( cFileName, GENERIC_READ,                            // Open the file
                               0, NULL, OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL, NULL);

             iTextLimit = GetFileSize( hEditFile, NULL);

             hGlobMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, iTextLimit);                // Allocate memory
             lpGlobMem = GlobalLock( hGlobMem);

             ReadFile( hEditFile, lpGlobMem, iTextLimit, &dwBytesRead, NULL);
             CloseHandle( hEditFile);
             RawCycle( lpGlobMem, iTextLimit);
             }
          }
        break;

        case IDM_SAVE:
         {
          int iRet;

           iRet = GetSaveFileName( &strOpenFile);                                        // Create a Save dialog box
           if( iRet != 0)                                                                // If the filename was specified
            {
             DWORD dwBytesWritten, dwBytesRead;

               hEditFile = CreateFile( cFileName, GENERIC_WRITE,                         // Create a file
                                 0, NULL, CREATE_ALWAYS,
                                 FILE_ATTRIBUTE_NORMAL, NULL);

              // RawCycle( lpGlobMem, iTextLimit);
               WriteFile( hEditFile, lpGlobMem, iTextLimit, &dwBytesWritten, NULL);     // Write the text to the file
               CloseHandle( hEditFile);                                                  // Close the file

               GlobalUnlock( hGlobMem);
               GlobalFree( hGlobMem);                                                             // Free the allocated memory
             }
          }
        break;

        case IDM_PAT:
         DialogBoxParam( hGlobalInstance, "PatDialog", hwnd,                             // Create a modal dialog box from
         (DLGPROC)DlgProc, 0);
        break;

        case IDM_EXIT:
         DestroyWindow( hwnd);
        break;
        }
     return 0;

     case WM_DESTROY:
      PostQuitMessage( 0);
     return 0;
     }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
  }

BOOL CALLBACK DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)               // Dialog box procedure
 {
  static HWND hButton;

   switch(uMsg)
    {
     case WM_INITDIALOG:
      hButton = GetDlgItem( hDlg, IDR_BUTTON);
     return FALSE;

     case WM_COMMAND:
      if((HWND)lParam == hButton)
       {
        char buffer[20];
        int i;

         bGlobPat = 0;
         for( i = 0; i < 8; i++)
          {
           if( BST_CHECKED == IsDlgButtonChecked( hDlg, IDR_CHECK_0 + i))
            bGlobPat = bGlobPat | (1 << i);
           }

          codLength = GetDlgItemText( hDlg, IDR_EDIT_TEXT, codText, 256);
      //    wsprintf( buffer, "%lX", codLength);
      //    MessageBox( hDlg, buffer,codText, MB_OK);

      //   wsprintf( buffer, "%lX", bGlobPat);
      //   MessageBox( hDlg, buffer, buffer, 0);
         SendMessage( hDlg, WM_CLOSE, 0, 0);
        }
     break;

     case WM_CLOSE:                                                                       // If the close button was pressed
      EndDialog( hDlg, 0);                                                                // Close dialog
     return TRUE;
     }

    return FALSE;
  }


