#include <graphics.h>
#include <dos.h>
#include <math.h>
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "prnbrdr.c"
#include "sndmsgs.c"

int gdriver = DETECT, gmode, errorcode;
int midx, midy, i;
int presskey, position, action;
int z=0;

double Gx, Gy;

void mouse(int m)
{
        int mode;
        if (m == 0)
                mode = 2;
	else mode = m;
        asm{
                mov ax, mode
                int 33h
        }
}

class screen
{
float mx, my, //Размеры экрана
msx, msy;     //Масштабы по x и y
public:
screen()
    {
	int d=DETECT, m;
	initgraph(&gdriver, &gmode, ".\\");
	mx=getmaxx(); my=getmaxy();
	msx=(0.8*mx)/10.0;
	msy=(0.8*my)/10.0;
    }

~screen()
    {
	setbkcolor(0);
	closegraph();
	printf("\nBuy!!! ;-)\n\n");
    }

void axis();
void GraphXY(int);
void title(int);
};
//BLACK
void screen::axis()
	{
	setcolor(8);
	line(0.5*mx,    0.1*my, 0.5*mx, 0.9*my);     //Ось y
	line(0.1*mx-40, 0.5*my, 0.9*mx+40, 0.5*my);   //Ось x

	//line(0.1*mx-40, 0.5*my, 0.1*mx-30, 0.5*my-3);
	//line(0.1*mx-40, 0.5*my, 0.1*mx-30, 0.5*my+3);
	line(0.9*mx+40, 0.5*my, 0.9*mx+30, 0.5*my-3);
	line(0.9*mx+40, 0.5*my, 0.9*mx+30, 0.5*my+3);
	line(0.9*mx+30, 0.5*my-3, 0.9*mx+30, 0.5*my+3);
        setfillstyle(SOLID_FILL, 8);
	floodfill(0.9*mx+31, 0.5*my-1, 8);
	floodfill(0.9*mx+31, 0.5*my+1, 8);

	line(0.5*mx,    0.1*my, 0.5*mx-3, 0.1*my+10);
	line(0.5*mx,    0.1*my, 0.5*mx+3, 0.1*my+10);
	line(0.5*mx+3,    0.1*my+10, 0.5*mx-3, 0.1*my+10);
	floodfill(0.5*mx+2, 0.1*my+9, 8);
	floodfill(0.5*mx-2, 0.1*my+9, 8);
	//line(0.5*mx,    0.9*my, 0.5*mx-3, 0.9*my-10);
	//line(0.5*mx,    0.9*my, 0.5*mx+3, 0.9*my-10);
	settextstyle(0, 0, 1);
	setcolor(4);
	outtextxy(mx-32, 0.5*my+10, "X");
	outtextxy(0.5*mx+15, 0.1*my,    "Y");
	setcolor(4);
	char st[10];
	int As;
	Gx=-4.5;
	while(Gx<=4.501)
		{
		sprintf(st, "%4.1f", Gx);
		As=0.5*mx+msx*Gx;
		if(Gx!=0.0)
		line(As,       0.5*my+3, As,       0.5*my-3);
		if(Gx<0)
		outtextxy(As-20, 0.5*my+10, st);
		else
		outtextxy(As-20, 0.5*my-15, st);
		Gx+=1;
		}

	Gy=-4.5;
	while(Gy<=4.501)
		{
		sprintf(st, "%4.1f", Gy);
		As=0.5*my-msy*Gy;
		if(Gy!=0.0)
		line(0.5*mx-3, As,       0.5*mx+3, As);
		if(Gy!=0.0)
		if(Gy>0)
		outtextxy(0.5*mx-40, As-5, st);
		else
		outtextxy(0.5*mx+10, As-5, st);
		Gy+=1;
		}
	}

void screen::GraphXY(int Fn=0)
	{
	Gx=-5.0;
	while(Gx<=5.001)
		{
		if (Fn==1)
		Gy=sin(Gx);
		else
		if (Fn==2)
		Gy=cos(Gx);
		else
		Gy=tan(Gx);
		putpixel(0.5*mx+msx*Gx, 0.5*my-msy*Gy, 2);
		Gx=Gx+0.0001;
		}
	}

void screen::title(int Fn=0)
{
setcolor(3);
settextstyle(4,0,2);
if(Fn==1)
outtextxy(0.2*mx, 0.15*my, "sin (x)");
else
if(Fn==2)
outtextxy(0.2*mx, 0.15*my, "cos (x)");
else
outtextxy(0.2*mx, 0.15*my, "tn (x)");
settextstyle(0,0,0);
}



class button
{
public:
	void enables(void);
	button(int, int, char *);
	void hide(void)
	{
	setcolor(getbkcolor());
	bar3d(x, y, x+100, y+50, 3, 3);
	setcolor(getbkcolor());
	outtextxy(x+5, y+23, str);
	}
	void disables(void);
private:
	char str[50];
	int x, y;
};

button::button(int x, int y, char *str)
{
strcpy(button::str, str);
button::x=x;
button::y=y;
enables();
}

void button::enables(void)
{
setcolor(7);
setfillstyle(SOLID_FILL, 7);
bar3d(x, y, x+100, y+50, 3, 3);
setcolor(4);
outtextxy((x+(50))-(textwidth(str)/2), y+25-(textheight(str)/2), str);
}

void button::disables(void)
{
setcolor(getbkcolor());
setfillstyle(EMPTY_FILL, 7);
bar3d(x, y, x+100, y+50, 3, 3);
setcolor(7);
outtextxy((x+(50))-(textwidth(str)/2), y+25-(textheight(str)/2), str);
}


class AboutME
{
public:
	/*
	AboutME()
	{
	AboutME::str="<EMPRY>";
	}
	~AbojutME()
	{
	delete AboutME::str;
	}
	*/

	void show(char *str, int z=0, int col=7, int size=0, int style=0)
		{
		AboutME::z=z;
		AboutME::size=size;
		AboutME::style=style;
		strcpy(AboutME::str, str);
		setcolor(col);
		settextstyle(style, 0, size);
		PrnText();
		}

	void hide()
		{
		setcolor(getbkcolor());
		settextstyle(style, 0, size);
		PrnText();
		}
private:
void PrnText()
{
outtextxy(midx-(textwidth(str)/2), z, str);
settextstyle(DEFAULT_FONT, 0, 0);
}
int size, style, z;
char str[100];
};


int main(void)
{
screen n;
 /* read result of initialization */
char *error="All Ok!";
   int errorcode = graphresult();
   if (errorcode != grOk)  /* an error
       occurred */
   {
      sprintf(error, "Ошибка графики: %s", grapherrormsg(errorcode));
      prnborder(error, 4);
      ErrSnd();
      exit(1); /* terminate with error code */
   }

mouse(1);

   AboutME HEADER;
   setbkcolor(8);
   midx = getmaxx() / 2;
   midy = getmaxy() / 2;

   MainMenu:
   mouse(1);
   cleardevice();
   setbkcolor(8);
   presskey=0;
   action=0;
   position=1;
   setcolor(7);
   outtextxy(midx/2, 0, "Для выхода нажмите клавишу Esc");
   button T1(100+20, 160, "1) Обо мне");
   button T2(220+20, 160, "2) SIN(x)");
   T2.disables();
   button T3(340+20, 160, "3) COS(x)");
   T3.disables();

   TheButtons:
   presskey=0;
   presskey=getch();
   if(!presskey)
   {
   presskey=getch();
   switch(presskey)
	{
	case 75:
	if(position==1)
	{
	T1.disables();
	T3.enables();
	position=3;
	}
	else
	if(position==2)
	{
	T2.disables();
	T1.enables();
	position=1;
	}
	else
	if(position==3)
	{
	T3.disables();
	T2.enables();
	position=2;
	}
	goto TheButtons;
	case 77:
	if(position==1)
	{
	T1.disables();
	T2.enables();
	position=2;
	}
	else
	if(position==2)
	{
	T2.disables();
	T3.enables();
	position=3;
	}
	else
	if(position==3)
	{
	T3.disables();
	T1.enables();
	position=1;
	}
	goto TheButtons;
	default:
	goto TheButtons;
	}
   }
   else
   switch(presskey)
	{
	case 13:
	case 32:
	action=position;
	goto sw_action;
	case '1':
	action=1;
	goto sw_action;
	case '2':
	action=2;
	goto sw_action;
	case '3':
	action=3;
	goto sw_action;
	case 27:
	goto Exit;
	sw_action:
	default:
	switch(action)
		{
		case 1:
		mouse(0);
		for(i=0; i<3; i++)
		{
		T1.enables();
		delay(70);
		T1.disables();
		delay(70);
		}
		break;
		case 2:
		mouse(0);
		for(i=0; i<3; i++)
		{
		T2.enables();
		delay(70);
		T2.disables();
		delay(70);
		}
		break;
		case 3:
		mouse(0);
		for(i=0; i<3; i++)
		{
		T3.enables();
		delay(70);
		T3.disables();
		delay(70);
		}
		}
	 T1.hide();
	 T2.hide();
	 T3.hide();
	 delay(1000);
	}


   switch(action)
   {
   case 1:
	mouse(1);
	cleardevice();setbkcolor(1);
	//(char *str, int z=0 int col=7, int size=0, int style=0)
	delay(80);
	HEADER.show("Wohlhabende.NET", 50, YELLOW, 8, 4);
	delay(80);
	HEADER.show("Автор: Виталий Дмитриевич Новичков", 150, LIGHTGRAY, 0, 0);
	delay(80);
	HEADER.show("Студент МГТУ ГА", 160, LIGHTGRAY, 0, 0);
	delay(80);
	HEADER.show("Родился 19 июня 1992 года", 170, LIGHTCYAN, 0, 0);
	delay(80);
	HEADER.show("Живу в городе Москва", 190, LIGHTBLUE, 0, 0);
	delay(80);
	HEADER.show("В районе Ховрино", 200, LIGHTCYAN, 0, 0);

	int cx=245;
	int cy=352, cr=56;
	setcolor(15);
	setfillstyle(0,0);
	line(cx-cr, cy-cr, cx-cr, cy+cr);
	line(cx+cr, cy-cr, cx+cr, cy+cr);
	line(cx-cr, cy-cr, cx+cr, cy-cr);
	line(cx-cr, cy+cr, cx+cr, cy+cr);
	circle(cx, cy, cr);


	if(!getch())getch();
	z=0;
	while(z<getmaxy()/2)
		{
		//int left, int top, int right, int bottom
		bar(0,0,getmaxx(),z);
		delay(1);
		z+=3;
		}
	goto MainMenu;

   case 2:
	cleardevice();setbkcolor(15);
	n.axis();
	n.GraphXY(1);
	n.title(1);
	if(!getch())getch();
	goto MainMenu;

   case 3:
	cleardevice();setbkcolor(15);
	n.axis();
	n.GraphXY(2);
	n.title(2);
	if(!getch())getch();
	goto MainMenu;

   default:
   goto MainMenu;
   }
   Exit:
   z=0;
   setcolor(getbkcolor());
   setfillstyle(SOLID_FILL, 7);
   while(z<getmaxy())
	{
	//int left, int top, int right, int bottom
	bar3d(0,0,getmaxx(),z, 0, 0);
	delay(1);
	z+=5;
	}

   cleardevice();
   /* clean up */
   return 0;
}