/*
	Schrodinger's Box Haven  code version -0.1 alpha
        Copyright (C) 1994, Gordon Chan

	You can do whatever ya want with this code as long as you leave this
        copyright & disclaimer intact.  You can hack it up all you want, etc...
        No guarantees.

	Send comments, flames, bug reports, etc ... to
		au233@freenet.carleton.ca  <---- (preferred address for now)
		gjc@achilles.net
		gchan@ccs.carleton.ca
*/


/* Here's the copyrights & disclaimers from the Opium Den and unixCB codes */

/* Opium Den */
/*
  val's haven code v -0.85

        Copyright (C) 1994 Joel Ward

        Warranty:
                Don't blame me for anything.

        You can do whatever the fuck you want with this code as long as you
don't remove this copyright/disclaimer notice.
*/

/* unixCB */
/*
  
  cbd.c
  
  "cbd.c" is the main code for the CB simulator.
  
  Copyright (c) 1992, Gary Grossman.  All rights reserved.
  Send comments and questions to: garyg@soda.berkeley.edu
  
  */

#include <stdio.h>
#include <string.h>

#include "linked_lists.h"
#include "handles_and_channels.h"
#include "main.h"
#include "misc_commands.h"
#include "user_output.h"


void change_name (user, name)
	struct user *user;
	char *name;
{
	static char temp [100];

	toggle_user (user, Fcomm_line);
	if (*name) {
		name[NAMEMAX-1] = '\0';
sprintf (temp, " * %s/%s is now %s/%s\r\n", user->name, user->description, 
	name, user->description);
		strncpy (user->name, name, NAMEMAX);
		user->name [NAMEMAX-1] = '\0';
		handle_channel_output (user, temp);
	} else
		write_user (user->desc, "Please choose a REAL name!\r\n");
	user->linecharmax = INPUTMAX;
}


void change_description (user, description)
	struct user *user;
	char *description;
{
	static char temp [100];

	toggle_user (user, Fcomm_line);
	if (*description) {
		description[DESCRIPTIONMAX-1] = '\0';
sprintf (temp, " * %s/%s is now %s/%s\r\n", user->name, user->description,
	user->name, description);
		strncpy (user->description, description, DESCRIPTIONMAX-1);
		user->description [DESCRIPTIONMAX-1] = '\0';
		handle_channel_output (user, temp);
	} else
		write_user (user->desc, "Please choose a REAL description!\r\n");
	user->linecharmax = INPUTMAX;

}


/* routines for handling private messages */

void handle_private (user, other_user)
	struct user *user;
	char *other_user;
{
	char temp [500];
	struct user *u;

	if (*other_user) {
		u = (struct user *) find_user (other_user);
		if (u) {
			user->private_to = u;
			write_user (user->desc, "Message: ");
			clear_queue (user->input);
			user->present_comm = process_private;
		} else {
			toggle_user (user, Fcomm_line);
			toggle_user (user, Fmultiple_comm);
			sprintf (temp, ">> %s is not logged on.\r\n", other_user);
			write_user (user->desc, temp);
		}
	} else {
		write_user (user->desc, ">> No message sent.\r\n");
		toggle_user (user, Fcomm_line);
		toggle_user (user, Fmultiple_comm);
	}
	user->linecharmax = INPUTMAX;
} 


void process_private(user, message)
  struct user *user;
  char *message;
{
  char temp[600];

  toggle_user(user, Fcomm_line);
  toggle_user(user, Fmultiple_comm);
	
  if (find_user(int2str(user->private_to->desc)) && *message) {
    if (!user || !user->private_to->gags || 
        !testbit(user->private_to->gags, user->desc-1)) {
      sprintf(temp, "(%d,p %s) %s\r\n", user->desc, user->name, message);
        process_output(user->private_to, 
         process_message(user->private_to, user, message, 2));
    }
    sprintf(temp, ">> Private message sent to %s on line %d.\r\n", 
     user->private_to->name, user->private_to->desc);
    write_user(user->desc, temp);
  } else if (*message)
    write_user(user->desc, ">> User is no longer logged on.\r\n");
  else
    write_user(user->desc, ">> No message sent.\r\n");
}


/* routine used for handling yells */

void yell (user, message)
	struct user *user;
	char *message;
{
	char temp[600];

	toggle_user (user, Fcomm_line);
	if (is_user (user, Fhush) ) {
		write_user (user->desc, ">> You cannot yell when hushed.\r\n");
		return;
	}
	if (*message) {
		sprintf (temp, "(*%d, %s*) %s\r\n", user->desc, user->name, message);
	/*	handle_yells_output (user, temp); */
		handle_yells_output (user, message);
	} else
		write_user (user->desc, ">> You didn't yell anything.\r\n");	
}
	
/* routines used for handling channels */


void change_channel (user, name)
	struct user *user;
	char *name;
{
	char temp[200];
	struct user *u;
	struct channel 	*new_channel, *old_channel;

	write_err ("at beginning of change_channel\r\n");

	if (!*name) {
		write_user (user->desc, ">> Please choose a REAL channel!\r\n");
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
		return;
	}

	new_channel = (struct channel *) find_channel (name);
	old_channel = user->channel;


	write_err ("after find_channel\r\n");

	if (!new_channel) {
		if ( (new_channel = (struct channel *) malloc (sizeof(struct channel))) 
		  == (struct channel *) 0) {
			write_user (user->desc, ">> Channel could not be allocated.  Channel has not been changed.\r\n");
			toggle_user (user, Fcomm_line);
			user->linecharmax = INPUTMAX;
			return;
		} else { 
			write_err ("before add_channel\r\n");
			add_channel (new_channel, name);
			write_err ("after add_channel\r\n");
		}	
	}

	write_err ("after !new_channel\r\n");

	if (new_channel == old_channel) {
		toggle_user (user, Fcomm_line);
		write_user (user->desc, ">> Same channel buddy.\r\n");
		user->linecharmax = INPUTMAX;
		return;
	}
	if (new_channel->lock) {
		sprintf (temp, ">> Channel %s is locked.  Sorry.\r\n", new_channel->name);
		write_user (user->desc, temp);
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
		return;
	}

	user->channel = new_channel;
	new_channel->count++;

	if (--(old_channel->count)) {
		sprintf (temp, ">> %s on line %d has wandered off to %s.\r\n",
		  user->name, user->desc, user->channel->name);
		if (old_channel->lock == user) {
			old_channel->lock = (struct user *) 0;
			strcat (temp, ">> Channel has been unlocked.\r\n");
		}		
		for (u = firstuser; u; u=u->next)
			if (u->channel == old_channel)
				process_output (u, temp);
						
	} else 
		delete_channel (old_channel);

	toggle_user (user, Fcomm_line);	
	sprintf (temp, ">> %s on line %d has joined.\r\n", user->name, user->desc);	
	for (u = firstuser; u; u = u->next)
		if (u->channel == new_channel)
			process_output (u, temp);

	user->linecharmax = INPUTMAX;
	write_err ("at end of change_channel\r\n");
}


struct channel *find_channel (channel)
	char *channel;
{
	struct channel *c;

	for (c = firstchannel; c && strncmp(channel, c->name, CHANNELMAX); c = c->next);
	return c;
}
			

void add_channel (chan, name)
	struct channel *chan;
	char *name;
{
	struct channel *c;

	initilize_channel (chan, name);

	write_err ("	channel added (before for loop)\r\n");
	for (c = firstchannel; c && c->next; c = c->next);	
	c->next = chan;

	write_err ("	channel added\r\n");
}


void initilize_channel (chan, name)
	struct channel *chan;
	char *name;
{
	strncpy (chan->name, name, CHANNELMAX);
	chan->name[CHANNELMAX-1] = '\0';
	chan->next = (struct channel *) 0;
	chan->lock = (struct user *) 0;
	chan->count = 0;
}


void delete_channel (channel)
	struct channel *channel;
{
	struct channel *c;
	
	if (channel == firstchannel) 
		firstchannel = channel->next;
	else {
		for (c = firstchannel; c->next && channel != c->next; c = c->next);
		c->next = channel->next;
	}

	write_err ("	channel deleted\r\n");
	free (channel);
}


void lock_channel (user, text)
	struct user *user;
	char *text;
{
	char temp[100];
	struct user *u;

	if (!strcmp (user->channel->name, "blah") ) {
		write_user (user->desc, ">> You cannot lock the main channel.\r\n");
		return;
	}
		
	if (!user->channel->lock) {
		user->channel->lock = user;
		sprintf (temp, ">> Channel %s has been locked by %s on line %d.\r\n", user->channel->name, user->name, user->desc);
		for (u = firstuser; u; u = u->next)
			if (u->channel == user->channel)
				process_output (u, temp);		
	} else if (user != user->channel->lock) {
		sprintf (temp, ">> Channel %s is already locked.\r\n", user->channel->name);
		write_user (user->desc, temp);
	} else if (user == user->channel->lock) {
		user->channel->lock = (struct user *) 0;
		sprintf (temp, ">> Channel %s has been unlocked by %s on line %d.\r\n", 
		  user->channel->name, user->name, user->desc);
		for (u = firstuser; u; u = u->next)
			if (u->channel == user->channel)
				process_output (u, temp);		
	}		
}


void channel_list (user, text)
	struct user *user;
	char *text;
{
	struct channel *c;
	char temp[120];

	write_user (user->desc, "   Channel	#  Secured by\r\n");	

	for (c = firstchannel; c; c = c->next) {
		sprintf (temp, "   %-*s %d %s\r\n", CHANNELMAX, c->name,
						    c->count, c->lock->name);
		write_user (user->desc, temp);
	}
}		
	
