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

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

#include "GUIC_Application.hpp"
#include "GUIC_Button.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_FileExamine.hpp"
#include "GUIC_GGFXPicture.hpp"
#include "GUIC_ImageButton.hpp"
#include "GUIC_Label.hpp"
#include "GUIC_Message.hpp"
#include "GUIC_Panel.hpp"
#include "GUIC_PathString.hpp"
#include "GUIC_Prop.hpp"
#include "GUIC_Screen.hpp"
#include "GUIC_Separator.hpp"
#include "GUIC_SlideButton.hpp"
#include "GUIC_StringType.hpp"
#include "GUIC_System.hpp"
#include "GUIC_Textfield.hpp"

#include "ManagerWindow.hpp"
#include "PrefsWindow.hpp"

#include "GUIC_PropWithArrows.hpp"
GUIC_PropWithArrowsC *prop;

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

class ManagerWindowC_ListEntry : public GUIC_ObjectC
	{
	public:
		ManagerWindowC_ListEntry	(GUIC_FileExamineC *file, STRPTR temp, GUIC_TextfieldC *message);
		~ManagerWindowC_ListEntry	(VOID);
		
		STRPTR		getClass				(VOID);
		VOID			print					(VOID);
		LONG			compare				(GUIC_ObjectC &o);
		
		STRPTR 		fileName, dimensions, thumbnailName;
		LONG			fileSize;
		
	protected:	
		VOID	cleanUp	(VOID);
	};

ManagerWindowC_ListEntry::ManagerWindowC_ListEntry	(GUIC_FileExamineC *file, STRPTR temp, GUIC_TextfieldC *message)
{
	CHAR dummy[1024];

	fileName		= 0;
	GUIC_SystemC::reallocString(&fileName, file->getName());

	thumbnailName	= 0;
	fileSize				= file->getSize();
	dimensions			= 0;
	
	/* Nachschauen, ob schon ein Thumbnail im TMP Verzeichnis liegt */
	try
		{
		GUIC_FileExamineC filex ( temp, file->getFilePart() );
		GUIC_SystemC::reallocString ( &dimensions, filex.getFilenote() );
		GUIC_SystemC::reallocString ( &thumbnailName, filex.getName() );
		}
	catch (GUIC_Exception &x)
		{
		/* Dann liegt noch kein Thumbnail vor */
		try
			{
			sprintf(dummy, "Creating thumbnail for file: %s", fileName);
			message->setText(dummy);
			
			GUIC_GGFXPictureC pic (fileName);

			LONG w = pic.getWidth();
			LONG h = pic.getHeight();
			
			sprintf(dummy, "%ld x %ld", w, h );
			GUIC_SystemC::reallocString(&dimensions, dummy);
			
			pic.scaleToBox(100,100);
			
			strcpy(dummy, temp);
			AddPart(dummy, file->getFilePart(), 1024);
			GUIC_SystemC::reallocString(&thumbnailName, dummy);
			
			pic.saveJPEG(thumbnailName, 90);
			
			GUIC_FileExamineC filex(thumbnailName);
			filex.setFilenote(dimensions);
			}
		catch (GUIC_Exception &x) { GUIC_SystemC::reallocString(&dimensions, "No memory!"); }
		}
}
ManagerWindowC_ListEntry::~ManagerWindowC_ListEntry	(VOID)
{
	if (fileName)	delete [] fileName;
}

STRPTR 	ManagerWindowC_ListEntry::getClass				(VOID)
{
	return "ManagerWindowC_ListEntry";
}
VOID		ManagerWindowC_ListEntry::cleanUp					(VOID)
{
}
LONG		ManagerWindowC_ListEntry::compare				(GUIC_ObjectC &o)
{
	return Stricmp(fileName, ((ManagerWindowC_ListEntry *)&o)->fileName); // Just compare the two file names	
}
VOID		ManagerWindowC_ListEntry::print						(VOID)
{
	cout << "[" << getClass() << "," << this << ",Name=" << fileName << "]" << endl;
}

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

ManagerWindowC::ManagerWindowC 			(GUIC_ApplicationC &a, GUIC_ScreenC &s, PrefsWindowC &p) : GUIC_WindowC(20,20)
{
	app 				= &a;
	screen 			= &s;
	pWindow			= &p;
	
	pa_window		= new GUIC_PanelC		 	(GUIC_Vertical);
	sp_line1			= new GUIC_SeparatorC	(GUIC_Horizontal);
	sp_line2			= new GUIC_SeparatorC	(GUIC_Horizontal);
	
	/* 1. Zeile: Quell-Pfad */
	pa_sourcePath	= new GUIC_PanelC				(GUIC_Horizontal);
	la_sourcePath		= new GUIC_LabelC				("_Source Path:");
	bt_sourcePath	= new GUIC_ImageButtonC	(GUIC_PathImage);
	tf_sourcePath		= new GUIC_TextfieldC			(GUIC_Text);
	
	bt_sourcePath->setShortcut('s');
	
	pa_sourcePath->add(la_sourcePath);
	pa_sourcePath->add(tf_sourcePath);
	pa_sourcePath->add(bt_sourcePath);

	/* 2. Zeile: Thumbnails */
	LONG x=1, y=1;
	pa_thumbnails	= new GUIC_PanelC			(5, 3);
	for (LONG i=0; i<NUMBER_OF_THUMBNAILS; i++) 
		{
		bt_thumbnails[i] = new GUIC_SlideButtonC (NULL, 100, 100);
		pa_thumbnails->add(bt_thumbnails[i], x, y);
		x++;
		if (x == 6) { y++; x=1; }
		}

	/* 2. Zeile: Ziel-Pfad */
	pa_destPath	= new GUIC_PanelC				(GUIC_Horizontal);
	la_destPath	= new GUIC_LabelC				("_Destination Path:");
	bt_destPath	= new GUIC_ImageButtonC	(GUIC_PathImage);
	tf_destPath	= new GUIC_TextfieldC			(GUIC_Text);
	
	bt_destPath->setShortcut('d');
	
	pa_destPath->add(la_destPath);
	pa_destPath->add(tf_destPath);
	pa_destPath->add(bt_destPath);

	/* 4. Zeile: Message */
	pa_message 	= new GUIC_PanelC (GUIC_Horizontal);
	la_message	= new GUIC_LabelC ("Message:");
	tf_message	= new GUIC_TextfieldC (GUIC_Text);

	pa_message->add(la_message);
	pa_message->add(tf_message);
	
	pa_window->add(pa_sourcePath);
//	pa_window->add(pa_thumbnails);
	pa_window->add(sp_line1);
	pa_window->add(pa_destPath);
	pa_window->add(sp_line2);
	pa_window->add(pa_message);
	
	prop	= new GUIC_PropWithArrowsC (0, 10, 5);
	pa_window->add(prop);
	
	add(pa_window);
	
	activate();
	setTitle("Gallery - Manager");
	setGuideContext("ManagerWindow");

	app->addPrefs("ManagerWindow", this);
	app->addPrefs("ManagerWindowSourcePath", pr_sourcePath);
	app->addPrefs("ManagerWindowDestinationPath", pr_destPath);
}
ManagerWindowC::~ManagerWindowC 		(VOID)
{
	cleanUp();
}

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

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

BOOL 	ManagerWindowC::action 			(GUIC_EventC &event)
{
	static BOOL firstTime = TRUE;
	
	switch (event.id)
		{
		case GUIC_GadgetEvent:
			return TRUE;
			break;
		case GUIC_ObjectEvent:
			if (event.object == (GUIC_GUIObjectC *) bt_sourcePath)
				{
				if (pr_sourcePath.request(this)) 
					{
					app->setBusy(TRUE);
					tf_sourcePath->setText ( pr_sourcePath.getPath() );
					setSource();
					app->setBusy(FALSE);
					}
				}
			else if (event.object == (GUIC_GUIObjectC *) bt_destPath)
				{
				if (pr_destPath.request(this)) tf_destPath->setText(pr_destPath.getPath());
				}
			else if (event.object == (GUIC_GUIObjectC *) prop)
				{
				}
			else // Thumbnails abprüfen
				{
				for (LONG i=0; i<NUMBER_OF_THUMBNAILS; i++)
					{
					if (event.object == (GUIC_GUIObjectC *) bt_thumbnails[i])
						{
						LONG thumbnail = firstThumbnail + i;
						if (thumbnail <= sourceFiles.length())
							{
							ManagerWindowC_ListEntry *entry = (ManagerWindowC_ListEntry *) sourceFiles.objectAt(thumbnail);
							CHAR dummy[1024];
							sprintf(dummy, "Filename: %s\nFilesize: %ld\nDimensions: %s", entry->fileName, entry->fileSize, entry->dimensions);
							GUIC_MessageC message ("Picture Information:", dummy, "Show|Delete|Move|Copy|Cancel");
							LONG answer = message.request(this);
							switch (answer)
								{
								case 1:
									showFile(entry);
									break;
								case 2:
									deleteFile(entry, i);
									break;
								case 3:
									moveFile(entry, i);
									break;
								case 4:
									copyFile(entry);
									break;
								}
							}
						}
					}
				}
			return TRUE;
			break;
		case GUIC_OpenWindow:
			setBusy(TRUE);
			tf_sourcePath->setText(pr_sourcePath.getPath());
			tf_destPath->setText(pr_destPath.getPath());
			if (firstTime) setSource(); 
			firstTime = FALSE;
			setBusy(FALSE);
			return TRUE;
			break;
		case GUIC_CloseWindow:
			screen->remove(this);
			return TRUE;
			break;
		}
	return FALSE;
}

VOID		ManagerWindowC::setSource		(VOID)
{
	ManagerWindowC_ListEntry *entry;
	CHAR		dummy[128];
	LONG 	count = 1;
	STRPTR 	temp = pWindow->ps_temporaryPath->get();
					
	// Die alte Liste löschen 
	while (sourceFiles.length()) delete (ManagerWindowC_ListEntry *) sourceFiles.remove(1);
	
	// Und die neuen Files einlesen
	try
		{
		GUIC_FileExamineC *filex;
		GUIC_DirectoryExamineC direx (pr_sourcePath.getPath());
		
		while (( filex = direx.examineNext() ) )
			{
			if (filex->getFileType() == GUIC_PictureFile)
				{
				sprintf(dummy, "Scanning source directory: %ld", count++);
				tf_message->setText(dummy);
				entry = new ManagerWindowC_ListEntry(filex, temp, tf_message);
				if (entry) sourceFiles.addSorted(entry); // sonst war kein Speicher mehr frei zum Laden des Files
				}
			}
		}
	catch (GUIC_Exception &x)
		{
		GUIC_ErrorC err ("Exception caught:", x.getMessage());
		err.request(this);
		}
		
	tf_message->setText("Loading thumbnails.");
	
	LONG len = sourceFiles.length(), i;
	
	for (i=0; i<NUMBER_OF_THUMBNAILS; i++)
		{
		if (i < len)
			{
			entry = (ManagerWindowC_ListEntry *) sourceFiles.objectAt(i+1);
			bt_thumbnails[i]->set(entry->fileName);
			}
		else bt_thumbnails[i]->set(NULL);
		}

	firstThumbnail=1;
	tf_message->setText("");
}
VOID		ManagerWindowC::showFile		(ManagerWindowC_ListEntry *entry)
{
}
VOID		ManagerWindowC::deleteFile		(ManagerWindowC_ListEntry *entry, LONG button)
{
	GUIC_FileC f1 ( entry->fileName );
	GUIC_FileC f2 ( entry->thumbnailName ); 
	
	if (f1.remove()) 
		{
		bt_thumbnails[button]->set(NULL);
		GUIC_SystemC::reallocString(&entry->fileName, "");
		}
	else 
		{
		GUIC_ErrorC err ("Caution:", "Could not delete file from disk.");
		err.request(this);
		}
				
	if (! f2.remove())
		{
		GUIC_ErrorC err ("Caution:", "Could not delete thumbnail from disk.");
		err.request(this);
		}
}
VOID		ManagerWindowC::moveFile		(ManagerWindowC_ListEntry *entry, LONG button)
{
	if (copyFile(entry)) deleteFile(entry, button);
}
BOOL		ManagerWindowC::copyFile			(ManagerWindowC_ListEntry *entry)
{
	GUIC_FileC f1	( entry->fileName );
	
	STRPTR 	path	= pr_destPath.getPath();
	STRPTR 	file		= f1.getFilePart();
	LONG 	len		= strlen (path) + strlen(file) + 5;
	STRPTR 	buffer	= new CHAR [len];
	
	strcpy(buffer, path);
	AddPart(buffer, file, len);
	
	if (f1.doesExist())
		{
		GUIC_FileC *dest = new GUIC_FileC (buffer);
		BOOL exists=dest->doesExist();
		delete dest; dest=0;
		
		if (exists)
			{
			STRING s="File\n'";
			s += buffer;
			s += "'\nexists already";
			GUIC_MessageC msg ("Caution:", s, "Override|More information|Cancel");
			LONG result = msg.request(this);
			if (result == 0) return FALSE;
			if (result == 2) 
				{
/*				sleep();
				pWindow->showPicture("");
				if (iWindow == 0) iWindow = new InformationWindowC(*app, *screen);
				screen->add(iWindow);
				iWindow->setPictures(f1.getName(), buffer1);
				waken(); 
*/				
				cerr << "Noch nicht implementiert." << endl;
				return FALSE;
				}
			}
			
		if (f1.copy ( buffer ) ) return TRUE;
		
		GUIC_ErrorC err ("Caution:", "Could not copy picture to destination.");
		err.request(this);
		}
		
	return FALSE;

}

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

VOID 		ManagerWindowC::cleanUp			(VOID)
{
	while (sourceFiles.length()) delete (ManagerWindowC_ListEntry *) sourceFiles.remove(1);
	
	delete pa_message;
	delete la_message;
	delete tf_message;

	for (LONG i=0; i<NUMBER_OF_THUMBNAILS; i++) delete bt_thumbnails[i];
	delete pa_thumbnails;

	delete bt_destPath;
	delete la_destPath;
	delete tf_destPath;
	delete pa_destPath;

	delete bt_sourcePath;
	delete la_sourcePath;
	delete tf_sourcePath;
	delete pa_sourcePath;
	
	delete sp_line1;
	delete sp_line2;
	delete pa_window;
	
	delete prop;
}

