// TDZ - Text engine of Dimouse & Zubik for IF games, december 2007 by Dimouse

#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <curses.h>
#include <stdlib.h>
#include <time.h>
#include <fstream.h>
#define	SN 6 //scenes num

int inv[100]; //inventory - IDs of objects that you currently possess
int lastitem;
bool perenos=0;
char dunno[200];
bool dunno_f=0;
bool view=0;
int cur_verb;
int curscene=1;
WINDOW *win_verbs;

int find_next_space(char *str, int pos){
for(int q=pos+1;q<abs(strlen(str));q++)
if(str[q]==32) return q-pos;
return -1; //abnormal termination
}

void mvwaddstr2(WINDOW *win, int x, int y, char *str){
//mvwaddstr(win, x, y, str);
if(perenos==0) mvwaddstr(win, x, y, str);
if(perenos==1){
	int q2=y;
	for(int q=0;q<abs(strlen(str));q++){
		if(str[q]==32){
			int eol=q2%80+find_next_space(str,q);
			if(eol>79){
				q2+=79-q2%80;
			}
		}
		mvwaddch(win,x+q2/80,q2%80,unsigned char(str[q]));
		q2++;
	}
}
}


class obj{
public:
char discr[500]; //disciption (result of "look at" command)
char name[30]; //name (one word!!!)
char name_t[30]; //tvoritel'nyj padeg!
int num; //ID

//int decl();
void show_discr(int *,WINDOW *);
};

/*int obj::decl(){
// to be written
return 1;
}
*/

class action{
public:
char w[1][80]; //"magic" words to trigger action
int word; //number of words in w
int what; //object num
int what2;//for two-objects actions and for hero's interactions (talking etc) - then it's hero's num
int where;//scene num
int conditions[100][3]; //action num (with scene num) and action state in order for this action to be done
int results[100][3]; //action num (with scene num) and action state to be changed afterwards
int inv_change[10]; //items to be added to inventory
int inv_change_s[10]; // scene of it
int state; //action state: 0 - ready, 1 - done, -1 - cannot be done
int num; //ID of action to be able to initialize it
char answer[300]; //phrase you see on the screen afterwards

void show_result(int *,WINDOW *);
};

class hero{
public:
char name[30];
action ac[100];
};

class scene{
public:
char discr[1000]; //discription
char name[30]; //name (multiply words, only for internal use)
obj o[100]; //objects
int objnum; //number of objects
action a[100]; //actions in this scene
int actnum; //number of actions
int num; //ID
int exits[4]; //exits

void show_discr(int *,WINDOW *);
int decl();
};

int scene::decl(){
//the description of file format is as follows:
//&
//name of location/
//discription of location (result of "look around") with * for marking active words/
//4 numbers for exits -1 - inactive, 1 - active
//objects in the scene, until zero (0) as follows:
//ID_num name name_t discr /
//actions in the scene, until zero (0) as follows:
//command word obj scene cond_num cond_scene_num cond_state res_num res_scene_num res_state inv_to_add inv_to_add_scene state num answer
fstream fs;
char tmp[30];
int nnum=0, exit=0;
fs.open("scenes.dat",ios::in);
if(!fs.is_open()) return 0;
while(!fs.eof()&&!exit){
	fs>>tmp;
	if(strcmp(tmp,"&")==0) nnum++;
	if(nnum==scene::num+1) exit=1;
}
fs>>tmp;
strcpy(scene::name,"");
while(strcmp(tmp,"/")!=0){
	strcat(scene::name,tmp);
	strcat(scene::name," ");
	fs>>tmp;
}
fs>>tmp;
strcpy(scene::discr,"");
while(strcmp(tmp,"/")!=0){
	strcat(scene::discr,tmp);
	strcat(scene::discr," ");
	fs>>tmp;
}
fs>>scene::exits[0];
fs>>scene::exits[1];
fs>>scene::exits[2];
fs>>scene::exits[3];

//objects declaration
int curnum=0,onum=1;
//fs>>onum;
while(onum!=0&&curnum<100){
	fs>>onum;
	scene::o[curnum].num=onum;
	fs>>scene::o[curnum].name;
	fs>>scene::o[curnum].name_t;
	fs>>tmp;
	strcpy(scene::o[curnum].discr,"");
	while(strcmp(tmp,"/")!=0){
		strcat(scene::o[curnum].discr,tmp);
		strcat(scene::o[curnum].discr," ");
		fs>>tmp;
	}
	curnum++;
}
scene::objnum=curnum;

//and now for actions declaration:
onum=1;
int anum=0;
curnum=0;
int curnum2=0;
while(onum!=0&&curnum<100){
	fs>>onum;
	//scene::a[curnum].what=onum;
	if(onum==1) strcpy(scene::a[curnum].w[0],"поговорить");
	if(onum==2) strcpy(scene::a[curnum].w[0],"взять");
	if(onum==3) strcpy(scene::a[curnum].w[0],"съесть");
	if(onum==4) strcpy(scene::a[curnum].w[0],"совместить");
	if(onum==5) strcpy(scene::a[curnum].w[0],"обнюхать");
	if(onum==6) strcpy(scene::a[curnum].w[0],"одеть");
	if(onum==7) strcpy(scene::a[curnum].w[0],"снять");
	if(onum==8) strcpy(scene::a[curnum].w[0],"ощупать");
	if(onum==9) strcpy(scene::a[curnum].w[0],"открыть");
	if(onum==10)strcpy(scene::a[curnum].w[0],"закрыть");
	if(onum==11)strcpy(scene::a[curnum].w[0],"отдать");
	if(onum==12)strcpy(scene::a[curnum].w[0],"прочитать");

	fs>>scene::a[curnum].word;
	fs>>scene::a[curnum].what;
	if(onum==4) fs>>scene::a[curnum].what2;
	else scene::a[curnum].what2=0;
	
	fs>>scene::a[curnum].where;
	fs>>tmp;
	anum=1;
	curnum2=0;
	while(anum!=0){
		fs>>anum;
		scene::a[curnum].conditions[curnum2][0]=anum;
		fs>>scene::a[curnum].conditions[curnum2][1];
		fs>>scene::a[curnum].conditions[curnum2][2];
		curnum2++;
	}
	anum=1;
	curnum2=0;
	fs>>tmp;
	while(anum!=0){
		fs>>anum;
		scene::a[curnum].results[curnum2][0]=anum;
		fs>>scene::a[curnum].results[curnum2][1];
		fs>>scene::a[curnum].results[curnum2][2];
		curnum2++;
	}
	fs>>tmp;
	anum=1;
	curnum2=0;
	while(anum!=0){
		fs>>anum;
		scene::a[curnum].inv_change[curnum2]=anum;
		fs>>scene::a[curnum].inv_change_s[curnum2];
		curnum2++;
	}
	fs>>scene::a[curnum].state;
	fs>>scene::a[curnum].num;

	fs>>tmp;
	strcpy(scene::a[curnum].answer,"");
	while(strcmp(tmp,"/")!=0){
		strcat(scene::a[curnum].answer,tmp);
		strcat(scene::a[curnum].answer," ");
		fs>>tmp;
	}
	curnum++;
}
scene::actnum=curnum;

return 1;
}

void scene::show_discr(int *line, WINDOW *win){
	int bold=0;
	int q2=0;
	wattrset(win, COLOR_PAIR(1));
	for(int q=0;q<int(strlen(scene::discr));q++){
		if(scene::discr[q]=='*'&&bold==0){
			wattrset(win, COLOR_PAIR(2));
			bold=1;
		}
		else if(scene::discr[q]=='*'&&bold==1){
			wattrset(win, COLOR_PAIR(1));
			bold=0;
		}
		else{
			if(unsigned char(scene::discr[q])==32&&perenos==1){ //space
				int eol=q2%80+find_next_space(scene::discr,q);
				if(eol>79){
					q2+=79-q2%80;
					*line+=1;
					if(*line>20){
						scroll(win);
						*line-=1;
					}
				}
			}
			mvwaddch(win, *line/*+q2/80*/, q2%80, unsigned char(scene::discr[q]));
			q2++;
		if(q2%80==0&&perenos==0){
			*line+=1;
			if(*line>20){
				scroll(win);
				*line-=1;
			}
		}
		}
	}
	*line+=1;
	q2=20;
	int first=1;
	mvwaddstr(win, *line, 0, "Вы видите выходы к: ");
	if(scene::exits[0]!=-1){
		mvwaddstr(win, *line, q2, "востоку");
		q2+=7;
		first=0;
	}
	if(scene::exits[1]!=-1){
		if(!first){
			mvwaddstr(win, *line, q2, ", ");
			q2+=2;
		}
		mvwaddstr(win, *line, q2, "западу");
		q2+=6;
		first=0;
	}
	if(scene::exits[2]!=-1){
		if(!first){
			mvwaddstr(win, *line, q2, ", ");
			q2+=2;
		}
		mvwaddstr(win, *line, q2, "северу");
		q2+=6;
		first=0;
	}
	if(scene::exits[3]!=-1){
		if(!first){
			mvwaddstr(win, *line, q2, ", ");
			q2+=2;
		}
		mvwaddstr(win, *line, q2, "югу");
		q2+=3;
		first=0;
	}
	mvwaddstr(win, *line, q2, ".");
	*line+=1;

	if(*line>20){
				scroll(win);
				*line-=1;
	}
//	*line+=strlen(scene::discr)/80+1;
	//cout<<"You see exits to ";
	//if(scene::exits[0]!=-1) cout<<"East ";
	//if(scene::exits[1]!=-1) cout<<"West ";
	//if(scene::exits[2]!=-1) cout<<"North ";
	//if(scene::exits[3]!=-1) cout<<"South ";
	//cout<<endl;
}

void obj::show_discr(int *line, WINDOW *win){
	int bold=0;
	int q2=0;
	for(int q=0;q<int(strlen(obj::discr));q++){
		if(obj::discr[q]=='*'&&bold==0){
			wattrset(win, COLOR_PAIR(2));
			bold=1;
		}
		else if(obj::discr[q]=='*'&&bold==1){
			wattrset(win, COLOR_PAIR(1));
			bold=0;
		}
		else{
			if(unsigned char(obj::discr[q])==32&&perenos==1){ //space
				int eol=q2%80+find_next_space(obj::discr,q);
				if(eol>79){
					q2+=79-q2%80;
					*line+=1;
					if(*line>20){
						scroll(win);
						*line-=1;
					}
				}
			}
			mvwaddch(win, *line/*+q2/80*/, q2%80, unsigned char(obj::discr[q]));
			q2++;
			if(q2%80==0&&perenos==0){
			*line+=1;
			if(*line>20){
				scroll(win);
				*line-=1;
			}
		}
		}
	}
	//*line+=/*strlen(obj::discr)*/q2/80+1;
	*line+=1;
	if(*line>20){
				scroll(win);
				*line-=1;
	}
}

void action::show_result(int *line, WINDOW *win){
	int bold=0;
	int q2=0;
	for(int q=0;q<int(strlen(action::answer));q++){
		if(action::answer[q]=='*'&&bold==0){
			wattrset(win, COLOR_PAIR(2));
			bold=1;
		}
		else if(action::answer[q]=='*'&&bold==1){
			wattrset(win, COLOR_PAIR(1));
			bold=0;
		}
		else{
			if(unsigned char(action::answer[q])==32&&perenos==1){ //space
				int eol=q2%80+find_next_space(action::answer,q);
				if(eol>79){
					q2+=79-q2%80;
					*line+=1;
					if(*line>20){
						scroll(win);
						*line-=1;
					}
				}
			}
			mvwaddch(win, *line/*+q2/80*/, q2%80, unsigned char(action::answer[q]));
			q2++;
			if(q2%80==0&&perenos==0){
			*line+=1;
			if(*line>20){
				scroll(win);
				*line-=1;
			}
		}
		}
	}
	//*line+=/*strlen(action::answer)*/q2/80+1;
	*line+=1;
	if(*line>20){
				scroll(win);
				*line-=1;
	}
}

//--------------------------------------------------
int WaitForUser(void);
int SubWinTest(WINDOW *);
int BouncingBalls(WINDOW *);
void trap(int);
int to_rus(int);
scene s1[SN]; //global and demo levels
//--------------------------------------------------

class parser{
public:
char buffer[10][80]; //buffer for input string
int word; //number of words in the input string

parser::parser();
int read(int, WINDOW *);
int analyze(int *, WINDOW *);
int test_scene(scene *,int *, WINDOW *);
};

parser::parser(){
	for(int j=0;j<10;j++){
		//buffer[j] = new char[81];
		for(int i=0;i<80;i++) buffer[j][i]=0;
	}
	word=0;
}

void draw_verbs(){
char verbs[21][20]={"выход","помощь","осмотреться","инвентарь","осмотреть","поговорить","взять","съесть",
"совместить","обнюхать","одеть","снять","ощупать","открыть","закрыть","отдать","прочитать","идти"};
int pos=0;
wattrset(win_verbs, COLOR_PAIR(1));
//if(cur_verb==i) wattrset(win_com, COLOR_PAIR(1));
for(int i=0;i<18;i++){
if(cur_verb==i) wattrset(win_verbs, COLOR_PAIR(3));
if(cur_verb+1==i) wattrset(win_verbs, COLOR_PAIR(1));
mvwaddstr2(win_verbs, pos/80, pos%80, verbs[i]);
pos+=strlen(verbs[i])+1;
}
wrefresh(win_verbs);
}

int parser::read(int line, WINDOW * win){
void draw_verbs();

static const char spinner[5] = "/-\\|";
int spinner_count = 0;
int end=0;
int c,c2;
int pos=0, pos2=0;
int space_flag=-1; //this means you can insert verb by pressing space

word=0;
if(view==1)draw_verbs();

wattrset(win, COLOR_PAIR(3));
		while (!end)
		{
			c = wgetch(win);

			if (c == ERR)
			{
				spinner_count++;
				if (spinner_count == 4)
					spinner_count = 0;
				mvwaddch(win, line, 1+pos+pos2, spinner[spinner_count]);
				wrefresh(win);
			}
			else{
				if((c2=to_rus(c))!=0&&pos<80){
					//add char to the screen and to the buffer
					buffer[word][pos]=c2;
					mvwaddch(win, line, 1+pos2+pos, c2);
					pos++;
					space_flag=0;
				}
				if(c==8&&pos>0){
					//delete char
					buffer[word][pos-1]=0;
					mvwaddch(win, line, 1+pos2+pos, ' ');
					pos--;
				}
				if(c==32&&space_flag==-1/*&&view==1*/){
					//you add a verb from win_verbs to the command line
					char verbs[21][20]={"выход","помощь","осмотреться","инвентарь","осмотреть","поговорить","взять","съесть",
						"совместить","обнюхать","одеть","снять","ощупать","открыть","закрыть","отдать","прочитать","идти"};
					for(int i=0;i<abs(strlen(verbs[cur_verb]));i++){
						buffer[word][pos]=unsigned char(verbs[cur_verb][i]);
						mvwaddch(win, line, 1+pos2+pos, unsigned char(verbs[cur_verb][i]));
						pos++;
					}
					//c=32;
					space_flag=0;
					if(cur_verb<=3) c=10;
				}
				if(c==32&&space_flag==0){
					//space pressed - next word
					mvwaddch(win, line, 1+pos2+pos, ' ');
					pos2+=pos+1;
					pos=0;
					word++;
					space_flag=1;
					if(word>=10){
						//line++;
						pos=0;
						pos2=0;
						end=1;
					}
				}
				if(c==10||c==13){
					//finish
					mvwaddch(win, line, 1+pos2+pos, ' ');
					//line++;
					pos=0;
					pos2=0;
					end=1;
				}
				if(view==1){ //verbs routines
					if(c==KEY_LEFT&&cur_verb>0){
						cur_verb--;
						draw_verbs();
					}
					if(c==KEY_RIGHT&&cur_verb<17){
						cur_verb++;
						draw_verbs();
					}


				}
				//if(c!=32) space_flag=0;
			}	
		}
wattrset(win, COLOR_PAIR(1));
return 1;
}

int parser::test_scene(scene *ts,int *line, WINDOW *win){
//and now for main part: actions!!!
int qtrue=0,qtrue2=0;
int qact=-1;
int do_flag=0;
int nevozmogn=0;

for(int q=0;q<ts->actnum-1;q++){
//	int do_flag=0;
	//for(int q2=0;q2<s1.a[q].word;q2++)
	int do_flag2=0;
	if(ts->a[q].word==3){
		if(strcmp(ts->a[q].w[0],"совместить")==0){ //for merging items
			if(strcmp(ts->a[q].w[0],buffer[0])!=0)do_flag2=1;
			for(int q2=0;q2<s1[ts->a[q].where/1000].objnum;q2++)
				if(s1[ts->a[q].where/1000].o[q2].num==ts->a[q].what) qtrue=q2;
			for(q2=0;q2<s1[ts->a[q].where%1000].objnum;q2++)
				if(s1[ts->a[q].where%1000].o[q2].num==ts->a[q].what2) qtrue2=q2;
			if(strcmp(s1[ts->a[q].where/1000].o[qtrue].name_t,buffer[1])!=0&&strcmp(s1[ts->a[q].where%1000].o[qtrue2].name_t,buffer[1])!=0)do_flag2=1;
			if(strcmp(s1[ts->a[q].where/1000].o[qtrue].name_t,buffer[3])!=0&&strcmp(s1[ts->a[q].where%1000].o[qtrue2].name_t,buffer[3])!=0)do_flag2=1;
			if(strcmp(buffer[2],"и")!=0)do_flag2=1;
			if(!do_flag2){
				//if(s1.a[qact].state!=0)
				qact=q;
			}
			do_flag2=0;
		}
	}
	if(ts->a[q].word==2){
		if(strcmp(ts->a[q].w[0],"поговорить")==0){ //talk to
			if(strcmp(ts->a[q].w[0],buffer[0])!=0)do_flag2=1;
			for(int q2=0;q2<s1[ts->a[q].where].objnum;q2++){
				if(s1[ts->a[q].where].o[q2].num==ts->a[q].what) qtrue=q2;
			}
			if(strcmp(s1[ts->a[q].where].o[qtrue].name,buffer[2])!=0)do_flag2=1;
			if(strcmp(buffer[1],"с")!=0)do_flag2=1;
			if(!do_flag2){
				//if(s1.a[qact].state!=0)
				qact=q;
			}
			do_flag2=0;
		}
	}
	if(ts->a[q].word==1){
		if(strcmp(ts->a[q].w[0],buffer[0])!=0)do_flag2=1;
		for(int q2=0;q2<s1[ts->a[q].where].objnum;q2++){
				if(s1[ts->a[q].where].o[q2].num==ts->a[q].what) qtrue=q2;
		}
		if(strcmp(s1[ts->a[q].where].o[qtrue].name_t,buffer[1])!=0)do_flag2=1;
		if(!do_flag2){
			//if(qact!=-1){
			//	if(s1.a[qact].state!=0)
			qact=q;
			//}
			//else
			qact=q;
		}
		do_flag2=0;
	}
//}


	if(qact!=-1){

	if(ts->a[qact].state==0){
	//check conditions:
		int q=0;
		int do_flag=0;
		int cond_w,cond_s;
		while(ts->a[qact].conditions[q][0]!=0){
			cond_w=ts->a[qact].conditions[q][0];
			cond_s=ts->a[qact].conditions[q][2];
			if(s1[ts->a[qact].conditions[q][1]].a[cond_w].state!=cond_s)do_flag=1;
			q++;
		}
		if(do_flag==0){//all conditions are fulfilled
		//now change states of actions in result
//mvwaddstr2(win, *line, 0, "OK!!!");
			int cond_w,cond_s;
			q=0;
			while(ts->a[qact].results[q][0]!=0){
				cond_w=ts->a[qact].results[q][0];
				cond_s=ts->a[qact].results[q][2];
				if(cond_w==-1){
					ts->a[qact].show_result(line,win);
					//napms(5000);
					return -1; //death
				}
				s1[ts->a[qact].results[q][1]].a[cond_w].state=cond_s;
				q++;
			}
			q=0;
			//change inventory now:
			while(ts->a[qact].inv_change[q]!=0){
				if(ts->a[qact].inv_change_s[q]>0){
					inv[lastitem]=ts->a[qact].inv_change_s[q]*100+ts->a[qact].inv_change[q];
					lastitem++;
				}
				else{
					int q_item=0;
					for(int qi=0;qi<lastitem;qi++)
						if(ts->a[qact].inv_change_s[q]*(-100)+ts->a[qact].inv_change[q]==inv[qi]) q_item=qi;
					for(qi=q_item;qi<lastitem-1;qi++)
						inv[qi]=inv[qi+1];
					inv[lastitem-1]=0;
					lastitem--;
				}
				q++;
			}
			ts->a[qact].state=1;
			ts->a[qact].show_result(line,win);
			return 1;
		}
		else{
			nevozmogn=2;
		//mvwaddstr2(win, *line, 0, "Похоже что перед этим надо что-то сделать.");
		//*line+=1;
		//return 1;
		}
	}
	else{
		nevozmogn=3;
		//mvwaddstr2(win, *line, 0, "В данный момент это сделать невозможно.");
		//*line+=1;
		//return 1;
	}
}
}
return nevozmogn;
}

//interactive part of the game:
int parser::analyze(int *line, WINDOW *win){
//exit
if(strcmp(buffer[0],"выход")==0&&word==0) return 0;
//look around
if(strcmp(buffer[0],"осмотреться")==0&&word==0){
	s1[curscene].show_discr(line, win);
	return 1;
}
//help
if(strcmp(buffer[0],"помощь")==0&&word==0){
	mvwaddstr2(win, *line, 0, "Доступные команды интерпретатора: выход, помощь, осмотреться, осмотреть <объект>, инвентарь, поговорить с <человек>, взять <объект>, съесть <объект>,");
	*line+=2;
	if(*line>20){
		scroll(win);
		scroll(win);
		*line-=2;
	}
	mvwaddstr2(win, *line, 0, "совместить <объект> и <объект>, обнюхать <объект>, одеть <объект>, снять <объект>, ощупать <объект>, открыть <объект>, закрыть <объект>, отдать <объект>");
	*line+=2;
	if(*line>20){
		scroll(win);
		scroll(win);
		*line-=2;
	}
	mvwaddstr2(win, *line, 0,  "<человеку>, прочитать <объект>, идти на <восток/запад/север/юг>");
	*line+=1;
	if(*line>20){
		scroll(win);
		*line-=1;
	}

	return 1;
}
//inventory
if(strcmp(buffer[0],"инвентарь")==0&&word==0){
	mvwaddstr2(win, *line, 0, "Ваш инвентарь: ");
	int q=0,qtrue;
	int pos=15;
	while(inv[q]!=0){
		for(int q2=0;q2<s1[inv[q]/100].objnum;q2++){
			if(s1[curscene].o[q2].num==inv[q]%100) qtrue=q2;
		}
		if(q>0){
			mvwaddstr2(win, *line, pos, ", ");
			pos+=2;
		}
		wattrset(win, COLOR_PAIR(2));
		mvwaddstr2(win, *line, pos, s1[curscene].o[qtrue].name);
		wattrset(win, COLOR_PAIR(1));
		pos+=strlen(s1[curscene].o[qtrue].name);
		q++;
	}
	if(q==0){
		mvwaddstr2(win, *line, pos, "пусто");
		pos+=5;
	}
	mvwaddstr2(win, *line, pos, ".");
	pos++;
	*line+=pos/80+1;
	return 1;
}

//look at
for(int q=0;q<s1[curscene].objnum;q++){
	if(strcmp(buffer[0],"осмотреть")==0&&strcmp(buffer[1],s1[curscene].o[q].name_t)==0&&word==1){
		s1[curscene].o[q].show_discr(line, win);
	//	mvwaddstr(win, *line, 1, "yes");
		return 1;
	}
	//mvwaddstr(win, *line, 1, s1.o[1].name);
	//*line++;
}

//go to
if(word==2)
if(strcmp(buffer[0],"идти")==0&&strcmp(buffer[1],"на")==0){
	int do_exit=1;
	if(strcmp(buffer[2],"восток")==0&&s1[curscene].exits[0]!=-1) curscene=s1[curscene].exits[0];
	else if(strcmp(buffer[2],"запад")==0&&s1[curscene].exits[1]!=-1) curscene=s1[curscene].exits[1];
	else if(strcmp(buffer[2],"север")==0&&s1[curscene].exits[2]!=-1) curscene=s1[curscene].exits[2];
	else if(strcmp(buffer[2],"юг")==0&&s1[curscene].exits[3]!=-1) curscene=s1[curscene].exits[3];
	else do_exit=0;
	if(do_exit){
	mvwaddstr2(win, *line, 0,  "Вы успешно перешли на локацию ");
	mvwaddstr2(win, *line, 30,  s1[curscene].name);
	*line+=1;
	if(*line>20){
		scroll(win);
		*line-=1;
	}
	return 1;
	}
	if(!do_exit){
	mvwaddstr2(win, *line, 0,  "Туда пройти нельзя.");
	*line+=1;
	if(*line>20){
		scroll(win);
		*line-=1;
	}
	return 1;
	}
}

//testing actions of current and global scenes
int nevozmogn=parser::test_scene(&s1[0],line,win);
int nevozmogn2=parser::test_scene(&s1[curscene],line,win);

if(nevozmogn==-1||nevozmogn2==-1) return 0;
if(nevozmogn==3||nevozmogn2==3){
mvwaddstr2(win, *line, 0, "В данный момент это сделать невозможно.");
*line+=1;
return 1;
}
if(nevozmogn==2||nevozmogn2==2){
mvwaddstr2(win, *line, 0, "Похоже что перед этим надо что-то сделать.");
*line+=1;
return 1;
}

if(nevozmogn==0&&nevozmogn2==0&&dunno_f==1){
		mvwaddstr2(win, *line, 0, dunno);
		*line+=1;
}

return 1;
}

int to_rus(int c){
if(c==97||c==65) return 228;
if(c==98||c==66) return 168;
if(c==99||c==67) return 225;
if(c==100||c==68)return 162;
if(c==101||c==69)return 227;
if(c==102||c==70)return 160;
if(c==103||c==71)return 175;
if(c==104||c==72)return 224;
if(c==105||c==73)return 232;
if(c==106||c==74)return 174;
if(c==107||c==75)return 171;
if(c==108||c==76)return 164;
if(c==109||c==77)return 236;
if(c==110||c==78)return 226;
if(c==111||c==79)return 233;
if(c==112||c==80)return 167;
if(c==113||c==81)return 169;
if(c==114||c==82)return 170;
if(c==115||c==83)return 235;
if(c==116||c==84)return 165;
if(c==117||c==85)return 163;
if(c==118||c==86)return 172;
if(c==119||c==87)return 230;
if(c==120||c==88)return 231;
if(c==121||c==89)return 173;
if(c==122||c==90)return 239;
if(c==91)return 229;
if(c==93)return 234;
if(c==59)return 166;
if(c==39)return 237;
if(c==44)return 161;
if(c==46)return 238;
if(c>=48&&c<=57)return c;

return 0;
}

int WaitForUser(void)
{
	chtype ch;

	nodelay(stdscr, TRUE);
	halfdelay(50);

	ch = getch();

	nodelay(stdscr, FALSE);
	nocbreak();		/* Reset the halfdelay() value */
	cbreak();

	return (ch == '\033') ? ch : 0;
}

/* Trap interrupt */

void trap(int sig)
{
	if (sig == SIGINT)
	{
		endwin();

		exit(0);
	}
}

//MAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAINMAIN
int main(int argc, char **argv)
{
	WINDOW *win;

int seed, width, height;
int j,i;
int end_all=0;
int line=3;

#ifdef XCURSES
	Xinitscr(argc, argv);
#else
	initscr();
#endif
	seed = time((time_t *)0);
        srand(seed);

	start_color();
# if defined(NCURSES_VERSION) || (defined(PDC_BUILD) && PDC_BUILD > 3000)
	use_default_colors();
# endif
	cbreak();
	noecho();

	curs_set(0);

#if !defined(__TURBOC__) && !defined(OS2)
	signal(SIGINT, trap);
#endif
	noecho();

	/* refresh stdscr so that reading from it will not cause it to 
	   overwrite the other windows that are being created */

	refresh();

	/* Create a drawing window */

	width  = 80;
	height = 25;
	cur_verb=0;

	fstream config;
	char tmp[10];
	int red,green,blue;
	int red2,green2,blue2;

	config.open("tdz.cfg",ios::in);
	if(config.is_open()){
	config>>tmp;
	config>>red>>green>>blue;
	init_color(10, red, green, blue);
	config>>red2>>green2>>blue2;
	init_color(11, red2, green2, blue2);
	init_pair(1, 10, 11);

	config>>red>>green>>blue;
	init_color(12, red, green, blue);
	config>>red2>>green2>>blue2;
	init_color(13, red2, green2, blue2);
	init_pair(2, 12, 13);

	config>>red>>green>>blue;
	init_color(14, red, green, blue);
	config>>red2>>green2>>blue2;
	init_color(15, red2, green2, blue2);
	init_pair(3, 14, 15);
	
	config>>tmp>>tmp; //perenos
	if(strcmp(tmp,"On")==0)perenos=1;
	else perenos=0;

	config>>tmp; //answer for dunno
	config>>tmp;

	strcpy(dunno,"");
	while(strcmp(tmp,"/")!=0){
		strcat(dunno,tmp);
		strcat(dunno," ");
		config>>tmp;
	}

	if(strcmp(dunno,"Off ")==0)
		dunno_f=0;
	else dunno_f=1;

	config>>tmp; //interface type, classic or casual
	config>>tmp;
	if(strcmp(tmp,"Casual")==0)
		view=1;
	else view=0;

	}
	else{
	init_pair(1, COLOR_WHITE, COLOR_BLUE);

	init_pair(2, COLOR_RED, COLOR_BLUE);
//	wattrset(win, COLOR_PAIR(2));

	init_pair(3, COLOR_GREEN, COLOR_BLUE);
//	wattrset(win, COLOR_PAIR(3));
	}

	WINDOW *win1,/**win_verbs,*/*win_com;

	if(view==1){ //casual mode on!
		win1 = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
		//win1=newwin(0,0,0,0);
		win = newwin(22, 80, 0, 0);
		win_verbs = newwin(2, 80, 23, 0);
		win_com = newwin(1, 80, 22, 0);

		if (win1 == NULL||win==NULL||win_verbs==NULL||win_com==NULL)
		{
			endwin();
			return 1;
		}
		wclear(win1);
		wclear(win_verbs);
		wclear(win_com);
		overlay(win,win1);
		overlay(win_verbs,win1);
		overwrite(win_com,win1);
		//wbkgd(win, COLOR_PAIR(1));
		wbkgd(win_verbs, COLOR_PAIR(1));
		wbkgd(win_com, COLOR_PAIR(3));
		wrefresh(win1);
		wrefresh(win_verbs);
		wrefresh(win_com);

	}
	else{
		win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
		
		if (win == NULL)
		{
			endwin();
			return 1;
		}
	}

	wbkgd(win, COLOR_PAIR(1));

	werase(win);
	wrefresh(win);
    wattrset(win, 0);
	wtimeout(win, 200);
	keypad(win, TRUE);
	wtimeout(win_com,200);
	keypad(win_com, TRUE);

	PDC_save_key_modifiers(TRUE);
	PDC_return_key_modifiers(TRUE);
	curs_set(0);		/* turn cursor off */
	scrollok(win, TRUE);

	parser par;

	s1[curscene].num=1;
	s1[curscene].decl();
	s1[curscene].show_discr(&line, win);
	s1[0].num=0;
	s1[0].decl();
	s1[2].num=2;
	s1[2].decl();
	s1[3].num=3;
	s1[3].decl();
	s1[4].num=4;
	s1[4].decl();
	s1[5].num=5;
	s1[5].decl();

	//s1[0].show_discr(&line, win);
	for(int q=0;q<100;q++)inv[q]=0;
	inv[0]=105;
	lastitem=1;

	wattrset(win, COLOR_PAIR(3));
	mvwaddstr2(win, 0, 22, "Dimouse & Zubik corporation presents:");
	mvwaddstr2(win, 1, 15, "New interactive fiction adventure engine called TDZ");

	while(!end_all){
		
		wrefresh(win);
		if(view==0)if(par.read(line,win))line++;
		if(view==1){
			par.read(0,win_com);
			wrefresh(win);
			wclear(win_com);
			wrefresh(win_com);
		}

		//mvwaddstr(win, 20, 1, par.buffer[0]);
		wattrset(win, COLOR_PAIR(1));
		if(!par.analyze(&line,win)) end_all=1;

		for(int q=0;q<s1[curscene].actnum;q++)
			if(s1[1].a[q].num==8)
				if(s1[1].a[q].state==1){ //demo finished
					wattrset(win, COLOR_PAIR(3));
					mvwaddstr2(win, line, 0, "This demo is finished.");
					end_all=1;
				}
		//scroll window if needed
		if(line>20){
			for(int q=0;q<line-20;q++)scroll(win);
			line=20;
		}						
		
		//clear stuff
		for(j=0;j<10;j++)
		for(i=0;i<80;i++) par.buffer[j][i]=0;
		par.word=0;
	}

	
	nodelay(stdscr, FALSE);
	wattrset(win, COLOR_PAIR(3));
	mvwaddstr2(win, line, 0, "See ya!!! Press any key to exit");
	end_all=0;
	while (!end_all)
	{
			char c = wgetch(win);

			if (c != ERR)
			end_all=1;
	}
	
	//wgetch(win);
	//napms(5000);
	endwin();

	return 0;
}

/* End of NEWDEMO.C */
