musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/* 
 * MusicMUD - Documentation module
 * Copyright (C) 1998-2003 Abigail Brady
 * 
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 */
#include <unistd.h>
#include <ctype.h>

#include "musicmud.h"
#include "State.h"
#include "verbs.h"
#include "misc.h"
#include "msi.h"
#include "util.h"
#include "levels.h"
#include "pflags.h"
#include "Pager.h"
#include "pflagnames.h"
#include "MudObject.h"
#include "paths.h"
#include "config.h"
#include "wordwrap.h"

#include <set>

#define MODULE "info"


static bool verb_info(MudObject *o, int argc, const char *argv[]);

static const char *lowercase(const char *what) {
  static char foo[4096];
  char *a=foo;
  foo[0] = 0;
  while (*what) {
    *a = tolower(*what);
    what++;
    a++;
  }
  *a=0;
  return foo;
}

static int fgets_v(char *buf, int max, FILE *f)
{
  while (max>0) {
    int ch = fgetc(f);
    if (ch == EOF) {
      return 1;
    }
    *buf = ch;
    buf++;
    max--;
    if (ch == '\v') { *buf = 0; return 0; }
    if (ch == '\n') { *buf = 0; return 0; }
  }
  *buf = 0;
  return 0;
}

static bool do_pagerstate_display(FILE *f, Player *who, PagerState *p) {
  const char *grepfor = p->get("grepfor");
  const char *title = p->get("title");

  char bptr[4096], *buffer;
  int rows = ::rows(who)-2;
  if (who->get_int("copious", 0)==1) {
    who->printf("\n");
  }
  for (int i=0;i<rows;i++) {
    if (i==0 && title) {
      who->printf("%s\n\n", title_for(title, who).c_str());
      p->set("footer", "yes");
      p->unset("title");
      continue;
    }

    buffer = bptr;
    fgets_v(buffer, 4000, f);
    if (feof(f)) {
      if (title || p->get("footer"))
	who->printf("\n%s\n", footer_for(who).c_str());
      return true;
    }
    if (buffer[0]=='@' && buffer[1]=='@') 
      switch (buffer[2]) {
default:
      case '@':
      case '|':
      case '<':
      case '>':
	i--;
	goto cont; /* continue out of loop */
      case 'p':
	if (i > 2)	  
	  return 0;
      case 'N':
	sprintf(buffer, "Dear %s, \n", who->get("name"));
	break;
      case '=':
	if (strchr(buffer, '\n'))
	  *strchr(buffer, '\n')=0;
	if (buffer[3]) 
	  who->printf("%s\n", title_for(buffer+3, who).c_str());
	else
	  who->printf("%s\n", footer_for(who).c_str());
	goto cont;	
      case '-':
	if (strchr(buffer, '\n'))
	  *strchr(buffer, '\n')=0;
	if (buffer[3]) 
	  who->printf("%s\n", title_for(buffer+3, who, "^B", "^-").c_str());
	else
	  who->printf("%s\n", footer_for(who, "^B", "^-").c_str());
	goto cont;	
      case 'h':
	if (strchr(buffer, '\n'))
	  *strchr(buffer, '\n')=0;
	if (buffer[3]) 
	  who->printf("%s\n", title_for(buffer+3, who, "^R").c_str());
	else
	  who->printf("%s\n", footer_for(who, "^R").c_str());
	goto cont;
      case 'c':
	{
	  int width = columns(who);
	  int strwidth = colour_strlen(buffer+3, who);
	  width /= 2;
	  strwidth /= 2;
	  string blah;
	  
	  int needed = width - strwidth;
	  if (needed>0 && needed<500) {
	    while (needed) {
	      blah += " ";
	      needed--;
	    }
	  }
	  blah += (buffer+3);	  
	  who->printf("%s", blah.c_str());
	  goto cont;	  
	}
      }
	  
    if (grepfor && *grepfor && !strstr(buffer, grepfor)) {
      i--;
      goto cont;
    }
    
    who->printf("%s", buffer);
    
  cont:;
  }
  long was = ftell(f);
  fseek(f, 0, SEEK_END);
  long now = ftell(f);
  fseek(f, was, SEEK_SET);
  if (was == now) {
    if (title || p->get("footer"))
      who->printf("\n%s\n", footer_for(who).c_str());
    return true;
  }
  return false;
}

static bool verb_help(MudObject *o, int argc, const char *argv[]) {
    if (argc<2) {
	o->spewfile(DATA_HELP, "helpall", false);
	return true;
    }
    
    char alias[4096];
    strcpy(alias,"alias.");
    strncat(alias,argv[1],4089);
    alias[4095]='\0';
    if(const char *aliasvalue = o->get(alias))
    {
    	o->printf("You have ^W%s^n set as an alias. It expands to ^W%s^n.\n", argv[1], aliasvalue);
	return true;
    }
    
    Verb *v=get_verb(argv[1]);
    if (v) v = v->drill();
    
    const char *id = v?v->id:lowercase(argv[1]);
    if (o->spewfile(DATA_HELP, id, false, ssprintf("|help %s", id).c_str())) {
      return true;
    }

    if (v && streq(v->get("module"), "action")) {
	o->interpretf("action %s", v->id);
	return true;
    }

    if (v) {
      o->printf("The '%s' command is undocumented.\n", v->id);
      return true;
    }

    verb_info(o, argc, argv);

    return true;
}

static bool verb_info(MudObject *o, int argc, const char *argv[]) {
    if (argc<2) {
	o->spewfile(DATA_INFO, "info");
	return true;
    }

    char thing[8000];
    sprintf(thing, "%s.i", lowercase(argv[1]));
    if (o->spewfile(DATA_INFO, thing, false)) return true;

    sprintf(thing, "%ss.i", lowercase(argv[1]));
    if (o->spewfile(DATA_INFO, thing, false)) return true;

    sprintf(thing, "%s", lowercase(argv[1]));
    if (strlen(thing)) {
      thing[strlen(thing)-1]=0;
    }
    strcat(thing, ".i");
    if (o->spewfile(DATA_INFO, thing, false)) return true;

    if (streq(argv[0], "info")) 
      o->printf("Unable to find a matching info file for %s.\n", argv[1]);
    else
      o->printf("Unable to find a matching help file for %s.\n", argv[1]);
    return true;
}

static bool verb_policy(MudObject *o, int argc, const char *argv[]) {
    if (argc<2) {
	o->spewfile(DATA_POLICY, "index");
	return true;
    }

    char thing[8000];
    sprintf(thing, "%s", lowercase(argv[1]));
    if (o->spewfile(DATA_POLICY, thing, false)) return true;

    sprintf(thing, "%ss", lowercase(argv[1]));
    if (o->spewfile(DATA_POLICY, thing, false)) return true;

    sprintf(thing, "%s", lowercase(argv[1]));
    if (strlen(thing)) {
      thing[strlen(thing)-1]=0;
    }
    if (o->spewfile(DATA_POLICY, thing, false)) return true;

    o->printf("Unable to find a matching policy file for %s.\n", argv[1]);
    return true;
}

static bool verb_viewfile(MudObject *o, int argc, const char **argv) {
    if (argc < 2) return true;
    o->spewfile(DATA_FILES, lowercase(argv[1]));
    return true;
}

static bool verb_credits(MudObject *who, int, const char **) {
    who->spewfile(DATA_INFO, "credits.i");
    return true;
}

static bool verb_wizlist(Player *who, int, const char **) {
    FILE *i = xopen(VARDATA, "wizlist", "r");
    if (!i) {
      who->printf("Can't open the data file.\n");
      return true;
    }

    Divert d(who, "wizlist");
    
    who->printf("The following players are Administrators on %s.\n", THE_MUDNAME);

    const char *lr = 0;
    int col = 0;

    set<string> did;   
 
    while (1) {
	int privs;
	char name[256];
	char buffer[1024];
	fgets(buffer, 1020, i);
	if (feof(i)) break;
	
	char *b = buffer;
	while (*b == '0' && (*(b+1)!=' ')) b++;
	sscanf(b, "%i %s", &privs, name);
        if (did.find(name)!=did.end())
           continue;
        did.insert(name);
	if (privs>10000)
	  privs = 99999-privs;

	if (privs >= LEV_COMMANDER) {
	    const char *nlr = get_rank(privs);
	    if (!streq(nlr, lr)) {
		if (col != 0) who->printf("\n");
		who->printf("\n^W%s^n\n\n", nlr);
		col = 0;
	    }
	    string foos=lookup_name(name);
	    const char *foo=foos.c_str();
	    who->printf("%s", foo);
	    int len = colour_strlen(foo, who);
	    while (len<14) {
	      who->printf(" ");
	      len++;
	    }
	    col++;
	    if (col==5) {
		who->printf("\n");
		col=0;
	    }
	    lr = nlr;
	}
    }
    if (col!=0)
	who->printf("\n");
    who->printf("\n");
    xclose(i);
    
    return true;
}

#define CLEANUP pagerstate_display = 0;

#include "verbmodule.h"

void startup() {

pagerstate_display = do_pagerstate_display;

AUTO_VERB(wizlist, 3, 0, PFL_NONE);
AUTO_VERB(info, 3, 0, PFL_NONE);
AUTO_VERB(credits, 3, 0, PFL_NONE);
AUTO_VERB(policy, 3, 0, PFL_NONE);
AUTO_VERB(help, 2, 0, PFL_NONE);
AUTO_VERB(viewfile, 8, 0, PFL_NONE);

}