/*
** GUI Functions
*/

#include "config.h"

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

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

#include "gui.h"
#include "amsterlogo.h"
#include "infowinicon.h"
#include "msgwinicon.h"
#include "chatwinicon.h"
#include "napster.h"
#include "download.h"
#include "prefs.h"
#include "info.h"
#include "msg.h"

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

void prf_save(void);
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_clrall(void);

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()) {
		while(DoMethod(gui->app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit) {
			if (sigs) {
				sigs = Wait(sigs|SIGBREAKF_CTRL_C|tcpsig);
				if (sigs&SIGBREAKF_CTRL_C)
					break;
				if (sigs&tcpsig) {
					if(nap_listen()) gui_napon=0;
				}
			}
		}
		if(gui_napon) nap_logout();
	}
	gui_free();
}


void gui_free(void)
{
	if (gui->app) MUI_DisposeObject(gui->app);
	if (gui->redlamp) MUI_DisposeObject(gui->redlamp);
	if (gui->greenlamp) MUI_DisposeObject(gui->greenlamp);
	if (gui->yellowlamp) MUI_DisposeObject(gui->yellowlamp);
	if (gui->msg_mcc) MUI_DeleteCustomClass(gui->msg_mcc);
	if (gui->info_mcc) MUI_DeleteCustomClass(gui->info_mcc);
	if (gui->prf_mcc) MUI_DeleteCustomClass(gui->prf_mcc);
	if (gui->dl_mcc) MUI_DeleteCustomClass(gui->dl_mcc);
	if (MUIMasterBase!=0) CloseLibrary(MUIMasterBase);
}


MUIF songlistdisp(REG(a2) char **array, REG(a1) songdata sd)
{
	static char buf[50],buf2[50];

	if (sd) {
		if(sd->link < 5)
			*array++ = "\33c\33o[1]";
		else if(sd->link < 8)
			*array++ = "\33c\33o[2]";
		else
			*array++ = "\33c\33o[3]";
		*array++ = sd->title;
		sprintf(buf,"\33c%d/%d",sd->bitrate,sd->freq);
		*array++ = buf;
		sprintf(buf2,"\33r%ld",sd->size);
		*array++ = buf2;
		*array++ = sd->user;
		*array = nap_getlinktype(sd->link);
	} else {
		*array++ = "\33c@";
		*array++ = "\33cSong";
		*array++ = "\33ckbps/kHz";
		*array++ = "\33cSize";
		*array++ = "\33cUser";
		*array = "\33cLink";
	}
	return(0);
}


int gui_setup(void)
{
	static struct Hook songlistdispHook = { {0,0}, &songlistdisp, NULL, NULL };

	MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN);
	if (!MUIMasterBase) {
		printf("Cannot open "MUIMASTER_NAME" V%d!\n",MUIMASTER_VMIN);
		return(0);
	}

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

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

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

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

	gui->app = ApplicationObject,
		MUIA_Application_Title, "Amster",
		MUIA_Application_Version, "$VER: Amster "AMSTER_VERSION" ("AMSTER_DATE")",
		MUIA_Application_Description, "Naspter Client",
		MUIA_Application_Base, "AMSTER",
		MUIA_Application_Menustrip, MenustripObject,
			Child, MenuObject,
				MUIA_Menu_Title, "Amster",
				Child, gui->muimenu = MenuitemObject,
					MUIA_Menuitem_Title, "About MUI...",
				End,
				Child, gui->muisetmenu = MenuitemObject,
					MUIA_Menuitem_Title, "MUI Settings...",
				End,
				Child, gui->quitmenu = MenuitemObject,
					MUIA_Menuitem_Title, "Quit",
				End,
			End,
		End,


		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->mwin = NewObject(gui->msg_mcc->mcc_Class,NULL,TAG_DONE),


		SubWindow, gui->win = WindowObject,
		MUIA_Window_ID, MAKE_ID('M','A','I','N'),
		MUIA_Window_Title, "Amster v"AMSTER_VERSION" ("AMSTER_DATE")",
		MUIA_Window_ScreenTitle, "Amster v"AMSTER_VERSION" - Copyright (c) 1999 Gürer"
					" Özen, released under GPL.",
		WindowContents, VGroup,
			Child, HGroup,
				Child, BodychunkObject,
					TextFrame,
					MUIA_Background, MUII_BACKGROUND,
					MUIA_FixWidth, AMSTERLOGO_WIDTH,
					MUIA_FixHeight, AMSTERLOGO_HEIGHT,
					MUIA_Bitmap_Width, AMSTERLOGO_WIDTH,
					MUIA_Bitmap_Height, AMSTERLOGO_HEIGHT,
					MUIA_Bodychunk_Depth, AMSTERLOGO_DEPTH,
					MUIA_Bodychunk_Body, (ULONG *)AMSTERLOGO_BODY,
					MUIA_Bodychunk_Compression, AMSTERLOGO_COMPRESSION,
					MUIA_Bodychunk_Masking, AMSTERLOGO_MASKING,
					MUIA_Bitmap_SourceColors, (ULONG *)AMSTERLOGO_COLORS,
				End,
				Child, HSpace(0),
				Child, gui->infoicon = BodychunkObject,
					ImageButtonFrame,
					MUIA_Background, MUII_ButtonBack,
					MUIA_FixWidth, INFOWINICON_WIDTH,
					MUIA_FixHeight, INFOWINICON_HEIGHT,
					MUIA_Bitmap_Width, INFOWINICON_WIDTH,
					MUIA_Bitmap_Height, INFOWINICON_HEIGHT,
					MUIA_Bodychunk_Depth, INFOWINICON_DEPTH,
					MUIA_Bodychunk_Body, (ULONG *)INFOWINICON_BODY,
					MUIA_Bodychunk_Compression, INFOWINICON_COMPRESSION,
					MUIA_Bodychunk_Masking, INFOWINICON_MASKING,
					MUIA_Bitmap_SourceColors, (ULONG *)INFOWINICON_COLORS,
					MUIA_Bitmap_Transparent, 0,
					MUIA_InputMode, MUIV_InputMode_RelVerify,
				End,
				Child, HSpace(0),
				Child, gui->msgicon = BodychunkObject,
					ImageButtonFrame,
					MUIA_Background, MUII_ButtonBack,
					MUIA_FixWidth, MSGWINICON_WIDTH,
					MUIA_FixHeight, MSGWINICON_HEIGHT,
					MUIA_Bitmap_Width, MSGWINICON_WIDTH,
					MUIA_Bitmap_Height, MSGWINICON_HEIGHT,
					MUIA_Bodychunk_Depth, MSGWINICON_DEPTH,
					MUIA_Bodychunk_Body, (ULONG *)MSGWINICON_BODY,
					MUIA_Bodychunk_Compression, MSGWINICON_COMPRESSION,
					MUIA_Bodychunk_Masking, MSGWINICON_MASKING,
					MUIA_Bitmap_SourceColors, (ULONG *)MSGWINICON_COLORS,
					MUIA_Bitmap_Transparent, 0,
					MUIA_InputMode, MUIV_InputMode_RelVerify,
				End,
				Child, HSpace(0),
				Child, gui->chaticon = BodychunkObject,
					ImageButtonFrame,
					MUIA_Background, MUII_ButtonBack,
					MUIA_FixWidth, CHATWINICON_WIDTH,
					MUIA_FixHeight, CHATWINICON_HEIGHT,
					MUIA_Bitmap_Width, CHATWINICON_WIDTH,
					MUIA_Bitmap_Height, CHATWINICON_HEIGHT,
					MUIA_Bodychunk_Depth, CHATWINICON_DEPTH,
					MUIA_Bodychunk_Body, (ULONG *)CHATWINICON_BODY,
					MUIA_Bodychunk_Compression, CHATWINICON_COMPRESSION,
					MUIA_Bodychunk_Masking, CHATWINICON_MASKING,
					MUIA_Bitmap_SourceColors, (ULONG *)CHATWINICON_COLORS,
					MUIA_Bitmap_Transparent, 0,
					MUIA_InputMode, MUIV_InputMode_RelVerify,
					MUIA_Disabled, TRUE,
				End,
				Child, HSpace(0),
			End,
			Child, HGroup,
				Child, gui->inbut = SimpleButton("_Connect"),
				Child, gui->outbut = SimpleButton("_Disconnect"),
				Child, gui->setbut = SimpleButton("_Settings..."),
			End,
			Child, RectangleObject,
				MUIA_FixHeight, 8,
				MUIA_Rectangle_HBar, TRUE,
			End,
			Child, HGroup,
				Child, Label2("Search"),
				Child, gui->str = StringObject,
					StringFrame,
					MUIA_HorizWeight, 400,
					MUIA_String_MaxLen, 80,
					MUIA_CycleChain, 1,
				End,
				Child, Label2("Max"),
				Child, gui->maxstr = StringObject,
					StringFrame,
					MUIA_String_Accept, "0123456789",
					MUIA_String_Integer, 15,
					MUIA_String_MaxLen, 4,
					MUIA_CycleChain, 1,
				End,
			End,
			Child, HGroup,
				Child, Label("Result:"),
				Child, gui->sstat = TextObject, End,
			End,
			Child, NListviewObject,
				MUIA_NListview_NList, gui->songlist = NListObject,
					InputListFrame,
					MUIA_NList_Title, TRUE,
					MUIA_NList_Format, "BAR, BAR, BAR, BAR, BAR, BAR",
					MUIA_NList_DisplayHook, &songlistdispHook,
					MUIA_CycleChain, 1,
				End,
			End,
			Child, HGroup,
				Child, gui->rembut = SimpleButton("Cl_ear"),
				Child, gui->clrbut = SimpleButton("Clear _All"),
				Child, gui->dlbut = SimpleButton("Do_wnload"),
			End,
			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,
		End,
		End,

	End;

	if (!gui->app) {
		printf("Cannot create mui app!\n");
		return(0);
	}

	gui->redlamp = LampObject,
		MUIA_Lamp_Type, MUIV_Lamp_Type_Big,
		MUIA_Lamp_Red, 0xffffffff,
		MUIA_Lamp_Green, 0x00000000,
		MUIA_Lamp_Blue, 0x00000000,
	End;
	gui->greenlamp = LampObject,
		MUIA_Lamp_Type, MUIV_Lamp_Type_Big,
		MUIA_Lamp_Red, 0x00000000,
		MUIA_Lamp_Green, 0xffffffff,
		MUIA_Lamp_Blue, 0x00000000,
	End;
	gui->yellowlamp = LampObject,
		MUIA_Lamp_Type, MUIV_Lamp_Type_Big,
		MUIA_Lamp_Red, 0xffffffff,
		MUIA_Lamp_Green, 0xffffffff,
		MUIA_Lamp_Blue, 0x00000000,
	End;
	if(!gui->redlamp || !gui->greenlamp || !gui->yellowlamp) {
		printf("Cannot create lamp objects!\n");
		return(0);
	}
	DoMethod(gui->songlist,MUIM_NList_UseImage,gui->redlamp,1,0);
	DoMethod(gui->songlist,MUIM_NList_UseImage,gui->yellowlamp,2,0);
	DoMethod(gui->songlist,MUIM_NList_UseImage,gui->greenlamp,3,0);

	DoMethod(gui->infoicon,MUIM_Notify,MUIA_Pressed,FALSE,gui->iwin,1,INFO_OPEN);
	DoMethod(gui->msgicon,MUIM_Notify,MUIA_Pressed,FALSE,gui->mwin,1,MSG_OPEN);

	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->setbut,MUIM_Notify,MUIA_Pressed,FALSE,gui->swin,1,PRF_OPEN);
	DoMethod(gui->str,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,gui->app,3,MUIM_CallHook,&handleHook,10);
	DoMethod(gui->rembut,MUIM_Notify,MUIA_Pressed,FALSE,gui->app,3,MUIM_CallHook,&handleHook,30);
	DoMethod(gui->clrbut,MUIM_Notify,MUIA_Pressed,FALSE,gui->app,3,MUIM_CallHook,&handleHook,31);
	DoMethod(gui->dlbut,MUIM_Notify,MUIA_Pressed,FALSE,gui->app,3,MUIM_CallHook,&handleHook,42);

	DoMethod(gui->muimenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,2,MUIM_Application_AboutMUI,gui->win);
	DoMethod(gui->muisetmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,2,MUIM_Application_OpenConfigWindow,0);
	DoMethod(gui->quitmenu,MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,gui->app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
	DoMethod(gui->win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,gui->app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

	gui_state(0);

	set(gui->win,MUIA_Window_Open,TRUE);

	return(1);
}


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

	switch(*id) {
		case 0:
			if(gui_napon) break;
			set(gui->inbut,MUIA_Disabled,TRUE);
			set(gui->lamp,MUIA_Lamp_Color,MUIV_Lamp_Color_Connecting);
			set(gui->stat,MUIA_Text_Contents,"Connecting...");
			if(nap_login()) gui_napon=1; else gui_state(0);
			break;
		case 1:
			if(gui_napon) nap_logout();
			gui_napon=0;
			break;
		case 10:
			if(!gui_napon) break;
			GetAttr(MUIA_String_Acknowledge,gui->str,&tmp);
			GetAttr(MUIA_String_Integer,gui->maxstr,&tmp2);
			if(tmp2<3) tmp2=3;
			if(tmp2>100) tmp2=100;
			if(tmp) {
				gui_sfcount=0;
				if(pref_clrlist) gui_clrall();
				nap_search((char *)tmp,tmp2);
				gui_searchstat(1);
			}
			break;
		case 30:
			DoMethod(gui->songlist,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&tmp);
			if(tmp) {
				DoMethod(gui->songlist,MUIM_NList_Remove,MUIV_NList_Remove_Active);
				free((songdata)tmp);
			}
			break;
		case 31:
			gui_clrall();
			break;
		case 42:
			if(!gui_napon) break;
			DoMethod(gui->songlist,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&tmp);
			if(tmp) nap_request((songdata)tmp);
			break;
		case 99:
			if (dl_flush() && !gui_napon) nap_logout();
			break;
	}
	return(0);
}


void gui_clrall(void)
{
	u_long tmp;
	set(gui->songlist,MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
	while(1) {
		DoMethod(gui->songlist,MUIM_NList_GetEntry,0,&tmp);
		if(!tmp) break;
		DoMethod(gui->songlist,MUIM_NList_Remove,MUIV_NList_Remove_First);
		free((songdata)tmp);
	}
	set(gui->songlist,MUIA_NList_Quiet, MUIV_NList_Quiet_None);
}


void gui_state(int s)
{
	switch(s) {
		case 0:
			set(gui->inbut,MUIA_Disabled,FALSE);
			set(gui->outbut,MUIA_Disabled,TRUE);
			set(gui->lamp,MUIA_Lamp_Color,MUIV_Lamp_Color_Off);
			gui_clrall();
			set(gui->stat,MUIA_Text_Contents,"Not connected to a server.");
			gui_searchstat(0);
			break;
		case 1:
			set(gui->inbut,MUIA_Disabled,TRUE);
			set(gui->outbut,MUIA_Disabled,FALSE);
			set(gui->lamp,MUIA_Lamp_Color,MUIV_Lamp_Color_Ok);
			break;
	}
}


void gui_foundsong(songdata song)
{
	DoMethod(gui->songlist,MUIM_NList_InsertSingle,song,MUIV_NList_Insert_Bottom);
	gui_sfcount++;
}


void gui_searchstat(int f)
{
	static char buf[80];

	switch(f) {
		case 0:
			set(gui->sstat,MUIA_Text_Contents,"");
			break;
		case 1:
			set(gui->sstat,MUIA_Text_Contents,"searching...");
			break;
		case 2:
			if(gui_sfcount==0) {
				set(gui->sstat,MUIA_Text_Contents,"No files found.");
			} else {
				sprintf(buf,"%d files found.",gui_sfcount);
				set(gui->sstat,MUIA_Text_Contents,buf);
			}
			break;
	}
}


void gui_srvstat(int a, int b, int c)
{
	static char buf[100];
	sprintf(buf,"%d songs in %d libraries (%d gb)",b,a,c);
	set(gui->stat,MUIA_Text_Contents,buf);
}
