/*
 * MultiMail offline mail reader
 * message list

 Copyright (c) 1996 Kolossvary Tamas <thomas@tvnet.hu>
 Copyright (c) 1997 John Zero <john@graphisoft.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"

LetterListWindow::LetterListWindow()
{
	lsorttype = mm.resourceObject->getInt(LetterSort);
}

void LetterListWindow::listSave()
{
	static const char *saveopts[] = { "Marked", "All", "This one",
		"Quit" };

	int marked = !(!mm.areaList->getNoOfMarked());

	int status = interface->WarningWindow("Save which?", saveopts +
		!marked, 3 + marked);
	if (status) {
		bool saveok = interface->letterwindow.Save(status);
		if ((status == 1) && saveok)
			Move(DOWN);
	}
}

void LetterListWindow::NextUnread()
{
	do {
		Move(DOWN);
		mm.letterList->gotoActive(active);
	} while (mm.letterList->getRead() && ((active + 1) < NumOfItems()));
}

void LetterListWindow::FirstUnread()
{
	position = 0;
	active = 0;
}

void LetterListWindow::PrevUnread()
{
	do {
		Move(UP);
		mm.letterList->gotoActive(active);
	} while (mm.letterList->getRead() && (active > 0));
}

int LetterListWindow::NumOfItems()
{
	return mm.letterList->noOfActive();
}

void LetterListWindow::oneLine(int i)
{
	mm.letterList->gotoActive(position + i);

	int st = mm.letterList->getStatus();

	char *p = list->lineBuf;
	p += sprintf(p, format, (st & MS_MARKED) ? 'M' : ' ',
	    (st & MS_REPLIED) ? '~' : ' ', (st & MS_READ) ? '*' : ' ',
		mm.letterList->getMsgNum(), mm.letterList->getFrom(),
		    mm.letterList->getTo(), mm.letterList->getSubject());

	if (mm.areaList->isCollection()) {
		const char *origArea = mm.areaList->
			getDescription(mm.letterList->getAreaID());
		if (origArea)
			sprintf(p - 15, " %-13.13s ", origArea);
	}

	chtype linecol = mm.letterList->isPersonal() ? C_LLPERSONAL :
		C_LISTWIN;

	letterconv_in(list->lineBuf);
	DrawOne(i, (st & MS_READ) ? noemph(linecol) : emph(linecol));
}

bool LetterListWindow::oneSearch(int x, const char *item)
{
	const char *s;

	mm.letterList->gotoActive(x);

	s = searchstr(mm.letterList->getFrom(), item);
	if (!s) {
		s = searchstr(mm.letterList->getTo(), item);
		if (!s)
			s = searchstr(mm.letterList->getSubject(), item);
	}

	return !(!s);
}

void LetterListWindow::MakeActive()
{
	char topline[72];
	int tot, maxFromLen, maxToLen, maxSubjLen;

	tot = COLS - 19;
	maxSubjLen = tot / 2;
	tot -= maxSubjLen;
	maxToLen = tot / 2;
	maxFromLen = tot - maxToLen;

	if (!mm.areaList->hasTo() || (mm.areaList->isCollection() &&
	    !mm.areaList->isReplyArea())) {
		maxSubjLen += maxToLen;
		maxToLen = 0;
	}

	if (mm.areaList->isReplyArea()) {
		maxSubjLen += maxFromLen;
		maxFromLen = 0;
	}

	sprintf(format, "%%c%%c%%c%%6d  %%-%d.%ds %%-%d.%ds %%-%d.%ds",
		maxFromLen, maxFromLen, maxToLen, maxToLen,
			maxSubjLen, maxSubjLen);

	interface->areas.Select();

	sprintf(topline, "Letters in %.60s (%d)",
		mm.areaList->getDescription(), NumOfItems());
	areaconv_in(topline);

	list_max_y = (NumOfItems() < LINES - 11) ? NumOfItems() : LINES - 11;
	list = new InfoWin(list_max_y + 3, COLS - 4, 2, C_LLBBORD,
		topline, C_LLTOPTEXT2);

	list->attrib(C_LLTOPTEXT1);
	list->put(0, 3, "Letters in ");

	sprintf(topline, "   Msg#  %%-%d.%ds %%-%d.%ds %%-%d.%ds",
		maxFromLen, maxFromLen, maxToLen, maxToLen,
			maxSubjLen, maxSubjLen);
	list->attrib(C_LLHEAD);
	sprintf(list->lineBuf, topline, "From", "To", "Subject");
	list->put(1, 3, list->lineBuf);

	if (mm.areaList->isCollection())
		list->put(1, COLS - 19, "Area");
	list->touch();

	DrawAll();
	Select();
}

void LetterListWindow::Select()
{
	mm.letterList->gotoActive(active);
}

void LetterListWindow::ResetActive()
{
        active = mm.letterList->getActive();
}

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

void LetterListWindow::extrakeys(int key)
{
	Select();
	switch (key) {
	case MM_MINUS:
		PrevUnread();
		Draw();
		break;
	case '\t':
	case MM_PLUS:
		NextUnread();
		Draw();
		break;
	case 'U':
	case 'M':	// Toggle read/unread and marked from letterlist
		mm.letterList->setStatus(mm.letterList->getStatus() ^
			((key == 'U') ? MS_READ : MS_MARKED));
		interface->setAnyRead();
		Move(DOWN);
		Draw();
		break;
	case 'E':
		if (mm.areaList->isReplyArea())
			interface->letterwindow.KeyHandle('E');
		else
		    if (!mm.areaList->isCollection()) {
			if (mm.areaList->isEmail())
				interface->addressbook();
			interface->letterwindow.set_Letter_Params(
				mm.areaList->getAreaNo(), 'E');
			interface->letterwindow.EnterLetter();
		    }
		interface->changestate(letterlist);
		break;
	case 6:
		if (mm.areaList->isReplyArea())
			interface->letterwindow.KeyHandle(6);
		interface->changestate(letterlist);
		break;
	case 'K':
		if (mm.areaList->isReplyArea())
			interface->kill_letter();
		break;
	case 'L':
		mm.letterList->relist();
		ResetActive();
		interface->changestate(letterlist);
		break;
	case '$':
		mm.letterList->resort();
		DrawAll();
		break;
	case 'S':
		listSave();
		interface->changestate(letterlist);
	}
}
