/*
**	ToolBoxWin.c
**
**	Copyright (C) 1993,94,95,96,97 Bernardo Innocenti
**
**	Handle ToolBox panel
*/

#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <libraries/locale.h>
#include <workbench/workbench.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/wb.h>
#include <proto/asl.h>
#include <proto/icon.h>
#include <proto/xmodule.h>

#include "XModulePriv.h"
#include "Gui.h"



/* Gadgets IDs */

enum
{
	GD_ToolBoxGroup0,
		GD_ToolBoxGroup1,
			GD_ToolBoxGroup2,
				GD_Play,
				GD_EditSongs,
			GD_ToolBoxGroup3,
				GD_EditPatterns,
				GD_EditInstruments,
			GD_ToolBoxGroup4,
				GD_EditSequence,
				GD_Optimization,
	ToolBox_CNT
};



/*****************************/
/* Local function prototypes */
/*****************************/

static void EditInstrumentsClicked	(void);
static void EditSequenceClicked 	(void);
static void EditPatternsClicked 	(void);
static void OptimizationClicked 	(void);
static void PlayClicked				(void);
static void EditSongsClicked		(void);

static void ToolBoxMiNew			(void);
static void ToolBoxMiOpen			(void);
static void ToolBoxMiOpenNew		(void);
static void ToolBoxMiSave			(void);
static void ToolBoxMiSaveAs			(void);
static void ToolBoxMiSaveFormat		(void);
static void ToolBoxMiClearMod		(void);
static void ToolBoxMiAbout			(void);
static void ToolBoxMiHelp			(void);
static void ToolBoxMiIconify		(void);
static void ToolBoxMiQuit			(void);
static void ToolBoxMiUserInterface	(void);
static void ToolBoxMiSaveIcons		(void);
static void ToolBoxMiOverwrite		(void);
static void ToolBoxMiAskExit		(void);
static void ToolBoxMiOpenSettings	(void);
static void ToolBoxMiSaveSettings	(void);
static void ToolBoxMiSaveSettingsAs	(void);



static struct NewMenu ToolBoxNewMenu[] = {
	NM_TITLE, (STRPTR)MSG_PROJECT_MEN, NULL, 0, NULL, NULL,
	NM_ITEM, (STRPTR)MSG_NEW_MEN, (STRPTR)"N", 0, 0L, (APTR)ToolBoxMiNew,
	NM_ITEM, (STRPTR)MSG_OPEN_MEN, (STRPTR)"O", 0, 0L, (APTR)ToolBoxMiOpen,
	NM_ITEM, (STRPTR)MSG_OPEN_NEW_MEN, (STRPTR)"Y", 0, 0L, (APTR)ToolBoxMiOpenNew,
	NM_ITEM, (STRPTR)MSG_SAVE_MEN, (STRPTR)"S", 0, 0L, (APTR)ToolBoxMiSave,
	NM_ITEM, (STRPTR)MSG_SAVE_AS_MEN, (STRPTR)"A", 0, 0L, (APTR)ToolBoxMiSaveAs,
	NM_ITEM, (STRPTR)MSG_SAVE_FORMAT_MEN, (STRPTR)"F", 0, 0L, (APTR)ToolBoxMiSaveFormat,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, (STRPTR)MSG_CLEAR_MEN, (STRPTR)"K", 0, 0L, (APTR)ToolBoxMiClearMod,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, (STRPTR)MSG_ABOUT_MEN, (STRPTR)"?", 0, 0L, (APTR)ToolBoxMiAbout,
	NM_ITEM, (STRPTR)MSG_HELP_MEN, NULL, 0, 0L, (APTR)ToolBoxMiHelp,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, (STRPTR)MSG_ICONIFY_MEN, (STRPTR)"I", 0, 0L, (APTR)ToolBoxMiIconify,
	NM_ITEM, (STRPTR)MSG_QUIT_MEN, (STRPTR)"Q", 0, 0L, (APTR)ToolBoxMiQuit,
	NM_TITLE, (STRPTR)MSG_SETTINGS_MEN, NULL, 0, NULL, NULL,
	NM_ITEM, (STRPTR)MSG_USER_INTERFACE_MEN, NULL, 0, 0L, (APTR)ToolBoxMiUserInterface,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, (STRPTR)MSG_SAVE_ICONS_MEN, NULL, CHECKIT|MENUTOGGLE, 0L, (APTR)ToolBoxMiSaveIcons,
	NM_ITEM, (STRPTR)MSG_CONFIRM_OVERWRITE_MEN, NULL, CHECKIT|MENUTOGGLE, 0L, (APTR)ToolBoxMiOverwrite,
	NM_ITEM, (STRPTR)MSG_CONFIRM_EXIT_MEN, NULL, CHECKIT|MENUTOGGLE, 0L, (APTR)ToolBoxMiAskExit,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, (STRPTR)MSG_OPEN_SETTINGS_MEN, NULL, 0, 0L, (APTR)ToolBoxMiOpenSettings,
	NM_ITEM, (STRPTR)MSG_SAVE_SETTINGS_MEN, NULL, 0, 0L, (APTR)ToolBoxMiSaveSettings,
	NM_ITEM, (STRPTR)MSG_SAVE_SETTINGS_AS_MEN, NULL, 0, 0L, (APTR)ToolBoxMiSaveSettingsAs,
	NM_END, NULL, NULL, 0, 0L, NULL
};



static ULONG ToolBoxArgs[] =
{
	HGROUP_KIND, 0,
		VGROUP_KIND, 0,
			BUTTON_KIND, (ULONG)PlayClicked,			MSG_PLAY_GAD,			TAG_DONE,
			BUTTON_KIND, (ULONG)EditSongsClicked,		MSG_SONGS_GAD,			TAG_DONE,
			ENDGROUP_KIND,
		VGROUP_KIND, 0,
			BUTTON_KIND, (ULONG)EditPatternsClicked,	MSG_PATTERNS_DOTS_GAD,	TAG_DONE,
			BUTTON_KIND, (ULONG)EditInstrumentsClicked,	MSG_INSTRUMENTS_GAD,	TAG_DONE,
			ENDGROUP_KIND,
		VGROUP_KIND, 0,
			BUTTON_KIND, (ULONG)EditSequenceClicked,	MSG_SEQUENCE_DOTS_GAD,	TAG_DONE,
			BUTTON_KIND, (ULONG)OptimizationClicked,	MSG_OPTIMIZATION_GAD,	TAG_DONE,
			ENDGROUP_KIND,
		ENDGROUP_KIND,
	ENDGROUP_KIND
};



XDEF LONG ToolBoxWinTags[] =
{
	XMWIN_NewMenu,		(LONG)ToolBoxNewMenu,
	XMWIN_LayoutArgs,	(LONG)ToolBoxArgs,
	XMWIN_GCount,		ToolBox_CNT,
	XMWIN_Title,		MSG_TOOLBOX_TITLE,
	XMWIN_WindowFlags,	WFLG_CLOSEGADGET | WFLG_ACTIVATE,
	XMWIN_IDCMPFlags,	BUTTONIDCMP|IDCMP_MENUPICK|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW,
	XMWIN_PostOpenFunc,	(LONG)UpdateGuiSwitches,
	XMWIN_HelpNode,		(LONG)"ToolBox",
	TAG_DONE
};




/*********************/
/* ToolBox Functions */
/*********************/



GLOBALCALL void ToolBoxDropIcon (struct AppMessage *msg)
{
	struct WBArg	*wba = msg->am_ArgList;
	BPTR olddir;
	ULONG i;
	struct SongInfo *si;

	LockWindows();

	ObtainSemaphore (&XModuleBase->xm_BaseLock);

	olddir = CurrentDir (wba->wa_Lock);

	for (i = 0; i < msg->am_NumArgs; i++)
	{
		CurrentDir (wba->wa_Lock);

		if (si = xmLoadModule (wba->wa_Name,
			XMSNG_OldSong,		i ? NULL : XModuleBase->xm_CurrentSong,
			XMSNG_AddToList,	-1,
			XMSNG_Active,		i == (msg->am_NumArgs - 1),
			TAG_DONE))
			ReleaseSemaphore (&si->Lock);	/* For XMSNG_AddToList */

		wba++;
	}

	ReleaseSemaphore (&XModuleBase->xm_BaseLock);

	CurrentDir (olddir);
	UnlockWindows();
}



GLOBALCALL void ToolBoxOpenModule (CONST_STRPTR file, ULONG num, ULONG count)

/* Handle FileRequester Open Module message */
{
	struct SongInfo *si;

	LockWindows();

	ObtainSemaphore (&XModuleBase->xm_BaseLock);

	DB(kprintf ("opening song %ld of %ld\n", num, count));

	if (si = xmLoadModule (file,
		XMSNG_AddToList,	num ? (ULONG)XModuleBase->xm_CurrentSong : (ULONG)~0,
		XMSNG_Active,		num == (count - 1),
		XMSNG_OldSong,		num ? (ULONG)NULL : (ULONG)XModuleBase->xm_CurrentSong,
		TAG_DONE))
		ReleaseSemaphore (&si->Lock);	/* This is for XMSNG_AddToList */

	ReleaseSemaphore (&XModuleBase->xm_BaseLock);

	UnlockWindows();
}


GLOBALCALL void UpdateGuiSwitches ()
{
	struct MenuItem *item;
	struct WinUserData *wud = WDescr[WID_TOOLBOX].Wud;

	if (wud && wud->MenuStrip)
	{
		if (wud->Win) ClearMenuStrip (wud->Win);

		item = ItemAddress (wud->MenuStrip, SHIFTMENU(1) | SHIFTITEM(2) );

		/* Save Icons? */
		if (GuiSwitches.SaveIcons)
			item->Flags |= CHECKED;
		else
			item->Flags &= ~CHECKED;

		/* Confirm Overwrite? */
		item = item->NextItem;
		if (GuiSwitches.AskOverwrite)
			item->Flags |= CHECKED;
		else
			item->Flags &= ~CHECKED;

		/* Confirm Exit? */
		item = item->NextItem;
		if (GuiSwitches.AskExit)
			item->Flags |= CHECKED;
		else
			item->Flags &= ~CHECKED;

		if (wud->Win) ResetMenuStrip (wud->Win, wud->MenuStrip);
	}
}



/*******************/
/* ToolBox Gadgets */
/*******************/

static void EditInstrumentsClicked (void)
{
	NewWindow (WID_INSTRUMENTS);
}

static void EditSequenceClicked (void)
{
	NewWindow (WID_SEQUENCE);
}

static void OptimizationClicked (void)
{
	NewWindow (WID_OPTIMIZATION);
}

static void PlayClicked (void)
{
	NewWindow (WID_PLAY);
}

static void EditSongsClicked (void)
{
	NewWindow (WID_SONGINFO);
}

static void EditPatternsClicked (void)
{
	NewWindow (WID_PATTERN);
}



/**************/
/* Menu Items */
/**************/

static void ToolBoxMiNew (void)
{
	struct SongInfo *si;

	if (si = xmCreateSong (
		SNGA_ReadyToUse,	TRUE,
		XMSNG_AddToList,	-1,
		XMSNG_Active,		TRUE,
		TAG_DONE))
		ReleaseSemaphore (&si->Lock);	/* This is for XMSNG_AddToList */
	else
		DisplayBeep (NULL);
}



static void ToolBoxMiOpen (void)
{
	StartFileRequest (FREQ_LOADMOD, ToolBoxOpenModule);
}



static void ToolBoxMiOpenNew (void)
{
	ToolBoxMiNew();
	ToolBoxMiOpen();
}



static void ToolBoxMiSave (void)
{
	struct SongInfo *si;

	LockWindows();

	ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);

	if (si = XModuleBase->xm_CurrentSong)
	{
		ObtainSemaphoreShared (&si->Lock);

		if (!(LastErr = xmSaveModuleA (si, si->Path, NULL, NULL)))
			si->Changes = 0;

		ReleaseSemaphore (&si->Lock);
	}

	ReleaseSemaphore (&XModuleBase->xm_BaseLock);

	UnlockWindows();
}



static void ToolBoxMiSaveAs (void)
{
	struct SongInfo *si;
	UBYTE pathname[PATHNAME_MAX];

	LockWindows();

	ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);

	if (si = XModuleBase->xm_CurrentSong)
	{
		ObtainSemaphoreShared (&si->Lock);

		if (si->Path)
		{
			strncpy (pathname, si->Path, PATHNAME_MAX - 1);
			pathname[PATHNAME_MAX - 1] = '\0';
		}
		else pathname[0] = '\0';

		if (FileRequest (FREQ_SAVEMOD, pathname))
		{
			SetAttrs (si,
				SNGA_Path, pathname,
				TAG_DONE);

			ToolBoxMiSave();
		}

		ReleaseSemaphore (&si->Lock);
	}

	ReleaseSemaphore (&XModuleBase->xm_BaseLock);

	UnlockWindows();
}



static void ToolBoxMiClearMod (void)
{
	NewWindow (WID_CLEAR);
}



static void ToolBoxMiAbout (void)
{
	ShowRequest (MSG_ABOUT_TEXT, MSG_CONTINUE,
		XMODULEVER " " XMODULEDATE " " BUILDMODE,
		XMODULECOPY,
		AvailMem (MEMF_CHIP) >> 10,
		AvailMem (MEMF_FAST) >> 10,
		ScrInfo.PubScreenName[0] ? ScrInfo.PubScreenName : STR(MSG_DEFAULT),
		PubPort ? PubPortName : STR(MSG_DISABLED),
		CxPort ? CxPopKey : STR(MSG_DISABLED),
		Catalog ? Catalog->cat_Language : (UBYTE *)"English");
}



static void ToolBoxMiHelp (void)
{
	HandleHelp (NULL);
}

static void ToolBoxMiIconify (void)
{
	Iconify();
	DoNextSelect = FALSE;
}



static void ToolBoxMiQuit (void)
{
	DoNextSelect = 0;
	Quit = 1;
}



static void ToolBoxMiSaveFormat (void)
{
	NewWindow (WID_SAVERS);
}

static void ToolBoxMiUserInterface (void)
{
	NewWindow (WID_PREFS);
}



static void ToolBoxMiSaveIcons (void)
{
	GuiSwitches.SaveIcons ^= 1;
}



static void ToolBoxMiOverwrite (void)
{
	GuiSwitches.AskOverwrite ^= 1;
}



static void ToolBoxMiAskExit (void)
{
	GuiSwitches.AskExit ^= 1;
}



static void ToolBoxMiOpenSettings (void)
{
	UBYTE filename[PATHNAME_MAX];

	strcpy (filename, "XModule.prefs");

	if (FileRequest (FREQ_LOADMISC, filename))
		LastErr = LoadPrefs (filename);
}



static void ToolBoxMiSaveSettings (void)
{
	LastErr = SavePrefs ("PROGDIR:XModule.prefs");
}



static void ToolBoxMiSaveSettingsAs (void)
{
	UBYTE filename[PATHNAME_MAX];

	strcpy (filename, "PROGDIR:XModule.prefs");

	if (FileRequest (FREQ_SAVEMISC, filename))
		LastErr = SavePrefs (filename);
}

