/*
* MapPlot
*
* Simple map drawing program for MWDB-II/WDB-II data
*
*/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <winlib/winlib.h>

#include "mapplot.h"
#include "map.h"
#include "window.h"
#include "fsbox.h"
#include "wdb-ii.h"


void CheckMenuItems(VARS *v)
{
       int i, j;

       CheckMenuItem(v->hMenu, IDM_PLATE_CARREE, MF_UNCHECKED);
       CheckMenuItem(v->hMenu, IDM_MERCATOR, MF_UNCHECKED);
       CheckMenuItem(v->hMenu, IDM_ROBINSON, MF_UNCHECKED);
       CheckMenuItem(v->hMenu, IDM_HAMMER, MF_UNCHECKED);
       CheckMenuItem(v->hMenu, IDM_ORTHO, MF_UNCHECKED);

       switch (v->project) {
               case PLATE_CARREE:
                       i = IDM_PLATE_CARREE;
                       break;
               case MERCAT:
                       i = IDM_MERCATOR;
                       break;
               case ROBIN:
                       i = IDM_ROBINSON;
                       break;
               case HAMMER:
                       i = IDM_HAMMER;
                       break;
               case ORTHO:
                       i = IDM_ORTHO;
                       break;
       }
       CheckMenuItem(v->hMenu, i, MF_CHECKED);

       for (i = 1, j = 0; i < 256; i = i * 2, j++)
               CheckMenuItem(v->hMenu, 200 + j, MF_UNCHECKED);
       for (i = 1, j = 0; i < 256; i = i * 2, j++) {
               if (v->shwFeatures & i)
                       CheckMenuItem(v->hMenu, 200 + j, MF_CHECKED);
       }

       for (i = 1; i < 4; i++)
               CheckMenuItem(v->hMenu, 300 + i, MF_UNCHECKED);
       for (i = 1; i < 4; i++) {
               if (v->wdbShwBdyFeatures[i])
                       CheckMenuItem(v->hMenu, 300 + i, MF_CHECKED);
       }

       for (i = 1; i < 16; i++)
               CheckMenuItem(v->hMenu, 400 + i, MF_UNCHECKED);
       for (i = 1; i < 16; i++) {
               if (v->wdbShwCilFeatures[i])
                       CheckMenuItem(v->hMenu, 400 + i, MF_CHECKED);
       }

       for (i = 1; i < 13; i++)
               CheckMenuItem(v->hMenu, 500 + i, MF_UNCHECKED);
       for (i = 1; i < 13; i++) {
               if (v->wdbShwRivFeatures[i])
                       CheckMenuItem(v->hMenu, 500 + i, MF_CHECKED);
       }
}


BOOL RecallConfig(VARS *v)
{
       char szFileName[256], szTitleName[256];
       int fd;
       char wdbIIName[256];
       char curDir[256];

       szFileName[0] = '\0';
       szTitleName[0] = '\0';

       FileInitialize(1, v->confDir);

       if (! FileOpenDlg(v->hwndMain, szFileName, szTitleName))
               return FALSE;

       if ((fd = open(szFileName, O_RDONLY | O_BINARY)) == -1) {
               MBPrintf("", "%s", strerror(errno));
               return FALSE;
       }

       GetCurrentDirectory(256, (LPTSTR)curDir);
       if (strcmp(v->confDir, curDir))
               strcpy(v->confDir, curDir);

       read(fd, &v->project, sizeof(v->project));

       read(fd, &v->origLon, sizeof(v->origLon));
       read(fd, &v->origLat, sizeof(v->origLat));
       read(fd, &v->minMax, sizeof(v->minMax));
       read(fd, &v->zoom, sizeof(v->zoom));
       read(fd, &v->gridDeg, sizeof(v->gridDeg));

       read(fd, &v->shwFeatures, sizeof(v->shwFeatures));
       read(fd, &v->wdbShwBdyFeatures, sizeof(v->wdbShwBdyFeatures));
       read(fd, &v->wdbShwCilFeatures, sizeof(v->wdbShwCilFeatures));
       read(fd, &v->wdbShwRivFeatures, sizeof(v->wdbShwRivFeatures));

       read(fd, &v->colors, sizeof(v->colors));

       DeleteWDBIIMaps(v);

       while (read(fd, wdbIIName, 256) == 256)
               DoAddWDBIIMap(v, wdbIIName);

       close(fd);

       CheckMenuItems(v);
       InvalidateRect(v->hwndCont, NULL, FALSE);
       UpdateWindow(v->hwndCont);
       return TRUE;
}


BOOL SaveConfig(VARS *v)
{
       char szFileName[256], szTitleName[256];
       int fd;
       WDBII_MAP *p;
       char wdbIIName[256];
       char curDir[256];

       szFileName[0] = '\0';
       szTitleName[0] = '\0';

       FileInitialize(1, v->confDir);

       if (! FileSaveDlg(v->hwndMain, szFileName, szTitleName))
               return FALSE;

       if ((fd = open(szFileName, O_CREAT | O_WRONLY | O_BINARY,
                       S_IWRITE | S_IREAD)) == -1) {
               MBPrintf("", "%s", strerror(errno));
               return FALSE;
       }

       GetCurrentDirectory(256, (LPTSTR)curDir);
       if (strcmp(v->confDir, curDir))
               strcpy(v->confDir, curDir);

       write(fd, &v->project, sizeof(v->project));

       write(fd, &v->origLon, sizeof(v->origLon));
       write(fd, &v->origLat, sizeof(v->origLat));
       write(fd, &v->minMax, sizeof(v->minMax));
       write(fd, &v->zoom, sizeof(v->zoom));
       write(fd, &v->gridDeg, sizeof(v->gridDeg));

       write(fd, &v->shwFeatures, sizeof(v->shwFeatures));
       write(fd, &v->wdbShwBdyFeatures, sizeof(v->wdbShwBdyFeatures));
       write(fd, &v->wdbShwCilFeatures, sizeof(v->wdbShwCilFeatures));
       write(fd, &v->wdbShwRivFeatures, sizeof(v->wdbShwRivFeatures));

       write(fd, &v->colors, sizeof(v->colors));

       for (p = v->wdbIIMaps; p; p = p->next) {
               memset(wdbIIName, 0, 256);
               strcpy(wdbIIName, p->name);
               write(fd, wdbIIName, 256);
       }

       close(fd);
       return TRUE;
}


BOOL GetDataDir(VARS *v)
{
       char *p, szFileName[256], szTitle[256];

       szFileName[0] = '\0';
       strcpy(szTitle, "Choose Data Directory");
       DirInitialize();
       if (! DirOpenDlg(v->hwndMain, szFileName, szTitle))
               return FALSE;

       p = strrchr(szFileName, '\\');
       *p = '\0';
       strcpy(v->dataDir, szFileName);
       return TRUE;
}


void DoExitStuff(VARS *v)
{
       SavePlacement(v->hwndMain, "Software\\MapPlot");
       SetRegVal("Software\\MapPlot", "DataDir", (void*)(v->dataDir),
                       strlen(v->dataDir));
       SetRegVal("Software\\MapPlot", "Projection", (void*)&(v->project),
                       sizeof(v->project));
       SetRegVal("Software\\MapPlot", "Show", (void*)&(v->shwFeatures),
                       sizeof(v->shwFeatures));
       SetRegVal("Software\\MapPlot", "WDBShowBdy", (void*)&(v->wdbShwBdyFeatures),
                       sizeof(v->wdbShwBdyFeatures));
       SetRegVal("Software\\MapPlot", "WDBShowCil", (void*)&(v->wdbShwCilFeatures),
                       sizeof(v->wdbShwCilFeatures));
       SetRegVal("Software\\MapPlot", "WDBShowRiv", (void*)&(v->wdbShwRivFeatures),
                       sizeof(v->wdbShwRivFeatures));
       SetRegVal("Software\\MapPlot", "Colors", (void*)v->colors,
                       sizeof(v->colors));
       SetRegVal("Software\\MapPlot", "OrigLon", (void*)&(v->origLon),
                       sizeof(v->origLon));
       SetRegVal("Software\\MapPlot", "OrigLat", (void*)&(v->origLat),
                       sizeof(v->origLat));
       SetRegVal("Software\\MapPlot", "Zoom", (void*)&(v->zoom),
                       sizeof(v->zoom));
       SetRegVal("Software\\MapPlot", "GridSize", (void*)&(v->gridDeg),
                       sizeof(v->gridDeg));
       SetRegVal("Software\\MapPlot", "MinMax", (void*)&(v->minMax),
                       sizeof(v->minMax));
}


VARS* Init(HINSTANCE hInst, int nCmdShow)
{
       WNDCLASS wc;
       RECT rect;
       int x = CW_USEDEFAULT, y = 0, w = 640, h = 480;
       VARS *v;
       char *p;
       int i, j, id;

       v = (VARS *)malloc(sizeof(VARS));
       v->hInst = hInst;
       v->oldFocus = NULL;
       v->mapData = v->prevPoly = NULL;
       v->wdbIIMode = FALSE;
       v->wdbIIMaps = NULL;

       v->defColors[CLR_COAST] = RGB(32,144,32);
       v->defColors[CLR_COUNTRY] = RGB(255,128,64);
       v->defColors[CLR_STATE] = RGB(255,0,0);
       v->defColors[CLR_ISLAND] = RGB(32,144,32);
       v->defColors[CLR_LAKE] = RGB(128,128,255);
       v->defColors[CLR_RIVER] = RGB(128,128,255);
       v->defColors[CLR_BACKGR] = RGB(242,242,242);
       v->defColors[CLR_GRID] = RGB(210,210,210);

       if (! GetRegVal("Software\\MapPlot", "Projection", (void*)&(v->project),
                       sizeof(v->project))) {
               v->project = PLATE_CARREE;
       }

       if (! GetRegVal("Software\\MapPlot", "Show", (void*)&(v->shwFeatures),
                       sizeof(v->shwFeatures))) {
               v->shwFeatures = SHW_COAST | SHW_ISLAND | SHW_GRID;
       }

       memset(v->wdbShwBdyFeatures, 0, 20);
       if (! GetRegVal("Software\\MapPlot", "WDBShowBdy", (void*)&(v->wdbShwBdyFeatures),
                       sizeof(v->wdbShwBdyFeatures))) {
               v->wdbShwBdyFeatures[1] = 1;
               v->wdbShwBdyFeatures[2] = 1;
       }

       memset(v->wdbShwCilFeatures, 0, 20);
       if (! GetRegVal("Software\\MapPlot", "WDBShowCil", (void*)&(v->wdbShwCilFeatures),
                       sizeof(v->wdbShwCilFeatures))) {
               v->wdbShwCilFeatures[1] = 1;
               v->wdbShwCilFeatures[2] = 1;
       }

       memset(v->wdbShwRivFeatures, 0, 20);
       if (! GetRegVal("Software\\MapPlot", "WDBShowRiv", (void*)&(v->wdbShwRivFeatures),
                       sizeof(v->wdbShwRivFeatures))) {
               v->wdbShwRivFeatures[1] = 1;
               v->wdbShwRivFeatures[2] = 1;
       }

       if (! GetRegVal("Software\\MapPlot", "Colors", (void*)v->colors,
                       sizeof(v->colors))) {
               memcpy(v->colors, v->defColors, sizeof(v->defColors));
       }

       if (! GetRegVal("Software\\MapPlot", "OrigLon", (void*)&(v->origLon),
                       sizeof(v->origLon))) {
               v->origLon = 0.0;
       }

       if (! GetRegVal("Software\\MapPlot", "OrigLat", (void*)&(v->origLat),
                       sizeof(v->origLat))) {
               v->origLat = 0.0;
       }

       if (! GetRegVal("Software\\MapPlot", "Zoom", (void*)&(v->zoom),
                       sizeof(v->zoom))) {
               v->zoom = 1.0;
       }

       if (! GetRegVal("Software\\MapPlot", "GridSize", (void*)&(v->gridDeg),
                       sizeof(v->gridDeg))) {
               v->gridDeg = 15;
       }

       if (! GetRegVal("Software\\MapPlot", "MinMax", (void*)&(v->minMax),
                       sizeof(v->minMax))) {
               v->minMax.minLon = -180.;
               v->minMax.maxLon = 180.;
               v->minMax.minLat = -90.;
               v->minMax.maxLat = 90.;
       }

       wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
       wc.lpfnWndProc = (WNDPROC)MainWndProc;
       wc.cbClsExtra = 0;
       wc.cbWndExtra = sizeof(v);
       wc.hInstance = hInst;
       wc.hIcon = LoadIcon(hInst, "Icon");
       wc.hCursor = LoadCursor(NULL, IDC_ARROW);
       wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
       wc.lpszMenuName = "MainMenu";
       wc.lpszClassName = "MainWndClass";
       if (! RegisterClass(&wc))
               return NULL;

       wc.lpfnWndProc = (WNDPROC)ContWndProc;
       wc.lpszClassName = "ContWndClass";
       wc.lpszMenuName = (HMENU)NULL;
       if (! RegisterClass(&wc))
               return NULL;

       if (GetPlacement("Software\\MapPlot", &rect)) {
               x = rect.left;
               y = rect.top;
               w = rect.right - rect.left;
               h = rect.bottom - rect.top;
       }

       v->hwndMain = CreateWindow(
               "MainWndClass",
               "MapPlot",
               WS_OVERLAPPEDWINDOW,
               x, y, w, h,
               NULL, NULL, v->hInst, (LPVOID)v);

       v->hMenu = GetMenu(v->hwndMain);

       CheckMenuItems(v);

       memset(v->dataDir, 0, 256);
       if (! GetRegVal("Software\\MapPlot", "DataDir", (void*)(v->dataDir),
                       sizeof(v->dataDir))) {
               if (! GetDataDir(v))
                       return NULL;
       }

       GetCurrentDirectory(256, (LPTSTR)v->confDir);
       strcpy(v->wdbIIDir, "");

       if (! ReadMaps(v))
               return NULL;

       ShowWindow(v->hwndMain, nCmdShow);
       UpdateWindow(v->hwndMain);
       return v;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
               LPSTR lpCmdLine, INT nCmdShow)
{
       HACCEL hAccel;
       MSG msg;
       VARS *v;

       if (! (v = Init(hInstance, nCmdShow)))
               return 0;

       if (! (hAccel = LoadAccelerators(v->hInst, "Accel")))
               return 0;

       while (GetMessage (&msg, NULL, 0, 0)) {
               if (! TranslateAccelerator(v->hwndMain, hAccel, &msg)) {
                       TranslateMessage(&msg);
                       DispatchMessage(&msg);
               }
       }

       return msg.wParam;
}