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

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

#include "GUICINCLUDE:GUIC_FileExamine.hpp"
#include "GUICINCLUDE:GUIC_DirectoryExamine.hpp"
#include "GUICINCLUDE:GUIC_System.hpp"
#include "GUICINCLUDE:GUIC_StringType.hpp"
#include "GUICINCLUDE:GUIC_Screen.hpp"
#include "GUICINCLUDE:GUIC_Application.hpp"
#include "GUICINCLUDE:GUIC_Listview.hpp"
#include "GUICINCLUDE:GUIC_Button.hpp"
#include "GUICINCLUDE:GUIC_PathString.hpp"
#include "GUICINCLUDE:GUIC_Label.hpp"
#include "GUICINCLUDE:GUIC_Number.hpp"
#include "GUICINCLUDE:GUIC_Text.hpp"
#include "GUICINCLUDE:GUIC_Checkbox.hpp"
#include "GUICINCLUDE:GUIC_Exceptions.hpp"
#include "GUICINCLUDE:GUIC_Error.hpp"
#include "GUICINCLUDE:GUIC_Message.hpp"
#include "GUICINCLUDE:GUIC_File.hpp"
#include "GUICINCLUDE:GUIC_GGFXPicture.hpp"

#include "ManagerWindow.hpp"
#include "ThumbnailWindow.hpp"
#include "PictureWindow.hpp"
#include "GalleryWindow.hpp"
#include "InformationWindow.hpp"

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

static class ListEntryC : public GUIC_ObjectC
	{
	public:
		ListEntryC				(STRPTR s);
		~ListEntryC				(VOID);
		LONG		compare	(GUIC_ObjectC &o);
		STRPTR 	str;
	protected:
		VOID 		cleanUp	(VOID);
	};
	
ListEntryC::ListEntryC				(STRPTR s)
{
	str=0;
	GUIC_SystemC::reallocString(&str, s);
}
ListEntryC::~ListEntryC			(VOID)
{
	cleanUp();
}
VOID	ListEntryC::cleanUp		(VOID)
{
	if (str) delete str; str=0;
}
LONG	ListEntryC::compare	(GUIC_ObjectC &o)
{
	ListEntryC *e = (ListEntryC *)&o; 
	return Stricmp(str, e->str); 
}


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

ManagerWindowC::ManagerWindowC 						(GUIC_ApplicationC &a, GUIC_ScreenC &s) : GUIC_WindowC (-1,1000, 62, 36)
{
	app 		= &a;
	screen	= &s;
	tWindow	= 0;
	pWindow	= 0;
	iWindow	= 0;
	tWidth		= 200;
	tHeight	= 200;
	
	sourceLabel		= new GUIC_LabelC 			( 1, 1,25, 2, "_Source _Files");
	sourcePath			= new GUIC_PathStringC	( 1, 3,25, 2, "RAM:");
	source				= new GUIC_ListviewC		( 1, 5,25,20);
	
	deleteFile			= new GUIC_ButtonC			(27, 7, 8, 2, "_Delete");
	moveFile				= new GUIC_ButtonC			(27,10, 8, 2, "_Move ->");
	copyFile				= new GUIC_ButtonC			(27,13, 8, 2, "_Copy ->");
	genThumbnail		= new GUIC_ButtonC			(27,16, 8, 2, "_Thumb"); 

	destinationLabel	= new GUIC_LabelC 			(36, 1,25, 2, "D_estination d_irectories");
	destinationPath	= new GUIC_PathStringC	(36, 3,25, 2, "RAM:");
	destination			= new GUIC_ListviewC		(36, 5,25,20);
	
	width					= new GUIC_NumberC		( 1,26,15, 2, 0);
	mal						= new GUIC_TextC				(16,26, 5, 2, "x");
	height					= new GUIC_NumberC		(21,26,15, 2, 0);
	pixel					= new GUIC_TextC				(36,26, 8, 2, "Pixel");
	
	showLabel			= new GUIC_LabelC			(50,26, 8, 2, "Sho_w:");
	show					= new GUIC_CheckboxC		(58,26, 3, 2, TRUE);
	
	scaleLabel			= new GUIC_LabelC			(50,28, 8, 2, "Sc_ale:");
	scale					= new GUIC_CheckboxC		(58,28, 3, 2, TRUE);
	
	centerLabel		= new GUIC_LabelC			(50,30, 8, 2, "Ce_nter:");
	center					= new GUIC_CheckboxC		(58,30, 3, 2, TRUE);
	
	message				= new GUIC_TextC				( 1,33,60, 2, "");
	
	sourcePath			-> setHelp ("Sets the source path of pictures.");
	source				-> setHelp ("Select the picture to work with.");
	destinationPath	-> setHelp ("Sets the destination path for pictures.");
	destination			-> setHelp ("Select the directory to copy the picture.");
	deleteFile			-> setHelp ("Deletes the picture from disk.");
	moveFile				-> setHelp ("Moves the picture to the selected directory.");
	copyFile				-> setHelp ("Copies the picture to the selected directory.");
	genThumbnail		-> setHelp ("Generates a thumbnail for the picture.");
	width					-> setHelp ("The width of the picture (when shown).");
	height					-> setHelp ("The height of the picture (when shown).");
	show					-> setHelp ("Check if you want to see the picture.");
	scale					-> setHelp ("Scale the picture if it is too large.");
	center					-> setHelp ("Center the picture on the screen.");
	
	mal 		-> setBorder(FALSE);
	pixel		-> setBorder(FALSE);
	
	width		-> setFrontPen ( GUIC_ShinePen );
	height		-> setFrontPen ( GUIC_ShinePen );
	message	-> setFrontPen ( GUIC_FillPen );
	
	mal 	-> setJustification ( GUIC_Center );
	width	-> setJustification ( GUIC_Center );
	height	-> setJustification ( GUIC_Center );
	pixel	-> setJustification ( GUIC_Center );
	
	source				-> setShortcut ('f');
	sourcePath			-> setShortcut ('s');
	destination			-> setShortcut ('i');
	destinationPath	-> setShortcut ('e');
	show					-> setShortcut ('w');
	scale					-> setShortcut ('a');
	center					-> setShortcut ('n');
	
	add ( sourceLabel );
	add ( destinationLabel );
	add ( sourcePath );
	add ( destinationPath );
	add ( source );
	add ( destination );
	add ( deleteFile );
	add ( moveFile );
	add ( copyFile );
	add ( genThumbnail );
	add ( width );
	add ( mal );
	add ( height );
	add ( pixel );
	add ( showLabel );
	add ( show );
	add ( scaleLabel );
	add ( scale );
	add ( centerLabel );
	add ( center );
	add ( message );
	
	app->addPrefs("ManagerWindow", this);
	app->addPrefs("Source", 				sourcePath);
	app->addPrefs("Destination",		destinationPath);
	app->addPrefs("ShowPicture",		show);
	app->addPrefs("ScalePicture",		scale);
	app->addPrefs("CenterPicture", 	center);
	
	setGuideContext("ManagerWindow");
	setTitle ( "Gallery Picture Manager");
	setHelp ( TRUE );
	
	activate();
}
ManagerWindowC::~ManagerWindowC 					(VOID)
{
	cleanUp();
}

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

VOID		ManagerWindowC::setWindows				(ThumbnailWindowC &t, PictureWindowC &p)
{
	tWindow = &t;
	pWindow = &p;
	
	pWindow->setTextGadget ( message );
	pWindow->setNumberGadgets ( width, height );
	
	tWindow->setTextGadget ( message );
}
VOID		ManagerWindowC::setThumbnailDim		(LONG x, LONG y)
{
	if (! tWindow) return;
	tWindow->setDimensions(x,y);
	tWidth = x;
	tHeight = y;
}

VOID		ManagerWindowC::scanSource				(STRPTR s)
{
	message->set("Scanning source directory for pictures.");
	
	source->delAllItems();
	
	try
		{
		GUIC_FileExamineC *filex = 0;
		GUIC_DirectoryExamineC direx (s);
		
		while ((filex = direx.examineNext() ))
			{
			STRING fileName = filex->getFilePart();
			if (filex->getFileType() == GUIC_PictureFile) 
				{
				if (fileName.right(5) == (STRING)"_.jpg") continue;
				source->addItem(fileName);
				}
			}
		}
	catch (GUIC_Exception &e)
		{
		GUIC_ErrorC err("Exception caught:", e.getMessage() );
		err.request(this);
		}
	
	source->sortItems();
}
VOID		ManagerWindowC::scanDestination			(STRPTR userRoot)
{
	message->set("Scanning destination directory.");
	
	destination->delAllItems();
	
	try
		{
		GUIC_FileExamineC *filex = 0;
		GUIC_DirectoryExamineC direx (userRoot);
		
		while ((filex = direx.examineNext() ))
			{
			if (filex->isDirectory()) destination->addItem( filex->getFilePart() );
			}
		}
	catch (GUIC_Exception &e)
		{
		GUIC_ErrorC err("Exception caught:", e.getMessage() );
		err.request(this);
		}
	
	destination->sortItems();
}

STRPTR	ManagerWindowC::getDestination			(LONG i)
{
	return destination->getItem(i);
}

STRPTR	ManagerWindowC::getThumbnailName	(VOID)
{
	ULONG sel = source->getSelected();
	if (sel == -1) return "";
	
	STRING fileName = source->getItem(sel);

	LONG i = fileName.length();
	while (--i) if (fileName[i] == '.') break;

	STRING thumbName = sourcePath->get();
	if (thumbName.right(1) != (STRING) ":") thumbName += "/";
	thumbName += fileName.left(i);
	thumbName += "_.jpg";

	static STRPTR result = 0;
	GUIC_SystemC::reallocString ( &result, thumbName);
	
	return result;
}
STRPTR	ManagerWindowC::getPictureName			(VOID)
{
	ULONG sel = source->getSelected();
	if (sel == -1) return "";
	
	STRING fileName = source->getItem(sel);

	STRING picName = sourcePath->get();
	if (picName.right(1) != (STRING) ":") picName += "/";
	picName += fileName;

	static STRPTR result = 0;
	GUIC_SystemC::reallocString ( &result, picName);
	
	return result;
}

VOID		ManagerWindowC::showPic					(VOID)
{
	sleep();
	
	tWindow->showThumbnail ( getThumbnailName() );
	if ( show->get() ) pWindow->showPicture ( getPictureName() );
	
	waken();
}
VOID		ManagerWindowC::deletePic					(VOID)
{
	GUIC_FileC f1 ( getPictureName() );
	GUIC_FileC f2 ( getThumbnailName() ); 
	
	if (f1.remove()) 
		{
		source->delItem();
		showPic();
		}
	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::movePic					(VOID)
{
	if (copyPic()) deletePic();
}
BOOL		ManagerWindowC::copyPic						(VOID)
{
	GUIC_FileC f1	( getPictureName() );
	GUIC_FileC f2	( getThumbnailName() ); 
	
	STRPTR path1	= destinationPath->get();
	STRPTR path2	= getDestination( destination->getSelected() );
	STRPTR file		= f1.getFilePart();
	STRPTR thumb	= f2.getFilePart();

	LONG lenPic 		= strlen (path1) + strlen(path2) + strlen(file) + 5;
	LONG lenThumb	= strlen (path1) + strlen(path2) + strlen(thumb) + 5;
	
	STRPTR buffer1	= new CHAR [lenPic];
	STRPTR buffer2	= new CHAR [lenThumb];
	
	strcpy(buffer1, path1);
	strcpy(buffer2, path1);
	
	AddPart(buffer1, path2, lenPic);
	AddPart(buffer2, path2, lenThumb);

	AddPart(buffer1, file, lenPic);
	AddPart(buffer2, thumb, lenThumb);
	
	
	if (f1.doesExist())
		{
		GUIC_FileC *dest = new GUIC_FileC (buffer1);
		BOOL exists=dest->doesExist();
		delete dest;
		
		if (exists)
			{
			STRING s="File\n'";
			s += buffer1;
			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();
				return FALSE;
				}
			}
			
		if ( f1.copy ( buffer1 ) )
			{
			if ( f2.doesExist() )
				{
				if ( f2.copy ( buffer2 ) )
					{
					return TRUE;
					}
				else
					{
					GUIC_ErrorC err ("Caution:", "Could not copy thumbnail to destination.");
					err.request(this);
					}
				}
			else 
				{
				GUIC_FileC oldThumbnail (buffer2);
				oldThumbnail.remove();
				return TRUE;
				}
			}
		else
			{
			GUIC_ErrorC err ("Caution:", "Could not copy picture to destination.");
			err.request(this);
			}
		}
		
	return FALSE;
}

BOOL		ManagerWindowC::action						(GUIC_EventC &e)
{
	switch (e.id)
		{
		case GUIC_GadgetEvent:
			if (e.gadget == (GUIC_GadgetC*) sourcePath)
				{
				sleep();
				scanSource( sourcePath->get() );
				showPic();
				if (source->length() > 0) enableGadgets(); else disableGadgets();
				waken();
				}
			else if (e.gadget == (GUIC_GadgetC*) destinationPath)
				{
				sleep();
				scanDestination( destinationPath->get() );
				waken();
				}
			else if (e.gadget == (GUIC_GadgetC*) source)
				{
				showPic();
				}
			else if (e.gadget == (GUIC_GadgetC*) show)
				{
				if ( show->get() ) 
					{
					sleep();
					pWindow->showPicture ( getPictureName() );
					waken();
					scale->enable();
					center->enable();
					genThumbnail->enable();
					}
				else 
					{
					scale->disable();
					center->disable();
					genThumbnail->disable();
					}
				}
			else if (e.gadget == (GUIC_GadgetC*) scale)
				{
				pWindow->setScaled(scale->get());
				}
			else if (e.gadget == (GUIC_GadgetC*) center)
				{
				pWindow->setCentered(center->get());
				}
			else if (e.gadget == (GUIC_GadgetC*) deleteFile)
				{
				sleep();
				deletePic();
				if (source->length() == 0) disableGadgets();
				waken();
				}
			else if (e.gadget == (GUIC_GadgetC*) moveFile)
				{
				sleep();
				movePic();
				if (source->length() == 0) disableGadgets();
				waken();
				}
			else if (e.gadget == (GUIC_GadgetC*) copyFile)
				{
				sleep();
				copyPic();
				waken();
				}
			else if (e.gadget == (GUIC_GadgetC*) genThumbnail)
				{
				sleep();
				
				try
					{
					GUIC_GGFXPictureC *pic = pWindow->getPicture();
					if (! pic) return TRUE;
					pic->scaleToBox	(tWidth, tHeight);
					pic->saveJPEG 	(getThumbnailName(), 90);
					tWindow->showThumbnail ( getThumbnailName() );
					}
				catch (GUIC_Exception &e) { GUIC_ErrorC err ("Exception caught:", e.getMessage()); err.request(this); }
				
				waken();
				}
			return TRUE;
			break;
		case GUIC_OpenWindow:
		
			if (! show->get() )
				{
				scale->disable();
				center->disable();
				genThumbnail->disable();
				}
				
			sleep();
			
			scanSource( sourcePath->get() );
			if (source->length() == 0) disableGadgets();
			
			scanDestination( destinationPath->get() );
			
			tWindow->showThumbnail ( getThumbnailName() );
			
			pWindow->setScaled(scale->get());
			pWindow->setCentered(center->get());
			if (show->get() ) pWindow->showPicture ( getPictureName() );

			waken();
			
			return TRUE;
			break;
		case GUIC_CloseWindow:
			return FALSE;
			break;
		default:
			cerr << "Got an event: " << e.id << endl;
		}
	
	return FALSE;
}

VOID		ManagerWindowC::disableGadgets			(VOID)
{
	deleteFile->disable();
	moveFile->disable();
	copyFile->disable();
	genThumbnail->disable();
}
VOID		ManagerWindowC::enableGadgets			(VOID)
{
	deleteFile->enable();
	moveFile->enable();
	copyFile->enable();
	if (show->get() ) genThumbnail->enable();
}

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

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

VOID 		ManagerWindowC::cleanUp						(VOID)
{	
	if (iWindow) delete iWindow;
	
	delete sourcePath;
	delete sourceLabel;
	delete source;
	
	delete destinationPath;
	delete destinationLabel;
	delete destination;

	delete deleteFile;
	delete moveFile;
	delete copyFile;
	delete genThumbnail;
	
	delete width;
	delete mal;
	delete height;
	delete pixel;
	delete showLabel;
	delete show;
	delete scaleLabel;
	delete scale;
	delete centerLabel;
	delete center;
	delete message;
}

