#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>

#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/utility_protos.h>

#include "GUIC_Application.hpp"
#include "GUIC_Checkbox.hpp"
#include "GUIC_Cycle.hpp"
#include "GUIC_Date.hpp"
#include "GUIC_DirectoryExamine.hpp"
#include "GUIC_Error.hpp"
#include "GUIC_Event.hpp"
#include "GUIC_Exceptions.hpp"
#include "GUIC_File.hpp"
#include "GUIC_FileString.hpp"
#include "GUIC_FileExamine.hpp"
#include "GUIC_Fillbar.hpp"
#include "GUIC_Frame.hpp"
#include "GUIC_GGFXPicture.hpp"
#include "GUIC_OldButton.hpp"
#include "GUIC_OldLabel.hpp"
#include "GUIC_OldListview.hpp"
#include "GUIC_PathString.hpp"
#include "GUIC_Screen.hpp"
#include "GUIC_SlidingInteger.hpp"
#include "GUIC_String.hpp"
#include "GUIC_StringType.hpp"
#include "GUIC_System.hpp"

#include "HTMLWindow.hpp"
#include "PrefsWindow.hpp"

#define COPYRIGHT	"<SMALL> index file created with 'Gallery', (c) 1997 by <A HREF=\"http://www.student.uni-kl.de/~hillenbr\" TARGET=_top>Markus Hillenbrand</A> </SMALL>"

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

class ScanEntry : public GUIC_ObjectC
	{
	public:
		ScanEntry							(GUIC_FileExamineC *file);
		~ScanEntry							(VOID);
		LONG		pack					(VOID);
		STRPTR	getClass				(VOID);
		LONG		compare				(GUIC_ObjectC &o);
		VOID		print					(VOID);
		
		STRPTR 		fileName, fileNote, name;
		LONG			fileSize;
		LONG			day, month, year;
		LONG			errorCode;
		
		ScanEntry *	parent;
		GUIC_ListC 	directories, files;
		LONG				entries;
		
	protected:	
		LONG	count		(VOID);
		VOID	cleanUp	(VOID);
	};

ScanEntry::ScanEntry							(GUIC_FileExamineC *file)
{
	fileName		= 0;
	GUIC_SystemC::reallocString(&fileName, file->getName());

	name			= 0;
	GUIC_SystemC::reallocString(&name, file->getFilePart());
	
	fileSize			= file->getSize();
	errorCode		= 0;
	parent				= 0;
	entries			= 0;
	
	GUIC_DateC *date = file->getDate();
	if (date)
		{
		day 		= date->getDay();
		month		= date->getMonth();
		year		= date->getYear();
		}
	
	fileNote		= 0;
	if (file->isDirectory())
		{
		STRPTR dummy	= file->getFilenote();
		if (dummy) GUIC_SystemC::reallocString(&fileNote, dummy);
		}
	
}
ScanEntry::~ScanEntry						(VOID)
{
	if (fileName)	delete [] fileName;
	if (name)		delete [] name;
	if (fileNote)		delete [] fileNote;
	
	while (files.length()) delete (ScanEntry *)files.remove(1);
	while (directories.length()) delete (ScanEntry *)directories.remove(1);
}
STRPTR 	ScanEntry::getClass			(VOID)
{
	return "ScanEntry";
}
VOID		ScanEntry::cleanUp				(VOID)
{
	
}
LONG		ScanEntry::compare			(GUIC_ObjectC &o)
{
	return Stricmp(fileName, ((ScanEntry *)&o)->fileName); // Just compare the two file names	
}
VOID		ScanEntry::print					(VOID)
{
	cout << "[" << getClass() << "," << this << ",Name=" << fileName << "]" << endl;
	files.print();
	directories.print();
}
LONG		ScanEntry::count				(VOID)
{
	LONG i, len;
	
	entries=files.length();
	
	len = directories.length();
	for (i=1; i<=len; i++) entries += ((ScanEntry *)directories.objectAt(i))->pack();
	
	return entries;
}
LONG		ScanEntry::pack					(VOID)
{
	LONG i, len, result;
	ScanEntry *entry;
	
	result = count();
	
	len = directories.length();
	for (i=1; i<=len; i++) 
		{
		entry = (ScanEntry *)directories.objectAt(i);
		if (! entry->entries)
			{
			directories.remove(i);
			delete entry;
			i--;
			len--;
			}
		}

	return result;
}

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

HTMLWindowC::HTMLWindowC							(GUIC_ApplicationC &a, GUIC_ScreenC &s, PrefsWindowC &p) : GUIC_WindowC (53,30)
{
	app					= &a;
	screen			= &s;
	pWindow			= &p;
	
	ps_path			= new GUIC_PathStringC			( 1, 1,51, 2, "RAM:");
	la_show			= new GUIC_OldLabelC				(27, 4,22, 2, "Show _thumbnail:");
	cb_show			= new GUIC_CheckboxC				(49, 4, 3, 2, TRUE);
	fr_picture		= new GUIC_FrameC					(27, 7,25,17, "Thumbnail");
	lv_message	= new GUIC_OldListviewC			( 1, 4,25,20);
	gp_picture		= 0;
	bt_start			= new GUIC_OldButtonC			( 1,25, 8, 4, "_Start");
	fb_status		= new GUIC_FillbarC					(10,25,42, 4, 0);

	lv_message	-> setReadOnly(TRUE);
	cb_show 		-> setShortcut('t');
	
	add(ps_path);
	add(la_show);
	add(cb_show);
	add(fr_picture);
	add(lv_message);
	add(bt_start);
	add(fb_status);

	app -> addPrefs("PathToScan", ps_path);
	app -> addPrefs("HTMLWindow", this);
	app -> addPrefs("ShowThumbnails", cb_show);
	
	setTitle("Gallery - HTML Generator");
	setGuideContext("HTMLWindow");
	
	activate();
}
HTMLWindowC::~HTMLWindowC							(VOID)
{
	cleanUp();
}

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

STRPTR	HTMLWindowC::getClass						(VOID)
{
	return "HTMLWindowC";
}

BOOL		HTMLWindowC::action							(GUIC_EventC &e)
{
	static LONG oldPriority;
	
	switch (e.id)
		{
		case GUIC_GadgetEvent:
			if (e.gadget == (GUIC_GadgetC *) bt_start)
				{
				// Set the status to 0
				fb_status->set(0);
				
				// Change the Task's priority
				if (pWindow->cb_priority->get()) oldPriority = SetTaskPri(FindTask(NULL), pWindow->si_priority->get() );
				
				try 
					{
					GUIC_DirectoryExamineC dir ( ps_path->get() );
				
					app->setBusy(TRUE);
					
					ps_path->setEnabled(FALSE);
					bt_start->set("Stop");
					lv_message->delAllItems();
					
					lv_message->addItem("Scanning directory.");
					GUIC_FileExamineC filex ( ps_path->get() );
					ScanEntry firstEntry (&filex);
					setBusy(FALSE);
					scanDirectory(dir, firstEntry);
					firstEntry.pack();
					setBusy(TRUE);
					lv_message->addItem("Directory scanned.");

					lv_message->addItem("Creating thumbnails.");
					setBusy(FALSE);
					statusActual	= 0;
					statusTotal		= firstEntry.entries;
					createThumbnails(createHTMLDir(pWindow->ps_thumbnailPath->get(), dir.getName()), dir, firstEntry);
					firstEntry.pack();
					setBusy(TRUE);
					lv_message->addItem("Thumbnails created.");

					lv_message->addItem("Creating HTML files.");
					setBusy(FALSE);
					statusActual	= 0;
					statusTotal		= firstEntry.entries;
					createHTMLFiles(createHTMLDir(pWindow->ps_thumbnailPath->get(), dir.getName()), dir, firstEntry);
					setBusy(TRUE);
					lv_message->addItem("HTML files created.");

					if (pWindow->cb_thumbnailDelete->get())
						{
						lv_message->addItem("Deleting thumbnails.");
						setBusy(FALSE);
						deleteThumbnails(pWindow->ps_thumbnailPath->get(), dir.getName());
						setBusy(TRUE);
						lv_message->addItem("Thumbnails deleted.");
						}

					lv_message->addItem("Freeing memory.");
					}
				catch (GUIC_Exception &ex)
					{
					GUIC_ErrorC err ("Error", ex.getMessage() );
					err.request(this);
					}

				lv_message->addItem("Done.");

				ps_path->setEnabled(TRUE);
				bt_start->set("_Start");

				// Change the priority again
				if (pWindow->cb_priority->get()) SetTaskPri(FindTask(NULL), oldPriority );

				app->setBusy(FALSE);
				}
			return TRUE;
			break;
		case GUIC_OpenWindow:
			return TRUE;
			break;
		case GUIC_CloseWindow:
			screen->remove(this);
			return TRUE;
			break;
		}
	
	return FALSE;
}

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

VOID		HTMLWindowC::scanDirectory				(GUIC_DirectoryExamineC &dir, ScanEntry &parent)
{
	ScanEntry *entry;
	
	try
		{
		GUIC_FileExamineC *file = dir.examineNext();
		while (file)
			{
			if (file->isDirectory())
				{
				GUIC_DirectoryExamineC nextDir (file->getName());

				entry = new ScanEntry(file);
				entry->parent = &parent;
				parent.directories.addSorted(entry);

				scanDirectory(nextDir, *entry); 
				}
			else
				{
				entry = new ScanEntry(file);
				entry->parent = &parent;
				parent.files.addSorted(entry);
				}
			
			GUIC_EventC *event = app->checkEvent();
			if (event && event->id == GUIC_GadgetEvent) throw GUIC_AbortX("User Abort");
			
			file = dir.examineNext();
			}
		}
	catch (GUIC_Exception &) { throw; }
}
VOID		HTMLWindowC::createThumbnails		(STRPTR thumbnailDir, GUIC_DirectoryExamineC &dir, ScanEntry &firstEntry)
{
	GUIC_GGFXPictureC *oldPic = 0;
	BOOL aborted = FALSE;
	BOOL showIt	= cb_show->get();
	
	// First, we must define the offset in the file names. 
	STRPTR	dirName	= dir.getName();
	LONG		offset 	= strlen(dirName); if (dirName[offset-1] != ':') offset++;

	// Change the current directory to the thumbnails' directory
	BPTR lock = Lock (thumbnailDir, SHARED_LOCK);
	if (! lock) throw GUIC_Exception("Thumbnail directory does not exist!");
	BPTR oldDir = CurrentDir(lock);
	
	fb_status->set(0);
	
	try
		{
		// Now we can create the thumbnails and their directories 
		LONG	tWidth			= pWindow->si_thumbnailWidth->get();
		LONG	tHeight		= pWindow->si_thumbnailHeight->get();
		BOOL	tHide			= pWindow->cb_thumbnailHide->get();
		LONG	quality		= pWindow->si_quality->get();
		LONG	pWidth		= 0;
		LONG	pHeight		= 0;
		CHAR	filenote[64];
		LONG	len, i;
		
		len = firstEntry.directories.length();
		for (i=1; i<=len; i++)
			{
			ScanEntry *entry = (ScanEntry *)firstEntry.directories.objectAt(i);
			createDirectory(&entry->fileName[offset]);
			createThumbnails(thumbnailDir, dir, *entry);
			}
		
		len = firstEntry.files.length();
		for (i=1; i<=len; i++) 
			{
			ScanEntry *entry = (ScanEntry *)firstEntry.files.objectAt(i);

			fb_status->set( (100*++statusActual) / statusTotal );
			// Check for user abort
			GUIC_EventC *event = app->checkEvent();
			if (event && event->id == GUIC_GadgetEvent) throw GUIC_AbortX();
	
			GUIC_FileC file (&entry->fileName[offset]);
			if (file.doesExist()) continue;
				
			GUIC_FileExamineC fex (entry->fileName);
			if (fex.getFileType() != GUIC_PictureFile) // if  (! fex.isPicture() )
				{
				delete (ScanEntry *)firstEntry.files.remove(i);
				i--;
				len--;
				continue;
				}

			try
				{
				// load the new one
				gp_picture	= new GUIC_GGFXPictureC(28,9,23,14,entry->fileName);
				pWidth		= gp_picture->getWidth();
				pHeight		= gp_picture->getHeight();
				gp_picture	-> setScaled(TRUE);
				gp_picture	-> setCentered(TRUE);
					
				// scale and save the thumbnail
				gp_picture->scaleToBox(tWidth, tHeight);
				gp_picture->saveJPEG(&entry->fileName[offset], quality);
				
				// set filenote and hide flag
				GUIC_FileExamineC file (&entry->fileName[offset]);
				if (tHide) file.setHidden(TRUE);
				sprintf(filenote, "%ld x %ld", pWidth, pHeight);
				file.setFilenote(filenote);

				// remove the old picture and show the new one
				if (oldPic) { if (showIt) remove(oldPic); delete oldPic; oldPic=0; }
				oldPic = gp_picture; gp_picture=0;
				if (showIt) add(oldPic);
				}
			catch (GUIC_Exception &ex)
				{
				if (gp_picture) 
					{
					entry->errorCode = gp_picture->getErrorCode();
					delete gp_picture; gp_picture=0;
					}
				CHAR text [256];
				sprintf(text, "ERROR: %s", file.getFilePart());
				lv_message->addItem(text);
				}
			}	
		}
	catch (GUIC_AbortX)
		{
		aborted = TRUE;
		}
	catch (GUIC_Exception &ex)
		{
		GUIC_ErrorC err ("Error", ex.getMessage() );
		err.request(this);
		}

	if (oldPic) 
		{
		if (showIt) remove(oldPic);
		delete oldPic; 
		oldPic=0; 
		}
	
	// Change the directory		
	CurrentDir(oldDir);
	UnLock(lock);

	if (aborted) throw GUIC_AbortX("User Abort");
}

VOID		HTMLWindowC::createHTMLFiles			(STRPTR thumbnailDir, GUIC_DirectoryExamineC &dir, ScanEntry &firstEntry)
{
	BOOL		aborted		= FALSE;

	// Change the current directory to the thumbnails' directory
	BPTR lock = Lock (thumbnailDir, SHARED_LOCK);
	if (! lock) throw GUIC_Exception("HTML directory does not exist!");
	BPTR oldDir = CurrentDir(lock);

	// First, we must define the offset in the file names. 
	STRPTR	dirName	= dir.getName();
	LONG		offset 	= strlen(dirName); if (dirName[offset-1] != ':') offset++;
		
	fb_status->set(0);
	
	try
		{
		createHTMLFiles2(thumbnailDir, offset, firstEntry);
		}
	catch (GUIC_AbortX)
		{
		aborted = TRUE;
		}
	catch (GUIC_Exception &ex)
		{
		GUIC_ErrorC err ("Error", ex.getMessage() );
		err.request(this);
		}

	// Change back to the program's directory
	CurrentDir(oldDir);
	UnLock(lock);
	
	if (aborted) throw GUIC_AbortX("User Abort");
}
VOID		HTMLWindowC::createHTMLFiles2		(STRPTR thumbnailDir, LONG offset, ScanEntry &firstEntry)
{
	LONG		directories	= firstEntry.directories.length();
	LONG		files			= firstEntry.files.length();
	STRPTR	dummy		= 0;
	
	ScanEntry *	entry;
	STRPTR			dirname, title;
	LONG				i;
	
	dirname 	= firstEntry.parent ? &firstEntry.fileName[offset] : "";
	title 		= firstEntry.fileNote;
	if (! title || title[0]==0) title = firstEntry.name;
	
	// Set some useful variables
	BOOL		frames					= pWindow->cb_frames->get();
	STRPTR	baseName				= pWindow->st_filename->get();
	STRPTR	suffix						= pWindow->cy_suffix->getActive() == 1 ? ".html" : ".htm";
	LONG		menuframeWidth	= pWindow->si_frameWidth->get();
	LONG 	linesInTable				= pWindow->si_tableLines->get();
	LONG		columnsInTable		= pWindow->si_tableColumns->get();
	BOOL		showDimensions	= pWindow->cb_showDimensions->get();
	BOOL		showSize				= pWindow->cb_showSize->get();
	BOOL		showDate				= pWindow->cb_showDate->get();
	LONG		tableBorderSize		= pWindow->si_tableBorderSize->get();
	STRPTR	pattern1					= pWindow->fs_pattern1->get();
	STRPTR	pattern2					= pWindow->fs_pattern2->get();
	STRPTR	sound1					= pWindow->fs_sound1->get();
	STRPTR	sound2					= pWindow->fs_sound2->get();
	STRPTR	color1						= pWindow->st_tableColor1->get(); if (color1) color1 = &color1[2];
	STRPTR	color2						= pWindow->st_tableColor2->get(); if (color2) color2 = &color2[2];
	STRPTR	upImage					= pWindow->fs_up->get();				
	STRPTR	leftImage				= pWindow->fs_left->get();				
	STRPTR	rightImage				= pWindow->fs_right->get();			
	
	if (!Stricmp(pattern1, "")) pattern1=0;
	if (!Stricmp(pattern2, "")) pattern2=0;
	
	if (!Stricmp(sound1, "")) sound1=0;
	if (!Stricmp(sound2, "")) sound2=0;

	if (!Stricmp(upImage, "")) upImage=0;
	if (!Stricmp(leftImage, "")) leftImage=0;
	if (!Stricmp(rightImage, "")) rightImage=0;

	if (files)
		{
		// find out the dimensions and the name of the gallery
		ldiv_t d = ldiv (files, columnsInTable );
		LONG lines = d.quot;
		if (d.rem) lines++;

		d = ldiv (lines, linesInTable);
		LONG galleries = d.quot;
		if (d.rem) galleries++;

		// Create the Frames if neccessary
		if (frames)
			{
			// Write the frameset file
			GUIC_SystemC::reallocString(&dummy, baseName, suffix);
			GUIC_FileC gallery(dirname, dummy, GUIC_Write);

			gallery.write("<HTML>\n\n  <TITLE>Gallery '");
			gallery.write(title);
			gallery.write("'</TITLE>\n\n  <FRAMESET COLS=");
			gallery.write(menuframeWidth);
			gallery.write(",*>\n    <FRAME NAME=F1 SRC=\"");
			gallery.write(baseName);
			gallery.write("0"); 
			gallery.write(suffix); 
			gallery.write("\" MarginHeight=0 MarginWidth=0 Scrolling=\"auto\" FrameBorder=0>\n    <FRAME NAME=F2 SRC=\"");
			gallery.write(baseName);
			gallery.write("1"); 
			gallery.write(suffix); 
			gallery.write("\" MarginHeight=0 MarginWidth=0 Scrolling=\"auto\" FrameBorder=0>\n  </FRAMESET>\n\n</HTML>\n");

			// now create the overview over the galleries
			GUIC_SystemC::reallocString(&dummy, baseName, "0", suffix);
			GUIC_FileC overview (dirname, dummy, GUIC_Write);

			overview.write("<HTML>\n\n<BODY");
			if (pattern1)
				{
				overview.write(" BACKGROUND=\"");
				overview.write(makeURL(pattern1, thumbnailDir, dirname) );
				overview.write("\"");
				}
			overview.write(">\n\n");
			if (sound1)
				{
				overview.write(" <BGSOUND SRC=\"");
				overview.write(makeURL(sound1, thumbnailDir, dirname) );
				overview.write("\">\n");
				}
			overview.write("  <H2 ALIGN=Center> Gallery </H2><BR>\n\n  <UL>\n");
			
			for (i=1; i<=galleries; i++)
				{
				overview.write("    <LI><A HREF=\"");
				overview.write(baseName);
				overview.write(i);
				overview.write(suffix); 
				overview.write("\" TARGET=F2>Part ");
				overview.write(i);
				overview.write("</A> <BR>\n");
				}
			overview.write("  </UL>\n\n  <BR><BR>\n\n");
			
			if (directories)
				{
				overview.write("  <H2 ALIGN=Center> More Galleries </H2><BR>\n\n  <UL>\n");
				for (i=1; i<=directories; i++)
					{
					entry = (ScanEntry *)firstEntry.directories.objectAt(i);
					overview.write("    <LI><A HREF=\"");
					overview.write(entry->name);
					overview.write("/");
					overview.write(baseName);
					overview.write(suffix);
					overview.write("\" TARGET=_top>");
					overview.write(entry->name);
					overview.write("</A> <BR>\n");		
					}
				overview.write("  </UL>\n\n  <BR><BR>\n\n");
				}
				
			overview.write("  <CENTER>\n    <A HREF=\"../");
			overview.write(baseName);
			overview.write(suffix); 
			overview.write("\" TARGET=_top> <IMG SRC=\""); 

			if (upImage)
				{
				overview.write(makeURL(upImage, thumbnailDir, dirname));
				overview.write("\" ALT=\"[up]\" BORDER=0></A>\n");
				}
			else overview.write("internal-gopher-menu\" BORDER=0> up </A>\n");

			overview.write("  </CENTER>\n\n</BODY>\n\n</HTML>\n");
			}

		// Create the galleries now
		LONG count = 0, number, boundary;
		for (number=1; number<=galleries; number++)
			{
			CHAR filename[256];
			sprintf(filename, "%s%ld%s", baseName, number, suffix);
			GUIC_FileC indexFile(dirname, filename, GUIC_Write);

			// write head and title
			indexFile.write("<HTML>\n\n<HEAD>\n  <TITLE> "); 
			indexFile.write(title); 
			indexFile.write(" </TITLE>\n</HEAD>\n\n<BODY");
			if (pattern2)
				{
				indexFile.write(" BACKGROUND=\"");
				indexFile.write(makeURL(pattern2, thumbnailDir, dirname) );
				indexFile.write("\"");
				}
			indexFile.write(">\n");
			if (sound2)
				{
				indexFile.write("<BGSOUND SRC=\"");
				indexFile.write(makeURL(sound2, thumbnailDir, dirname) );
				indexFile.write("\">\n");
				}
			indexFile.write("\n  <CENTER>\n\n    <H2>"); 
			indexFile.write(title);
			indexFile.write("</H2> (Part ");
			indexFile.write(number);
			indexFile.write(" of ");
			indexFile.write(galleries);
			indexFile.write(")<BR>\n\n    <HR>\n\n    <TABLE BORDER=");
			indexFile.write(tableBorderSize);
			indexFile.write(" CELLSPACING=4 CELLPADDING=4>\n");

			boundary = count + columnsInTable*linesInTable;
			if (boundary>files) boundary = files;

			for (i=count; i<boundary; i++)
				{
				entry = (ScanEntry *)firstEntry.files.objectAt(i+1);

				fb_status->set( (100*++statusActual) / statusTotal );
				// Check for user abort
				GUIC_EventC *event = app->checkEvent();
				if (event && event->id == GUIC_GadgetEvent) throw GUIC_AbortX();

				// Check if there are enough entries per line in the table
				if (count++ % columnsInTable == 0) indexFile.write("      <TR>\n");
	
				// write the picture data
				indexFile.write("        <TD BGCOLOR=\"777777\"> <CENTER>");
				indexFile.write("<A HREF=\"");
				indexFile.write(makeURL(entry->fileName, thumbnailDir, dirname ) );
				indexFile.write("\"> <IMG SRC=\"");
				indexFile.write(entry->name);
				indexFile.write("\" ALT=[Thumbnail] BORDER=0> <BR>");
				indexFile.write(entry->name);
				indexFile.write(" </A>");
				
				if (showDimensions)
					{
					try
						{
						indexFile.write("<BR>");
						GUIC_FileExamineC f (&entry->fileName[offset]);
						indexFile.write(f.getFilenote());
						}
					catch (GUIC_Exception &e) {}
					}
					
				if (showDate)
					{
					indexFile.write("<BR>");
					indexFile.write(entry->day);
					indexFile.write(".");
					indexFile.write(entry->month);
					indexFile.write(".");
					indexFile.write(entry->year);
					}
					
				if (showSize)
					{
					indexFile.write("<BR> Size: ");
					indexFile.write(entry->fileSize);
					}
									
				indexFile.write(" </TD>\n");
				}
	
			indexFile.write("    </TABLE>\n\n");

			if (! frames && galleries>1) // then create jump points
				{
				indexFile.write("    <BR>\n\n");
	
				if (number > 1) 
					{
					indexFile.write("    <A HREF=\"");
					indexFile.write(baseName);
					indexFile.write(number-1);
					indexFile.write(suffix);
					indexFile.write("\">");
					if (leftImage)
						{
						indexFile.write(" <IMG SRC=\"");
						indexFile.write(makeURL(leftImage, thumbnailDir, dirname));
						indexFile.write("\" ALT=\"[prev]\" BORDER=0></A>\n");
						} 
					else indexFile.write("[prev] </A>\n");
					}
				else if (leftImage)
					{
					indexFile.write("    <IMG SRC=\"");
					indexFile.write(makeURL(leftImage, thumbnailDir, dirname));
					indexFile.write("\" ALT=\"[prev]\" BORDER=0>\n");
					}
				else indexFile.write("    [prev]  \n");
	
				for (LONG gal=1; gal<=galleries; gal++)
					{
					if (number != gal)
						{
						indexFile.write("    <A HREF=\"");
						indexFile.write(baseName);
						indexFile.write(gal);
						indexFile.write(suffix);
						indexFile.write("\">");
						indexFile.write(gal);
						indexFile.write("</A> \n");
						}
					else 
						{
						indexFile.write("    ");
						indexFile.write(gal);
						indexFile.write(" \n");
						}
					}
				
				if (number < galleries) 
					{
					indexFile.write("    <A HREF=\"");
					indexFile.write(baseName);
					indexFile.write(number+1);
					indexFile.write(suffix); 
					indexFile.write("\">");
					if (rightImage)
						{
						indexFile.write(" <IMG SRC=\"");
						indexFile.write(makeURL(rightImage, thumbnailDir, dirname));
						indexFile.write("\" ALT=\"[next]\" BORDER=0></A>\n");
						} 
					else indexFile.write(" [next]</A>\n");
					}
				else if (rightImage)
					{
					indexFile.write("    <IMG SRC=\"");
					indexFile.write(makeURL(rightImage, thumbnailDir, dirname));
					indexFile.write("\" ALT=\"[next]\" BORDER=0>\n");
					}
				else indexFile.write("    [next]\n");
				
				indexFile.write("    <BR>\n    <A HREF=\"../");
				indexFile.write(baseName);
				indexFile.write(suffix); 
				indexFile.write("\"> <IMG SRC=\""); 

				if (upImage)
					{
					indexFile.write(makeURL(upImage, thumbnailDir, dirname));
					indexFile.write("\" ALT=\"[up]\" BORDER=0></A>\n\n");
					}
				else  indexFile.write("internal-gopher-menu\" BORDER=0> up </A>\n\n");
				}
	
			indexFile.write("    <HR>\n\n    ");
			indexFile.write(COPYRIGHT);
			indexFile.write("\n\n  </CENTER>\n\n</BODY>\n\n</HTML>\n");
			}
		}
	else
		{
		// Create the directories
		GUIC_SystemC::reallocString(&dummy, baseName, suffix);
		GUIC_FileC indexFile(dirname, dummy, GUIC_Write);
		
		indexFile.write("<HTML>\n\n<HEAD>\n  <TITLE> "); 
		indexFile.write(title); 
		indexFile.write(" </TITLE>\n</HEAD>\n\n<BODY");
		if (pattern1)
			{
			indexFile.write(" BACKGROUND=\"");
			indexFile.write( makeURL(pattern1, thumbnailDir, dirname) );
			indexFile.write("\"");
			}
		indexFile.write(">\n");
		if (sound1)
			{
			indexFile.write("<BGSOUND SRC=\"");
			indexFile.write( makeURL(sound1, thumbnailDir, dirname) );
			indexFile.write("\">\n");
			}
		indexFile.write("\n  <CENTER>\n\n  <H1>"); 
		indexFile.write(title); 
		indexFile.write("</H1>\n\n  <HR><BR><BR>\n\n");

		indexFile.write("  <TABLE BORDER=");
		indexFile.write(tableBorderSize);
		indexFile.write(" CELLSPACING=4 CELLPADDING=4>\n");
		indexFile.write("    <TR> <TH BGCOLOR=\""); 
		indexFile.write(color1); 
		indexFile.write("\"> <CENTER> <H3> Gallery Name </H3> </TH> <TH BGCOLOR=\""); 
		indexFile.write(color1); 
		indexFile.writeLn("\"> <CENTER> <H3> Entries </H3> </TH> </TR>");

		for (i=1; i<=directories; i++)
			{
			entry = (ScanEntry *)firstEntry.directories.objectAt(i);
			
			STRPTR filenote	= entry->fileNote;
			if (! filenote || ! filenote[0]) filenote=entry->name;

			indexFile.write("    <TR> <TD BGCOLOR=\"");
			indexFile.write(color2);
			indexFile.write("\"> <CENTER> <A HREF=\"");
			indexFile.write(entry->name);
			indexFile.write("/");
			indexFile.write(baseName);
	
			if (! frames) indexFile.write("1");
		
			indexFile.write(suffix);
			indexFile.write("\"> ");
			indexFile.write(filenote);
			indexFile.write(" </A> </TD> <TD BGCOLOR=\"");
			indexFile.write(color2);
			indexFile.write("\"> <CENTER> ");
			indexFile.write(entry->entries);
			indexFile.write(" </TD> </TR>\n");
			}

		indexFile.write("  </TABLE><BR>\n\n  <A HREF=\"../");
		indexFile.write(baseName);
		indexFile.write(suffix);
		indexFile.write("\"> <IMG SRC=\""); 

		if (upImage)
			{
			indexFile.write(makeURL(upImage, thumbnailDir, dirname));
			indexFile.write("\" ALT=\"[up]\" BORDER=0></A>\n\n");
			}
		else  indexFile.write("internal-gopher-menu\" BORDER=0> up </A>\n\n");

		indexFile.write("  <HR>\n  ");
		indexFile.write(COPYRIGHT);
		indexFile.write("\n\n</BODY>\n\n</HTML>");
		}
		
	for (i=1; i<=directories; i++) createHTMLFiles2(thumbnailDir, offset, *(ScanEntry *)firstEntry.directories.objectAt(i));
}

VOID		HTMLWindowC::deleteThumbnails		(STRPTR tDir, STRPTR pDir)
{
	try
		{
		GUIC_DirectoryExamineC direx ( createHTMLDir(tDir, pDir) );
		STRPTR realname = direx.getName();
		LONG offset = strlen(realname); if (realname[offset-1] != ':') offset++;
		delThumbs(direx, pDir, offset);
		}
	catch (GUIC_Exception &) { throw; }
}

VOID		HTMLWindowC::delThumbs					(GUIC_DirectoryExamineC &tDir, STRPTR pDir, LONG offset)
{
	CHAR toDelete[1024];
	
	try
		{
		GUIC_FileExamineC *file = tDir.examineNext();
		while (file)
			{
			toDelete[0]=0;
			
			if (file->isDirectory())
				{
				GUIC_DirectoryExamineC nextDir (file->getName());
				delThumbs(nextDir, pDir, offset);
				}
			else 
				{
				CHAR dummy[1024];
				strcpy(dummy, pDir);
				AddPart(dummy, &file->getName()[offset], 1024);
				
				GUIC_FileC f (dummy);
				if (! f.doesExist())
					{
					if (file->getFileType() == GUIC_PictureFile) 
						{
						CHAR text [256];
						sprintf(text, "DELETE: %s", file->getFilePart());
						lv_message->addItem(text);
						strcpy(toDelete, file->getName());
						}
					}
				}
			
			GUIC_EventC *event = app->checkEvent();
			if (event && event->id == GUIC_GadgetEvent) throw GUIC_AbortX("User Abort");
			
			file = tDir.examineNext();
			
			if (toDelete[0]) DeleteFile(toDelete);
			}
		}
	catch (GUIC_Exception &) { throw; }
}

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

BOOL		HTMLWindowC::createDirectory			(STRPTR p)
{
	BPTR lock = CreateDir(p);
	if (! lock) 
		{
		lock = Lock(p, SHARED_LOCK);
		if (! lock) return FALSE;
		}
		
	UnLock(lock);
	return TRUE;
}
BOOL		HTMLWindowC::createDirectory			(STRPTR exists, STRPTR p)
{
	BPTR lock = Lock(exists, SHARED_LOCK);
	if (! lock) return FALSE;
	
	BPTR oldDir	= CurrentDir(lock);
	BPTR newDir	= CreateDir(p);
	if (! newDir) newDir = Lock(p, SHARED_LOCK);
	
	CurrentDir(oldDir);
	UnLock(lock);
	
	if (! newDir) return FALSE;
	UnLock(newDir);
	return TRUE;
}
BOOL		HTMLWindowC::copyFile						(GUIC_FileC &file, STRPTR dir1, STRPTR dir2, STRPTR name)
{
	LONG len = strlen(dir1) + strlen(dir2) + strlen(name) + 10;
	STRPTR newfile = new CHAR [len];
	strcpy(newfile, dir1);
	AddPart(newfile, dir2, len);
	AddPart(newfile, name, len);
	BOOL result = file.copy(newfile);
	delete [] newfile;
	return result;
}
STRPTR	HTMLWindowC::makeURL					(STRPTR file, STRPTR dir, STRPTR dir2)
{
	static STRPTR result = 0;
	
	LONG equal = 0;
	while (file[equal] && dir[equal] && file[equal] == dir[equal]) equal++;
	
	if (equal)
		{
		STRING dots=""; 
		LONG pos=equal;
		if (dir[equal]) 
			{
			dots += "../";
			while (dir[++pos]) if (dir[pos] == '/') dots += "../";
			}
		pos=-1;
		if (dir2[0])
			{
			dots+="../";
			while (dir2[++pos]) if (dir2[pos] == '/') dots += "../";
			}
		GUIC_SystemC::reallocString(&result, (STRPTR) dots, &file[equal]);
		}
	else GUIC_SystemC::reallocString(&result, "file:///", file);
	
	return result;
}
STRPTR	HTMLWindowC::createHTMLDir			(STRPTR thumbnailDir, STRPTR scanDir)
{
	STRPTR filePart = 0;
	LONG last = strlen(scanDir) - 1;
	
	if (scanDir[last] == ':')
		{
		GUIC_SystemC::reallocString(&filePart, scanDir);
		filePart[last] = 0;
		}
	else GUIC_SystemC::reallocString(&filePart, FilePart(scanDir));
	
	static STRPTR result = 0;
	if (result) delete [] result;
	LONG len = strlen(thumbnailDir) + strlen(filePart) + 5;
	result = new CHAR [len];
	strcpy(result, thumbnailDir);
	AddPart(result, filePart, len);
	delete [] filePart;
	
	if (! createDirectory(result)) throw GUIC_Exception("Can't create thumbnail directory.");
	
	return result;
}

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

VOID		HTMLWindowC::cleanUp						(VOID)
{
	delete ps_path;
	delete la_show;
	delete cb_show;
	delete fr_picture;
	delete lv_message;
	delete bt_start;
	delete fb_status;

	if (gp_picture) { remove(gp_picture); delete gp_picture; }
}

