/***************************************************************************/
/*                            IBRAHIM AL-SHARIF                            */
/*                                GRAPHICS                                 */
/*				  PROJECT.3                                */
/***************************************************************************/
#include<graphics.h>
#include<dos.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
#include <time.h>
#define p printf
#define s scanf
#define PI 3.1415927 //used for showing application
#define d 90   //Delay Time
#define max 3        /** TO  choice any number of vertices **/

void INITIALIZE();//initialze for graphics
void Mmain();//function to be called in the main directly
void Interface();//Interface before starting in program
void font();//the function to change Fonts and show the functions dealed with
void ENDGRAPH();//getch+closegrap(); :  closes down the graphics system
void Display();//choices between Display file, Transformation, Exit

struct{          //This struct is used for dispalyfile representation

		       char cmd[32];
	float operand1;float operand2;float operand3;
	float operand4;float operand5;float operand6;
       }                  command;
//used six operands since ellipse has six operands


// I used a struct to represent contents of vertices
typedef struct object {
			int x;
			int y;
		      };

//for showing contents in different fonts
char *fname[] = { "PROGRAM TO DEAL WITh :",
		  "DISPLAY FILE",
		  "TRANSLATION",
		  "SCALLING",
		  "ROTATION",
		  "SHEARING_ x",
		  "SHAEARING_y",
		  "INST:NABIL ARMAN&SAFAA Al-JUBEH",
		  "STUDENT:IBRAHIM AL-SHARIF",
		};


void translation(object T[],int h,int v);//translation function Prototype
void scaling    (object T[],int,int,float,float);//scaling function Prototype
void rotation   (object T[],int ,int,int);//rotation function Prototype
void shearing_x (object T[],float);//shearing on x function Prototype
void shearing_y (object T[],float);//shearing on y function Prototype
void Disfile();//display file reading representation
void points();//enter the number of points for transformation process
void first(object S[]);//in order to plot first object
void drow_object(object T[]);//function to draw object
void drow_old	(object T[],object S[]);//Some steps to draw the primary triangle
int i;  //variables used in the program
/*********************************<Main>*************************************/
int main(void)
{
   Interface();//for interface before start the program
   INITIALIZE();//initialize for the graphics mode
   Mmain();//has the inputs

return 0;
}
/***************************<INITIALIZATION GRAPH>***************************/
void INITIALIZE()
{
/*request auto detection*/
int gdriver =DETECT, gmode,errorcode;

/*initialize graphics and local variables*/
initgraph(&gdriver, &gmode ,"c:\\tc\\bgi");

	/*read result of initialization*/
	errorcode = graphresult();

	/*an error occurred*/
	if(errorcode != grOk)
	{
	p("Graphics error : %s \n",grapherrormsg(errorcode));
	p("Press any key to halt:");
	getch();
	exit(1);
	}
}//END INITIALIZE
/********************************<Mmain>*************************************/
void Mmain()//function that to be called in the main
{

points();    //enter the points

}//Mmain
/******************************<interface>***********************************/
/***************************<points>***************************************/
void points()
{
object T[max];      //to make an array of (max) numbers
object S[max];      //for saving the first input points
int choice=1;  //choose from cases
int j,h,v,xp,yp,theta;    //some variable to use in porogram
float sx,sy,shear;     //some variable to use in porogram

settextstyle(TRIPLEX_FONT, HORIZ_DIR, 3);    /* select the text style */
p("\n\n				Welcome for you\n "
       "_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n\n");
p("\n\n   Please  insert the three vertices :\n\n\n");
for( j=0;j<max;j++)   //To take the vertices from the user
    {
    p("\n     	      ***   Insert the x of the vertice number (%d):",j+1);
    s("%d",&T[j].x);
//Note:  S: as struct ,  s: denotes for scanf
    if(T[j].x>639) T[j].x=639;//restriction
    if(T[j].x<0) T[j].x=0;    //restriction
    S[j].x=T[j].x;          //save initial values
    p("\n     	      ***   Insert the y of the vertice number (%d):",j+1);
    s("%d",&T[j].y);
    if(T[j].y>639) T[j].y=479; //restriction
    if(T[j].y<0) T[j].y=0;     //restriction
    S[j].y=T[j].y;          //save initial values
    }
//Note:  S: as struct ,  s: denotes for scanf
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 3);    /* select the text style */
drow_old(T,S);    //some steps(clear,set color,draw,first object,out text,reset color)
getch();            // wait for a key
while(choice!=5)    // Loop of statments untill the user insert # 5
{
    clearviewport(); //clear the viewport
    gotoxy(1,4);  //moves the cursor to the given position

    dal:p("				Welcome for you\n "
       "_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n\n");
    p("THERE ARE 5 KINDS OF THE TRANSFORMATION :\n\n\n\n"
	   "	1)-  TRANSLATION .\n"
	   "	2)-  ROTATION    .\n"
	   "	3)-  SCALING     .\n"
	   "  	4)-  SHEARING    .\n"
	   "        5)-  EXIT        .\n\n\n"
	   "INSERT THE KIND OF TRANSFORMATION YOU WANT  : ");
    s("%d",&choice);
//Note:  S: as struct ,  s: denotes for scanf
    clearviewport();          //clear the viewport
    gotoxy(1,5);     //moves the cursor to the given position
    switch(choice)//control to branch to one of a list of possible statements
      {
      case 1:    //TRANSLATION
		 T[0].x=S[0].x;//take the first values
		 T[0].y=S[0].y;//take the first values
		 T[1].x=S[1].x;//take the first values
		 T[1].y=S[1].y;//take the first values
		 T[2].x=S[2].x;//take the first values
		 T[2].y=S[2].y;//take the first values
	     p("\n   ** insert the value of x-access change:");
	     s("%d",&h);
	     p("\n   ** insert the value of y-access change:");
	     s("%d",&v);
	     drow_old(T,S); //some steps(clear,set color,draw,first object,out text,reset color)
//Note:  S: as struct ,  s: denotes for scanf
	     translation(T,h,v); //function translate to a new position
      break;

      case 2:    //ROTATION
		 T[0].x=S[0].x;//take the first values
		 T[0].y=S[0].y;//take the first values
		 T[1].x=S[1].x;//take the first values
		 T[1].y=S[1].y;//take the first values
		 T[2].x=S[2].x;//take the first values
		 T[2].y=S[2].y;//take the first values
	     p("\n  ** insert the x_axis of the pivot point(fixed):");
	     s("%d",&xp);
	     p("\n  ** insert the y_axis of the pivot point(fixed):");
	     s("%d",&yp);
	     p("\n   ** insert the angle that you want:");
	     s("%d",&theta);
	     drow_old(T,S); //some steps(clear,set color,draw,first object,out text,reset color)
//Note:  S: as struct ,  s: denotes for scanf
	     rotation(T,xp,yp,theta);//rotate object around specified point
      break;

      case 3:    //SCALING
		 T[0].x=S[0].x;//take the first values
		 T[0].y=S[0].y;//take the first values
		 T[1].x=S[1].x;//take the first values
		 T[1].y=S[1].y;//take the first values
		 T[2].x=S[2].x;//take the first values
		 T[2].y=S[2].y;//take the first values
	     p("\n   ** insert the y_axis of the pivot point(fixed):");
	     s("%d",&xp);
	     p("\n   ** insert the y_axis of the pivot point(fixed):");
	     s("%d",&yp);
	     p("\n   ** insert the Sx :");
	     s("%f",&sx);
	     p("\n   ** insert the Sy :");
	     s("%f",&sy);
	     drow_old(T,S); //some steps(clear,set color,draw,first object,out text,reset color)
//Note:  S: as struct ,  s: denotes for scanf
	     scaling(T,xp,yp,sx,sy);//change the size
      break;

      case 4:   //SHEARING
		seil:p("\n   ** Do you want :"
		   "\n\n  1)-  x-shearing.\n\n  2)-  y-shearing.");
	     s("%d",&i);
	     if((i!=1)&&(i!=2)){ clrscr();INITIALIZE();goto seil;/*shearing page*/}
		 T[0].x=S[0].x;//take the first values
		 T[0].y=S[0].y;//take the first values
		 T[1].x=S[1].x;//take the first values
		 T[1].y=S[1].y;//take the first values
		 T[2].x=S[2].x;//take the first values
		 T[2].y=S[2].y;//take the first values
	     p("\n** Insert the value of shearing (then presss enter):");
	     s("%f",&shear);
	     drow_old(T,S); //some steps(clear,set color,draw,first object,out text,reset color)
//Note:  S: as struct ,  s: denotes for scanf
	     if(i==1)
		shearing_x(T,shear); //vertical distortion of the object
	     if(i==2)
		shearing_y(T,shear); //horizontal distortion of the object
      break;

      case 5://EXIT
	     settextstyle(7, HORIZ_DIR, 5);      /* select the text style */
	     outtextxy(200,100,"GOOD BYE"); /* output a message */
	     outtextxy(100,220,"THE BEST FOR YOU"); /* output a message */
	     outtextxy(130,340,"IBRAHIM AL-SHARIF"); /* output a message */
	     getch();
	     exit(0);

      default:/*else*/goto dal;//stay in transformation page

      }//switch
    drow_object(T); //draw the object by throwing the vertices array
    outtextxy(T[max-1].x,T[max-1].y,"NEW TRIANGLE");/* output a message */
    getch();          // wait for a key
}//while

ENDGRAPH();    // closes down the graphics system

}//points
/*****************************<Displayfile>**********************************/
void Disfile()
{
clrscr();
FILE *ptr;
int midx, midy;INITIALIZE();
ptr=fopen("c:\\disfile.txt","r+");
if(ptr==NULL)
{settextstyle(7, HORIZ_DIR, 5);      /* select the text style */
outtextxy(100,200,"NO FILE DETECTED");getch();exit(1);}//output a message
else

while(!feof(ptr))
 {
long curpos = ftell(ptr);
 fseek(ptr, curpos, 0);
 fscanf(ptr,"%s",command.cmd);//read the name of shape

if((strcmp(command.cmd,"circle"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	circle(command.operand1,command.operand2,command.operand3);
	getch();  // wait for a key
	}//if of circle

if((strcmp(command.cmd,"line"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	fscanf(ptr,"%f",&command.operand4);
	line(command.operand1,command.operand2,command.operand3,command.operand4);
	getch();  // wait for a key
	}//if of line

if((strcmp(command.cmd,"bar"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	fscanf(ptr,"%f",&command.operand4);
	bar(command.operand1,command.operand2,command.operand3,command.operand4);
	getch();  // wait for a key
	}//if of bar

if((strcmp(command.cmd,"rectangle"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	fscanf(ptr,"%f",&command.operand4);
	rectangle(command.operand1,command.operand2,command.operand3,command.operand4);
	getch();  // wait for a key
	}//if of rectangle

if((strcmp(command.cmd,"ellipse"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	fscanf(ptr,"%f",&command.operand4);
	fscanf(ptr,"%f",&command.operand5);
	fscanf(ptr,"%f",&command.operand6);
	ellipse(command.operand1,command.operand2,command.operand3,command.operand4,command.operand5,command.operand6);
	getch();  // wait for a key
	}//if of ellipse

if((strcmp(command.cmd,"fillellipse"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	fscanf(ptr,"%f",&command.operand4);
	fillellipse(command.operand1,command.operand2,command.operand3,command.operand4);
	getch();  // wait for a key
	}//if of fillellipse


if((strcmp(command.cmd,"bar3d"))==0)
	{
	fscanf(ptr,"%f",&command.operand1);
	fscanf(ptr,"%f",&command.operand2);
	fscanf(ptr,"%f",&command.operand3);
	fscanf(ptr,"%f",&command.operand4);
	fscanf(ptr,"%f",&command.operand5);
	fscanf(ptr,"%f",&command.operand6);
	bar3d(command.operand1,command.operand2,command.operand3,command.operand4,command.operand5,command.operand6);
	getch();  // wait for a key
	}//if of fillellipse

 }//while loop
fclose(ptr);//close the file
closegraph();    //closes down the graphics system
Display();      //go to choices between Display file, Transformation, Exit
}
/******************************<TRANSLATION>*********************************/
void translation(object T[],int h,int v)
{
   for(i=0;i<max;i++)//loop to change the current vertices by given values
      {
      T[i].x = T[i].x +h;   //change of x
      T[i].y = T[i].y +v;   //change of y
      }
}//Translation
/*******************************<SCALLING>***********************************/
void scaling(object T[],int xp,int yp,float sx,float sy)
{
   for(i=0;i<max;i++) //loop to change the current vertices by given values
   {
      T[i].x = float(T[i].x - xp)* sx + xp;  //change of x
      T[i].y = float(T[i].y - yp)* sy + yp;  //change of y
   }
}//Scalling
/******************************<ROTATION>************************************/
void rotation (object T[],int xp,int yp,int theta)
{
   for(i=0;i<max;i++)//loop to change the current vertices by given values
   {
     int   x_temp=T[i].x;//to save value before change
     T[i].x = float((T[i].x - xp) * cos ( theta*PI/180 ) - (T[i].y - yp)*sin(theta*PI/180)+xp);//change of x
     T[i].y = float((T[i].y - yp) * cos ( theta*PI/180 ) + (x_temp - xp)*sin(theta*PI/180)+yp);//change of y
   }
}//Rotation
/********************************<SHEARING>**********************************/
void shearing_x(object T[],float shx)
{
   for(i=0;i<max;i++) //loop to change the current vertices by given values
       T[i].x+=shx*T[i].y;  //no distortion on horizontal ==> change of x
}//Shearing_x
/************<function make horizontal distortion of the object>*************/
void shearing_y (object T[],float shy)
{
   for(i=0;i<max;i++) //loop to change the current vertices by given values
      T[i].y+=shy*T[i].x;  //no distortion on vertical ==> change of y
}//Shearing_y
/**************<do some steps before change the vertices>*******************/
void drow_old(object T[],object S[])
{
   clearviewport();       // clear the viewport
   setcolor(WHITE);       //sets the current drawing color
   first(S);            //draw first object
   drow_object(T);       //draw the object
   outtextxy(T[max-1].x,T[max-1].y,"PRIMARY TRIANGLE"); //output a message
   setcolor(RED);         //sets the current drawing color
}//drow_old
/******************************<draw the object>*****************************/
void drow_object(object T[])
{
   for(i=0;i<max-1;i++)//loop to draw all lines unless the last
	   line (T[i].x,T[i].y,T[i+1].x,T[i+1].y); //draw line
   line (T[max-1].x,T[max-1].y,T[0].x,T[0].y); //draw the last line
   outtextxy(130,420,"Press any key to continue"); /* output a message */

}//drow_object
/******************************<first object>********************************/
void first(object S[])
{
   for(i=0;i<max-1;i++)//loop to draw all lines unless the last
	   line (S[i].x,S[i].y,S[i+1].x,S[i+1].y); //draw line
   line (S[max-1].x,S[max-1].y,S[0].x,S[0].y); //draw the last line

}//first object
/****************************<ENDGRAPH FUNCTION>*****************************/
void ENDGRAPH()
{
getch();          // wait for a key
closegraph();    // close down the graphics system
}//endgraph
/**************************<DISPLAY>***************************************/
void Display()
{
char ch;      //for entered character
clrscr();        //clear the screen
gotoxy(1, 1); cprintf("旼컴컴컴컴컴컴컴컴컴커");
gotoxy(1, 2); cprintf("�  Show  ISPLAY FILE �");
gotoxy(1, 3); cprintf("읕컴컴컴컴컴컴컴컴컴켸");
gotoxy(57, 1); cprintf("旼컴컴컴컴컴컴컴컴컴컴커");
gotoxy(57, 2); cprintf("�  Show  RANSFORMATION �");
gotoxy(57, 3); cprintf("읕컴컴컴컴컴컴컴컴컴컴켸");
gotoxy(37, 19); cprintf("旼컴컴커");
gotoxy(37, 20); cprintf("�  xit �");
gotoxy(37, 21); cprintf("읕컴컴켸");
textcolor(15);
gotoxy(9, 2); cprintf("D");
gotoxy(65, 2); cprintf("T");
gotoxy(39,20); cprintf("E");
ch=getch();//take the entered character and comparing it

if(ch=='D'||ch=='d')
  {
textcolor(8);
  clrscr();
Disfile();//call display file
  }
else if(ch=='T' || ch=='t') //if entered character is T or t
{clrscr();INITIALIZE();points();}//end of else if

if (ch=='E'||ch=='e') //if entered character is E or e
exit(1);//leave the executable program

else //any character except (E or e) or (X or x) will return to same display
Display();  //choices between Display file, Transformation, Exit
}//Dispaly file

/**************************<Display file>************************************/
void Interface()
{
clrscr();     //clear the screen
delay(d);    //delay with value (d) can change its value at define section
textcolor(WHITE);
gotoxy(43, 10); cprintf("3");//start of appearing HomeWork 3 in returning side
delay(d);//delay with value (d) can change its value at define section
gotoxy(43, 10); cprintf(" ");
gotoxy(41, 10); cprintf("K");
delay(d); //delay with value (d) can change its value at define section
gotoxy(41, 10); cprintf(" ");
gotoxy(40, 10); cprintf("R");
delay(d); //delay with value (d) can change its value at define section
gotoxy(40, 10); cprintf(" ");
gotoxy(39, 10); cprintf("O");
delay(d); //delay with value (d) can change its value at define section
gotoxy(39, 10); cprintf(" ");
gotoxy(38, 10); cprintf("W");
delay(d); //delay with value (d) can change its value at define section
gotoxy(38, 10); cprintf(" ");
gotoxy(37, 10); cprintf("E");
delay(d); //delay with value (d) can change its value at define section
gotoxy(39, 10); cprintf(" ");
gotoxy(38, 10); cprintf("M");
delay(d); //delay with value (d) can change its value at define section
gotoxy(38, 10); cprintf(" ");
gotoxy(37, 10); cprintf("O");
delay(d); //delay with value (d) can change its value at define section
gotoxy(37, 10); cprintf(" ");
gotoxy(36, 10); cprintf("H");
clrscr(); //delay with value (d) can change its value at define section
gotoxy(36, 10); cprintf(" ");
delay(d); //delay with value (d) can change its value at define section
textcolor(15);
gotoxy(36, 10); cprintf("H");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(36, 10); cprintf("H");
textcolor(15);
gotoxy(37, 10); cprintf("O");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(37, 10); cprintf("O");
textcolor(15);
gotoxy(38, 10); cprintf("M");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(38, 10); cprintf("M");
textcolor(15);
gotoxy(39, 10); cprintf("E");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(39, 10); cprintf("E");
textcolor(15);
gotoxy(40, 10); cprintf("W");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(40, 10); cprintf("W");
textcolor(15);
gotoxy(41, 10); cprintf("O");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(41, 10); cprintf("O");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(42, 10); cprintf("R");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(42, 10); cprintf("R");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(43, 10); cprintf("K");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(43, 10); cprintf("K");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(44, 10); cprintf(" ");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
textcolor(8);
gotoxy(45, 10); cprintf("3");
delay(d); //delay with value (d) can change its value at define section
textcolor(8);
gotoxy(45, 10); cprintf("3");            //end of HomeWork 3 appearing
sleep(2); //delay with value (2) can change its value
INITIALIZE();
font();//to change Fonts and show the functions dealed with
closegraph();   //close down the graphics system
Display(); //choices between Display file, Transformation, Exit
}
/*********************************<Font>************************************/
void font()
{
   delay(d+20);//delay with value (d) can change its value at define section
   int style, midx, midy;  //to change fonts
   int size = 1;
  midx = getmaxx() / 2;    //take the size of x of the screen divided by two
  midy = getmaxy() / 2;    //take the size of y of the screen divided by two

  settextjustify(CENTER_TEXT, CENTER_TEXT);//far text

   /* loop through the available text styles */
   for (style=DEFAULT_FONT; style<=GOTHIC_FONT+4; style++)
   {
      cleardevice(); //clear the device
      if (style == TRIPLEX_FONT)
	 size = 4;
  settextstyle(style, HORIZ_DIR, size);/* select the text style */
  outtextxy(midx, midy, fname[style]); /* output a message */
      getch();   //wait for a key
   }

  closegraph();    //close down the graphics system
  Display(); //choices between Display file, Transformation, Exit
}//font

