/*
** GUI Functions
*/

#include "include/config.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/asl.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>

#include "include/mui.h"
#include <MUI/Lamp_mcc.h>
#include <MUI/NListview_mcc.h>

#include "include/gui.h"
#include "include/protos.h"
#include "include/napster.h"
#include "include/download.h"
#include "include/prefs.h"
#include "include/info.h"
#include "include/msg.h"
#include "include/rexx.h"
#include "include/search.h"
#include "include/share.h"
#include "include/panel.h"
#include "include/chat.h"
#include "include/about.h"
#include "include/thread.h"
#include "include/url.h"
#include "amster_Cat.h"

struct Library *MUIMasterBase=0;
struct guidata mygui;
struct guidata *gui = &mygui;
int gui_napon=0;
int gui_napcon=0;

void gui_free(void);
int gui_setup(void);
MUIF gui_handle(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) u_long *id);
MUIF dl_dispatch(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg);
void gui_about(void);
void gui_appicon(int t);

struct Hook handleHook = {{0,0}, &gui_handle, NULL, NULL};


void gui_run(unsigned long tcpsig)
{
	ULONG sigs=0;

	memset(gui,0,sizeof(struct guidata));
	if (gui_setup()) {
		prf_event(PRFE_STARTUP);
		DoMethod(gui->shwin,SHARE_LOAD);
		while(1) {
			while(DoMethod(gui->app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit) {
				if (sigs) {
					sigs = Wait(sigs|SIGBREAKF_CTRL_C|tcpsig|th_sigmask);
					if(sigs&SIGBREAKF_CTRL_C) break;
					if(sigs&tcpsig) nap_listen();
					if(sigs&th_sigmask) th_poll();
				}
			}
			if(!dl_count) break;
			if(dl_count && MUI_Request(gui->app,gui->win,0L,
									   (char *)MSG_REALLYQUIT_TITLE,
									   (char *)MSG_REALLYQUIT_GAD,
									   (char *)MSG_REALLYQUIT)) break;
		}
		prf_event(PRFE_EXIT);
		if(prf->autosave && sharechanged) DoMethod(gui->shwin, SHARE_SAVE);
		if(gui_napon || gui_napcon) nap_logout();
	}
	gui_free();
}


void gui_free(void)
{
	gui_appicon(-1);
	if(gui->app) MUI_DisposeObject(gui->app);
	lamp_dispose();
	if(gui->url_mcc) MUI_DeleteCustomClass(gui->url_mcc);
	if(gui->msg_mcc) MUI_DeleteCustomClass(gui->msg_mcc);
	if(gui->info_mcc) MUI_DeleteCustomClass(gui->info_mcc);
	if(gui->about_mcc) MUI_DeleteCustomClass(gui->about_mcc);
	if(gui->prf_mcc) MUI_DeleteCustomClass(gui->prf_mcc);
	if(gui->dl_mcc) MUI_DeleteCustomClass(gui->dl_mcc);
	if(gui->share_mcc) MUI_DeleteCustomClass(gui->share_mcc);
	if(gui->search_mcc) MUI_DeleteCustomClass(gui->search_mcc);
	if(gui->panel_mcc) MUI_DeleteCustomClass(gui->panel_mcc);
	if(gui->chat_mcc) MUI_DeleteCustomClass(gui->chat_mcc);
	if(MUIMasterBase) CloseLibrary(MUIMasterBase);
}


int gui_setup(void)
{
	long winopen;
	u_long *aboutmenu,*muimenu,*helpmenu,*hidemenu,*quitmenu;
	u_long *openmenu,*savemenu,*saveasmenu;
	u_long *debugmenu,*dlmenu,*sharemenu,*usermenu,*chatmenu;
	u_long *muiprfmenu,*prfmenu,*saveprfmenu;
	u_long *rxexemenu;

	localize_array(nap_linktype);

	MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN);
	if (!MUIMasterBase) {
		printf(MSG_NO_LIBRARY,MUIMASTER_NAME,MUIMASTER_VMIN);
		return(0);
	}

	gui->url_mcc = MUI_CreateCustomClass(NULL,MUIC_Text,NULL,sizeof(struct urldata),url_dispatch);
	if(!gui->url_mcc) return(0);

	gui->panel_mcc = MUI_CreateCustomClass(NULL,MUIC_Group,NULL,sizeof(struct paneldata),panel_dispatch);
	if(!gui->panel_mcc) return(0);

	gui->search_mcc = MUI_CreateCustomClass(NULL,MUIC_Group,NULL,sizeof(struct searchdata),search_dispatch);
	if(!gui->search_mcc) return(0);

	gui->dl_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct dldata),dl_dispatch);
	if (!gui->dl_mcc) return(0);

	gui->share_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct shdata),share_dispatch);
	if (!gui->share_mcc) return(0);

	gui->prf_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct prfdata),prf_dispatch);
	if (!gui->prf_mcc) return(0);

	gui->info_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct infodata),info_dispatch);
	if (!gui->info_mcc) return(0);

	gui->about_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct aboutdata),about_dispatch);
	if (!gui->about_mcc) return(0);

	gui->msg_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct msgdata),msg_dispatch);
	if (!gui->msg_mcc) return(0);

	gui->chat_mcc = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,sizeof(struct chatdata),chat_dispatch);
	if (!gui->chat_mcc) return(0);

	if(!lamp_create()) return(0);

	gui->app = ApplicationObject,
		MUIA_Application_Title, "Amster",
		MUIA_Application_Version, "$VER: Amster "AMSTER_VERSION" ("AMSTER_DATE")",
		MUIA_Application_Description, MSG_CX_DESCRIPTION,
		MUIA_Application_Base, "AMSTER",
		MUIA_Application_Commands, &rexx_cmds,
		MUIA_Application_HelpFile, AMSTER_HELP,
		MUIA_Application_Menustrip, MenustripObject,
			Child, MenuObject,
				MUIA_Menu_Title, MSG_AMSTER_MENU,
				Child, aboutmenu = makemenu(MSG_AMSTER_ABOUT),
				Child, muimenu = makemenu(MSG_AMSTER_ABOUTMUI),
				Child, helpmenu = makemenu(MSG_AMSTER_HELP),
				Child, makemenu(NULL),
				Child, hidemenu = makemenu(MSG_AMSTER_HIDE),
				Child, quitmenu = makemenu(MSG_AMSTER_QUIT),
			End,
			Child, MenuObject,
				MUIA_Menu_Title, MSG_PROJECT_MENU,
				Child, openmenu = makemenu(MSG_PROJECT_OPEN),
				Child, savemenu = makemenu(MSG_PROJECT_SAVE),
				Child, saveasmenu = makemenu(MSG_PROJECT_SAVEAS),
			End,
			Child, MenuObject,
				MUIA_Menu_Title, MSG_WINDOWS_MENU,
				Child, debugmenu = makemenu(MSG_WINDOWS_DEBUG),
				Child, sharemenu = makemenu(MSG_WINDOWS_SHARE),
				Child, dlmenu = makemenu(MSG_WINDOWS_DOWNLOAD),
				Child, usermenu = makemenu(MSG_WINDOWS_USER),
				Child, chatmenu = makemenu(MSG_WINDOWS_CHAT),
			End,
			Child, MenuObject,
				MUIA_Menu_Title, MSG_SETTINGS_MENU,
				Child, gui->iconpanelmenu = maketmenu(MSG_SETTINGS_ICONPANEL),
				Child, makemenu(NULL),
				Child, muiprfmenu = makemenu(MSG_SETTINGS_MUI),
				Child, prfmenu = makemenu(MSG_SETTINGS_CONFIG),
				Child, makemenu(NULL),
				Child, saveprfmenu = makemenu(MSG_SETTINGS_SAVE),
			End,
			Child, MenuObject,
				MUIA_Menu_Title, MSG_AREXX_MENU,
				Child, rxexemenu = makemenu(MSG_AREXX_EXECUTE),
			End,
		End,

		SubWindow, gui->win = WindowObject,
		MUIA_Window_ID, MAKE_ID('M','A','I','N'),
		MUIA_Window_Title, "Amster v"AMSTER_VERSION,
		WindowContents, HGroup,
			Child, VGroup,
				Child, gui->searchpanel = NewObject(gui->search_mcc->mcc_Class,NULL,TAG_DONE),
				Child, RectangleObject,
					MUIA_FixHeight, 8,
					MUIA_Rectangle_HBar, TRUE,
				End,
				Child, HGroup,
					Child, gui->stat = TextObject,
						TextFrame,
						MUIA_Background, MUII_TextBack,
						MUIA_Text_PreParse, "\33c",
					End,
					Child, gui->lamp = LampObject,
						MUIA_Lamp_Type, MUIV_Lamp_Type_Huge,
						MUIA_Lamp_Color, MUIV_Lamp_Color_Off,
					End,
				End,
				Child, HGroup,
					Child, gui->inbut = SimpleButton(MSG_CONNECT_GAD),
					Child, gui->outbut = SimpleButton(MSG_DISCONNECT_GAD),
					Child, gui->rebut = SimpleButton(MSG_RECONNECT_GAD),
				End,
			End,
			Child, gui->rect = HGroup,
				Child, RectangleObject,
					MUIA_FixWidth, 4,
					MUIA_Rectangle_VBar, TRUE,
				End,
				Child, gui->iconpanel = NewObject(gui->panel_mcc->mcc_Class,NULL,TAG_DONE),
			End,
		End,
		End,

		SubWindow, gui->awin = NewObject(gui->about_mcc->mcc_Class,NULL,TAG_DONE),
		SubWindow, gui->swin = NewObject(gui->prf_mcc->mcc_Class,NULL,TAG_DONE),
		SubWindow, gui->iwin = NewObject(gui->info_mcc->mcc_Class,NULL,TAG_DONE),
		SubWindow, gui->dwin = NewObject(gui->dl_mcc->mcc_Class,NULL,TAG_DONE),
		SubWindow, gui->shwin = NewObject(gui->share_mcc->mcc_Class,NULL,TAG_DONE),
		SubWindow, gui->mwin = NewObject(gui->msg_mcc->mcc_Class,NULL,TAG_DONE),

	End;

	if (!gui->app) {
		printf(MSG_APP_ERROR);
		return(0);
	}

	DoMethod(gui->inbut,MUIM_Notify,MUIA_Pressed,FALSE,gui->app,3,MUIM_CallHook,&handleHook,0);
	DoMethod(gui->outbut,MUIM_Notify,MUIA_Pressed,FALSE,gui->app,3,MUIM_CallHook,&handleHook,1);
	DoMethod(gui->rebut,MUIM_Notify,MUIA_Pressed,FALSE,gui->app,3,MUIM_CallHook,&handleHook,2);

	DoMethod(gui->iconpanelmenu,MUIM_Notify,MUIA_Menuitem_Checked,MUIV_EveryTime,gui->app,3,MUIM_CallHook,&handleHook,50);

	DoMethod(aboutmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->awin,3,MUIM_Set,MUIA_Window_Open,TRUE);
	DoMethod(muimenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,2,MUIM_Application_AboutMUI,gui->win);
	DoMethod(helpmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,5,MUIM_Application_ShowHelp,gui->win,AMSTER_HELP,0,0);
	DoMethod(hidemenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,3,MUIM_Set,MUIA_Application_Iconified,TRUE);
	DoMethod(quitmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

	DoMethod(openmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->shwin,1,SHARE_LOADAS);
	DoMethod(savemenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->shwin,1,SHARE_SAVE);
	DoMethod(saveasmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->shwin,1,SHARE_SAVEAS);

	DoMethod(debugmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->iconpanel,1,PANEL_OPENDEBUG);
	DoMethod(dlmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->iconpanel,1,PANEL_OPENDL);
	DoMethod(sharemenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->iconpanel,1,PANEL_OPENSHARE);
	DoMethod(usermenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->iconpanel,1,PANEL_OPENMSG);
	DoMethod(chatmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->iconpanel,1,PANEL_NEWCHAT);

	DoMethod(muiprfmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,2,MUIM_Application_OpenConfigWindow,0);
	DoMethod(prfmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->iconpanel,1,PANEL_OPENPRF);
	DoMethod(saveprfmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->swin,1,PRF_SAVEALL);

	DoMethod(rxexemenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,3,MUIM_CallHook,&handleHook,31);

	DoMethod(gui->win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,gui->app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

	prf_load();

	if(prf->noiconpanel) {
		set(gui->iconpanelmenu,MUIA_Menuitem_Checked,FALSE);
		set(gui->rect,MUIA_ShowMe,FALSE);
	} else {
		set(gui->iconpanelmenu,MUIA_Menuitem_Checked,TRUE);
	}

	strcpy(sharepath,prf->dlpath);
	gui_appicon(0);
	gui_state(-2);
	set(gui->win,MUIA_Window_Open,TRUE);
	get(gui->win,MUIA_Window_Open,&winopen);
	if(!winopen) {
		printf(MSG_ERR_NOWINDOW);
		return(0);
	}

	if(!prf->user) DoMethod(gui->iconpanel,PANEL_OPENPRF);

	if(prf->user && prf->autocon) {
		nap_login();
		return(1);
	}

	set(gui->stat,MUIA_Text_Contents,MSG_STATUS2_NOTCONNECTED);
	return(1);
}


MUIF gui_handle(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) u_long *id)
{
	u_long tmp;

	switch(*id) {
		case 0:
			if(!gui_napon) nap_login();
			break;
		case 1:
			nap_logout();
			set(gui->stat,MUIA_Text_Contents,MSG_STATUS2_NOTCONNECTED);
			break;
		case 2:
			if(gui_napon) nap_logout();
			nap_login();
			break;
		case 31:
			{
			struct FileRequester *freq;
			freq = AllocAslRequestTags(ASL_FileRequest,TAG_DONE);
			if(!freq) break;
			tmp = AslRequestTags(freq,
			                     ASLFR_TitleText, MSG_SELECTRX_TITLE,
			                     ASLFR_DoSaveMode, TRUE,
			                    TAG_DONE);
			if(tmp) {
				static char buf[512];
				strcpy(buf,freq->fr_Drawer);
				AddPart(buf,freq->fr_File,511);
				rexx_execute(buf,NULL);
			}
			FreeAslRequest(freq);
			break;
			}
		case 50:
			GetAttr(MUIA_Menuitem_Checked,gui->iconpanelmenu,&tmp);
			if(tmp==TRUE)
				set(gui->rect,MUIA_ShowMe,TRUE);
			else
				set(gui->rect,MUIA_ShowMe,FALSE);
			break;
	}
	return(0);
}


void gui_state(int s)
{
	switch(s) {
		case -1:
			prf_event(PRFE_DISCONNECT);
		case -2:
			gui_napon = 0;
			gui_napcon = 0;
			set(gui->inbut,MUIA_Disabled,FALSE);
			set(gui->outbut,MUIA_Disabled,TRUE);
			set(gui->rebut,MUIA_Disabled,TRUE);
			set(gui->lamp,MUIA_Lamp_Color,MUIV_Lamp_Color_Off);
			DoMethod(gui->searchpanel,SEARCH_CLEAR,1);
			gui_appicon(2);
			break;
		case 0:
			gui_napcon = 1;
			set(gui->inbut,MUIA_Disabled,TRUE);
			set(gui->outbut,MUIA_Disabled,FALSE);
			set(gui->lamp,MUIA_Lamp_Color,MUIV_Lamp_Color_Connecting);
			set(gui->stat,MUIA_Text_Contents,MSG_STATUS2_CONNECTING);
			break;
		case 1:
			prf_event(PRFE_CONNECT);
			gui_napon = 1;
			gui_napcon = 0;
			set(gui->inbut,MUIA_Disabled,TRUE);
			set(gui->outbut,MUIA_Disabled,FALSE);
			set(gui->rebut,MUIA_Disabled,FALSE);
			set(gui->lamp,MUIA_Lamp_Color,MUIV_Lamp_Color_Ok);
			gui_appicon(1);
			break;
	}
}


void gui_srvstat(int a, int b, int c)
{
	gui_stat((char*)MSG_STATUS2_SONGSONLINE,b,a,c);
}


void gui_found(song s)
{
	DoMethod(gui->searchpanel,SEARCH_FOUND,s);
}


void localize_array(char *array[])
{
	char **x;

	for(x=array;*x;x++)
		*x = (char *)((struct FC_String *)(*x))->msg;
}


void gui_stat(char *msg, ...)
{
	static char buf[256];
	va_list ap;

	va_start(ap,msg);
	vsprintf(buf,msg,ap);
	va_end(ap);
	set(gui->stat,MUIA_Text_Contents,buf);
}


void gui_appicon(int t)
{
	static struct DiskObject *on, *off;

	switch(t) {
		case 0:
			on = GetDiskObject("PROGDIR:Icons/Amster_online");
			off = GetDiskObject("PROGDIR:Icons/Amster_offline");
			break;

		case -1:
			if(on) FreeDiskObject(on);
			if(off) FreeDiskObject(off);
			break;

		case 1:
			if(on) set(gui->app,MUIA_Application_DiskObject,on);
			break;

		case 2:
			if(off) set(gui->app,MUIA_Application_DiskObject,off);
			break;

	}
}
