/*
 * MultiMail offline mail reader
 * area list

 Copyright (c) 1996 Kolossvary Tamas <thomas@vma.bme.hu>
 Copyright (c) 1999 William McBrine <wmcbrine@clark.net>

 Distributed under the GNU General Public License.
 For details, see the file COPYING in the parent directory. */

#include "interfac.h"

//**************        LittleAreaListWindow    *****************

void LittleAreaListWindow::MakeActive()
{
	position = active = 0;
	areanum = -1;

	disp = 0;
	do
		mm.areaList->gotoActive(disp++);
	while (mm.areaList->isCollection());
	disp--;

	list_max_y = (NumOfItems() < LINES - 10) ? NumOfItems() : LINES - 10;
	list_max_x = 52;
	top_offset = 3;

	borderCol = C_LALBTEXT;

	list = new InfoWin(list_max_y + 4, 54, 3, borderCol, 0, 0, 4,
		top_offset);

	mm.areaList->gotoArea(mm.letterList->getAreaID());
	active = mm.areaList->getActive() - disp;

	list->put(1, 2, "Reply goes to area:");

	DrawAll();

	Select();
}

void LittleAreaListWindow::Select()
{
	mm.areaList->gotoActive(active + disp);
}

void LittleAreaListWindow::Delete()
{
	delete list;
}

int LittleAreaListWindow::getArea()
{
	return areanum;
}

int LittleAreaListWindow::NumOfItems()
{
	return mm.areaList->noOfActive() - disp;
}

void LittleAreaListWindow::oneLine(int i)
{
	mm.areaList->gotoActive(position + i + disp);
	sprintf(list->lineBuf, "%c%-50.50s ", (!mm.areaList->isShortlist()
		&& (mm.areaList->getType() & ACTIVE)) ? '*' : ' ',
		mm.areaList->getDescription());
	areaconv_in(list->lineBuf);
	DrawOne(i, C_LALLINES);
}

searchret LittleAreaListWindow::oneSearch(int x, const char *item,
	int ignore)
{
	ignore = ignore;
	mm.areaList->gotoActive(x + disp);
	return searchstr(mm.areaList->getDescription(), item) ? True : False;
}

bool LittleAreaListWindow::extrakeys(int key)
{
	switch (key) {
	case MM_ENTER:
		Select();
		areanum = mm.areaList->getAreaNo();
		break;
	case 'L':
		interface->areas.Select();
		interface->areas.KeyHandle('L');
	}
	return false;
}

//*************         AreaListWindow          ******************

void AreaListWindow::FirstUnread()
{
	int i;

	position = active = 0;
	for (i = 0; i < NumOfItems(); i++) {
		mm.areaList->gotoActive(i);
		if (!mm.areaList->getNoOfUnread())
			Move(DOWN);
		else
			break;
	}
	if (i == NumOfItems()) {
		position = active = 0;
		for (i = 0; i < NumOfItems(); i++) {
			mm.areaList->gotoActive(i);
			if (!mm.areaList->getNoOfLetters())
				Move(DOWN);
			else
				break;
		}
	}
}

int AreaListWindow::NumOfItems()
{
	return mm.areaList->noOfActive();
}

void AreaListWindow::oneLine(int i)
{
	char *p = list->lineBuf;

	mm.areaList->gotoActive(position + i);

	int attrib = mm.areaList->getType();

	if (position + i == active) {
		p += sprintf(p, "%.20s", mm.areaList->getAreaType());

		if (mm.areaList->isNetmail())
			p += sprintf(p, ", Netmail");
		else
			if (mm.areaList->isInternet())
				p += sprintf(p, ", Email");
			else
				if (mm.areaList->isUsenet())
					p += sprintf(p, ", Usenet");
				else
					if (attrib & ECHO)
						p += sprintf(p, ", Echo");

		if (attrib & PERSONLY)
			p += sprintf(p, ", Pers");
		else
			if (attrib & PERSALL)
				p += sprintf(p, ", Pers+All");

		int q = 27 - (p - list->lineBuf);
		while (--q > 0)
			sprintf(p++, " ");
		p = list->lineBuf;

		list->attrib(C_ALINFOTEXT2);
		list->put(list_max_y + 4, 8, p);

		sprintf(p, format2, mm.areaList->getDescription());
		areaconv_in(p);
		list->put(list_max_y + 5, 20, p);

		list->delay_update();
	}
	p += sprintf(p, format, ((attrib & ADDED) ? '+' :
		((attrib & DROPPED) ? '-' : ((attrib & ACTIVE) &&
		!mm.areaList->isShortlist()) ? '*' : ' ')),
		mm.areaList->getShortName(), mm.areaList->getDescription());

	if (mm.areaList->getNoOfLetters())
		p += sprintf(p, "  %5d  ", mm.areaList->getNoOfLetters());
	else
		p += sprintf(p, "      .  ");

	if (mm.areaList->getNoOfUnread())
		p += sprintf(p, "  %5d   ", mm.areaList->getNoOfUnread());
	else
		p += sprintf(p, "      .   ");

	if (mode)
		if (mm.areaList->getNoOfPersonal())
			sprintf(p, "   %5d   ",
				mm.areaList->getNoOfPersonal());
		else
			sprintf(p, "       .   ");

	chtype ch = (attrib & (REPLYAREA | ADDED | DROPPED)) ?
		C_ALREPLINE : C_ALPACKETLINE;

	areaconv_in(list->lineBuf);
	DrawOne(i, mm.areaList->getNoOfUnread() ? emph(ch) : noemph(ch));
}

searchret AreaListWindow::oneSearch(int x, const char *item, int mode)
{
	const char *s;
	searchret retval;

	mm.areaList->gotoActive(x);

	s = searchstr(mm.areaList->getShortName(), item);
	if (!s)
		s = searchstr(mm.areaList->getDescription(), item);

	retval = s ? True : False;
	if (!s && (mode < s_arealist) && mm.areaList->getNoOfLetters()) {
		int oldactive = active;
		ResetActive();
		mm.areaList->getLetterList();
		mm.letterList->relist();
		interface->changestate(letterlist);
		interface->letters.setActive(-1);
		retval = interface->letters.search(item, mode);
		if (retval != True) {
			active = oldactive;
			interface->changestate(arealist);
			delete mm.letterList;
		}
	}

	return retval;
}

void AreaListWindow::Select()
{
	mm.areaList->gotoActive(active);
}

void AreaListWindow::ResetActive()
{
	active = mm.areaList->getActive();
}

void AreaListWindow::MakeActive()
{
	int padding, middle;
	char tmp[80], tpad[7];

	mode = mm.driverList->hasPersonal();

	sprintf(tmp, "Message Areas (%d)", NumOfItems());

	list_max_y = LINES - 15;
	list_max_x = COLS - 6;
	top_offset = 2;

	borderCol = C_ALBORDER;

	list = new InfoWin(list_max_y + 7, list_max_x + 2, 2, borderCol,
		tmp, C_ALBTEXT, 7);

	list->attrib(C_ALHEADTEXT);
	list->put(1, 3, "Area#  Description");
	int newloc = list_max_x - 15;
	if (mode)
		newloc -= 11;
	list->put(1, newloc, "Total   Unread");
	if (mode)
		list->put(1, list_max_x - 9, "Personal");

	list->horizline(list_max_y + 2, list_max_x);

	padding = list_max_x - 28;
	if (mode)
		padding -= 11;
	sprintf(format, "%%c%%6s  %%-%d.%ds", padding, padding);

	middle = (list_max_x - 2) >> 1;

	list->attrib(C_ALINFOTEXT);
	list->put(list_max_y + 3, 3, "BBS:");
	list->put(list_max_y + 3, middle, " Sysop:");
	list->put(list_max_y + 4, 2, "Type:");
	list->put(list_max_y + 4, middle, "Packet:");
	list->put(list_max_y + 5, 2, "Area description:");

	sprintf(tpad, "%%.%ds", (middle < 87) ? middle - 8 : 79);
	middle += 8;

	list->attrib(C_ALINFOTEXT2);
	const char *bb = mm.resourceObject->get(BBSName);
	sprintf(tmp, tpad, (bb && *bb) ? bb : "(unknown)");
	charconv_in(tmp);
	list->put(list_max_y + 3, 8, tmp);

	const char *sy = mm.resourceObject->get(SysOpName);
	sprintf(tmp, tpad, (sy && *sy) ? sy : "(unknown)");
	charconv_in(tmp);
	list->put(list_max_y + 3, middle, tmp);

	list->put(list_max_y + 4, middle, mm.resourceObject->get(PacketName));

	padding = list_max_x - 20;
	sprintf(format2, "%%-%d.%ds", padding, padding);

	DrawAll();
	Select();
}

void AreaListWindow::Delete()
{
	delete list;
}

void AreaListWindow::Prev()
{
	do {
		Move(UP);
		Select();
	} while (!mm.areaList->getNoOfLetters() &&
		 (mm.areaList->getActive() > 0));
}

void AreaListWindow::Next()
{
	do {
		Move(DOWN);
		Select();
	} while (!mm.areaList->getNoOfLetters() &&
		 (mm.areaList->getActive() <
		  mm.areaList->noOfActive() - 1));
}

bool AreaListWindow::extrakeys(int key)
{
	bool end = false;

	Select();
	switch (key) {
	case 'E':
		if (!mm.areaList->isCollection()) {
			if (mm.areaList->isEmail()) {
				interface->addressbook();
				Select();
			}
			interface->letterwindow.set_Letter_Params(
				mm.areaList->getAreaNo(), 'E');
			interface->letterwindow.EnterLetter();
			interface->redraw();
		}
		break;
	case 'L':
		mm.areaList->relist();
		ResetActive();
		interface->redraw();
		break;
	case 'S':
	case KEY_IC:
	case 'U':
	case KEY_DC:
		if (mm.areaList->hasOffConfig()) {
			if ((key == 'S') || (key == KEY_IC))
				mm.areaList->Add();
			else
				mm.areaList->Drop();
			interface->setUnsavedNoAuto();
			Move(DOWN);
			Draw();
		} else
			interface->nonFatalError(
				"Offline config is unavailable");
	}
	return end;
}
