/*
** Amster - Channel List
** Copyright © 2000-2001 by Jacob Laursen
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "amster.h"

#include <proto/dos.h>
#include <proto/utility.h>

#include <MUI/NListview_mcc.h>

#include "amster_Cat.h"

/* Private prototypes */

MUI_LIST_DISP_DECL(ChannelListDisplay, struct ChannelEntry *entry);
MUI_NLIST_COMP_DECL(ChannelListCompare);
MUI_LIST_DEST_DECL(ChannelListDestruct, struct ChannelEntry *entry);


MUI_DISPATCH(ChannelListDispatch)
{
	struct ChannelListData *data;

	switch (msg->MethodID) {
		case OM_NEW:
			return(ChannelListNew(cl, obj, (APTR)msg));
		case CHANLIST_UPDATE:
			{
			u_long item;
			data = INST_DATA(cl, obj);

			set(data->LV_Channel, MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
			while (1) {
				DoMethod(data->LV_Channel, MUIM_NList_GetEntry, 0, &item);
				if (!item) break;
				DoMethod(data->LV_Channel, MUIM_NList_Remove, MUIV_NList_Remove_First);
			}
			set(data->LV_Channel, MUIA_NList_Quiet, MUIV_NList_Quiet_None);
			nap_sendbuf(NAPC_LIST_CHANNELS, "");
			break;
			}
		case CHANLIST_JOIN:
			{
/*			  channel c = NULL;*/
			struct ChannelEntry *entry;
			Object *win;
			data = INST_DATA(cl, obj);

			DoMethod(data->LV_Channel, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
			if (entry) {
/*				if (chat_chans->name) c = chat_findchan(entry->Name);
				if (!c) {*/
#ifdef AMSTER_DEBUG
gui_debug("join it!");
#endif
					win = NewObject(gui->chat_mcc->mcc_Class, NULL, TAG_DONE);
					if (!win) return NULL;
					DoMethod(gui->app, OM_ADDMEMBER, win);
					set(win, MUIA_Window_Open, TRUE);
					DoMethod(win, CHAT_JOINCHANNEL, entry->Name);
/*				}
				else {
#ifdef AMSTER_DEBUG
gui_debug("already joined");
#endif
				}*/
			}
			return NULL;
			}
		case CHANLIST_ENTRY:
			{
			struct ChannelEntry *entry;
			data = INST_DATA(cl, obj);

			if (entry = malloc(sizeof(struct ChannelEntry))) {
				entry->Name = strdup((char *)(((muimsg)msg)->arg1));
				entry->NumUsers = (int)(((muimsg)msg)->arg2);
				entry->Topic = strdup((char *)(((muimsg)msg)->arg3));
				DoMethod(data->LV_Channel, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
			}
			break;
			}
	}
	return(DoSuperMethodA(cl, obj, msg));
}


ULONG ChannelListNew(struct IClass *cl, Object *obj, struct opSet *msg)
{
	static const struct Hook ChannelListDispHook = { {NULL, NULL}, &ChannelListDisplay,  NULL, NULL };
	static const struct Hook ChannelListCompHook = { {NULL, NULL}, &ChannelListCompare,  NULL, NULL };
	static const struct Hook ChannelListDestHook = { {NULL, NULL}, &ChannelListDestruct, NULL, NULL };

	struct ChannelListData *data;

	Object *LV_Channel;
	Object *BT_Update, *BT_Join;

	if (obj = (Object *)DoSuperNew(cl, obj,
		MUIA_HelpNode, "channellist",
		MUIA_Window_Title, MSG_CHANNELLIST_TITLE,
		MUIA_Window_ID, MAKE_ID('C','H','L','S'),
		WindowContents, VGroup,
			Child, LV_Channel = NListviewObject,
				MUIA_NList_Input, TRUE,
				MUIA_NListview_NList, NListObject,
					InputListFrame,
					MUIA_NList_ListBackground, MUII_ListBack,
					MUIA_NList_Title, TRUE,
					MUIA_NList_Format, "BAR,BAR,",
					MUIA_NList_DisplayHook, &ChannelListDispHook,
					MUIA_NList_CompareHook2, &ChannelListCompHook,
					MUIA_NList_DestructHook, &ChannelListDestHook,
				End,
			End,
			Child, HGroup,
				Child, BT_Join   = SimpleButton(MSG_CHANNELLIST_JOIN_GAD),
				Child, BT_Update = SimpleButton(MSG_CHANNELLIST_UPDATE_GAD),
			End,
		End,
		TAG_MORE, msg->ops_AttrList))
	{
		data = INST_DATA(cl, obj);
		data->LV_Channel  = LV_Channel;

		DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, obj, 3, MUIM_Set, MUIA_Window_Open, FALSE);

		DoMethod(BT_Update, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, CHANLIST_UPDATE);
		DoMethod(BT_Join,   MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, CHANLIST_JOIN);

		DoMethod(LV_Channel, MUIM_Notify, MUIA_NList_TitleClick,  MUIV_EveryTime, LV_Channel, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);
		DoMethod(LV_Channel, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, LV_Channel, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2);
		DoMethod(LV_Channel, MUIM_Notify, MUIA_NList_SortType,    MUIV_EveryTime, LV_Channel, 3, MUIM_Set, MUIA_NList_TitleMark,  MUIV_TriggerValue);
		DoMethod(LV_Channel, MUIM_Notify, MUIA_NList_SortType2,   MUIV_EveryTime, LV_Channel, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue);

		return((ULONG)obj);
	}
	return NULL;
}


MUI_LIST_DISP(ChannelListDisplay, struct ChannelEntry *entry)
{
	static char users[5];

	if (entry) {
		*array++ = entry->Name;
		sprintf(users, "%d", entry->NumUsers);
		*array++ = users;
		*array = entry->Topic;
	}
	else {
		*array++ = (char *)MSG_CHANNELLIST_NAME;
		*array++ = (char *)MSG_CHANNELLIST_USERS;
		*array   = (char *)MSG_CHANNELLIST_TOPIC;
	}

	return NULL;
}


MUI_NLIST_COMP(ChannelListCompare)
{
	struct ChannelEntry *entry1 = ncm->entry1;
	struct ChannelEntry *entry2 = ncm->entry2;
	LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask;
	LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask;
	ULONG result = 0;

	if (ncm->sort_type == MUIV_NList_SortType_None) return (0);

	if (col1 == 0) {
		if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
			result = (LONG) stricmp(entry2->Name, entry1->Name);
		else
			result = (LONG) stricmp(entry1->Name, entry2->Name);
	}
	else if (col1 == 1) {
		if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
			result = entry2->NumUsers - entry1->NumUsers;
		else
			result = entry1->NumUsers - entry2->NumUsers;
	}
	else if (col1 == 2) {
		if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
			result = (LONG) stricmp(entry2->Topic, entry1->Topic);
		else
			result = (LONG) stricmp(entry1->Topic, entry2->Topic);
	}

	if ((result != 0) || (col1 == col2)) return (result);

	if (col2 == 0) {
		if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
			result = (LONG) stricmp(entry2->Name, entry1->Name);
		else
			result = (LONG) stricmp(entry1->Name, entry2->Name);
	}
	else if (col2 == 1) {
		if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
			result = entry2->NumUsers - entry1->NumUsers;
		else
			result = entry1->NumUsers - entry2->NumUsers;
	}
	else if (col2 == 2) {
		if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
			result = (LONG) stricmp(entry2->Topic, entry1->Topic);
		else
			result = (LONG) stricmp(entry1->Topic, entry2->Topic);
	}

	return (result);
}


MUI_LIST_DEST(ChannelListDestruct, struct ChannelEntry *entry)
{
	free(entry);
	return NULL;
}
