#include "WimpLib:SaveAs.h"

#include <string.h>

#include "WimpLib:Desktop.h"
#include "WimpLib:Exception.h"
#include "WimpLib:File.h"
#include "WimpLib:Menu.h"
#include "WimpLib:Message.h"
#include "WimpLib:Window.h"
#include "WimpLib:Task.h"
#include "WimpLib:Utils.h"

#define Icon_SaveIcon 0
#define Icon_SaveText 1
#define Icon_SaveCancel 2
#define Icon_SaveSave 3
#define Icon_SaveSel 4

static void SaveAs_SetSelFlag(HWind id, Document* pDoc, bool bSel)
{
	Icon_SetHighlight(id, Icon_SaveSel, bSel);

	// Choose the filename to display
	if (bSel)
		Icon_SetData(id, Icon_SaveText, Msg_Lookup("Selection"));
	else
		Icon_SetData(id, Icon_SaveText, Document_GetPathName(pDoc));

	// Set an invisible caret, so that we can grab key presses
	Icon_SetFocus(id, 1, -1);
}

static bool SaveAs_DoSave(HWind id, Document* pDoc, const View* pSender, bool bSel)
{
	char name[256];
	const _kernel_oserror* err;

    snprintf(name, sizeof(name), "%s", Icon_GetData(id, Icon_SaveText));
	if (!strlen(name))
	{
		Task_ReportError("NoName");
		return false;
	}

	if (File_GetLeafName(name) == name)
	{
		Task_ReportError("FlErr2");
		return false;
	}

	// Convert spaces to hardspaces
	for (char* pc = name; *pc; pc++)
	{
		if (*pc == ' ') *pc = 0xa0;
	}

	if (bSel)
	{
		err = XFer_SendToFile(    name
					, Document_GetFileType(pDoc)
					, (XFer_SendProc) pSender->m_VPtr->FSendSelection
					, NULL
					, (void*) pSender);

		Task_ReportOSError(err);

		return (err == NULL);
	}
	else
		return Document_DoFileSave(pDoc, name);
}

void SaveAs_AskSaveAs(Document* pDoc, const View* pSender, bool bSetSelFlag, bool bAllowSelFlag)
{
	Event* e;
	unsigned int mask = Task_GetPollMask();
	int   bOpen = true;
	HWind id = HWind_None;
	char  sprite[9];
	CSize size;

	try
	{
		id = throw_Window_CreateFrom("SaveAs", NULL);
	}
	catch
	{
		Task_ReportException();
		return;
	}
	catch_end

	// Choose the sprite to display
	snprintf(sprite, sizeof(sprite), "file_%03x", Document_GetFileType(pDoc));
	size = Desktop_GetNamedSpriteSize(sprite);
	Icon_SetData(id, Icon_SaveIcon, size.cx ? sprite : "file_xxx");

	// Set selection button status
	Icon_SetDimmed(id, Icon_SaveSel, !bAllowSelFlag);

	Menu_OpenSubWindow(id);

	SaveAs_SetSelFlag(id, pDoc, bSetSelFlag);

	while (bOpen && Window_IsOpen(id))
	{
		// allow key presses
		e = Task_PollIdle(mask & ~EPollMask_Key, Task_GetPollTimeStep());

		switch (e->Type)
		{
			case EEvent_Key:
			{
				const Event_Key* key = e->pData;

				switch(key->code)
				{
					case 27: // Test ESC key
					{
						bOpen = false;
						continue;
					}
					break;
					case 13: // Test RETURN key
					{
						if (SaveAs_DoSave(id, pDoc, pSender, bSetSelFlag))
							bOpen = false;
						continue;
					}
					break;
				}
				// Other keys are not processed
				Task_WimpProcessKey(key->code);
				continue;
			}
			break;
			case EEvent_Mouse:
			{
				const Mouse* m = e->pData;

				if (m->w == id)
				{
					switch(m->i)
					{
						case Icon_SaveSel:
						{
							bSetSelFlag = !bSetSelFlag;
							SaveAs_SetSelFlag(id, pDoc, bSetSelFlag);
						}
						break;
						case Icon_SaveCancel:
						{
							bOpen = false;
						}
						break;
						case Icon_SaveSave:
						{
							if (SaveAs_DoSave(id, pDoc, pSender, bSetSelFlag))
								bOpen = false;
						}
						break;
						case Icon_SaveIcon:
						{
							const char* leafname = File_GetLeafName(Icon_GetData(id, Icon_SaveText));

							if ((m->but & (EBut_DragSelect | EBut_DragAdjust))
							&&  strlen(leafname))
							{
								DragDrop_Info Info = DragDrop_DragFile(pDoc, 0, Document_GetExportTypes(pDoc));

								if (!bSetSelFlag)
								{
									if (Document_Send(pDoc, &Info, leafname))
										bOpen = false;
								}
								else
								{
									if (DragDrop_Send(&Info
											, leafname
											, 0
											, (XFer_SendProc) pSender->m_VPtr->FSendSelection
											, NULL
											, NULL
											, NULL
											, Task_ReportOSError
											, false
											, (void*) pSender))
										bOpen = false;
								}
							}
						}
						break;
					}
					continue;
				}
			}
			break;
		}

		// Normal processing
		Task_ProcessEvent(e);
	}

	// Close and destroy Window
	if (Window_IsOpen(id))
		Menu_Close();

	Window_Delete(id);

	return;
}
