/* $Id: choose_folder.cpp,v 1.13 2004/01/02 04:05:36 fesnel Exp $ */
/*******************************************************************************
 *   This program is part of the XFMail email client.                          *
 *                                                                             *
 *   Copyright : (C) 1995-1998 Gennady B. Sorokopud (gena@NetVision.net.il)    *
 *               (C) 1995 Ugen. J. S. Antsilevich (ugen@latte.worldbank.org)   *
 *               (C) 1998-2004 by the Archimedes Project                       *
 *                   http://sourceforge.net/projects/archimedes                *
 *                                                                             *
 *             --------------------------------------------                    *
 *                                                                             *
 *   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.  *
 *                                                                             *
 *   Additional Permission granted:                                            *
 *                                                                             *
 *   This program is designed to use the XForms library, so we consider        *
 *   permission to link to that non-GPL-compatible library is implicit.        *
 *   However, in case this is not considered so, we explicitly state:          *
 *                                                                             *
 *   "As a special exception, the Archimedes Project, with the permission      *
 *    of all earlier copyright holders, formally gives permission to link      *
 *    this program with the XForms library, and distribute the resulting       *
 *    executable without the source code for XForms in the source              *
 *    distribution".                                                           *
 *                                                                             *
 ******************************************************************************/


#include <glib.h>

#include <fmail.h>
#include <umail.h>
#include <choose_folder.h>
#include "cfgfile.h"

extern cfgfile Config;

FD_Choose_Folder *choose;
FD_Create_Folder *create;
FD_Create_Subfold *createsub;
struct _mail_folder *pfold = NULL;
static int ready = 0;
static int crready = 0;
static int subcrready = 0;
static char wrkfolder[MAX_FOLD_NAME_LEN] = "inbox";
#define MAX_PUP_FOLDERS 28

void choose_dbl(FL_OBJECT * obj, long param) {
	fl_trigger_object(choose->Ready_Button);
}

void choose_browse(FL_OBJECT * obj, long param) {
	if(fl_mouse_button() == FL_MIDDLE_MOUSE)
		choose_dbl(obj, param);
}

void New_Folder_Call(FL_OBJECT * obj, long param) {
	int i;
	struct _mail_folder *fld;

	fl_deactivate_form(choose->Choose_Folder);

	if(fl_get_button_numb(obj) == 1)
		fld = create_folder(NULL, 0);
	else {
		fld =
		get_folder_by_index_noskip(fl_get_browser
								   (choose->Folder_Browse) - 1);
		if(fld)
			fld = create_subfolder(fld, NULL);
	}

	if(fld == NULL) {
		fl_activate_form(choose->Choose_Folder);
		return;
	}

	redraw_fld_win();

	fl_freeze_form(choose->Choose_Folder);
	fl_clear_browser(choose->Folder_Browse);
	for(i = 0; i < (int)mailbox.size(); i++)
		fl_add_browser_line(choose->Folder_Browse,
							get_fld_line(mailbox[i]));
	fl_select_browser_line(choose->Folder_Browse, 1);
	fl_set_browser_topline(choose->Folder_Browse, 1);
	strcpy(wrkfolder, "inbox");
	fl_unfreeze_form(choose->Choose_Folder);

	fl_activate_form(choose->Choose_Folder);

	return;
}

void choose_init() {
	choose=create_form_Choose_Folder();
}

void choose_free() {
	fl_free(choose);
}

struct _mail_folder *choose_folder() {
	int i, w, h, redr, wrkind;
	struct _mail_folder *fld, *pfold;
	char geom[16];
	FL_OBJECT *obj;

	if(ready) {
		XRaiseWindow(fl_display, choose->Choose_Folder->window);
		display_msg(MSG_WARN, "choose folder",
					"Dialog is currently in use, close it and open again");
		return NULL;
	}

	ready = 1;

	pfold = get_folder_by_name(wrkfolder);
	wrkind = pfold ? get_folder_index_noskip(pfold) : 0;

	fl_clear_browser(choose->Folder_Browse);
	fl_freeze_form(choose->Choose_Folder);
	for(i = 0; i < (int)mailbox.size(); i++)
		fl_add_browser_line(choose->Folder_Browse,
							get_fld_line(mailbox[i]));
	fl_unfreeze_form(choose->Choose_Folder);

	fl_set_browser_fontsize(choose->Folder_Browse,
							Config.getInt("ChooseFolderFSize",
										  FL_DEFAULT_SIZE));
	fl_set_browser_fontstyle(choose->Folder_Browse,
							 Config.getInt("ChooseFolderFStyle",
										   FL_NORMAL_STYLE));
	fl_set_object_color(choose->Folder_Browse,
						Config.getInt("ChooseFolderBgCol",
									  FL_TOP_BCOL),
						Config.getInt("ChooseFolderFgCol",
									  FL_YELLOW));
	fl_select_browser_line(choose->Folder_Browse, wrkind + 1);
	fl_set_browser_topline(choose->Folder_Browse, wrkind + 1);

	fl_set_browser_dblclick_callback(choose->Folder_Browse, choose_dbl, 0);

	Config.setFlags("chfoldgeom", CF_NOTCHANGED);
	w = 250;
	h = 280;
	sscanf(Config.get("chfoldgeom", "").c_str(), "%d %d", &w, &h);
	fl_set_form_minsize(choose->Choose_Folder, 250, 280);
	fl_set_form_maxsize(choose->Choose_Folder, 500, 700);
	fl_set_form_size(choose->Choose_Folder, w, h);
	fl_show_form(choose->Choose_Folder, FL_PLACE_FREE, FL_TRANSIENT,
				 "Choose Folder");

	while(ready == 1) {
		obj = fl_do_only_forms();

		if(obj == choose->Ready_Button)
			ready = 2;
		else if(obj == choose->Cancel_Button)
			ready = 3;
	}

	i = fl_get_browser(choose->Folder_Browse);

	sprintf(geom, "%d %d", choose->Choose_Folder->w,
			choose->Choose_Folder->h);
	Config.set("chfoldgeom", geom);
	fl_hide_form(choose->Choose_Folder);

	if(ready == 2) {
		ready = 0;
		if(i <= 0)
			return NULL;

		fld = get_folder_by_index_noskip(i - 1);
		if(fld) {
			strcpy(wrkfolder, get_folder_full_name(fld));
			redr = 0;
			for(pfold = fld->pfold; pfold; pfold = pfold->pfold) {
				if(!(pfold->flags & FEXPND)) {
					expand_collapse_tree(pfold, 0);
					redr = 1;
				}
			}
			if(redr)
				redraw_fld_win();
		}

		return fld;
	}

	ready = 0;
	return NULL;
}

struct _mail_folder *pup_choose_folder(FL_FORM * form) {
	int fpup, i, k, p, p1, jump, subfold = 1;
	int popupsnum = 0;
	char ptext[MAX_FOLDER_ALIAS_NAME + 1];
	FL_PUP_ENTRY *pmenu;
	struct _mail_folder *fold = NULL;

	if(
	  (pmenu =
	   (FL_PUP_ENTRY *) malloc(sizeof(FL_PUP_ENTRY) * mailbox.size() *
							   2)) == NULL) {
		display_msg(MSG_FATAL, "pup_choose_folder", "malloc failed");
		return NULL;
	}

	fpup =
	fl_newpup(form ? form->
			  window : (main_form ? main_form->window : fl_root));
	for(i = 0, p = 0; i < (int)mailbox.size(); i++) {
		pmenu[p].callback = NULL;
		pmenu[p].shortcut = NULL;
		pmenu[p].mode = 0;
		pmenu[p++].text = strdup(mailbox[i]->sname);

		if(popupsnum >= MAX_PUP_FOLDERS)
			break;

		if(((i + 1) < (int)mailbox.size()) &&
		   (mailbox[i + 1]->level > mailbox[i]->level)) {
			subfold++;
			popupsnum++;
			pmenu[p].callback = NULL;
			pmenu[p].shortcut = NULL;
			pmenu[p].mode = 0;
			snprintf(ptext, sizeof(ptext), "/%s", mailbox[i]->sname);
			pmenu[p++].text = strdup(ptext);
		} else
			if(((i + 1) < (int)mailbox.size()) &&
			   (mailbox[i + 1]->level < mailbox[i]->level)) {
			jump = mailbox[i]->level - mailbox[i + 1]->level;
			subfold -= jump;
			if(subfold < 1)
				subfold = 1;
			while(jump--) {
				pmenu[p].callback = NULL;
				pmenu[p].shortcut = NULL;
				pmenu[p].mode = 0;
				pmenu[p++].text = NULL;
			}
		}
	}

	for(i = 0; i < subfold; i++)
		pmenu[p++].text = NULL;

	fl_setpup_entries(fpup, pmenu);
	k = fl_dopup(fpup) - 1;
	for(i = 0, p1 = 0; (i < (int)mailbox.size()) && (p1 < p); i++, p1++) {
		if(p1 == k)
			fold = mailbox[i];
		if(pmenu[p1].text)
			free((char *) pmenu[p1].text);
		if(((i + 1) < (int)mailbox.size()) &&
		   (mailbox[i + 1]->level != mailbox[i]->level)) {
			jump = abs(mailbox[i]->level - mailbox[i + 1]->level);
			while(jump--) {
				p1++;
				if(p1 >= p)
					break;
				if(pmenu[p1].text)
					free((char *) pmenu[p1].text);
			}
		}
	}

	/* THIS IS A HACK!! (Until T.C. fixes freeing of nested pop-ups) */
	for(i = fpup + 1; i <= fpup + popupsnum; i++)
		fl_freepup(i);

	fl_freepup(fpup);
	free(pmenu);

	return fold;
}

void Subfolder_Call(FL_OBJECT * obj, long param) {
	char buf[255];

	if(!pfold || !createsub)
		return;

	snprintf(buf, sizeof(buf), "%s%c%s", pfold->fold_path, pfold->hdelim,
			 fl_get_input(obj));
	fl_set_input(createsub->Subfolder_Path, buf);
}

void Subfolder_Path_Call(FL_OBJECT * obj, long param) {
}

void Create_Name_Call(FL_OBJECT * obj, long param) {
}

void Create_Local_Call(FL_OBJECT * obj, long param) {
	fl_deactivate_object(create->Create_File);
}

void Create_Mbox_Call(FL_OBJECT * obj, long param) {
	fl_activate_object(create->Create_File);
}

void Create_Remote_Call(FL_OBJECT * obj, long param) {
	fl_deactivate_object(create->Create_File);
}

void Create_File_Call(FL_OBJECT * obj, long param) {
	char *fname;

	fl_set_fselector_title("Select mailbox file");
	fname =
	(char *) fl_show_file_selector("Mailbox", homedir, "*", "mbox");
	if(!fname || !*fname)
		return;

	fl_set_input(create->Create_Name, fname);
}

struct _mail_folder *create_subfolder(struct _mail_folder *pfolder,
									  char *name) {
	struct _mail_folder *folder;
	char *p, fname[MAX_FOLD_NAME_LEN];

	if(subcrready) {
		XRaiseWindow(fl_display, create->Create_Folder->window);
		display_msg(MSG_WARN, "create subfolder",
					"Dialog is currently in use, close it and open again");
		return NULL;
	}

	if((pfolder == NULL) || (pfolder->hdelim == '\0'))
		return NULL;

	if(pfolder->status & NOINFR) {
		display_msg(MSG_WARN, "create subfolder",
					"This folder can not have subfolders");
		return NULL;
	}

	folder = NULL;
	subcrready = 1;
	pfold = pfolder;

	createsub = create_form_Create_Subfold();

	fl_deactivate_object(createsub->Subfolder_Path);
	fl_set_input(createsub->Subfolder_Name, name ? name : "");
	snprintf(fname, sizeof(fname), "%s%c%s", pfolder->fold_path,
			 pfolder->hdelim, name ? name : "");
	fl_set_input(createsub->Subfolder_Path, fname);
	snprintf(fname, sizeof(fname), "Create subfolder in %s",
			 pfolder->sname);
	fl_set_object_label(createsub->Subfolder_Title, fname);
	fl_set_input_return(createsub->Subfolder_Name, FL_RETURN_ALWAYS);


	fl_set_form_minsize(createsub->Create_Subfold, 360, 150);
	fl_set_form_maxsize(createsub->Create_Subfold, 360, 150);
	fl_show_form(createsub->Create_Subfold, FL_PLACE_MOUSE, FL_TRANSIENT,
				 "Create Subfolder");
	if(fl_do_only_forms() == createsub->Subfolder_Cancel)
		goto crsubexit;

	name = (char *) fl_get_input(createsub->Subfolder_Name);
	if(strlen(name) < 1)
		goto crsubexit;

	if(strlen(name) >= MAX_FOLD_NAME_LEN) {
		display_msg(MSG_WARN, "create subfolder",
					"Subfolder name too long");
		goto crsubexit;
	}

	if(strchr(name, pfolder->hdelim)) {
		display_msg(MSG_WARN, "create subfolder",
					"Subfolder name can not contain %c", pfolder->hdelim);
		goto crsubexit;
	}

	p = name;
	while(*p != '\0') {
		if(!isgraph(*p)) {
			display_msg(MSG_WARN, "create subfolder",
						"Illegal character in subfolder name");
			name = NULL;
			break;
		}
		p++;
	}

	if(name == NULL)
		goto crsubexit;

	strcpy(fname, name);
	name = rem_tr_space(fname);

	folder = NULL;

	switch(pfolder->type) {
		case F_MH:
			folder = create_mh_folder(pfolder, name);
			break;

		case F_MBOX:
			folder = create_mbox_folder(pfolder, name);
			break;

		case F_IMAP:
			folder = create_imap_folder((struct _imap_src *) pfolder->spec,
										pfolder, name);
			break;
	}

	if(folder) {
		if(pfolder->sort != -1)
			folder->sort = pfolder->sort;
		if(pfolder->From)
			folder->From = copy_address(pfolder->From);
		if (pfolder->To)
			folder->To = copy_address(pfolder->To);
		if(pfolder->color != -1)
			folder->color = pfolder->color;
		folder->flags |=
		(pfolder->
		 flags & (FNCOUNT | FNTRASH | FSHRECP | FCHECK | FRKEEP |
				  FNVALD));
	}
	crsubexit:
	fl_hide_form(createsub->Create_Subfold);
	fl_free_form(createsub->Create_Subfold);
	fl_free(createsub);
	createsub = NULL;

	subcrready = 0;
	pfold = NULL;
	save_folders_conf(NULL, F_MH | F_MBOX);

	return folder;
}

struct _mail_folder *create_folder(char *name, int ftype) {
	struct _mail_folder *folder;
	char *p, fname[MAX_FOLD_NAME_LEN];

	if(crready) {
		XRaiseWindow(fl_display, create->Create_Folder->window);
		display_msg(MSG_WARN, "create folder",
					"Dialog is currently in use, close it and open again");
		return NULL;
	}

	folder = NULL;
	crready = 1;

	create = create_form_Create_Folder();

	fl_set_input(create->Create_Name, name ? name : "");

	switch(ftype) {
		case F_MH:
			fl_set_button(create->Create_Local, 1);
			fl_deactivate_object(create->Create_File);
			break;

		case F_IMAP:
			fl_set_button(create->Create_Remote, 1);
			fl_deactivate_object(create->Create_File);
			break;

		case F_MBOX:
			fl_set_button(create->Create_Mbox, 1);
			fl_activate_object(create->Create_File);
			break;

		default:
			fl_set_button(create->Create_Local, 1);
			fl_deactivate_object(create->Create_File);
			ftype = F_MH;
			break;
	}

	if(imap_connected() == 0)
		fl_deactivate_object(create->Create_Remote);

	fl_set_form_minsize(create->Create_Folder, 360, 150);
	fl_set_form_maxsize(create->Create_Folder, 360, 150);
	fl_show_form(create->Create_Folder, FL_PLACE_MOUSE, FL_TRANSIENT,
				 "Create Folder");
	if(fl_do_only_forms() == create->Create_Cancel)
		goto crexit;

	name = (char *) fl_get_input(create->Create_Name);
	if(strlen(name) < 1)
		goto crexit;

	if(strlen(name) >= MAX_FOLD_NAME_LEN) {
		display_msg(MSG_WARN, "create", "Folder name too long");
		goto crexit;
	}

	p = name;
	while(*p != '\0') {
		if(!isgraph(*p)) {
			display_msg(MSG_WARN, "create",
						"Illegal character in folder name");
			name = NULL;
			break;
		}
		p++;
	}

	if(name == NULL)
		goto crexit;

	strcpy(fname, name);
	name = rem_tr_space(fname);

	folder = NULL;
	if(fl_get_button(create->Create_Local)) {
		if(name[0] == '.') {
			display_msg(MSG_WARN, "create",
						"Illegal character in folder name");
			goto crexit;
		}
		folder = create_mh_folder(NULL, name);
	} else if(fl_get_button(create->Create_Remote)) {
		struct _imap_src *imap;

		if(current_folder && (current_folder->type & F_IMAP))
			imap = (struct _imap_src *) current_folder->spec;
		else {
			if(imap_connected() == 1)
				imap = get_imap_connection(NULL);
			else
				imap =
				get_imap_connection((char *)
									fl_show_input("Account name:",
												  ""));
		}
		folder = create_imap_folder(imap, NULL, name);
	} else if(fl_get_button(create->Create_Mbox))
		folder = create_mbox_folder(NULL, name);

	crexit:
	fl_hide_form(create->Create_Folder);
	fl_free_form(create->Create_Folder);
	fl_free(create);
	create = NULL;

	crready = 0;
	save_folders_conf(NULL, F_MH | F_MBOX);

	return folder;
}
