/*
** Chat Window
*/

#include "include/config.h"

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

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

#include "include/gui.h"
#include "include/msg.h"
#include "include/chat.h"
#include "include/panel.h"
#include "include/napster.h"
#include "amster_Cat.h"

channel chat_chans = NULL;

ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg);
MUIF chat_msgdisp(REG(a2) char **array, REG(a1) struct chatmsg *m);
void chat_say(struct chatdata *data, char *user, char *msg);
void chat_saysys(struct chatdata *data, char *msg);
void chat_echo(struct chatdata *data, char *msg);
void chat_command(struct chatdata *data);
channel chat_findchan(char *name);


MUIF chat_dispatch(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
{
	struct chatdata *data = INST_DATA(cl,obj);

	switch(msg->MethodID) {
		case OM_NEW: return(chat_new(cl,obj,(APTR)msg));
		case CHAT_COMMAND:
			chat_command(data);
			return(0);
		case CHAT_JOINACK:
			data->chn.joinflag = 2;
			chat_saysys(data,"joined.");
			return(0);
		case CHAT_PUBLICMSGRECV:
			chat_say(data,(char *)(((muimsg)msg)->arg1),(char *)(((muimsg)msg)->arg2));
			return(0);
		case CHAT_JOINMSG:
			DoMethod(data->userlist,MUIM_NList_InsertSingle,(char *)(((muimsg)msg)->arg1),MUIV_NList_Insert_Bottom);
			return(0);
		case CHAT_USERPART:
			/* fix me */
			return(0);
		case CHAT_CHANNELTOPIC:
			set(data->topicstr,MUIA_String_Contents,((muimsg)msg)->arg1);
			return(0);

	}
	return(DoSuperMethodA(cl,obj,msg));
}


ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg)
{
	static struct Hook msgdispHook = { {0,0}, &chat_msgdisp, NULL, NULL };
	struct chatdata *data;
	Object *rect,*chantxt,*topicstr,*msglist,*userlist,*msgstr;

	obj = (Object *)DoSuperNew(cl,obj,
		MUIA_Window_Title, "Amster Chat",
		MUIA_Window_ID, MAKE_ID('C','H','A','T'),
		WindowContents, VGroup,
			Child, rect = HGroup,
				Child, chantxt = TextObject,
					MUIA_HorizWeight, 0,
					MUIA_Text_Contents, "#none",
				End,
				Child, topicstr = StringObject,
					StringFrame,
					MUIA_CycleChain, 1,
				End,
			End,
			Child, HGroup,
				Child, NListviewObject,
					MUIA_HorizWeight, 75,
					MUIA_NListview_NList, msglist = NListObject,
						ReadListFrame,
						MUIA_NList_Input, FALSE,
						MUIA_NList_Format, "BAR P=\33r,",
						MUIA_NList_DisplayHook, &msgdispHook,
						MUIA_NList_DefaultObjectOnClick, FALSE,
						MUIA_NList_AutoVisible, TRUE,
						MUIA_NList_AutoCopyToClip, TRUE,
						MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
					End,
				End,
				Child, BalanceObject, End,
				Child, NListviewObject,
					MUIA_HorizWeight, 25,
					MUIA_NListview_NList, userlist = NListObject,
						InputListFrame,
						MUIA_NList_DefaultObjectOnClick, FALSE,
						MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
						MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
						MUIA_CycleChain, 1,
					End,
				End,
			End,
			Child, msgstr = StringObject,
				StringFrame,
				MUIA_CycleChain, 1,
			End,
		End,
		TAG_MORE, msg->ops_AttrList);

	if(!obj) return(0);

	data = INST_DATA(cl,obj);
	data->rect = rect;
	data->chantxt = chantxt;
	data->topicstr = topicstr;
	data->msglist = msglist;
	data->userlist = userlist;
	data->msgstr = msgstr;

	data->chn.next = chat_chans;
	chat_chans = &data->chn;
	data->chn.joinflag = 0;
	data->chn.name = NULL;
	data->chn.win = obj;

	DoMethod(msgstr,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,obj,1,CHAT_COMMAND);
	DoMethod(msgstr,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,obj,3,MUIM_Set,MUIA_Window_ActiveObject,msgstr);

	DoMethod(obj,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,MUIV_Notify_Application,5,MUIM_Application_PushMethod,gui->iconpanel,2,PANEL_DISPOSECHAT,obj);

	return((ULONG)obj);
}


MUIF chat_msgdisp(REG(a2) char **array, REG(a1) struct chatmsg *m)
{
	*array++ = m->user;
	*array = m->msg;
	return(0);
}


void chat_say(struct chatdata *data, char *user, char *msg)
{
	struct chatmsg *m;

	m = malloc(sizeof(struct chatmsg));
	if (!m) return;

	m->user = strdup(user);
	m->msg = strdup(msg);

	DoMethod(data->msglist,MUIM_NList_InsertSingleWrap,m,MUIV_NList_Insert_Bottom,2,NULL);
	set(data->msglist,MUIA_NList_First,MUIV_NList_Active_Bottom);
}


void chat_saysys(struct chatdata *data, char *msg)
{
	chat_say(data,"\33b***",msg);
}


void chat_echo(struct chatdata *data, char *msg)
{
	chat_say(data,"\33b»",msg);
}


void chat_command(struct chatdata *data)
{
	u_long tmp;
	char *com;

	GetAttr(MUIA_String_Acknowledge,data->msgstr,&tmp);
	com = (char *)tmp;

	if(!gui_napon) {
		chat_saysys(data,"connect to server first!");

	} else if(com[0]=='/') {
		if(strnicmp("join",com+1,4)==0 && strlen(com)>6) {
			data->chn.name = strdup(com+6);
			nap_sendbuf(NAPC_CHANNELJOIN,data->chn.name);
			data->chn.joinflag = 1;
			chat_saysys(data,"joining...");
		}

	} else {
		if(data->chn.joinflag==2) {
			chat_echo(data,com);
			sprintf(nap_buf,"%s %s",data->chn.name,com);
			nap_send(NAPC_PUBLICMSGSEND);
		} else {
			chat_saysys(data,"not joined!");
		}
	}

	set(data->msgstr,MUIA_String_Contents,NULL);
}


void chat_interpret(u_int com, char *data)
{
	channel c;

	switch(com) {
		case NAPC_PUBLICMSGRECV:
			c = chat_findchan(nap_token(&data));
			if(!c) break;
			DoMethod(c->win,CHAT_PUBLICMSGRECV,nap_token(&data),data);
			break;
		case NAPC_JOINACK:
			c = chat_findchan(data);
			if(!c) break;
			DoMethod(c->win,CHAT_JOINACK);
			break;
		case NAPC_USERPART:
			c = chat_findchan(nap_token(&data));
			if(!c) break;
			DoMethod(c->win,CHAT_USERPART,nap_token(&data));
			break;
		case NAPC_JOINMSG:
		case NAPC_USERLIST:
			c = chat_findchan(nap_token(&data));
			if(!c) break;
			DoMethod(c->win,CHAT_JOINMSG,nap_token(&data));
			break;
/*		case NAPC_USERLISTEND:
			break; */
		case NAPC_CHANNELTOPIC:
			c = chat_findchan(nap_token(&data));
			if(!c) break;
			DoMethod(c->win,CHAT_CHANNELTOPIC,data);
			break;

	}
}


channel chat_findchan(char *name)
{
	channel c = chat_chans;

	while(c) {
		if(stricmp(c->name,name)==0) return(c);
		c = c->next;
	}
	return(0);
}
