#include<allegro.h>
#include"error.h"
#include"genback.h"
extern COLOR_MAP additive;

struct FILTER
{
 int f[5][5];
 int div;
};

FILTER blur={{{1,1,1,1,1},
              {1,1,2,1,1},
              {1,2,2,2,1},
              {1,1,2,1,1},
              {1,1,1,1,1}},
              30};
FILTER aa={{{0,0,0 ,0,0},
            {0,1,3 ,1,0},
            {0,3,12,3,0},
            {0,1,3 ,1,0},
            {0,0,0 ,0,0}},
            26};
fix nx,ny;
void cb()
{
 nx+=0.1;
 if(nx>=SCREEN_W)
 {
  nx=0;
  ny++;
 }
 putpixel(screen,nx,ny,255);
}

void apply_filter(BITMAP *source,FILTER *flt,void (*callback)())
{
 BITMAP *dest=create_bitmap(source->w,source->h);
 if(dest==NULL) gen_error(ERR_MEMORY);
 clear(dest);
 solid_mode();

 int c;
 int r,g,b;

 for(int x=0;x<dest->w;x++)
 {
  for(int y=0;y<dest->h;y++)
  {
   r=0; g=0; b=0;
   for(int fx=0;fx<5;fx++)
   {
    for(int fy=0;fy<5;fy++)
    {
     c=getpixel(source,x+(fx-2),y+(fy-2));
     r+=getr(c)*flt->f[fx][fy];
     g+=getg(c)*flt->f[fx][fy];
     b+=getb(c)*flt->f[fx][fy];
    }
   }
   r/=flt->div;
   g/=flt->div;
   b/=flt->div;
   if(r<0) r=0;
   if(r>255) r=255;
   if(g<0) g=0;
   if(g>255) g=255;
   if(b<0) b=0;
   if(b>255) b=255;
   c=makecol(r,g,b);
   putpixel(dest,x,y,c);
   if(callback!=NULL) callback();
  }
 }
 blit(dest,source,0,0,0,0,dest->w,dest->h);
 destroy_bitmap(dest);
}

const int STARDUST=2000;
const int STARS=100;
void dogen(BITMAP *dest)
{
 clear(screen);
 textprintf(screen,font,SCREEN_W/2-10*8,SCREEN_H/2,255,"PLEASE WAIT");
 BITMAP *back=create_bitmap(640,480);
 if(back==NULL) gen_error(ERR_MEMORY);
 clear(back);
 // create stardust
 color_map=&additive;
 drawing_mode(DRAW_MODE_TRANS,NULL,0,0);
 int x,y,r,c;
 for(int n=0;n<STARDUST;n++)
 {
  x=rand()%back->w;
  y=rand()%back->h;
  r=rand()%back->w/20;
  c=makecol(0,0,rand()%20);
  circlefill(back,x,y,r,c);
 }
 apply_filter(back,&blur,cb); // blur
 // create stars
 for(int n=0;n<STARS;n++)
 {
  x=rand()%back->w;
  y=rand()%back->h;
  r=rand()%55+100;
  c=makecol(r,r,r+100);
  putpixel(back,x,y,c);
 }
 stretch_blit(back,dest,0,0,back->w,back->h,0,0,dest->w,dest->h);
 apply_filter(dest,&aa,cb);

 solid_mode();
}
void gen_back(BITMAP *dest)
{
 PALETTE pal;
 BITMAP *back=load_bitmap("back.pcx",pal);
 if(back==NULL)
 {
  dogen(dest);
 }
 else
 {
  if((back->w!=dest->w) || (back->h!=dest->h))
  {
   dogen(dest);
  }
  else
  {
   blit(back,dest,0,0,0,0,back->w,back->h);
  }
 }
 save_pcx("back.pcx",dest,pal);
}
