//---------------------------------------------------------------------------
#pragma hdrstop
#include "FHTMLGenerator.h"
#include <vector.h>
//---------------------------------------------------------------------------
AnsiString asProcessText(AnsiString _asText)
{
	AnsiString asParagraph;
    AnsiString asSubText;
    AnsiString asNewText = "";
    int iCursor  = 1;
    bool bFinish = false;

    do
    {
    	// Get a /r/n delimited string
    	asSubText = _asText.SubString(iCursor,_asText.Length() - iCursor+1);

        // Take the position of the next \r\n token
    	int iPos = asSubText.Pos("\r\n");
        if (iPos > 0)
    	{
            // If it's not the last token
            if (iPos < (asSubText.Length() - 2 + 1))
            {
				// asParagraph = "<p>"+asSubText.SubString(0,iPos-1) + "<\p>\r\n";
				asParagraph = asSubText.SubString(1,iPos-1);

				AnsiString asLastChar = asParagraph.SubString(asParagraph.Length(),1);
				if ( asLastChar != ">")
					 asParagraph += "<br>";

				asParagraph += "\r\n";

				iCursor += ((iPos-1) + 2);
            }
            else
            {
            	asParagraph = asSubText;
				bFinish = true;
			}
		}
		else
		{
			asParagraph = asSubText;
			bFinish = true;
		}

		asNewText += asParagraph;

	}while (! bFinish);

	return(asNewText);
}
//---------------------------------------------------------------------------
AnsiString asGetDateFromFilename(AnsiString _asFilename)
{
	// Hay que extraer todo lo que viene antes del #
    int iPos = _asFilename.Pos("#");
    int iLen = _asFilename.Length() - iPos;

	return ( _asFilename.SubString(1,iPos-1) );
}
//---------------------------------------------------------------------------
static AnsiString asDeleteTrailingBlanks(AnsiString _asString)
{
	int iPos = _asString.Length();
	char* szStr = _asString.c_str();

	while ((szStr[iPos] == '\n') || (szStr[iPos] == '\r') || (szStr[iPos] == 0))
		iPos--;

	return( _asString.SubString(0,iPos+1) );
}
//---------------------------------------------------------------------------
static void String2File(FILE *_fd,AnsiString _asString)
{
	AnsiString asStr = asDeleteTrailingBlanks(_asString);

	fwrite(asStr.c_str(),asStr.Length(),1,_fd);
    char szEOS[2] = {'\r','\n'};
    fwrite(&szEOS,2,1,_fd);
}
//---------------------------------------------------------------------------
static int filesize(FILE *fd)
{
	int iPos = ftell(fd);
	fseek(fd,-1,SEEK_END);
	int iSize = ftell(fd);
	fseek(fd,iPos,SEEK_SET);
	return(iSize+1);
}
//---------------------------------------------------------------------------
int iGetNumericMonth(char* _szStr)
{
	if (! stricmp(_szStr,"Jan")) return( 0);
    if (! stricmp(_szStr,"Feb")) return( 1);
    if (! stricmp(_szStr,"Mar")) return( 2);
	if (! stricmp(_szStr,"Apr")) return( 3);
    if (! stricmp(_szStr,"May")) return( 4);
    if (! stricmp(_szStr,"Jun")) return( 5);
    if (! stricmp(_szStr,"Jul")) return( 6);
	if (! stricmp(_szStr,"Aug")) return( 7);
    if (! stricmp(_szStr,"Sep")) return( 8);
    if (! stricmp(_szStr,"Oct")) return( 9);
	if (! stricmp(_szStr,"Nov")) return(10);
    if (! stricmp(_szStr,"Dec")) return(11);
	return(0);
}

//---------------------------------------------------------------------------
int iGetNumericDate(int _iDay,int _iMonth,int _iYear,int _iVersion)
{
	return ( _iVersion + 1000*_iDay + 1000*32*_iMonth + 1000*32*13*_iYear );
}
//---------------------------------------------------------------------------
int iGetNumericDate(char* _szStr)
{
    int iDay,iMonth,iYear,iVersion;
	char szMonth[16];

    sscanf(_szStr     ,"%02d",&iDay);
    sscanf(_szStr +  3,"%03s",szMonth);
    sscanf(_szStr +  7,"%d"  ,&iYear);
    sscanf(_szStr + 12,"%03d",&iVersion);

    iMonth = iGetNumericMonth(szMonth);

    return( iGetNumericDate(iDay,iMonth,iYear,iVersion) );
}
//---------------------------------------------------------------------------
typedef struct TFilenameDate{char m_szFilename[32];
}TFilenameDate;

int sort_function( const void *a, const void *b)
{
	TFilenameDate* A = (TFilenameDate*)a;
    TFilenameDate* B = (TFilenameDate*)b;

    // This is to get the reverse order of dates, first newer then older, and first entries first ...
    int iDateA =  iGetNumericDate(A->m_szFilename);	iDateA = ((iDateA/1000) * 1000) + (999 - (iDateA % 1000));
    int iDateB =  iGetNumericDate(B->m_szFilename);	iDateB = ((iDateB/1000) * 1000) + (999 - (iDateB % 1000));
    return (iDateB - iDateA);
}
//---------------------------------------------------------------------------
void CHTMLGenerator::GeneratePage(AnsiString _asFilename,AnsiString _asSourceDir,TProjectOptions& _roPO,bool _bIncludeDate)
{
	// Change to directory of this page
	chdir( _asSourceDir.c_str() );

	// First, build a list of all the files to be inserted
	vector <TFilenameDate> asFiles;
	TSearchRec oSR;
	if (FindFirst("*.entry",faAnyFile,oSR) == 0)
	{
		do{

			if (oSR.Attr !=  faDirectory)
			{
				TFilenameDate oFilenameDate;
				memset(oFilenameDate.m_szFilename,0,sizeof(TFilenameDate));
				strcpy(oFilenameDate.m_szFilename,oSR.Name.c_str());

				asFiles.push_back( oFilenameDate );
			}

		}while(FindNext(oSR) == 0);
		FindClose(oSR);
	}

	// Nothing to do in this dir? 
	if( asFiles.size() == 0) return;

	// Sort the list
	qsort((void*)&asFiles[0],asFiles.size(),sizeof(TFilenameDate),sort_function);

	FILE * fout = fopen(_asFilename.c_str(),"wb");
	if (fout == NULL) return;

 	FILE *fin;

	// Write header
	fin = fopen("header.htmlinc","rb");
	if (fin != NULL)
	{
		int iSize = filesize(fin);
		char* szBuffer = (char*)malloc(iSize+1);
		fread(szBuffer,iSize,1,fin);
		szBuffer[iSize] = 0;

        String2File(fout,szBuffer);

        free(szBuffer);
        fclose(fin);
    }
    else
    {
		String2File(fout,"<html><body>");
	}

	// Write all the files in the directory
	AnsiString asLastEntryDate = "";
	for (int i=0;i<asFiles.size();i++)
	{
		AnsiString asFilename = AnsiString(asFiles[i].m_szFilename);
		AnsiString asEntryDate= asGetDateFromFilename(asFilename);

		// Write Group PREFIX
		// if it's the first date entry ...
		if (asEntryDate != asLastEntryDate)
			String2File(fout,_roPO.m_asEGroupPRE);

		// if we want to include the entry dates ...
		if ((_bIncludeDate)	&& (asEntryDate != asLastEntryDate))
			String2File(fout,"<div class=\""+ _roPO.m_asDateTAG+"\">" + asEntryDate + "</div>");

		// include the file contents
		fin = fopen(asFilename.c_str(),"rb");
		if (fin != NULL)
		{
			int iSize = filesize(fin);
			char* szBuffer = (char*)malloc(iSize+1);
			fread(szBuffer,iSize,1,fin);
			szBuffer[iSize] = 0;

			String2File(fout,_roPO.m_asEntryPRE);
			String2File(fout,asProcessText(szBuffer));
			String2File(fout,_roPO.m_asEntryPOST);

			free(szBuffer);
			fclose(fin);
		}

		// Write group POSTFIX
		// If this is the last entry or the next is from a different day ...
		if ( ((i+1) == asFiles.size()) || (asEntryDate != asGetDateFromFilename(asFiles[i+1].m_szFilename)) )
		{
			String2File(fout,_roPO.m_asEGroupPOST);
		}

		// Set Last used entry date
		asLastEntryDate = asEntryDate;
	}

	String2File(fout,"<!--------------------------------------------------------------------------->");

    // Write footer
    fin = fopen("footer.htmlinc","rb");
    if (fin != NULL)
    {
    	int iSize = filesize(fin);
		char* szBuffer = (char*)malloc(iSize+1);
		fread(szBuffer,iSize,1,fin);
		szBuffer[iSize] = 0;
		String2File(fout,szBuffer);

        free(szBuffer);
        fclose(fin);
    }
    else
    {
		String2File(fout,"</body></html>");
    }

    fclose(fout);
 }
 //---------------------------------------------------------------------------
#pragma package(smart_init)
