/* -*- C++ -*-
/*
 * $Id: ini_news.cpp 1.18 1997/04/05 00:26:27 dumoulin Exp $
 */

/******************************************************************** */
/* Filename: Ini-News.cpp */
#if defined(_WIN64)
#pragma message("**** Building x64 ****" )
#endif

#pragma message ("START PLATTFORM DETECTION")

#if defined(_M_IX86)

#pragma message ("_M_IX86 defined.")

#endif

#if defined(_X86_)

#pragma message ("_X86_ defined.")

#endif

#if defined(_M_AMD64)

#pragma message ("_M_AMD64 defined.")

#endif

#if defined(_AMD64_)

#pragma message ("_AMD64_ defined.")

#endif

#if defined(_M_IA64)

#pragma message ("_M_IA64 defined.")

#endif

#if defined(_IA64_)

#pragma message ("_IA64_ defined.")

#endif

#if defined(_68K_)

#pragma message ("_68K_ defined.")

#endif

#if defined(_MPPC_)

#pragma message ("_MPPC_ defined.")

#endif

#pragma message ("END PLATTFORM DETECTION (MAKE SURE ONLY 1 IS DEFINED)")

#include <windows.h>
#include <windowsx.h>
#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop
#include "wvclass.h"
#include <stdlib.h>
#include <direct.h>
#include <time.h>
#include <commdlg.h>

/* Ray Dunn:99/10 */
static int AuxReadSortOption(const char* sDefSort, const char* sGrp);
/* Ray Dunn:99/10:End */

/*************************************************************************
  This function looks for the .Ini file and the NewsSrc file.  Each file
  is searched for separately and they need not be in the same directory.
  If neither file can be found, the user is asked to locate the files with
  an OPENFILENAME dialog box.  Once the location of the NewSrc file is
  known, it is saved in the WinVN.ini file.

  The search order is:
    Command Line (one or two entries)
    Environment variable "WINVN" or "winvn" (case sensitive in Win16)
    Current Working directory (set by "Properties" dialog)
	User AppData directory
    Application Directory
    Windows Directory (eg. C:\WINDOWS)
    Windows System Directory (eg. C:\WINDOWS\SYSTEM, \System32)
    the path
    result of an "Open File" dialog box (WinVN.ini only)
    the .INI file (NewSrc only)
    result of an "Open File" dialog box (NewSrc only)


  If the Function is sucessful, the szAppProFile variable contains the path and
  filename of the .Ini file and the szNewsSrc variable contains the path and
  filename of the NewSrc file.  If either file does not exist, the "Open
  File" dialog creates each file.  In all cases, the name of the NewSrc
  file is written to the .INI file for future accesses.

  RETURNS:  zero if sucessful
            -1 if one or both files could not be found

  NOTE: The command line allows for the use of unique names for the standard
        WinVn.ini and NewSrc files. The entry order is .Ini and then NewSrc.

 Command line examples are as follows:

  1.  c:\WinVn\My.Ini<sp>c:\Tom\NewsSrc.Tom  => both unique names

  2.  c:\Tom<sp>c:\Tom\NewsSrc.Tom        => standard .Ini, unique NewSrc
  2a. c:\Tom\<sp>c:\Tom\NewsSrc.Tom          (same, less ambiguous)

  3.  c:\Tom\TomVn.ini                    => unique .Ini, Standard NewSrc

  4.  c:\Tom                              => standard .Ini, Standard NewSrc
  4a. c:\Tom\                                (same, less ambiguous)

  In the first example, if both files exist, szAppProFile = "c:\WinVn\My.Ini",
  szNewsSrc = "c:\Tom\NewsSrc.Tom" and the function returns Zero.

 For all specification types other than the Command line:
 1. Only one entry may be made.
 2. The "Working directory" spec doesn't allow trailing "\".
 3. Syntax and algorithm are otherwise the same as for Command Line.

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

static struct ValStrTable SortOptionTable[] =
{
	IDM_SORT_DATE,      STR_SORT_DATE,
	IDM_SORT_SUBJECT,   STR_SORT_SUBJECT,
	IDM_SORT_LINES,     STR_SORT_LINES,
	IDM_SORT_THREADS,   STR_SORT_THREADS,
	IDM_SORT_THREADSUB, STR_SORT_THREADSUB,
	IDM_SORT_ARTNUM,    STR_SORT_ARTNUM,
	IDM_SORT_FROM,      STR_SORT_FROM,
	/* Ray Dunn:99/10
		Add new 2-level sort options.  Keep old ones so will auto convert from old to new
	*/
	IDM_SORT_DATE_TIME,      STR_SORT_DATE_TIME,
	IDM_SORT_DATE_SUBJECT,   STR_SORT_DATE_SUBJECT,
	IDM_SORT_DATE_LINES,     STR_SORT_DATE_LINES,
	IDM_SORT_DATE_ARTNUM,    STR_SORT_DATE_ARTNUM,
	IDM_SORT_DATE_FROM,      STR_SORT_DATE_FROM,
	IDM_SORT_SUBJECT_DATE,   STR_SORT_SUBJECT_DATE,
	IDM_SORT_SUBJECT_LINES,  STR_SORT_SUBJECT_LINES,
	IDM_SORT_SUBJECT_ARTNUM, STR_SORT_SUBJECT_ARTNUM,
	IDM_SORT_SUBJECT_FROM,   STR_SORT_SUBJECT_FROM,
	IDM_SORT_FROM_SUBJECT,   STR_SORT_FROM_SUBJECT,
	IDM_SORT_FROM_DATE,      STR_SORT_FROM_DATE,
	IDM_SORT_FROM_LINES,     STR_SORT_FROM_LINES,
	IDM_SORT_FROM_ARTNUM,    STR_SORT_FROM_ARTNUM,
	IDM_SORT_FILENAME,       STR_SORT_FILENAME,
	IDM_SORT_DATE_FILENAME,  STR_SORT_DATE_FILENAME,
	IDM_SORT_FROM_FILENAME,	 STR_SORT_FROM_FILENAME
/* Ray Dunn:99/10:End */

};

#define SORTOPTIONTABLESIZE (sizeof(SortOptionTable) / sizeof(SortOptionTable[0]))


/*
 //TODO: could use this:
BOOL PathRelativePathTo( LPTSTR pszPath,
    LPCTSTR pszFrom,
    DWORD dwAttrFrom,
    LPCTSTR pszTo,
    DWORD dwAttrTo
);
	//but requires shlwapi.dll version 4.71 or later
*/

//opposite (relative to absolute path) is GetFullPathName()

BOOL SplitRelativePath( const char* szPath, char *szPathFile )
{
	
	typedef  BOOL (WINAPI* pPATHRELATIVEPATHTO) ( LPTSTR  pszPath, LPCTSTR pszFrom,
							DWORD   dwAttrFrom, LPCTSTR pszTo, DWORD   dwAttrTo );

	pPATHRELATIVEPATHTO pPathRelativePathTo = NULL;
	HINSTANCE hLib = LoadLibrary("shlwapi.dll");
	if (hLib)
	{
		 pPathRelativePathTo = (pPATHRELATIVEPATHTO) ::GetProcAddress(	hLib, "PathRelativePathToA");

		if (pPathRelativePathTo)
		{
			char szOut[_MAX_PATH];

			if (pPathRelativePathTo( szOut, szPath, 0, szPathFile, FILE_ATTRIBUTE_NORMAL) )
			{
				TRACE("Relative path is %s\r\n", szOut); 
				strcpy(szPathFile, szOut);
				return TRUE;

			}

		}
	}

	if (!pPathRelativePathTo)
	{
	
		int nLen = 	strlen(szPath);

		if (szPath[nLen-1] == '\\')
			nLen--;
		
		if (_strnicmp(szPath, szPathFile, nLen)  == 0)
		{
			if (szPathFile[nLen] == '\\')
				nLen++;

			char *p = szPathFile + nLen;
			while (*p)
				*(szPathFile++) = *(p++);

			*szPathFile = '\0';
			return TRUE;
		}
	}

	return FALSE;
}

//look for full path containing C:\blah or \\zod\fop (returns true if not absolute)
BOOL IsRelativePath( LPCSTR szPath)
{
	BOOL bReturn = FALSE;
	//check for relative paths
	typedef  BOOL (WINAPI* pPATHISRELATIVE) ( LPCTSTR  pszPath );

	pPATHISRELATIVE pPathIsRelative = NULL;
	HINSTANCE hLib = LoadLibrary("shlwapi.dll");
	if (hLib)
	{
		 pPathIsRelative = (pPATHISRELATIVE) ::GetProcAddress(	hLib, "PathIsRelativeA");

		if (pPathIsRelative)
		{ 
			bReturn = pPathIsRelative( szPath);
		}

	}
	if (pPathIsRelative)
		return bReturn;

	return (*(szPath+1) != ':' && !(*szPath == '\\' && *(szPath+1) == '\\'));
}

BOOL MakeAbsolutePath(const char *szDir, char *szRelFile)
{

	char  szOut[_MAX_PATH];
	char szRoot[_MAX_PATH];

	if (!szDir || !*szDir || !szRelFile || !*szRelFile)
		return FALSE;

	DWORD dwAttrib = GetFileAttributes(szDir);
	if (dwAttrib == (DWORD) -1)
		return FALSE;
	
	strcpy(szRoot, szDir);
	if ( !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))
	{
		//null out filename part
		char *p = strrchr( (char *) szRoot, '\\');
		if (p)
			*(p+1) = '\0';

	}


	//check for relative paths
	typedef  BOOL (WINAPI* pPATHCOMBINE) ( LPCTSTR  pszDest, LPCTSTR pszDir, LPCTSTR pszFile );

	pPATHCOMBINE pPathCombine = NULL;
	HINSTANCE hLib = LoadLibrary("shlwapi.dll");
	if (hLib)
	{
		 pPathCombine = (pPATHCOMBINE) ::GetProcAddress( hLib, "PathCombineA");

		if (pPathCombine)
		{
			if (pPathCombine(szOut, szRoot, szRelFile))
			{
				strcpy(  szRelFile, (char *)szOut);
				return TRUE;
			}
			else
			{
				return FALSE;
			} 

		}
	}
	//we dont handle embedded relative paths
	strcpy((char *) szOut, (char *)szRoot);
	if (szOut[strlen(szOut)-1] == '\\')
		szOut[strlen(szOut)-1] = '\0';

	while( *szOut)
	{
		if (!strncmp(szRelFile, "..\\", 3))
		{
			//move up the tree
			char *p = strrchr(szOut, '\\');
			if (!p)
				return FALSE; //topped out
				
		}
		else if (!strncmp(szRelFile, ".\\", 2))
		{
			//current dir
			szRelFile += 1;
		}
		else if (!strncmp(szRelFile, "\\\\",2) || szRelFile[1] == ':')
		{
			//error cant use
			return FALSE;
		}
		else if (*szRelFile == '\\')
		{
			strcat(szOut, szRelFile);
			break; 
		}
		else
		{
			//a filename, just append
			strcat(szOut, "\\");
			strcat(szOut, szRelFile);
			break;
		}
	}
	strcpy(	szRelFile, szOut); 

	return TRUE;



}

#define CHECK_DIR 1
#define CHECK_FILE 2

/*  Routine to test existence of filename on path choice */
BOOL ProbeFilePath (char *szFileSrc, const char *szPath, const char *szFname, int iChk)
{
	DWORD stat;
	OFSTRUCT ofb;

	/* Check for non-directory file in the form of "x:\dir\...\dir\file.ext" */
	if (iChk & CHECK_FILE) 
	{
		lstrcpy (szFileSrc, szPath);

		stat = GetFileAttributes (szFileSrc);
		if (stat != (DWORD) -1)
		{
			//something exists
			if ( (stat & FILE_ATTRIBUTE_DIRECTORY) == 0)
			{
				//its not a directory
				if (OpenFile (szFileSrc, &ofb, OF_EXIST) != HFILE_ERROR) 
				{
					//found a file
					lstrcpy (szFileSrc, ofb.szPathName);
					return TRUE;
				}
			}
		}
	}
	
	
	// Check for path in the form of "x:\dir\...\dir[\]"
	if (iChk & CHECK_DIR) 
	{
		int i;
		lstrcpy (szFileSrc, szPath);
		i = lstrlen (szFileSrc);
		if (i) 
		{
			
			stat = GetFileAttributes (szFileSrc);
			if (stat != (DWORD) -1)
			{
				//something exists
				if ( (stat & FILE_ATTRIBUTE_DIRECTORY) == 0)
				{
					//its a file?
					while (i && szFileSrc[i - 1] != '\\')
					{
						szFileSrc[--i] = '\0';
					}
				}
				else if (szFileSrc[i - 1] != '\\')
				{
					szFileSrc[i++]= '\\';
					szFileSrc[i] = '\0';
				}
				//append default filename
				lstrcat (szFileSrc, szFname);
			}
			if (OpenFile (szFileSrc, &ofb, OF_EXIST) != HFILE_ERROR) 
			{
				lstrcpy (szFileSrc, ofb.szPathName);
				return (TRUE);
			}

		}

	}


	return FALSE;
}

int GetPossiblyQuotedString(char *dest, const char *src)
{

    const char  *p;
    const char  *s;
    char c = '\0';
    
	p = src;

	while (isspace((BYTE)*p))
		p++;

    if (*p =='"')
    {
        /* string is quote encapsulated */
        c = '"';
        p++;
    }

    s=p;
            
    while (*p != c  && (c ? 1: !isspace((BYTE)*p)) && *p != '\0' && *p != '\n')
        p++;

    if (*p == c || !c  )
    {

        if (c == '"' && *p != '"')
        {
            //looking for quoted string but ran off of string!
            *(dest) = '\0';
            //need more IN put
        }         
        

        strncpy(dest, s, p-s);
        *(dest+(p-s)) = '\0';
       
    }
    else
    {
        *dest = '\0';    
    }

    return (p-src);
}

	/*  See if we can find the WinVN.ini and NewSrc files... */
int LocIniSrc (HINSTANCE hInstance, LPSTR lpCmdLine)
{
	char szWPath[_MAX_PATH];
	char szBuf[MAXINTERNALLINE];
	unsigned int  i;

	const char szIniDef[] = "WinVN.ini";  /* ' .ini' default filename */
	const char szNewsDefault[] = "newsrc";  /* 'newsrc' default filename  */

	BOOL fProfileFound = FALSE;
	BOOL fNewsFound = FALSE;

	int iRvalue;
	int pos;
	LPSTR lpEnvStr;


	if (*lpCmdLine != '\0') 
	{   /* Look at the Command Line - path | path and file */
		
		iRvalue = lstrlen (lpCmdLine);

		pos = GetPossiblyQuotedString(szWPath, lpCmdLine);

		//  TRACE1 ("Checking Command Line: %s\n", szWPath);
		iRvalue = lstrlen (lpCmdLine);



		if (iRvalue > pos+6) // two entries on command line - check for path and/or path\file 
		{      
			fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR | CHECK_FILE);
			pos = GetPossiblyQuotedString(szWPath, lpCmdLine+pos+1 );
			fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_FILE);
		}
		else 
		{            /* single command line entry - path and/or path\file */
			fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR | CHECK_FILE);
			
			//read winvn.ini for newsrc path before looking in local dir.
			//allows for uniquely identified newsrc
			if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
			{
				if (IsRelativePath(szNewsSrc))
					MakeAbsolutePath(szAppProFile, szNewsSrc);
				
				fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
			}
			if (!fNewsFound)
				fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_DIR);
		}
		if (fProfileFound && fNewsFound)
			return 0;
	}



	/* Look in the Environment for a path */
	if ((lpEnvStr = getenv ("winvn")) == NULL) 
	{
		lpEnvStr = getenv ("WINVN");
	}

	if (lpEnvStr && (iRvalue = lstrlen (lpEnvStr))) 
	{
		/* found environment varible, check it out */
		lstrcpy (szWPath, lpEnvStr);

		//  TRACE1 ("Checking environment var: %s\n", szWPath);
		if (!fProfileFound)
			fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR | CHECK_FILE);

		//  TRACE1 ("Checking for newsrc in %s\n", szWPath);
		if (!fNewsFound)
			fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_DIR);
		
		if (fProfileFound && fNewsFound)
			return 0;
	}


	/* Look in the current working Directory */
	if (_getcwd (szWPath, sizeof (szWPath))) 
	{
		//  TRACE1 ("Checking current working directory: %s\n", szWPath);
		if (!fProfileFound)
			fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR);

		if (fProfileFound && !fNewsFound)
		{
			//read winvn.ini for newsrc path before looking in local dir.
			//allows for uniquely identified newsrc
			if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
			{
				if (IsRelativePath(szNewsSrc))
					MakeAbsolutePath(szAppProFile, szNewsSrc);
				
				fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
			}

		}

		//now look in same folder
		if (!fNewsFound)
			fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_DIR);

		if (fProfileFound && fNewsFound)
			return 0;
	}



	/* Look in WinVn's Directory */
	if (iRvalue = GetModuleFileName (hInstance, szWPath, sizeof (szWPath))) 
	{
		while (iRvalue--) 
		{     /* remove the module name */
			if (szWPath[iRvalue] == '\\') 
			{
				szWPath[++iRvalue] = 0;
				break;
			}
		}

		//  TRACE1 ("Checking WinVN directory: %s\n", szWPath);
		if (!fProfileFound)
			fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR);

		if (fProfileFound && !fNewsFound)
		{
			//read winvn.ini for newsrc path before looking in local dir.
			//allows for uniquely identified newsrc
			if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
			{
				if (IsRelativePath(szNewsSrc))
					MakeAbsolutePath(szAppProFile, szNewsSrc);
				
				fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
			}

		}		
		if (!fNewsFound)
			fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_DIR);

		if (fProfileFound && fNewsFound)
			return 0;
	}


	{
		LPTSTR pFile;

		fProfileFound = SearchPath( NULL, szIniDef, NULL, sizeof(szAppProFile),
		   szAppProFile, &pFile);

		if (fProfileFound && !fNewsFound)
		{
			//read winvn.ini for newsrc path before looking in local dir.
			//allows for uniquely identified newsrc
			if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
			{
				if (IsRelativePath(szNewsSrc))
					MakeAbsolutePath(szAppProFile, szNewsSrc);
				
				fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
			}

		}

		fNewsFound =  SearchPath( NULL, szNewsDefault, NULL, sizeof(szNewsSrc),
		   szNewsSrc, &pFile);
	}

	{
		//Check user's AppData folder
		if (getSpecialFolder(CSIDL_APPDATA, szWPath, sizeof(szWPath)/sizeof(szWPath[0])))
		{
			int nLen = _tcslen(	szWPath);
			if (nLen)
			{
				if (szWPath[nLen-1] != '\\')
				{
					_tcscat(szWPath, "\\");
					nLen++;
				}

				if (!fProfileFound)
					fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR);

				if (fProfileFound && !fNewsFound)
				{
					//read winvn.ini for newsrc path before looking in local dir.
					//allows for uniquely identified newsrc
					if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
					{
						if (IsRelativePath(szNewsSrc))
							MakeAbsolutePath(szAppProFile, szNewsSrc);
						
						fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
					}

				}
				
				if (!fNewsFound)
					fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_DIR);

				if (fProfileFound && fNewsFound)
					return 0;




				_tcscat(szWPath, "WinVn");

				if (GetFileAttributes(szWPath) == (DWORD) -1)
				{
					if (!CreateDirectory( szWPath, NULL))
					{
						//can't create dir
						szWPath[nLen-5] = '\0';

					}
				}
				
				if (!fProfileFound)
					fProfileFound = ProbeFilePath (szAppProFile, szWPath, szIniDef, CHECK_DIR);

				if (fProfileFound && !fNewsFound)
				{
					//read winvn.ini for newsrc path before looking in local dir.
					//allows for uniquely identified newsrc
					if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
					{
						if (IsRelativePath(szNewsSrc))
							MakeAbsolutePath(szAppProFile, szNewsSrc);
						
						fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
					}

				}


				if (!fNewsFound)
					fNewsFound = ProbeFilePath (szNewsSrc, szWPath, szNewsDefault, CHECK_DIR);

				if (fProfileFound && fNewsFound)
					return 0;
			}

		}


	}


	{

	/* Ask the user if he wants to create the files */
	OPENFILENAME ofn;


	memset (&ofn, 0, sizeof (ofn));
	ofn.lStructSize = sizeof (OPENFILENAME);

	//MDS give it the correct dir to keep it from asking for mydoc dir on Win98+
	if (GetFileAttributes(szWPath) == (DWORD) -1)
	{
		_getcwd (szWPath, sizeof (szWPath)); 
	}
	
	ofn.lpstrInitialDir = szWPath;

	LoadString(hInstance, IDS_INI_NEWS_FILENAME, szBuf, MAXINTERNALLINE);
	ofn.lpstrTitle = szBuf;

	ofn.Flags =	OFN_CREATEPROMPT | OFN_HIDEREADONLY	| OFN_LONGNAMES	| OFN_NOREADONLYRETURN | OFN_EXPLORER;


	
	if (!fProfileFound) 
	{
		char szCreated[32];

		ofn.lpstrFilter = "Init Files (*.INI)\0*.ini\0All Files (*.*)\0*.*\0";
		lstrcpy (szAppProFile, szIniDef);
		ofn.lpstrFile = szAppProFile;
		ofn.nMaxFile = sizeof (szAppProFile);
		ofn.lpstrDefExt = "INI";

		//    TRACE0("Checking user-specified filename\n");
		fProfileFound = GetOpenFileName (&ofn);
		if (fProfileFound) 
		{
			char dbuffer[9];
			char tbuffer[9];
			OFSTRUCT ofs;

			/* ofn.lpstrInitialDir = ...  */

			if (OpenFile (szAppProFile, &ofs, OF_EXIST) == HFILE_ERROR) 
			{
				_strdate (dbuffer);
				_strtime (tbuffer);

				//      TRACE1 ("Writing new WinVN.INI file to %s\n", szAppProFile);
				lstrcpy (szCreated, dbuffer);
				lstrcat (szCreated, " ");
				lstrcat (szCreated, tbuffer);

				WritePrivateProfileString (ADMIN, "Created", szCreated, szAppProFile);
			}
		}
	}


	/* Look for NewSrc spec in WinVN.INI */
	if (fProfileFound && !fNewsFound) 
	{
		//read winvn.ini for newsrc path before looking in local dir.
		//allows for uniquely identified newsrc
		if (GetPrivateProfileString (ADMIN, "Newsrc", "",szNewsSrc, sizeof (szNewsSrc), szAppProFile)) 
		{
			if (IsRelativePath(szNewsSrc))
				MakeAbsolutePath(szAppProFile, szNewsSrc);
			
			fNewsFound = ProbeFilePath (szNewsSrc, szNewsSrc, "", CHECK_FILE);
		}

	}


	/* Give up?  Ask the user where the file is... */
	if (fProfileFound && !fNewsFound) 
	{
		//doesn't work 
		//ofn.lpstrFilter = "No-ext Files (*.)\0*.\0All Files (*.*)\0*.*\0";
		ofn.lpstrFilter = "All Files (*.*)\0*.*\0";
		ofn.nFilterIndex = 0;
		lstrcpy (szNewsSrc, szNewsDefault);
		ofn.lpstrFile = szNewsSrc;
		ofn.nMaxFile = sizeof (szNewsSrc);
		ofn.lpstrDefExt = "";
		ofn.lpstrInitialDir = szAppProFile;

		fNewsFound = GetOpenFileName (&ofn);
		if (fNewsFound) 
		{
			HFILE hf;
			OFSTRUCT ofs;
			if (OpenFile (szNewsSrc, &ofs, OF_EXIST) == HFILE_ERROR) 
			{
				hf = OpenFile (szNewsSrc, &ofs, OF_CREATE);
				if (LoadString(hInstance, IDS_INI_NEWS_START, szBuf, MAXINTERNALLINE)) 
				{
					/* write some default newsgroups... */
					i = IDS_INI_NEWS_START;
					while ((i <= IDS_INI_NEWS_LAST) && (LoadString(hInstance, i, szBuf, MAXINTERNALLINE))) 
					{
						if (szBuf[0] != '\0') 
						{
							_lwrite (hf, szBuf, strlen(szBuf));
							_lwrite (hf, ": s0\r\n", 6);
						} 
						else 
						{
							break;
						}
						i++;
					}
				} 
				else 
				{

				}
				_lclose (hf);
				}
			}
		}
	}

	if (fProfileFound && fNewsFound)
		return 0;
	return (-1);
}


/*  Locate the WinVN.ini and NewSrc files... */
int fnLocateFiles (HINSTANCE hInstance, LPSTR lpCmdLine)
{
	int result;
	result = LocIniSrc (hInstance, lpCmdLine);
	if (!result) 
	{
		//  TRACE1 ("WinVN.INI file located: %s\n", szAppProFile);
		//  TRACE1 ("NewSrc file located:    %s\n", szNewsSrc);
		
		char rel[_MAX_PATH], here[_MAX_PATH];

		strcpy(here, szAppProFile);
		strcpy(rel, szNewsSrc);

		char *p = strrchr(here, '\\');
		if (p)
			*(p+1) = '\0';

		if (SplitRelativePath( here, rel ))
		{
			WritePrivateProfileString (ADMIN, "Newsrc", rel, szAppProFile);
		}
		else
		{
			WritePrivateProfileString (ADMIN, "Newsrc", szNewsSrc, szAppProFile);
		}
	}
	return (result);
}


// Read the group sort option from the .ini file

/* Ray Dunn:99/10
   Convert old one-level sort options to new 2 level
*/
int ReadSortOption(const char* sDefSort, const char* sGrp)
{ 
	int i;

	i = AuxReadSortOption(sDefSort, sGrp);
	switch (i)
	{
		case IDM_SORT_DATE:
			i = IDM_SORT_DATE_TIME;
			break;
		case IDM_SORT_SUBJECT:
			i = IDM_SORT_SUBJECT_ARTNUM;
			break;
		case IDM_SORT_FROM:
			i = IDM_SORT_FROM_ARTNUM;
			break;
	}
	return(i);
}

static int AuxReadSortOption(const char* sDefSort, const char* sGrp)
/* Ray Dunn:99/10:End */
{
	int retval;
	int i;
	char szTmp[MAXGROUPNAME+4];
	char mybuf[32];
	char sGlobDefSort[32];

	lstrcpy(szTmp, "N: ");
	lstrcat(szTmp, NNTPHost);
	GetPrivateProfileString(szTmp, "DefaultArtSort", sDefSort, sGlobDefSort, sizeof(sGlobDefSort), szAppProFile);

	lstrcpy(szTmp,"G: ");
	lstrcat(szTmp, sGrp);
	GetPrivateProfileString(szTmp, "SortOption", sGlobDefSort, mybuf, sizeof(mybuf), szAppProFile);
	retval = atoi(mybuf);
	if(!retval)
	{
		for(i = 0; i < SORTOPTIONTABLESIZE; i++)
		{
			if(!strcmp(mybuf, SortOptionTable[i].text))
			{
				return SortOptionTable[i].value;
			}
		}
		retval = IDM_SORT_ARTNUM; // gotta return something valid...
	}
	return retval;
}


// Write the group sort option to the .ini file
void WriteSortOption(int iOpt, const char* sGrp)
{
	char szTmp[MAXGROUPNAME+4];
	lstrcpy(szTmp,"G: ");
	lstrcat(szTmp, sGrp);
	int iDefault;

	iDefault = ReadSortOption("","");
	if (iOpt == iDefault)
	{
		//saving default, no need to clutter .ini
		WritePrivateProfileString(szTmp, "SortOption", NULL, szAppProFile);
		return;
	}

	for(int i = 0; i < SORTOPTIONTABLESIZE; i++)
	{
		if(iOpt == SortOptionTable[i].value)
		{
			WritePrivateProfileString(szTmp, "SortOption", SortOptionTable[i].text, szAppProFile);
			return;
		}
	}
	WritePrivateProfileString(szTmp, "SortOption", STR_SORT_ARTNUM, szAppProFile); // write something valid
}

// Write the group sort option to the .ini file
void WriteDefaultSortOption(int iOpt)
{
	char szTmp[MAXGROUPNAME+4];

	lstrcpy(szTmp, "N: ");
	lstrcat(szTmp, NNTPHost);

	for(int i = 0; i < SORTOPTIONTABLESIZE; i++)
	{
		if(iOpt == SortOptionTable[i].value)
		{
			WritePrivateProfileString(szTmp, "DefaultArtSort", SortOptionTable[i].text, szAppProFile);
			return;
		}
	}
	WritePrivateProfileString(szTmp, "DefaultArtSort", STR_SORT_ARTNUM, szAppProFile); // write something valid
}


// The following persistent classes get default values from the WinVN.ini file, work as
//  their builtin type/base class members do, then write values back to the .ini file
//  (if the data has changed) when the object is destructed.


// Persistent BOOL class


WMemPool WVPersBOOL::m_ClassPool(sizeof(WVPersBOOL), POOLBLOCKSIZE / sizeof(WVPersBOOL));


WVPersBOOL::WVPersBOOL(const char*sSection, const char*sKey, BOOL bDefault)
: m_bModified(FALSE), m_sSection(sSection), m_sKey(sKey), m_bDefault(bDefault)
{
	m_bValue = GetPrivateProfileInt(sSection, sKey, bDefault, szAppProFile);
}


WVPersBOOL::~WVPersBOOL()
{
	if(m_bModified)  // only need to rewrite info if data is modified...
	{
		if (m_bValue != m_bDefault)
			WritePrivateProfileInt(m_sSection, m_sKey, m_bValue, szAppProFile);
		else //if we are writing the default value, we don't need to store it   MDS 20001104
			WritePrivateProfileString (m_sSection, m_sKey, NULL, szAppProFile);
	}
}


WVPersBOOL& WVPersBOOL::operator=(const WVPersBOOL& rhs)
{
	m_bModified = TRUE;

	m_bValue = rhs.m_bValue;
	return *this;
}


WVPersBOOL& WVPersBOOL::operator=(const BOOL rhs)
{
	m_bModified = TRUE;

	m_bValue = rhs;
	return *this;
}


WVPersBOOL& WVPersBOOL::operator|=(const BOOL rhs)
{
	m_bModified = TRUE;

	m_bValue |= rhs;
	return *this;
}


WVPersBOOL& WVPersBOOL::operator&=(const BOOL rhs)
{
	m_bModified = TRUE;

	m_bValue &= rhs;
	return *this;
}



/*
 * Local Variables:
 * tab-width: 4
 * end:
 */
