/*
 *	Code from:		Philipp Meinen
 *	Copyright (C):		2003-2004 Philipp Meinen
 *
 *	Email:			lancelot@lancelot2k.dyndns.org
 *	Homepage:		http://lancelot2k.dyndns.org
 *	License:		GPL
 *							*/

#define _MAIN_CC_
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <ctime>
#include "classes.h"
#include "functions.h"
#include "signals.h"
#include "input_parameters.h"

/*
 * Programm options:
 *
 * -i		ignore that user is root
 * -c		only create a default configfile
 * -h		help
 * --help	help
 *
 */

int main(int argc, char * argv[])
{
	int ignore_root = 0;
	int startnormal = 1;
	if(argc > 1) {
		startnormal = 0;
		for(int i = 1; i < argc; i++)
		{
			/* check every argument */
			if(strcmp(argv[i], "-i") == 0) {
				ignore_root = 1;
				startnormal = 1;
			}
			if(strcmp(argv[i], "-c") == 0) {
				create_default_config();
				return 0;
			}
			if(strcmp(argv[i], "-t") == 0) {
				test_config_file();
				return 0;
			}
			if(strcmp(argv[i], "-v") == 0) {
				print_version();
				return 0;
			}
			if((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
				usage(argv[0]);
				return 0;
			}
		}
	}
	/* unknown argument are given */
	if(!startnormal) {
		printf("Unknown Argument given, try --help or -h\n");
		exit(1);
	}
	/* lets do a check who is using this programm */
	if(!getuid() || !geteuid()) {
		/* the effective or the real uid of this prozess is 0 */
		if(!ignore_root) {
			printf("You are root or this programm has the setuid-root flag set.\n");
			printf("If you know what you are doing start this programm with de option '-i'\n");
			printf("But you better use 'adduser' and add a new user (for chatting) to your system\n");
			exit(0);
		}
	}

	/* normal start */

	/* handle signals */
	signal(SIGINT, sig_handler);
	signal(SIGHUP, sig_handler);
	signal(SIGALRM, sig_handler);
	signal(SIGTERM, sig_handler);
	signal(SIGUSR1, sig_handler);
	signal(SIGUSR2, sig_handler);
	signal(SIGSTOP, sig_handler);
	signal(SIGCONT, sig_handler);
	signal(SIGTSTP, sig_handler);
	signal(SIGTTIN, sig_handler);
	signal(SIGTTOU, sig_handler);
	signal(SIGWINCH, sig_handler);

	/* Init random */
	srand(time(NULL));
	
	/* create objects of the classes */
	
	Classes.MsgDB         = new class Messages();
	Classes.TmpParameter  = new class Parameter();
	Classes.IrcUserDB     = new class UserDB();
	Classes.IrcUser       = new class User();
	Classes.Connection    = new class Server();
	Classes.IrcScreen     = new class Screen();
	Classes.Signals       = new class SigHandler();

	int input_check_ret = 0;
	int connection_ret;
	int last_connect_try = time(NULL)-(TIME_BETWEEN_CONNECT_RETRY+1);
	int time_now = last_connect_try;
	
	while(1) { /* main loop */
		time_now = time(NULL);
		switch(have_to_call_connect()){
			case 2:
				last_connect_try = time_now;
				Classes.Connection->Connect();
				break;
			case 1:
				if(last_connect_try < (time_now-TIME_BETWEEN_CONNECT_RETRY)) {
					last_connect_try = time_now;
					Classes.Connection->Connect();
				}
				break;
		}
		input_check_ret = CheckForInputData();
		if(input_check_ret == 1) { /* stdin data ready */
			Classes.IrcScreen->GetInput();
		}
		if(Classes.Connection->GetConnectStatus() == STATUS_CONNECTED) {
			/* we are not logged in, but the connection is established */
			Classes.Connection->LoginToServer();
		}
		if(Classes.Connection->GetConnectStatus() >= STATUS_CONNECTED) {
			/* we are connected to the irc network */
			if(input_check_ret == 2) { /* network data ready */
				connection_ret = Classes.Connection->GetInput();
				if(connection_ret == 1) { /* there was new input */
					Classes.IrcScreen->DrawTextScreen();
				} else { /* return value is 0, this means the connection maybe got lost -> check that */
					Classes.Connection->Disconnect();
				}
			}
			if(Classes.Connection->GetConnectStatus() >= STATUS_CONNECTED) {
				Classes.Connection->DoStartupJobs();
				Classes.Connection->PingServer();
			}
		}
	}
	return 0;
}

#undef _MAIN_CC_
