//
//  mainfrm.cpp - main form class implementation
//
//  $Id: mainfrm.cpp 54 2014-04-11 01:06:56Z brian $ 
//
//  Copyright (c) 1999-2014 by Precision Micro Control Corp. All rights reserved.
//
#include "stdafx.h"

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_COMMAND(ID_FILE_LOAD, OnFileLoad)
	//}}AFX_MSG_MAP
	ON_UPDATE_COMMAND_UI(IDC_XZERO, OnUpdateXZero)
	ON_UPDATE_COMMAND_UI(IDC_YZERO, OnUpdateYZero)
	ON_UPDATE_COMMAND_UI(IDC_ZZERO, OnUpdateZZero)
	ON_UPDATE_COMMAND_UI(IDC_XPLUS, OnUpdateXPlus)
	ON_UPDATE_COMMAND_UI(IDC_XMINUS, OnUpdateXMinus)
	ON_UPDATE_COMMAND_UI(IDC_YPLUS, OnUpdateYPlus)
	ON_UPDATE_COMMAND_UI(IDC_YMINUS, OnUpdateYMinus)
	ON_UPDATE_COMMAND_UI(IDC_ZPLUS, OnUpdateZPlus)
	ON_UPDATE_COMMAND_UI(IDC_ZMINUS, OnUpdateZMinus)
	ON_UPDATE_COMMAND_UI(IDC_START, OnUpdateStart)
	ON_UPDATE_COMMAND_UI(IDC_BLOCK, OnUpdateBlock)
	ON_UPDATE_COMMAND_UI(IDC_FHOLD, OnUpdateFhold)
	ON_EN_KILLFOCUS(IDC_FEED_OVERRIDE, OnKillfocusFeedOverride)
	ON_EN_KILLFOCUS(IDC_RAPID_OVERRIDE, OnKillfocusRapidOverride)
	ON_EN_KILLFOCUS(IDC_SPINDLE_OVERRIDE, OnKillfocusSpindleOverride)
END_MESSAGE_MAP()

// toolbar buttons - IDs are command buttons
static UINT BASED_CODE buttons[] =
{
	// same order as in the bitmap 'toolbar.bmp'
	ID_FILE_NEW,
	ID_FILE_OPEN,
	ID_FILE_SAVE,
		ID_SEPARATOR,
	ID_EDIT_CUT,
	ID_EDIT_COPY,
	ID_EDIT_PASTE,
		ID_SEPARATOR,
	ID_FILE_PRINT,
	ID_APP_ABOUT,
};

static UINT BASED_CODE indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

BOOL CMainFrame::DestroyWindow(void)
{
	m_app_settings.Save(GetSafeHwnd());
	return CMDIFrameWnd::DestroyWindow();
}

int CMainFrame::OnCreate(LPCREATESTRUCT create_struct)
{
	if (CMDIFrameWnd::OnCreate(create_struct) == -1)
		return -1;

	// find our INI file (for Vista or later this has to be in a writeable location)
	char ini_file[_MAX_PATH] = "wincnc.ini";

	HRESULT (WINAPI* SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR);		
	if ((SHGetFolderPath = (HRESULT (PASCAL*)(HWND, int, HANDLE, DWORD, LPTSTR))GetProcAddress(GetModuleHandle("shell32"), "SHGetFolderPathA")) != NULL)
	{
		char appdata_path[_MAX_PATH];
		if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, appdata_path)))
		{
			strncpy(ini_file, appdata_path, _MAX_PATH);
			strncat(ini_file, "\\Motion Control", _MAX_PATH - strlen(ini_file));
			CreateDirectory(ini_file, NULL);		// create folder, if needed
			strncat(ini_file, "\\Win CNC", _MAX_PATH - strlen(ini_file));
			CreateDirectory(ini_file, NULL);		// create folder, if needed
			strncat(ini_file, "\\wincnc.ini", _MAX_PATH - strlen(ini_file));
		}
	}
	m_app_settings.IniFile(ini_file);
	m_app_settings.Restore(GetSafeHwnd());

	if (!m_wndToolBar.Create(this) ||
		!m_wndToolBar.LoadBitmap(IDR_MAINFRAME) ||
		!m_wndToolBar.SetButtons(buttons, sizeof(buttons) / sizeof(UINT)))
	{
		TRACE("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT)))
	{
		TRACE("Failed to create status bar\n");
		return -1;      // fail to create
	}
	
	if (!m_wndControlPanel.Create(this, IDD_RUN_PANEL, CBRS_LEFT, 5432))
	{
		TRACE("Failed to create control panel\n");
		return -1;      // fail to create
	}
	else
		theApp.SetControlPanel(&m_wndControlPanel);
	
	return 0;
}

void CMainFrame::InitialUpdate()
{
	// Do initial update of front panel.
	m_wndControlPanel.InitialUpdate();

	// Don't start timer until after front panel is initialized! The timer service uses DDX data
	// objects which aren't connected to windows until DoDataExchange() is called for the first 
	// time in ControlPanel.InitialUpdate. But DoDataExchange can't be called until after the main 
	// frame is shown at the end of CWincncApp::InitInstance().
	CWnd::SetTimer(100, 100, NULL);
}

void CMainFrame::OnTimer(UINT nIDEvent)
{
	m_wndControlPanel.OnTimer();
}

void CMainFrame::OnFileLoad()
{
	theApp.GetMachine()->FileLoad();
}
