#include "stdio.h"
#include "graphics.h"
#include "dos.h"
#include "math.h"
#include "stdlib.h"
#include "alloc.h"

#define YES 0
#define NO  1
#define UP  1
#define CR 13
#define BS  8
#define Error_Rate 0.1
#define Increase_Rate 0.01
#define pai 3.1415927

void Z_02(void);

void prompt2(int m13);

void prompt(int m9);
void MessageOut(int m10, int m11, char *m12);
void out(int m4, int m5, int m6, int m7, int m8);
char * getstr(int m1, int m2, char *m3);
void back(void);
void trace1(void);
void trace2(void);
void trace3(void);

void main(void)
{
	int gd=DETECT, gm;
	initgraph(&gd, &gm, "");
	back();
	Z_02();

	getch();
	closegraph();
}

/* only for W > 3h */
void Z_02(void)
{
	char *height, *t, *z_02, *e_r, *w, *NullChar, *w_mm;
	static char *temp[8]={"Impedance    Z: ","Er            : ","Height        :","Width(mil)    : ","Width(mm)     : ","t(um)         : ","Cannot Calculate!","Impedance    Z: "};
	double Height, Z_02, E_r, W, W_mm, B, ita;
	double i;

	cleardevice();
	trace2();
	settextstyle(3,HORIZ_DIR,2);
	outtextxy(50,80,"Trace over Ground Plane");

	outtextxy(310,400,"Made by Daewoo Ryu");
	outtextxy(310,420,"http://www.compraza.co.kr");
	outtextxy(310,440,"E-mail: davidryu1@yahoo.co.kr");

	height = getstr(100,200,"Height(mm)? (ex:1.0)");
	z_02 = getstr(100,200,"Z(ohm)? (ex:50)");
	e_r = getstr(100,200,"Er? (ex:4.5)");
	t = getstr(100,200,"t(um)? (ex:35.0)");

	Height = atof(height);
	Z_02 = atof(z_02);
	E_r = atof(e_r);

	prompt2(0);
	B = 377.0*pai/(2*Z_02*sqrt(E_r));
	ita = sqrt((E_r+1)/2.0) * (Z_02/60.0) + ((E_r-1.0)/(E_r+1.0))*(0.226 + 0.12/E_r);

	if(Z_02 <= 44.0-2*E_r){
		W_mm = ((2.0*Height/pai)*(B-1.0-log(2*B-1)+((E_r-1)/(2*E_r))*(log(B-1) + 0.293-0.517/E_r)))*Height;
	}else{
		W_mm = ((8*exp(ita))/(exp(2*ita) - 2.0))*Height;
	}

	w = malloc(20 * sizeof(char));
	w_mm = malloc(20 * sizeof(char));
	prompt2(2);
	W = W_mm*39.37;
	w = gcvt(W,5,w);
	w_mm = gcvt(W_mm,5,w_mm);
	if( W != 0.0 ){
		MessageOut(130,200,temp[7]);
		MessageOut(130,220,temp[1]);
		MessageOut(130,240,temp[2]);
		MessageOut(130,260,temp[3]);
		MessageOut(130,280,temp[4]);
		MessageOut(130,300,temp[5]);
		outtextxy(260,205,z_02);
		outtextxy(260,225,e_r);
		outtextxy(260,245,height);
		outtextxy(260,265,w);
		outtextxy(260,285,w_mm);
		outtextxy(260,305,t);

	}else{
		MessageOut(130,200,temp[4]);
	}
}

void back(void){
	setbkcolor(CYAN);
	settextstyle(1,0,3);
	outtextxy(150,30,"PCB Impedance Matching");
	settextstyle(0,0,1);
	outtextxy(310,400,"Made by Daewoo Ryu");
	outtextxy(310,420,"http://www.compraza.co.kr");
	outtextxy(310,440,"E-mail: davidryu1@yahoo.co.kr");
}

void MessageOut(int x, int y, char *msg1){
	setfillstyle(1,BLACK);
	bar(x, y, x + 350, y + 20);
	setfillstyle(1,LIGHTGRAY);
	bar(x, y, x+350, y + 20);
	out(x, y, 350, 20, UP);
	setcolor(WHITE);
	outtextxy(x+5,y+5, msg1);
}

void trace1(void)
{
	setfillstyle(SOLID_FILL, BLUE);

	bar(400,100,500,110);
	bar(400,130,500,140);
	/* Width */
	line(400,90,400,100);
	line(500,90,500,100);
	line(400,95,500,95);
	line(400,95,405,90);
	line(400,95,405,100);
	line(500,95,495,90);
	line(500,95,495,100);
	outtextxy(430,80,"Width");
	/* T */
	line(400,100,390,100);
	line(400,110,390,110);
	line(395,90,395,120);
	line(395,100,390,95);
	line(395,100,400,95);
	line(395,110,390,115);
	line(395,110,400,115);
	outtextxy(380,100,"T");
	settextstyle(SMALL_FONT,0,1);
	outtextxy(360,120,"thickness of the trace");
	settextstyle(0,0,1);
	/* Height */
	line(500,110,510,110);
	line(500,130,510,130);
	line(505,90,505,150);
	line(505,110,500,100);
	line(505,110,510,100);
	line(505,130,500,135);
	line(505,130,510,135);
	outtextxy(510,120,"Height");
}

void trace2(void)
{
	setfillstyle(SOLID_FILL, BLUE);
	bar(400,100,500,110);
	setfillstyle(LTSLASH_FILL, BLUE);
	bar(400,130,500,140);
	/* Width */
	line(400,90,400,100);
	line(500,90,500,100);
	line(400,95,500,95);
	line(400,95,405,90);
	line(400,95,405,100);
	line(500,95,495,90);
	line(500,95,495,100);
	outtextxy(410,80,"Width");

	/* Height */
	line(500,110,510,110);
	line(500,130,510,130);
	line(505,90,505,150);
	line(505,110,500,100);
	line(505,110,510,100);
	line(505,130,500,135);
	line(505,130,510,135);
	outtextxy(510,120,"Height");

	/* T */
	line(400,100,390,100);
	line(400,110,390,110);
	line(395,90,395,120);
	line(395,100,390,95);
	line(395,100,400,95);
	line(395,110,390,115);
	line(395,110,400,115);
	outtextxy(380,100,"T");
	settextstyle(SMALL_FONT,0,4);
	outtextxy(360,120,"thickness of the trace");
	settextstyle(0,0,1);
}

void trace3(void)
{
	setfillstyle(SOLID_FILL, BLUE);
	bar(400,100,450,110);
	bar(480,100,530,110);
	/*Width*/
	line(400,90,400,100);
	line(450,90,450,100);
	line(400,95,450,95);
	line(400,95,405,90);
	line(400,95,405,100);
	line(450,95,445,90);
	line(450,95,445,100);
	outtextxy(410,80,"Width");
	/* Height */
	line(400,100,390,100);
	line(400,110,390,110);
	line(395,90,395,120);
	line(395,100,390,95);
	line(395,100,400,95);
	line(395,110,390,115);
	line(395,110,400,115);
	outtextxy(380,100,"T");
	settextstyle(SMALL_FONT,0,4);
	outtextxy(400,60,"thickness of the trace");
	settextstyle(0,0,1);
	line(400,70,385,95);
	line(385,95,385,90);
	line(385,95,390,95);
	/* Distance */
	line(450,110,450,120);
	line(480,110,480,120);
	line(430,115,500,115);
	line(450,115,445,110);
	line(450,115,445,120);
	line(480,115,485,110);
	line(480,115,485,120);
	outtextxy(460,125,"D");
}

void prompt(int i){
	void *buffer;
	unsigned size;
	static char *msg[6] = {"Must Input FileName !", "Cannot Find File !", "Cannot Make File !", "Out of memory!", "Wrong Selection!","\0"};
	size = imagesize(220,230,400,265);
	buffer = malloc(size);
	getimage(220,230,400,265, buffer);
	setfillstyle(0,2);
	bar(220,230,400,265);
	rectangle(220,230,400,265);
	rectangle(222,232,398,263);
	outtextxy(230,245,msg[i]);
	delay(65000);
	setfillstyle(0,2);
	bar(220,230,400,265);
	putimage(220,230,buffer, COPY_PUT);
	free(buffer);
}

void prompt2(int i){
	void *buffer;
	unsigned size;
	static char *msg[6] = {"Calculating !", "Please, Wait!!", "End of Calculation","Out of memory!", "Wrong Selection!","\0"};
	size = imagesize(220,230,400,265);
	buffer = malloc(size);
	getimage(220,230,400,265, buffer);
	setfillstyle(0,2);
	bar(220,230,400,265);
	rectangle(220,230,400,265);
	rectangle(222,232,398,263);
	outtextxy(230,245,msg[i]);
	delay(65000);
	setfillstyle(0,2);
	bar(220,230,400,265);
	putimage(220,230,buffer, COPY_PUT);
	free(buffer);
}
void out(int x, int y, int width, int height, int status)
{
   setlinestyle(SOLID_LINE,0x33,2);
   settextstyle(DEFAULT_FONT,0,0);
   setusercharsize(5,4,5,4);
   if(status){
        setcolor(WHITE);
        line(x,y,x+width,y);
        line(x,y,x,y+height);
        setcolor(BLACK);
        line(x+width,y,x+width,y+height);
        line(x,y+height,x+width,y+height);
   }

   else{
        setcolor(BLACK);
        line(x,y,x+width,y);
        line(x,y,x,y+height);
        setcolor(WHITE);
        line(x+width,y,x+width,y+height);
        line(x,y+height,x+width,y+height);
    }
}


char * getstr(int x, int y, char *msg){
        char ch[2]= {'\0', '\0'};
		char *ch1;
        unsigned int i = 0;
		int  EXIT = 2;
		void *buffer;
		ch1 = malloc(20 * sizeof(char));

		for( i = 0; i <= 19; i++){
				ch1[i] = '\0';
        }
		i = 0;
	if((buffer = malloc(imagesize( x, y, x + 350, y + 50))) == NULL){
		prompt(3);
	}
	else{
			if( x > 300){
				x = 300;
			}
			if( x < 90){
				x = 100;
			}
			if( y > 400){
				y = 400;
			}
			if( y < 40){
				y = 40;
			}
			getimage(x, y, x + 350, y + 50, buffer);
			setfillstyle(1,BLACK);
			bar(x, y, x + 350, y + 50);
			setfillstyle(1,LIGHTGRAY);
			bar(x, y, x+350, y + 50);
			out(x, y, 350, 50, UP);
	}
	setcolor(WHITE);

	outtextxy(x+20,y+20, msg);
	while(EXIT){
		 if(kbhit()){
			   ch[0] = getch();
			   switch(ch[0]){
					case CR : EXIT = 0;
							  break;
					case BS : if(i>0){
							  ch1[i]='\0';
							  setcolor(LIGHTGRAY);
							  outtextxy(x + 182 + i*10, y+20, ch);
							  setcolor(WHITE);
							  i--;
							  }
							  break;
					default : ch1[i++]= ch[0];
							  outtextxy(x + 182 + i*10, y+20, ch);
							  break;
				}
			 }
        }
		putimage(x, y, buffer, COPY_PUT);
		free(buffer);
		return(ch1);
}


