
/*	Copyright (C) G. Jespersen
	See Licence.txt.*/

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

#include "stdafx.h"
#include "DsLavSplit.h"

#include "MainFrm.h"
#include "DsLavDoc.h"

// CDsLavSplitterView
#include "DsLavSplitterView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDsLavApp

BEGIN_MESSAGE_MAP(CDsLavApp, CWinApp)
	//{{AFX_MSG_MAP(CDsLavApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDsLavApp construction

CDsLavApp::CDsLavApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance

	m_pDocument			= NULL;		// CDsLavDoc ptr
	m_hwndControlBar		= NULL;		// Handle to CControlBar
	m_hwndSplitterView	= NULL;		// Handle to CDsLavSplitterView - CMainFrame::OnHideLeftPane
	m_hwndTreeView		= NULL;		// Handle to CDsLavTreeView 
	m_hwndListView		= NULL;		// Handle to CDsLavListView
	m_hwndVideoView		= NULL;		// Handle to CDsLavVideoView
	m_hwndCurRightPane	= NULL;		// Handle to current right pane - list or video view 
	m_hwndDvdNavDlg		= NULL;		// Handle to modal CDvdNavDlg 


	// View ptrs.
	m_pSplitterView		= NULL;		// See CMainFrame::GetSplitterView() for swithing views

	// Get current directory at start up.
	// Note CFileDlg changes it when opening.
	TCHAR szPath[1024];
	::GetCurrentDirectory(sizeof(szPath) / sizeof(TCHAR), szPath);
	m_curDirectory = szPath;
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CDsLavApp object

CDsLavApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CDsLavApp initialization

BOOL CDsLavApp::InitInstance()
{
    // Initialize OLE libraries - must for CPlayer and LAV Filters.
	// MFC will call Coinitialize here and CoUninitialize on exit.
    if (!AfxOleInit())
    { 
		AfxMessageBox(_T("ERROR CDsLavApp::InitInstance Couldn't initialize COM"));
		return FALSE;
    }

	// 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.

	/* out 3d
	#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
	#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
	#endif
	*/

	/* out reg, mru
	// 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.
	SetRegistryKey(_T("Local AppWizard-Generated Applications"));

	int nMru = 0;
	LoadStdProfileSettings(nMru);  // Load standard INI file options (including MRU)*/

	// 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(CDsLavDoc),
		RUNTIME_CLASS(CMainFrame),				// main SDI frame window
		RUNTIME_CLASS(CDsLavSplitterView));		// CDsLavSplitterView w/ Tree & List Views
	AddDocTemplate(pDocTemplate);

	// 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;

	// The one and only window has been initialized, so show and update it.
	m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateWindow();

	// Register Clipboard format.
	m_uiCbMediaItem = ::RegisterClipboardFormat(_T("CbMediaItem"));

	return TRUE;
}

// Get User App Data folder.
// DsLavUser.dat
BOOL CDsLavApp::GetUserSettingsFolder(CString & path)
{
	// My Documents folder - CSIDL_PERSONAL - note CSIDL_MYDOCUMENTS is virtual
	//
	// CSIDL_LOCAL_APPDATA resolves to:
	//   C:\Documents and Settings\Administrator\Local Settings\Application Data\DsLav
	// CSIDL_APPDATA resolves to:
	//   C:\Documents and Settings\Administrator\Application Data\DsLav

	/*------------------------------------------------------------------
	It's not clear where the users application data folder will be created
	by the Setup Installer, as the user can choose a per-user or per-machine 
	installation.
	Here we use the CSIDL_APPDATA folder at application runtime. It should
	be created by the app if needed, and any required files copied there.
	-------------------------------------------------------------------*/
	
	TCHAR szPath[MAX_PATH];
	CString sub = _T("DsLav");

	// CSIDL_APPDATA - AppDataFolder Property
	//  Full path to the Application Data folder for the current user.
	 int csidl = CSIDL_APPDATA | CSIDL_FLAG_CREATE;

	// CSIDL_COMMON_APPDATA - CommonAppDataFolder Property
	//  Full path to the file directory containing application data 
	//  for All Users.
	//int csidl = CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE;

	// CSIDL_LOCAL_APPDATA - LocalAppDataFolder Property
	//  Full path to the file system directory that serves as the 
	//  data repository for local (non-roaming) applications. 
	//int csidl = CSIDL_LOCAL_APPDATA  | CSIDL_FLAG_CREATE;

	// Force folder creation. Installer should also create.
	HRESULT result = SHGetFolderPathAndSubDir(NULL,					// hWnd	
											  csidl,					// csidl
											  NULL,					// hToken
											  SHGFP_TYPE_CURRENT,	// dwFlags
											  sub,					// pszSubDir
											  szPath);
	if(result != S_OK)
	{
		// Big problems.
		TRACE(_T("ERROR CApp GetUserSettingsFolder - failed\n"));
		MessageBox(NULL, 
				   _T("Application was not installed properly."),
				   _T("DsLav"),
				   MB_ICONEXCLAMATION);
		return FALSE;
	}
	// OK
	path = szPath;
	return TRUE;

	/* Current diretory.
	if(m_curDirectory.IsEmpty())
		return FALSE;
	path = m_curDirectory;
	return TRUE;*/
}

// Called from:
//  CCurlinet::ShowDialogStatus.
void CDsLavApp::SetThreadMessage(const CString & str)
{
	CSingleLock singleLock(&m_critSection);

	// If available (not chancing waiting forever).
	if(!singleLock.IsLocked())
	{
		// vs2005 nust be INFINITE
		singleLock.Lock(INFINITE);	// Attempt to lock the shared resource
		if(singleLock.IsLocked())	// Resource has been locked
		{
			m_strBuff = str;		// Use the shared resource...
			singleLock.Unlock();	// Unlock the resource for others.
		}
	}
	// Else leave string as is.
}

// Called from:
//  CRadioBrowserUpdateDlg::OnStatusString().
BOOL CDsLavApp::GetThreadMessage(CString & str)
{
	CSingleLock singleLock(&m_critSection);

	// If available (not chancing waiting forever)
	if(!singleLock.IsLocked())
	{
		// vs2005 nust be INFINITE
		singleLock.Lock(INFINITE);	// Attempt to lock the shared resource
		if(singleLock.IsLocked())	// Resource now locked
		{
			str = m_strBuff;		// Use the shared resource...
			singleLock.Unlock();	// Unlock the resource for others.
			return TRUE;
		}
	}
	return FALSE;
}


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

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	CString	m_strAbout;
	//}}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() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	m_strAbout = _T("");
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	DDX_Text(pDX, IDC_EDIT_ABOUT, m_strAbout);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CDsLavApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CDsLavApp message handlers

BOOL CAboutDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	SetWindowText(_T("About DsLav"));
//	CString version = _T("0.5.0.0"); // Set RC File VersionInfo also - 7/2022 last 0.5.0.0

	// Get version from VS_VERSION_INFO. 7/22
	CString version;
	CDsLavDoc * pDoc = ((CDsLavApp*)AfxGetApp())->m_pDocument;
	if(pDoc)
		pDoc->GetVersion(version);

	// 8/8/2021 - move to tux
	m_strAbout.Format(	_T("DsLav version:  %s\r\n")
						_T("   https://www.dslav.tuxfamily.org\r\n\r\n")
						_T("Open source software used by this program:\r\n\r\n")
						_T("   LAV Filters:\r\n       https://www.github.com/Nevcairiel/LAVFilters\r\n")
						_T("   FFMPEG:\r\n       https://www.ffmpeg.org/\r\n")
						_T("   Curl:\r\n       https://www.curl.se\r\n")
						_T("   WolfSSL:\r\n       https://www.wolfssl.com\r\n")
						_T("   MPC-HC:\r\n       https://www.mpc-hc.org\r\n")
						_T("   Radio-Browser:\r\n       https://www.radio-browser.info"),
							version);
	UpdateData(FALSE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE

	// In RC file FILEOS 0x4L = VOS_WINDOWS32 ??
	//  https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo
}