
#ifndef _WVNZB_H_
#define _WVNZB_H_

#include "wvglob.h"
#include "wvclass.h"
#pragma warning( disable: 4786 ) //long identifier 
#include <set>


static unsigned char upcase[256] = {
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  ' ','!','"','#','$','%','&', 39,'(',')','*','+',',','-','.','/',
  '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
  '@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
  'P','Q','R','S','T','U','V','W','X','Y','Z','[', 92,']','^','_',
  '`','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
  'P','Q','R','S','T','U','V','W','X','Y','Z','{','|','}','~',127,

  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};


#define UPC(x) (upcase[(unsigned char)(x)])



typedef struct tagHEADERENTRY
{
	int	nPart;
	int nTotal;
	int nGPart;
	int nGTotal;
	int nFNameLen;
	unsigned long nIndex;
	char * Subject;
	char * Filename;
	header_p HeaderP;
	struct tagHEADERENTRY *pDupes;
	struct tagHEADERENTRY *pFiles;
} HEADERENTRY, *LPHEADERENTRY;

struct CompareEntrySubjects
{
	bool operator () ( const HEADERENTRY *a, const HEADERENTRY *b) const
	{
		
		if (*a->Subject && *b->Subject)
			return strcmp(a->Subject, b->Subject) < 0;
		else if (*b->Subject)
			return true;
		return false; 
	}
};

struct CompareEntryFilenames
{
	bool operator () ( const HEADERENTRY *a, const HEADERENTRY *b) const
	{
		
		if (a->nFNameLen == b->nFNameLen)
		{
			return _strnicmp(a->Filename, b->Filename, a->nFNameLen) < 0;
		}
		
		return 	(a->nFNameLen - b->nFNameLen) < 0;

	}
};

struct CompareGroupEntrys
{
	bool operator () ( const HEADERENTRY *a, const HEADERENTRY *b) const
	{
		

		if (a->nFNameLen == b->nFNameLen)
		{
			int nVal = !_strnicmp(a->Filename, b->Filename, a->nFNameLen);
			if (nVal == 0)
			{
				if (a->nTotal == b->nTotal)
				{
		
					return false;
				}
			}
			else
				return nVal < 0;
		}
		
		return 	(a->nFNameLen - b->nFNameLen) < 0;

	}
};

typedef std::set<LPHEADERENTRY, CompareEntrySubjects> HEADERLIST;
typedef std::set<LPHEADERENTRY, CompareEntryFilenames> FHEADERLIST;
typedef std::set<LPHEADERENTRY, CompareGroupEntrys> GHEADERLIST;

class WVFileSortHeaders
{
public:
	WVFileSortHeaders();
	~WVFileSortHeaders();

public:
	long SortDoc(TypDoc far * Doc, unsigned char selFlag =ART_SELECTED);
	void ClearList();

	LPHEADERENTRY FindBySubject( LPCSTR szSubject );
	LPHEADERENTRY FindByFilename( LPCSTR szSubject );

	LPHEADERENTRY FindHeaderSubject( LPHEADERENTRY pHeader );
	LPHEADERENTRY FindHeaderFilename( LPHEADERENTRY pHeader );

	int SelectArticlesBySubject( LPHEADERENTRY pEntry, int &nTotal, char nFlag, BOOL bIgnoreThisEntry);



	static LPHEADERENTRY ProcessSubject(LPCSTR szSubject, header_p pheader);

public:

	HEADERLIST m_SubjList;
	FHEADERLIST m_FilenameList;

	HEADERLIST::iterator m_sitr;
	FHEADERLIST::iterator m_fitr;

	std::pair<HEADERLIST::iterator, bool> m_hlret;
	std::pair<FHEADERLIST::iterator, bool> m_flret;


	
};


char * XMLEncode(const char * szLine);
char * UTF8Encode( const char * szIn);
BOOL IsFileNZB( const char * szFile);
long SaveArtNZB( TypDoc far * Doc, HANDLE hFile, BOOL bSelected, BOOL bAppend = FALSE, BOOL bUTF8 = TRUE);
long SelectLoadNZBArtList( TypDoc far * Doc, HANDLE hFile, long * pTotal = NULL);
long FileSortHeaders(TypDoc far * Doc, HEADERLIST* pList, unsigned char selFlag =ART_SELECTED );
void FreeFileSortHeaders(HEADERLIST* pList);

void ShowList(HEADERENTRY* pEntry);
#endif