#include <allegro.h>
#include <string>
#include <math.h>
#include <string.h>
using namespace std;
bool koord[680][550];
#define beyaz makecol(255, 255, 255)
#define kirm makecol(255, 16, 16)
#define mavi makecol(128, 128, 255)
#define gri makecol(128, 128, 128)
#define gri2 makecol(255, 128, 32)
#define PI 3.14159265

short int fark=4;
char k,sol[25];
bool mod1;
char a[20],b[20];

int kuvvet(int a,int b) {
 int i=0,s;
 s=1;
 for(i=0;i<b;i++) s*=a;
 return s;   
    
}    

void dosyaoku() {
    
  FILE *dosya;
  //dosya2=fopen("grafik2.ahmet","w");
  dosya=fopen("grafik.ahmet","r");
  char c;
  int i,j,k;
 /*  i=0;
  j=8;
  while(!feof(dosya)) {
      fscanf(dosya,"%c",&c);                
     if(j==512) {
      j=0;
      i++; 
      }         
    for(k=8;k>0;k--)
    {
                    if(c>=kuvvet(2,k)) {
          koord[i+k][512-(j-k)]=true;              
         c-=kuvvet(2,k);               
                        
                        }
           else  koord[i+k][512-(j-k)]=false;          
                    
                    }
    
            j+=8;    
                }                 
                      
    
    
       
                         
     
     */
     j=0;
     i=0;
    while(!feof(dosya)) {
      
      fscanf(dosya,"%c",&c);  
      if(j==512) {
           j=0;
           i++;      
      
      
                 
                }
              if(c=='1') koord[i][512-j]=true;
              else       koord[i][512-j]=false;
  /*   if(j==512) {
      j=0;
      i++; 
      }         
    for(k=0;k<8;k++)
    {
                    if(c>=kuvvet(2,8-k)) {
          koord[i][512-(j-k)]=true;              
         c-=kuvvet(2,8-k);               
                        
                        }
           else  koord[i][512-(j-k)]=false;          
                    
                    }
    
            j+=8;    */
            
            j++;
                }                  
     fclose(dosya);
     }


int logahmett(int b,int a) {
    
    int i=0,c;
    c=a;
    float f;
    while(a>1) {
      a=a/b;         
       i++;
      // printf("%d ",a);        
               
               }
    return i;
}
float logahmet(int b,int a) {
    int i=0,c;
    c=a;
    float f;
    while(a>1) {
      a=a/b;         
       i++;
      // printf("%d ",a);        
               
               }
     f=i*1.0;          
   if(pow(b,f)*1.0==c*1.0 )                    
    return f;
    
   else if (pow(b,f)*1.0>c*1.0 )  {
         while (pow(b,f)*1.0>c*1.0 ) f-=0.000001;
         return f;
         
         
         }
    else while (pow(b,f)*1.0<c*1.0 ) f+=0.000001;
         return f;
    
}

bool log_varmi(char *str) {
     int i=0;
   while(str[i]!='\0') {
       if(str[i]=='l') return true;
       i++;                
                       
                       }  
     return false;
     
     }

bool cos_varmi(char *str) {
     int i=0;
   while(str[i]!='\0') {
       if(str[i]=='c') return true;
       i++;                
                       
                       }  
     return false;
     
     }

bool sin_varmi(char *str) {
     int i=0;
   while(str[i]!='\0') {
       if(str[i]=='s') return true;
       i++;                
                       
                       }  
     return false;
     
     }

char * cos_coz(char *str) {
     char temp[50],sind[5];
     char kopya[50],kopya2[50],kopya3[50];
     int i,j,k;
     float l;
     i=0;
     j=0;
     strcpy(temp,str);
  //   puts(temp);
     while(temp[i]!='c'){
                
              kopya2[i]=temp[i];
               i++;        
                         
                         }
        kopya2[i]='\0';                 
     i+=3;
     while(temp[i]!='\0'){
             kopya[j]=temp[i];
              i++;           
              j++;
                         
                         }
                         kopya[j]='\0';
    //puts(kopya);
    sscanf(kopya,"%d",&k);
    i=0;
    j=0;
   // puts(kopya);
    while((kopya[i]>='0' && kopya[i]<='9') || kopya[i]=='-') i++;
    while(kopya[i]!='\0') {kopya3[j]=kopya[i]; i++; j++;     }
    kopya3[j]='\0';
 //   printf("kopya3:");
 //   puts(kopya3);
    
  //  printf(" '%d' ",k);
 //   puts(kopya3);
    sprintf(sind,"%.4f",cos(k*PI/180)); 
    strcat(kopya2,sind);
   strcat(kopya2,kopya3);
 //  strcat(kopya2,"4");
 // printf("kopya2:");  puts(kopya2); 
   strcpy(str,kopya2);
     }

char * sin_coz(char *str) {
     char temp[50],sind[5];
     char kopya[50],kopya2[50],kopya3[50];
     int i,j,k;
     float l;
     i=0;
     j=0;
     strcpy(temp,str);
  //   puts(temp);
     while(temp[i]!='s'){
                
              kopya2[i]=temp[i];
               i++;        
                         
                         }
        kopya2[i]='\0';                 
     i+=3;
     while(temp[i]!='\0'){
             kopya[j]=temp[i];
              i++;           
              j++;
                         
                         }
                         kopya[j]='\0';
    //puts(kopya);
    sscanf(kopya,"%d",&k);
    i=0;
    j=0;
   // puts(kopya);
    while((kopya[i]>='0' && kopya[i]<='9') || kopya[i]=='-') i++;
    while(kopya[i]!='\0') {kopya3[j]=kopya[i]; i++; j++;     }
    kopya3[j]='\0';
 //   printf("kopya3:");
 //   puts(kopya3);
    
  //  printf(" '%d' ",k);
 //   puts(kopya3);
    sprintf(sind,"%.4f",sin(k*PI/180)); 
    strcat(kopya2,sind);
   strcat(kopya2,kopya3);
 //  strcat(kopya2,"4");
 // printf("kopya2:");  puts(kopya2); 
   strcpy(str,kopya2);
     }

char * log_coz(char *str) {
     char temp[50],sind[5],c;
     char kopya[50],kopya2[50],kopya3[50];
     int i,j,k,m;
     float l;
     i=0;
     j=0;
     strcpy(temp,str);
  //   puts(temp);
     while(temp[i]!='l'){
                
              kopya2[i]=temp[i];
               i++;        
                         
                         }
        kopya2[i]='\0';                 
     i+=3;
     while(temp[i]!='\0'){
             kopya[j]=temp[i];
              i++;           
              j++;
                         
                         }
                         kopya[j]='\0';
    //puts(kopya);
    sscanf(kopya,"%d%c%d",&k,&c,&m);
    i=0;
    j=0;
   // puts(kopya);
    while((kopya[i]>='0' && kopya[i]<='9') || kopya[i]==',' || kopya[i]=='-' ) i++;
    while(kopya[i]!='\0') {kopya3[j]=kopya[i]; i++; j++;     }
    kopya3[j]='\0';
 //   printf("kopya3:");
 //   puts(kopya3);
    
  //  printf(" '%d' ",k);
 //   puts(kopya3);
    sprintf(sind,"%d",logahmett(k,m)); 
    strcat(kopya2,sind);
   strcat(kopya2,kopya3);
 //  strcat(kopya2,"4");
 // printf("kopya2:");  puts(kopya2); 
   strcpy(str,kopya2);
     }
  
  
bool carpimbul(char * k) {
     
     int i;
     for(i=0;k[i]!='\0';i++) if (k[i]=='*' || k[i]=='^' || k[i]=='/') return true;
     
     return false;
     
     }

bool strenter(char *s) {
     
     int i;
     bool enter=false;
     for(i=0;s[i]!='\0';i++) if (s[i]=='=') enter=true;
     
     return enter;
     
     
     }


float isle(char *str) {

      while(cos_varmi(str)) cos_coz(str);
         while(sin_varmi(str)) sin_coz(str);
         while(log_varmi(str)) log_coz(str);
    float s[30];
    char k[30];
    char c;
    float sol, sag;
    int i=0,t,j=0;
    /*
    k[0]='+';
    k[1]='*';
    k[2]='\0';
    s[0]=31;
    s[1]=3; 
    s[2]=50;*/
    sscanf(str,"%f%c%f%c%f%c%f%c%f%c%f%c%f%c%f%c%f%c%f%c%f%c%f%c",&s[0],&k[0],&s[1],&k[1],&s[2],&k[2],&s[3],&k[3],&s[4],&k[4],&s[5],&k[5],&s[6],&k[6],&s[7],&k[7],&s[8],&k[8],&s[9],&k[9],&s[10],&k[10]);
 // sscanf(str,"%d%c%d%c%d%c",&s[0],&k[0],&s[1],&k[1],&s[2],&k[2]);
          while(carpimbul(k)) {
  for(i=0;k[i]!='\0';i++) {
         if(k[i]=='/' || k[i]=='*' || k[i]=='^') {                
              if(k[i]=='*')  s[i]=s[i]*s[i+1];  
              if(k[i]=='/')  s[i]=s[i]/s[i+1]; 
          if(k[i]=='^')  s[i]=1.0*kuvvet(s[i],s[i+1]);
          
          //  printf("s0:%f  s1:%f s2:%f\n ",s[0],s[1],s[2]);           
                 for(j=i+1;k[j-1]!='\0';j++) {
                                 s[j]=s[j+1];
                                // printf("%d %d ");
                                 k[j-1]=k[j];
               }
                
                
                          }
                          
                          }
                          }
  
    while(k[0]!='\0') {
               if(k[0]=='+') s[0]= s[0]+s[1];
               if(k[0]=='-') s[0]= s[0]-s[1];
           //    printf("s0:%f  s1:%f s2:%f\n ",s[0],s[1],s[2]);
               for(i=1;k[i-1]!='\0';i++) {
                                 s[i]=s[i+1];
                                // printf("%d %d ");
                                 k[i-1]=k[i];
               }
               
               }
               return s[0];
     
               }

bool oncekipozitif, simdikipozitif;

bool cizdir(char * s,int x,int y) {
     int i=0,j;
     char kopya[5],sol[25],sag[25];
    strcpy(sol,"");
    strcpy(sag,"");
     for(i=0;s[i]!='=';i++) {
       if(s[i]=='x') {
       sprintf(kopya,"%d",x);
        strcat(sol,kopya);
        }
       else if(s[i]=='y') {
            sprintf(kopya,"%d",y);
        strcat(sol,kopya);
                    }
       else { sprintf(kopya,"%c",s[i]);
        strcat(sol,kopya);}
       
       
}
  
  
     for(j=i+1;s[j]!='\0';j++) {
              if(s[j]=='x') {
       sprintf(kopya,"%d",x);
        strcat(sag,kopya);
        }
       else if(s[j]=='y') {
            sprintf(kopya,"%d",y);
        strcat(sag,kopya);
                    }
       else { sprintf(kopya,"%c",s[j]);
        strcat(sag,kopya);}                 
                               
                               
                               }
       
     
     /*
     while(k!='=') {
            sscanf(s,"%c",&k);
            if(k=='x') sprintf(sol,"%d",x);
            else if (k=='y') sprintf(sol,"%d",y);
            else sprintf(sol,"%c",k);      
                   
                   }
     */
 
 //   if(x*x-y*20<fark && x*x-y*20>-fark ) return true;
 //   else return false; 
 // log(x*y)*10-y<fark
 //1.0*isle(sol)-1.0*isle(sag)<1.0*fark && 1.0*isle(sag)-1.0*isle(sol)<1.0*fark
 // 100*cos(x*PI/180)-y>-fark && 100*cos(x*PI/180)-y<fark
// i=logahmet(10,x)/1;

if(mod1) {
 if(1.0*isle(sol)-1.0*isle(sag)==0.0) koord[x+330][-y+256]=true;   
 else if(isle(sol)-isle(sag)>0) {
      simdikipozitif=true;
      if (!oncekipozitif) koord[x+330][-y+256]=true; 
      }
 else if (isle(sol)-isle(sag)<0) {
      simdikipozitif=false;
      if (oncekipozitif) koord[x+330][-y+256]=true; 
      }    
     else koord[x+330][-y+256]=false; 
     oncekipozitif=simdikipozitif;
     }
 else    if(1.0*isle(sol)-1.0*isle(sag)<1.0*fark && 1.0*isle(sag)-1.0*isle(sol)<1.0*fark) koord[x+330][-y+256]=true;    
     
     
    strcpy(a,sol);
    strcpy(b,sag);
     }


int main()
{
//dosya=fopen("fonks.txt","r"); 
//cizdir(islem,i,j);
      //   
        short int isik[11]; 
        mod1=true;
        allegro_init();
        install_keyboard();
        set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);
      bool enterhata=false;
        int i,j;
        for(i=0;i<660;i++)  for(j=0;j<512;j++) koord[i][j]=false;
        // all variables are here
        BITMAP* buffer = create_bitmap(800, 600); // initialize the double buffer
        string  edittext;                         // an empty string for editting
        string::iterator iter = edittext.begin(); // string iterator
        int     caret  = 0;                       // tracks the text caret
        bool    insert = true;                    // true of should text be inserted
        for(i=0;i<11;i++) isik[i]=0;
        char islem[50];
        // the game loop
        dosyaoku();      
 for(i=0;i<660;i++)  for(j=0;j<512;j++) if(koord[i][j]) putpixel(buffer,i,j,beyaz);
        do
        {
               
                while(keypressed())
                {
                        int  newkey   = readkey();
                        char ASCII    = newkey & 0xff;
                        char scancode = newkey >> 8;

                 
if((ASCII >= '0' && ASCII <= '9') || ASCII=='q' || ASCII=='Q' || ASCII=='w' || ASCII=='W' || ASCII=='q'
 || ASCII=='+' || ASCII=='^' || ASCII=='E' || ASCII=='e' || ASCII=='-' || ASCII=='x' || ASCII=='y' || ASCII=='/'
 || ASCII=='=' || ASCII=='*' || ASCII=='R' || ASCII=='r' || ASCII=='p' || ASCII=='P'  || ASCII=='t' || ASCII=='T'
 || ASCII=='c' || ASCII=='o' || ASCII=='s' || ASCII=='i' || ASCII=='n'|| ASCII=='l' ||  ASCII=='g' ||  ASCII==','
 )
                        {
                         if (ASCII >= '0' && ASCII <= '9') isik[0]=20;      
                           
                           if(ASCII=='q' || ASCII=='Q'){ ASCII='^';
                           isik[1]=20;
                           } 
                           if(ASCII=='w' || ASCII=='W' || ASCII=='+') {
                                         ASCII='+';
                                         isik[2]=20;
                                         }       
                           
                           if(ASCII=='e' || ASCII=='E' || ASCII=='-') {
                                         ASCII='-';
                                         isik[3]=20;
                                         }       
                           if(ASCII=='r' || ASCII=='R' || ASCII=='*') {
                                         ASCII='*';
                                         isik[4]=20;
                                         }      
                          if(ASCII=='p' || ASCII=='P' || ASCII=='/') {
                                         ASCII='/';
                                         isik[5]=20;
                                         }   
                           if(ASCII=='t' || ASCII=='T' || ASCII=='=') {
                                         ASCII='=';
                                         isik[6]=20;
                                         }               
                                                        
                              if(ASCII=='x' || ASCII=='X') {
                                         ASCII='x';
                                         isik[9]=20;
                                         } 
                             if(ASCII=='y' || ASCII=='Y') {
                                         ASCII='y';
                                         isik[10]=20;
                                         }                
                                                       
                                if(insert || iter == edittext.end())
                                iter = edittext.insert(iter, ASCII);
                                else
                                edittext.replace(caret, 1, 1, ASCII);

                                
                                caret++;
                                iter++;
                                
                      if(ASCII=='s' || ASCII=='S') {
                                     iter = edittext.insert(iter, 'i');
                                    caret++;
                                iter++;
                                  iter = edittext.insert(iter, 'n');
                                    caret++;
                                iter++;
                                    }           
                        if(ASCII=='c' || ASCII=='C') {
                                     iter = edittext.insert(iter, 'o');
                                    caret++;
                                iter++;
                                  iter = edittext.insert(iter, 's');
                                    caret++;
                                iter++;
                                    }           
                        }
                      
                        else
                        switch(scancode)
                        {
                                case KEY_DEL:
                                if(iter != edittext.end()) iter = edittext.erase(iter);
                                break;

                                case KEY_BACKSPACE:
                                    strcpy(islem,edittext.c_str()); 
                                    if(islem[edittext.length()-1]=='n') {
                                          caret--;
                                        iter--;
                                        iter = edittext.erase(iter);      
                                        
                                           caret--;
                                        iter--;
                                        iter = edittext.erase(iter);                         
                                                                        
                                                                        }
                                     if(islem[edittext.length()-1]=='s') {
                                          caret--;
                                        iter--;
                                        iter = edittext.erase(iter);      
                                        
                                           caret--;
                                        iter--;
                                        iter = edittext.erase(iter);                         
                                                                        
                                                                        }
                                if(iter != edittext.begin())
                                {
                                        caret--;
                                        iter--;
                                        iter = edittext.erase(iter);
                                }
                                
                               
                                
                                break;

                                case KEY_RIGHT:
                                if(iter != edittext.end())   caret++, iter++;
                                break;

                                case KEY_LEFT:
                                if(iter != edittext.begin()) caret--, iter--;
                                break;

                                case KEY_INSERT:
                                if(insert) insert = 0; else insert = 1;
                                break;
                                
                                case KEY_F1:
                                     dosyaoku();
                                     break;
                                case KEY_F2:
                                     mod1=!mod1;
                                   //  break;
                                case KEY_ENTER:
                                     {
                                               strcpy(islem,edittext.c_str());  //660 530
                                       for(i=0;i<660;i++) for(j=0;j<512;j++) koord[i][j]=false;       
                                 if(strenter(islem)){ 
                                                      clear(buffer);
                                                      for(i=-330;i<330;i++) { 
                                                      for(j=265;j>-256;j--){
                                                                             cizdir(islem,i,j);
                                                                             }
                                       if((i+330)%99==0)   {                                   clear(buffer);  
                textprintf_ex(buffer, font, 640, 460,mavi, -1, "Calculating....%%%d",((i+330)*(256-j)*100)/(660*512)   );                                   
                              blit(buffer, screen, 0, 0, 0, 0, 800, 600);    }
                                                                             }
                                                                             
                                     enterhata=false;
                                     }
                                     else  enterhata=true;         
                                               }
                                
                                default:

                                break;
                        }
                        if(scancode==KEY_A && fark>1) fark--,isik[6]=20,isik[8]=20;
                        if(scancode==KEY_D) fark++,isik[7]=20,isik[8]=20;
                
                }

        
             clear(buffer);   
           for(i=0;i<660;i++)  for(j=0;j<512;j++) if(koord[i][j]) putpixel(buffer,i,j,beyaz);
       //isle(i-330,-j+256,islem)
          if(enterhata) textout(buffer, font, "'=' not found in expression. ", 0, 555, kirm);
     if(!mod1)      textprintf_ex(buffer, font, 680, 160,isik[8]<=0 ? beyaz : mavi, -1, "Thickness: %d",fark);
       textprintf_ex(buffer, font, 700, 480,  mavi, -1, "COOLBLUE");
       textprintf_ex(buffer, font, 700, 490,  mavi, -1, "  GAME  ");
       textprintf_ex(buffer, font, 696, 500,  mavi, -1, " STUDIOS");
       
                textout(buffer, font, "Function: ", 0, 570, beyaz);
                 
                 textout(buffer, font, "KEYS", 710, 20, kirm);
                 textout(buffer, font, "0-9 : Digits", 680, 40, isik[0]<=0 ? beyaz : mavi);
                 textout(buffer, font, "Q: ^ (exponent)", 680, 55, isik[1]<=0 ? beyaz : mavi);
                 textout(buffer, font, "W: +", 680, 70, isik[2]<=0 ? beyaz : mavi);
                 textout(buffer, font, "E: -", 680, 85, isik[3]<=0 ? beyaz : mavi);
                 textout(buffer, font, "R: *", 680, 100, isik[4]<=0 ? beyaz : mavi);
                 textout(buffer, font, "P: /", 680, 115, isik[5]<=0 ? beyaz : mavi);
                  textout(buffer, font, "T: =", 680, 130, isik[6]<=0 ? beyaz : mavi);
                  textout(buffer, font,  "X", 690, 145, isik[9]<=0 ? beyaz : mavi);
                   textout(buffer, font, "Y", 720, 145, isik[10]<=0 ? beyaz : mavi);
         if(!mod1){         textout(buffer, font, "  <A  ", 680, 175, isik[8]<=0 ? beyaz : mavi);
                 textout(buffer, font, "    D>", 710, 175, isik[7]<=0 ? beyaz : mavi);}
              
              //   
               //  textout(buffer, font, "Thickness: %d", 680, 130, isik[8]<=0 ? beyaz : mavi);
                 textout(buffer, font, edittext.c_str(), 80, 570, beyaz);
                 hline(buffer, 80+caret*8,580,90+caret*8, gri);
                 textout(buffer, font, "-330 x" , 0, 270, gri2);
                 textout(buffer, font, "+256 y" , 335, 0, gri2);
                 textout(buffer, font, "-256 y" , 335, 520, gri2);
                 textout(buffer, font, "x +330" , 610, 270, gri2);
                // textout(buffer, font, a , 610, 290, gri2);
                //  textout(buffer, font, b , 610, 310, gri2);
                 textout(buffer, font, "Ahmet's Basic Function Grapher v0.8" , 250, 540, kirm);
                 hline(buffer, 0,512,800, beyaz);
                 hline(buffer, 5,256,655, gri);
           
                 hline(buffer, 655,256,660, gri2);
                 hline(buffer, 0,256,5, gri2);
                 vline(buffer, 660,0,512, beyaz);
                 vline(buffer, 330,5,525, gri);
                 vline(buffer, 330,0,5, gri2);
                 vline(buffer, 330,525,512, gri2);
                blit(buffer, screen, 0, 0, 0, 0, 800, 600);
  for(i=0;i<11;i++)    if  (isik[i]>0) isik[i]--;

        }while(!key[KEY_ESC]); // end of game loop

        // clean up
        destroy_bitmap(buffer);
        set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);

        return 0;
}
END_OF_MAIN()
