/*
** OpenURL - MUI preferences for openurl.library
** Written by Troels Walsted Hansen <troels@thule.no>
** Placed in the public domain.
**
** This module contains all initialization code and the main function.
*/

#include "prefs_common.h"
#include "prefs_main.h"
#include "prefs_app.h"
#include "prefs_prefswin.h"
#include "prefs_applist.h"
#include "prefs_browsereditwin.h"
#include "prefs_mailereditwin.h"

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

/* prototypes */

static STRPTR OpenLibs(VOID);
static VOID   CloseLibs(VOID);
static VOID   InitClassnames(VOID);
static STRPTR CreateClasses(VOID);
static VOID   DestroyClasses(VOID);
static struct DiskObject *GetMyDiskObject(int argc, char **argv);

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

/* stack */

LONG __stack = 8192;

/* library bases */

struct IntuitionBase *IntuitionBase = NULL;
struct Library *MUIMasterBase = NULL, *UtilityBase = NULL, *IconBase = NULL, 
               *OpenURLBase = NULL;

/* mui classes */

struct MUI_CustomClass *AppClass = NULL, *PrefsWinClass = NULL, *AppListClass = NULL, 
                       *BrowserEditWinClass = NULL, *MailerEditWinClass = NULL;

/* mui class names */

static const STRPTR UsedClasses[] = { "BetterString.mcc", "Textinput.mcc", "NListviews.mcc", NULL };
STRPTR stringclassname = "String.mui", listviewclassname = "Listview.mui", listclassname = "List.mui";

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

static STRPTR OpenLibs(VOID)
{
	if(!(MUIMasterBase = OpenLibrary("muimaster.library", 0)))
		return("Requires muimaster.library V19+ (MUI 3.8+)");

	if(MUIMasterBase->lib_Version < 19)
		return("Requires muimaster.library V19+ (MUI 3.8+)");

	if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
		return("Requires intuition.library V37+");

	if(!(UtilityBase = OpenLibrary("utility.library", 37)))
		return("Requires utility.library V37+");

	if(!(IconBase = OpenLibrary("icon.library", 37)))
		return("Requires icon.library V37+");

	if(!(OpenURLBase = OpenLibrary("openurl.library", 2)))
		return("Requires openurl.library V2+");

	return(NULL);
}

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

static VOID CloseLibs(VOID)
{
	if(OpenURLBase)   CloseLibrary(OpenURLBase);
	if(IconBase)      CloseLibrary(IconBase);
	if(UtilityBase)   CloseLibrary(UtilityBase);
	if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
	if(MUIMasterBase) CloseLibrary(MUIMasterBase);
}

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

static VOID InitClassnames(VOID)
{
	Object *o;

	/* string class */

	if((o = MUI_NewObjectA("Textinput.mcc", NULL)))
		stringclassname = "Textinput.mcc";
	else if((o = MUI_NewObjectA("BetterString.mcc", NULL)))
		stringclassname = "BetterString.mcc";
	else
		stringclassname = "String.mui";

	if(o) MUI_DisposeObject(o);

	/* list and listview class */

	if((o = NListviewObject, MUIA_NListview_NList, NListObject, End, End))
	{
		listviewclassname = "NListview.mcc";
		listclassname     = "NList.mcc";
		MUI_DisposeObject(o);
	}
}

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

static STRPTR CreateClasses(VOID)
{
	if(!(AppClass = MUI_CreateCustomClass(NULL, MUIC_Application, NULL,
	   sizeof(struct App_Data), App_Dispatcher)))
		return("Unable to create AppClass");

	if(!(PrefsWinClass = MUI_CreateCustomClass(NULL, MUIC_Window, NULL,
	   sizeof(struct PrefsWin_Data), PrefsWin_Dispatcher)))
		return("Unable to create PrefsWinClass");

	if(!(AppListClass = MUI_CreateCustomClass(NULL, MUIC_Group, NULL,
	   sizeof(struct AppList_Data), AppList_Dispatcher)))
		return("Unable to create AppListClass");

	if(!(BrowserEditWinClass = MUI_CreateCustomClass(NULL, MUIC_Window, NULL,
	   sizeof(struct BrowserEditWin_Data), BrowserEditWin_Dispatcher)))
		return("Unable to create BrowserEditWinClass");

	if(!(MailerEditWinClass = MUI_CreateCustomClass(NULL, MUIC_Window, NULL,
	   sizeof(struct MailerEditWin_Data), MailerEditWin_Dispatcher)))
		return("Unable to create MailerEditWinClass");

	return(NULL);
}

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

static VOID DestroyClasses(VOID)
{
	if(MailerEditWinClass)  MUI_DeleteCustomClass(MailerEditWinClass);
	if(BrowserEditWinClass) MUI_DeleteCustomClass(BrowserEditWinClass);
	if(AppListClass)        MUI_DeleteCustomClass(AppListClass);
	if(PrefsWinClass)       MUI_DeleteCustomClass(PrefsWinClass);
	if(AppClass)            MUI_DeleteCustomClass(AppClass);
}

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

static struct DiskObject *GetMyDiskObject(int argc, char **argv)
{
	STRPTR filename, iconname;
	struct DiskObject *iconobj = NULL;

	if(argc)
		filename = FilePart(argv[0]);
	else
		filename = (STRPTR)((struct WBStartup *)argv)->sm_ArgList->wa_Name;

	if((iconname = AllocVec(strlen(filename) + 9, MEMF_ANY)))
	{
		SPrintf(iconname, "PROGDIR:%s", filename);
		iconobj = GetDiskObject(iconname);
		FreeVec(iconname);
	}

	return(iconobj);
}

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

int main(int argc, char **argv)
{
	STRPTR error;
	int retval = RETURN_FAIL;
	struct DiskObject *dob = NULL;
	ULONG sigs = 0;
	Object *app = NULL, *win;

	/* open libraries */

	if(error = OpenLibs())
		goto done;

	/* init global classnames */

	InitClassnames();

	/* create MUI classes */

	if(error = CreateClasses())
		goto done;

	/* create MUI application object */

	app = AppObject,
		MUIA_Application_Title,       APPNAME,
		MUIA_Application_Version,     APPVERSTR,
		MUIA_Application_Copyright,   APPCOPYRIGHT,
		MUIA_Application_Author,      APPAUTHOR,
		MUIA_Application_Description, APPDESCR,
		MUIA_Application_Base,        APPBASENAME,
#ifdef MUIA_Application_UsedClasse
		MUIA_Application_UsedClasses, UsedClasses,
#endif
		MUIA_Application_DiskObject,  dob = GetMyDiskObject(argc, argv),
		MUIA_Application_Window,      win = NewObject(PrefsWinClass->mcc_Class, NULL, TAG_DONE),
	End;

	if(!app)
	{
		error = "Unable to create MUI application object";
		goto done;
	}

	/* get the openurl.library prefs */

	if(!DoMethod(win, MUIM_PrefsWin_GetPrefs, FALSE))
		goto done;

	set(win, MUIA_Window_Open, TRUE);
	if(!xget(win, MUIA_Window_Open))
	{
		error = "Unable to open window";
		goto done;
	}

	/* enter input loop */

	while(DoMethod(app, MUIM_Application_NewInput, &sigs) 
	      != MUIV_Application_ReturnID_Quit)
	{
		if(sigs)
		{
			sigs = Wait(sigs | SIGBREAKF_CTRL_C);
			if(sigs & SIGBREAKF_CTRL_C) break;
		}
	}

	retval = RETURN_OK;

done:
	if(error)
	{
		if(MUIMasterBase)
			MUI_RequestA(app, NULL, 0, APPNAME " · Error", "Abort", error, NULL);
		else
			Printf("%s\n", error);
	}

	if(app) MUI_DisposeObject(app);
	DestroyClasses();
	if(dob) FreeDiskObject(dob);
	CloseLibs();

	return(retval);
}
