// PSM.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "Defence.h"
#include "PSM.h"

#include "MainFrm.h"
#include "PSMDoc.h"
//#include "PSMView.h"
#include "NavigatorView.h"
#include "ChildFrame.h"
#include <AutoUpdate.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define APL_ALP_LANG_CODE_RUSSIAN 0x419
#define APL_ALP_LANG_CODE_ENGLISH 0x409
/////////////////////////////////////////////////////////////////////////////
// CPSMApp

BEGIN_MESSAGE_MAP(CPSMApp, CWinApp)
	//{{AFX_MSG_MAP(CPSMApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	ON_COMMAND(ID_AUTOUPATE_RUN, OnAutoupateRun)
	ON_COMMAND(ID_AUTOUPATE_SETUP, OnAutoupateSetup)
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
	// Standard print setup command
	ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPSMApp construction

void CopyOptions();

CPSMApp::CPSMApp()
{
	m_data=0;	
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CPSMApp object

CPSMApp theApp;

HINSTANCE g_psm_resource_handle=0;

void gSetPsmResourceHandle()
{
	if(0==g_psm_resource_handle)  return;

#ifdef _DEBUG	
	HINSTANCE curinst=AfxGetResourceHandle();
	if(g_psm_resource_handle!=curinst &&  0!=g_psm_resource_handle) 
	{
		CString buf;
		buf.Format(APL_T("Несоответствие ресурсов!\n\nТекущий указатель: 0x%x\n\nМожно тормазнуть определить какая гадина испортила ресурсы"),(int)curinst);
		AfxMessageBox(buf);
	}
#endif
	AfxSetResourceHandle(g_psm_resource_handle);
}

/////////////////////////////////////////////////////////////////////////////
// CPSMApp initialization

BOOL CPSMApp::InitInstance()
{
	g_psm_resource_handle=AfxGetResourceHandle();

	//Многоязычность интерфейса
	CaplTranslate::SetCurLocaleFromReg(); 


	CaplAutoUpdate au(_T("PSS"));
	au.LoadOptions();
	// вызываем проверку только если 1) источник обновления - файлы 2) если стоит флаг автообновляться
	if(au.m_source==0 && au.m_AutoUpdate)
	{
		if(au.Update(true,false)) return FALSE;
	}
	
	AfxEnableControlContainer();

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
#if _MSC_VER < 1400
	Enable3dControls();			// Call this when using MFC in a shared DLL
#endif
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Change the registry key under which our settings are stored.
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization.
	/*
    EnableShellOpen();
    RegisterShellFileTypes(TRUE);
    RegSetValue(HKEY_CLASSES_ROOT,_T(".p21") ,REG_SZ,_T("STEP.Document"),13);
    RegSetValue(HKEY_CLASSES_ROOT,_T(".step"),REG_SZ,_T("STEP.Document"),13);
	*/

	SetRegistryKey(_T("CALS Centre \"Applied Logistic\""));
	LoadStdProfileSettings(0);  // Load standard INI file options (including MRU)
	m_view_update = RegisterWindowMessage(_T("UPDATE_TREEITEM_VIEW"));
	m_view_disconnect = RegisterWindowMessage(_T("UPDATE_DISCONNECT"));

	CString buf;


	//Initializes the OLE DLLs
	if (!AfxOleInit())
	{
	  AfxMessageBox(_T("OLE initialization failed!"));
	  return FALSE;
	}

	CopyOptions();
	
	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.
/*
	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CPSMDoc),
		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
		RUNTIME_CLASS(CNavigatorView));//CPSMView));
	AddDocTemplate(pDocTemplate);
*/


	CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CPSMDoc),
		RUNTIME_CLASS(CChildFrame), // custom MDI child frame
		RUNTIME_CLASS(CNavigatorView));
	AddDocTemplate(pDocTemplate);

	// create main MDI Frame window
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;
	m_pMainWnd = pMainFrame;

	buf.Empty();
	buf.LoadString(AFX_IDS_APP_TITLE);
	pMainFrame->SetWindowText(buf);

	pDocTemplate->m_hMenuShared=pMainFrame->m_menu.Detach();
	//pMainFrame->m_hMenuDefault
	pMainFrame->OnUpdateFrameMenu(pMainFrame->m_hMenuDefault);
	
	if(AfxGetApp()->GetProfileInt(_T("MainFrame"),_T("Maximized"),0))
		m_pMainWnd->ShowWindow(SW_MAXIMIZE);
	else  m_pMainWnd->ShowWindow(SW_SHOW);
	//m_pMainWnd->CenterWindow();

	// Parse command line for standard shell commands, DDE, file open
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;


	m_pMainWnd->UpdateWindow();

	/*	Наследие DCOM
	static CaplOleMessageFilter MyFilter;
	MyFilter.SetMessagePendingDelay(100);
	MyFilter.EnableNotRespondingDialog(FALSE);
	MyFilter.EnableBusyDialog(FALSE);
	MyFilter.Register();
	*/

	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CaplTranslateDialog
{
	CBitmap m_bmp;
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	CStatic	m_logo;
	CaplHyperLink	m_www_cals_ru;
	CaplHyperLink	m_info_cals_ru;
	CString	m_ver;
	CString	m_mod_name;
	CString	m_mod_lic;
	CString	m_srv_lic;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CaplTranslateDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	m_ver = _T("");
	m_mod_lic = _T("");
	m_srv_lic = _T("");
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplTranslateDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	DDX_Control(pDX, IDC_STATIC_LOGO, m_logo);
	DDX_Control(pDX, IDC_WWW_CALS_RU, m_www_cals_ru);
	DDX_Control(pDX, IDC_INFO_CALS_RU, m_info_cals_ru);
	DDX_Text(pDX, IDC_VER, m_ver);
	DDX_Text(pDX, IDC_MOD_LIC, m_mod_lic);
	DDX_Text(pDX, IDC_SRV_LIC, m_srv_lic);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CaplTranslateDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CopyOptions();


// App command to run the dialog
void CPSMApp::OnAppAbout()
{
	CaplAPI *api = NULL;
	CDocTemplate *dt;
	POSITION pos;
	pos = GetFirstDocTemplatePosition();
	if(pos)
	{
		dt = GetNextDocTemplate(pos);
		if(dt)
		{
			pos = dt->GetFirstDocPosition();
			if(pos)
			{
				CDocument* pDoc = dt->GetNextDoc(pos);
				api = &((CPSMDoc*)pDoc)->m_api;
			}
		}
	}
	aplShowAboutDlg(api, NULL);
}

/////////////////////////////////////////////////////////////////////////////
// CPSMApp message handlers

BOOL CAboutDlg::OnInitDialog() 
{
	m_mod_lic= APL_T("Версия без ограничений");
	
	CaplTranslateDialog::OnInitDialog();
	CString buf,buf1,ver_sys=_T("?");
	m_info_cals_ru.SetURL(_T("mailto:info@cals.ru"));

	aplGetLogoBmp(m_bmp,this);
	m_logo.SetBitmap(HBITMAP(m_bmp));

	// Чтение версии
//	CString ininame=AfxGetApp()->m_pszHelpFilePath;
//	ininame.MakeLower();
//	ininame.Replace(_T("psm.hlp"),_T("pss.ver"));
//
//	CStdioFile f;
//	if(f.Open(ininame,CFile::modeRead|CFile::shareDenyRead|CFile::typeText))
//	{
//		while (f.ReadString(buf))
//		{
//			int i=buf.Find(_T("pssver="));
//			if(i>=0)
//			{
//				ver_sys=buf.Right(buf.GetLength()-7);
//				break;
//			}
//		}
//		f.Close();
//	}
	GetVersionClient(&ver_sys);
	m_ver= APL_T("Клиент : ");m_ver+=ver_sys;
	
	/*// Чтение версии из инсталятора
	HKEY inst_key=0;
	if(ERROR_SUCCESS==RegOpenKey(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\F1228DB45FC60474DAEDB3DDE909EAE8\\InstallProperties"),&inst_key))
	{
		unsigned char *ver_buf=new unsigned char[1024];
		ver_buf[0]=_T('\0');
		DWORD type_ver_buf=REG_SZ;
		DWORD len_ver_buf=1023;
		if(ERROR_SUCCESS==RegQueryValueEx(inst_key,_T("DisplayVersion"),0,
			&type_ver_buf,ver_buf,&len_ver_buf))
		{
			if((ver_sys==_T("?"))||(ver_sys!=ver_buf))
			{m_ver+=_T("  (");m_ver+=ver_buf;m_ver+=_T(")");}
		}
		delete ver_buf;
		RegCloseKey(inst_key);
	}*/


	// Чтение версии словаря
	CPSMDoc *doc=GetActiveDocument();
	if(doc!=0)
	{
		if(doc_data.IsConnected())
		{
			/* так было когда доп словарь был один
			buf.Format( APL_T("    Словарь : %s v%i"),LPCTSTR(doc_data.m_CurSchema),doc_data.m_CurSchemaVersion);
			m_ver+=buf;
			
			if(doc_data.m_CurSchema2!=_T(""))
			{
				buf.Format( APL_T(" + %s v%i"),LPCTSTR(doc_data.m_CurSchema2),doc_data.m_CurSchemaVersion2);
				m_ver+=buf;
			}*/

			m_ver+=APL_T("    Словарь : ");
			m_ver+=doc_data.GetDictionaryDescription();
		}
	}
	UpdateData(FALSE);
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CPSMApp::OnAutoupateRun() 
{
	CaplAPI *api = NULL;
	CDocTemplate *dt=0;
	POSITION pos;
	CPSMDoc* pPDoc=0;
	pos = GetFirstDocTemplatePosition();
	if(pos)
	{
		dt = GetNextDocTemplate(pos);
		if(dt)
		{
			pos = dt->GetFirstDocPosition();
			if(pos)
			{
				pPDoc = (CPSMDoc*)dt->GetNextDoc(pos);
				api = &(pPDoc)->m_api;
			}
		}
	}

	CaplAutoUpdate au(_T("PSS"));
	au.LoadOptions();
	// проверка вызывается вручную - источник обновления не проверяем
	if(api!=0)au.m_data=&(api->m_data);


	if(au.Update(false,true)) 
	{
		if(pPDoc!=0)
		{
			pPDoc->OnDbDisconnect();
			pPDoc->OnCloseDocument();
		}
	}
}

void CPSMApp::OnAutoupateSetup() 
{
	CaplAutoUpdate au(_T("PSS"));
	au.LoadOptions();
	au.SetOptions();
}

//******************************************************************************************

bool pdmRegGetParam(LPCTSTR sRazdel, LPCTSTR sParam, int &iVal, int defVal)
{
	iVal=defVal;

	HKEY key=0;
	if(ERROR_SUCCESS!=RegOpenKeyEx(HKEY_CURRENT_USER, sRazdel,0,KEY_READ,&key)) return false;

	DWORD dwType=0; //REG_DWORD
	DWORD dwValSize=4;
	BYTE pVal[4];

	bool bRes=false;
	if(ERROR_SUCCESS==RegQueryValueEx(key, sParam, NULL, &dwType, pVal, &dwValSize))
	{
		iVal=*pVal;
		bRes=true;
	}
	RegCloseKey(key);
	return bRes;
};

bool pdmRegSetParam(LPCTSTR sRazdel, LPCTSTR sParam, int iVal )
{
	HKEY key=0;
	if(ERROR_SUCCESS!=RegOpenKeyEx(HKEY_CURRENT_USER, sRazdel,0, KEY_WRITE,&key)) return false;

	DWORD dwVal=iVal;

	bool bRes=false;
	if(ERROR_SUCCESS==RegSetValueEx(key, sParam, NULL, REG_DWORD, (LPBYTE)&dwVal, sizeof(DWORD)))bRes=true;

	RegCloseKey(key);
	return bRes;
};


//******************************************************************************************

bool CopyRegParams(LPCTSTR sCommonParam, LPCTSTR sFromParam, LPCTSTR sToParam)
{
	CString sFrom(sCommonParam); sFrom+=sFromParam;
	CString sTo(sCommonParam); sTo+=sToParam;

	HKEY keyFrom=0, keyTo=0 ;

	if(ERROR_SUCCESS!=RegOpenKeyEx(HKEY_CURRENT_USER, sFrom, 0, KEY_ALL_ACCESS, &keyFrom)) return false;
	if(ERROR_SUCCESS!=RegOpenKeyEx(HKEY_CURRENT_USER, sTo, 0, KEY_ALL_ACCESS, &keyTo))
	{
		if(ERROR_SUCCESS!=RegCreateKeyEx(HKEY_CURRENT_USER, sTo, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyTo, NULL))
		{
			RegCloseKey(keyFrom);
			return false;
		}
	}

	int i=0;
	LONG lResult=0;
	DWORD dwSize = MAX_PATH;
	DWORD dwNameSize = MAX_PATH;
	TCHAR *szName =new TCHAR[MAX_PATH];

	while(true) // Перебор разделов
	{
		dwSize = MAX_PATH;
		lResult = RegEnumKeyEx(keyFrom, i, szName, &dwSize, NULL, NULL, NULL, NULL);
		i++;
		if (lResult != ERROR_SUCCESS) break;

		CString sRazdName(szName);
		//if(sRazdName.Find(_T("ControlBars"))>=0) continue;
		//if(sRazdName.Find(_T("InfoBar"))>=0) continue;

		CString sFrom1(sFromParam); sFrom1+=_T('\\');  sFrom1+=sRazdName;
		CString sTo1(sToParam);     sTo1+=_T('\\');    sTo1+=sRazdName;

		CopyRegParams(sCommonParam, sFrom1, sTo1);
	}
	

	// Перебор значений
	i=0;
	DWORD dwType=0;
	DWORD dwSizeVal = 4096;
	BYTE *pbValue =new BYTE[dwSizeVal];

	while(true)
	{
		dwNameSize = MAX_PATH;
		dwType=0;
		dwSizeVal = 4096;
		lResult = RegEnumValue(keyFrom, i, szName, &dwNameSize, NULL, &dwType, pbValue, &dwSizeVal);
		i++;

		if(ERROR_SUCCESS!=lResult) break;

		RegSetValueEx(keyTo, szName, NULL, dwType, pbValue, dwSizeVal);

		/*if(REG_DWORD==dwType)
		{
			RegSetValueEx(keyTo, szName, NULL, REG_DWORD, pbValue, sizeof(DWORD));
		}
		else if(REG_SZ==dwType)
		{
			RegSetValueEx(keyTo, szName, NULL, REG_SZ, pbValue, dwSizeVal);
		}*/
	}

	delete [] pbValue; pbValue=0;
	delete [] szName; szName=0;

	RegCloseKey(keyTo);
	RegCloseKey(keyFrom);

	return true;
}



//******************************************************************************************


// Копирует настройки из одной ветки в другую.
// Проблема возникла из-за переименования модуля из "PDM Step Suite" в "PDM"
// И, соответственно, изменилась ветка настроек
void CopyOptions()
{
	int iVal=0;
	pdmRegGetParam(_T("Software\\CALS Centre \"Applied Logistic\"\\PDM"), _T("__flagOptionsCopied"), iVal, 0);
	if(iVal!=0) return;

	CopyRegParams(_T("Software\\CALS Centre \"Applied Logistic\"\\"), _T("Модуль PDM"), _T("PDM"));

	pdmRegSetParam(_T("Software\\CALS Centre \"Applied Logistic\"\\PDM"), _T("__flagOptionsCopied"), 1);
}
