/* 
 *
 *    This application has was created by Timothy A. Graupmann. For
 *    any questions or comments send email to tgraupmann@yahoo.com.
 *
 *    This program provides a graphical user interface for the user
 *    to navigate the "Non-Repeating Fractal".
 *
 */


#include <allegro.h>
#include <math.h>


BITMAP *screen1, *screen2;


double magnitude(double re, double im)
{
   return sqrt(re*re+im*im);
}


void julia(double hscal, double wscal, double htran, double wtran)
{
   int x, y;
   int level, max_level;
   double cre, cim, zre, zim;
   double cmag, zmag;
   double vpos, hpos;
   double vinc, hinc;
   double i,j;
   int counter;

   x=0;
   y=0;
   level=0;
   max_level=21;
   cre=0.5;
   cim=0.5;
   cmag=magnitude(cre, cim);
   vpos=500*hscal+htran;
   hpos=500*wscal+wtran;
   vinc=hscal*2.0;
   hinc=wscal*2.0;
   i=-hpos;
   j=-vpos;
   counter=0;

   for(y=0; y<500; y++)
   {
      i=-hpos;
      for(x=0; x<500; x++)
      {
         zre=i;
         zim=j;
         level=0;
         zmag=magnitude(zre, zim);
         while((zmag<cmag)&&(level<max_level))
         {
	    zre+=magnitude(zre,zim)-cmag;
            zmag=magnitude(zre,zim);
	    zim+=zmag-cmag;
	    level++;
	 }
         putpixel(screen1,x,y,level);
         i+=hinc;

      }
      j+=vinc;
   }
   blit(screen1, screen, 0, 0, 262, 134, 500, 500);
}


int main(void) {
   int c,x,y;
   double hscal, wscal;
   double htran, wtran;
   PALETTE pal;

   allegro_init();
   set_color_depth(8);
   set_gfx_mode(GFX_AUTODETECT, 1024, 768, 0, 0);
   install_keyboard();

   screen1=create_bitmap(500, 500);
   screen2=create_bitmap(1024, 768);

   clear(screen);
   clear(screen1);
   clear(screen2);
   textout(screen, font, "* Use arrow keys for navigation", SCREEN_W/3, 10, 255);
   textout(screen, font, "* Use + to zoom in", SCREEN_W/3, 25, 255);
   textout(screen, font, "* Use - to zoom out", SCREEN_W/3, 40, 255);
   textout(screen, font, "* Use I to return to original position", SCREEN_W/3, 55, 255);
   textout(screen, font, "* Use S to save a screen shot", SCREEN_W/3, 70, 255);
   textout(screen, font, "* Use C to capture the screen", SCREEN_W/3, 85, 255);
   textout(screen, font, "* Use Q to quit", SCREEN_W/3, 100, 255);
   textout(screen, font, "Created by:", 800, 738, 255);
   textout(screen, font, "Timothy A. Graupmann", 800, 748, 255);
   textout(screen, font, "tgraupmann@yahoo.com", 800, 758, 255);
   //rect(screen, 0, 0, 1023, 767, 255);
   rect(screen, 261, 133, 762, 634, 255);

   for (c=1; c<4; c++) {
      pal[c].r = c*16;
      pal[c].g = 0;
      pal[c].b = 0;
   }
      pal[4].r = 63;
      pal[4].g = 0;
      pal[4].b = 0;
   for (c=5; c<9; c++) {
      pal[c].r = 0;
      pal[c].g = 63-(c-5)*16;
      pal[c].b = 0;
   }
      pal[9].r = 0;
      pal[9].g = 0;
      pal[9].b = 0;
   for (c=10; c<13; c++) {
      pal[c].r = 0;
      pal[c].g = 0;
      pal[c].b = (c-9)*16;
   }
      pal[13].r = 0;
      pal[13].g = 0;
      pal[13].b = 0;
   for (c=14; c<17; c++) {
      pal[c].r = (c-13)*16;
      pal[c].g = (c-13)*16;
      pal[c].b = 63;
   }
      pal[17].r = 63;
      pal[17].g = 63;
      pal[17].b = 63;
   for (c=18; c<21; c++) {
      pal[c].r = 63-16*(c-17);
      pal[c].g = 63-16*(c-17);
      pal[c].b = 63-16*(c-17);
   }
   pal[21].r=0;
   pal[21].g=0;
   pal[21].b=0;

   pal[0].r=0;
   pal[0].g=0;
   pal[0].b=0;
   pal[255].r=63;
   pal[255].g=63;
   pal[255].b=63;
   set_pallete(pal);

   for(x=1; x<50; x++)
      for(y=0; y<220; y++)
         putpixel(screen,x,y+1,y/10);

   hscal=0.0015;
   wscal=0.0015;
   htran=0;
   wtran=0;

   julia(hscal, wscal, htran, wtran);

   while(!key[KEY_Q])
   {
      if(key[KEY_I])
      {
         hscal=0.0015;
         wscal=0.0015;
         htran=0;
         wtran=0;
         julia(hscal, wscal, htran, wtran);
      }
      else if((readkey() & 0xff) == '+')
      {
         hscal=hscal/1.1;
         wscal=wscal/1.1;
         julia(hscal, wscal, htran, wtran);
      }
      else if((readkey() & 0xff) == '-')
      {
         hscal=hscal*1.1;
         wscal=wscal*1.1;
         julia(hscal, wscal, htran, wtran);
      }
      else if(key[KEY_LEFT])
      {
         wtran+=5*wscal;
         julia(hscal, wscal, htran, wtran);
      }
      else if(key[KEY_RIGHT])
      {
         wtran-=5*wscal;
         julia(hscal, wscal, htran, wtran);
      }
      else if(key[KEY_UP])
      {
         htran+=5*hscal;
         julia(hscal, wscal, htran, wtran);
      }
      else if(key[KEY_DOWN])
      {
         htran-=5*hscal;
         julia(hscal, wscal, htran, wtran);
      }
      else if(key[KEY_S])
      {
         save_bmp("orf6.bmp", screen1, pal);
      }
      else if(key[KEY_C])
      {
         blit(screen, screen2, 0, 0, 0, 0, 1024, 768);
         save_bmp("orf6_screen.bmp", screen2, pal);
      }

   }

   destroy_bitmap(screen1);
   destroy_bitmap(screen2);

   allegro_exit();
}
