#include <forms.h>
#include <errno.h>
#include <sys/param.h>
#include "aux.h"
#include "sula.h"
#include "chanwin.h"
#include "global.h"
#include "cmd.h"
#include "help.h"

void whatis(int argc, char **argv, Winstruct *win){

	if(argc==1){ /* /whatis	*/
		fl_addto_browser(win->chanwin->brow2, PROMPT"whatis what?");
		#if DEBUG > 9
		print_cmd_tree(cmdTree , 8);
		#endif
		return ;
	}else
	if( !strncasecmp(argv[1], "-help", 2) ){ 
		show_std_help(uppercase(argv[0]), NULL, win->chanwin);
		return ;
	}
	else{
		Cmd *p;
		char *buf=NULL;
		p=find_cmd( argv[1] , CMD_NORMAL|CMD_CTCP);
		if(!p){
			buf=(char *)malloc(sizeof(char)*(strlen(argv[1])+30+strlen(PROMPT)));
			sprintf(buf, PROMPT"%s:  nothing appropriate", argv[1]);
			fl_addto_browser(win->chanwin->brow2, buf);
			free(buf);
			return ;
		}
		if(p->help){
			 buf=(char *)malloc(sizeof(char)*(strlen(p->name)+
			 strlen(p->help)+5+strlen(PROMPT)));
			 sprintf(buf, PROMPT"%s: %s", p->name,p->help);
			 fl_addto_browser(win->chanwin->brow2,buf);
		}
		else{
		 	buf=(char *)malloc(sizeof(char)*(strlen(argv[1])+40+strlen(PROMPT)));
			sprintf(buf, PROMPT"%s:  no entry found", argv[1]);
			fl_addto_browser(win->chanwin->brow2, buf);
		}
		free(buf);
	}
	return;
}

void apropos(int argc, char **argv, Winstruct *win){
       static void show_apropos(Cmd *p,const char *cmd, FL_OBJECT *brow,int *);

	if(argc==1){ /* /apropos	*/
		fl_addto_browser(win->chanwin->brow2, PROMPT"apropos what?");
	}
	else
	if( !strncasecmp(argv[1], "-help", 2) ){ 
		show_std_help(uppercase(argv[0]), NULL, win->chanwin);
	}else
	{
		int i=0;
		show_apropos(cmdTree, 
		lowercase(argv[1]),win->chanwin->browser, &i);
		if(i==0){
			char *buf=(char *)malloc(sizeof(char)*(strlen(argv[1])+32+strlen(PROMPT)));
			sprintf(buf, PROMPT"apropos %s: nothing appropriate", argv[1]);
			fl_addto_browser(win->chanwin->brow2, buf);
			free(buf) ;
		}
	}
}

static void show_apropos(Cmd *p, char *str, FL_OBJECT *brow, int *i){
	static int j=0;

	if(p){
		char buf[MAXLINE];
		show_apropos(p->left, str, brow,i);
		if(strstr(lowercase(p->name), str) || 
		(p->help && strstr(lowercase(p->help), str))) {
			sprintf(buf, "@f%s%-24.20s- %s%s",  p->type&CMD_IN?" ":"*", 
		 	p->name,  p->type&CMD_CTCP?"(CTCP) ":"", p->help?p->help:""
		   );
			fl_addto_browser(brow, buf);
			(*i)++; 
		}
		if(++j==no_of_cmds)
			j=0;
		show_apropos(p->right, str, brow,i);
	}
}

void help(int argc, char **argv, Winstruct *win){
/* show help on a cmd*/
       static void show_cmds_in_columns(Cmd *p, FL_OBJECT *brow);

	if(argc==1){
		fl_addto_browser(win->chanwin->browser,"@-");
		fl_addto_browser(win->chanwin->browser,"@b@i\t\tHelp Topics");
	       	show_cmds_in_columns(cmdTree,win->chanwin->browser);

		return ;
	}
	else
	if( !strncasecmp(argv[1], "-help", 2) ){ 
		show_std_help(uppercase(argv[0]), NULL, win->chanwin);
		return ;
	}else

	{
		char buf[MAXLINE], *buf2=NULL;
		Cmd *cmd;
		int i=1;
		cmd=find_cmd(argv[1],CMD_NORMAL);
		if(!cmd) goto out;

		buf[0]='\0';
		while(++i<argc)
			strcat(buf, argv[i]);
		buf2=(char *)malloc(sizeof(char)*(strlen(cmd->name)+10+strlen(buf))) ;
		sprintf(buf2,"%s -h %s", cmd->name, buf[0]?buf:"");
		if(cmd->type & CMD_FD){
			int j=-1;
			for(i=0; i<win_count;i++)
				if(win==&winstruct[i]){
				 j=i; break;
				 }
			if(j<0) err_quit("winstruct bug");
			i=new_process_cmd(buf2, j);
		}else i=process_cmd(buf2, win);
		if(i)
		{
out:
			buf2=(char *)malloc(sizeof(char)*(strlen(argv[1])+strlen(PROMPT)+30));
			sprintf(buf2, PROMPT"%s: Unknown command", argv[1]);
			fl_addto_browser(win->chanwin->brow2, buf2);
		}
		return;
	}

    return;
}

static void show_cmds_in_columns(Cmd *p, FL_OBJECT *brow){
	static char buf[100];
	char s[50];
	static int i=0, total=0;
	if(i==0) buf[0]='\0';
	if(p){
		show_cmds_in_columns(p->left, brow);
		if(i==0) strcat(buf, "@f");
		sprintf(s, "%-1.1s%-15.13s", p->type&CMD_IN?" ":"*", p->name);
		strcat(buf, s);
		i++;  total= ++total%no_of_cmds;
		if(i==4 || total==0){
			i=0;
			fl_addto_browser(brow, buf);
			buf[0]='\0';
		}
		show_cmds_in_columns(p->right, brow);
	}
}
