#include "scrX11.H"
sprite_linear_nontransparenttype *spriteptr=NULL;
sprite_linear_nontransparenttype *hoehenptr=NULL;
sprite_linear_nontransparenttype *wasserptr=NULL;
sprite_linear_nontransparent_screentype *screenptr=NULL;
sprite_linear_nontransparent_screentype *screen2ptr=NULL;

void paint(int aktx,int akty,uint8 wasser)
{
  if (wasser)
    {
      int16 l=wasser/16+179;
      //      if (l>allsprites_ketteptr->paletteptr->anzentries)
      //	l=allsprites_ketteptr->paletteptr->anzentries;
      screenptr->putpixel(aktx,akty,l);
    }
  else
    screenptr->putpixel(aktx,akty,spriteptr->getpixel(aktx,akty));
}

void incwasser(int x,int y,uint8 anz)
{
  uint8 w=(uint8)wasserptr->getpixel(x,y);
  if (w<=255-anz)
    w+=anz;
  else
    w=255;
  wasserptr->putpixel(x,y,(char)w);
  paint(x,y,w);
}

void decwasser(int x,int y,uint8 anz)
{
  uint8 w=(uint8)wasserptr->getpixel(x,y);
  if (w>=anz)
    w-=anz;
  else
    w=0;
  wasserptr->putpixel(x,y,(char)w);
  paint(x,y,w);
}

void dechoehe(int x,int y)
{
  uint8 w;
  if (hoehenptr->getpixel_clip(x,y,(char *)&w))
    return;
  if (w!=0)
    {
      w--;
      hoehenptr->putpixel(x,y,(char)w);
    }
}

void inchoehe(int x,int y)
{
  uint8 w;
  if (hoehenptr->getpixel_clip(x,y,(char *)&w))
    return;
  if (w!=255)
    {
      w++;
      hoehenptr->putpixel(x,y,(char)w);
    }
}

// NB: -1 falls ausserhalb 
int16 gethoehe(int x,int y)
{
  uint8 f;
  if (hoehenptr->getpixel_clip(x,y,(char *)&f))
    return -1;
  int16 lhoehe=f;
  int16 wasser=(uint8)wasserptr->getpixel(x,y);
  return (lhoehe+wasser);
}

inline void tryflow(int aktx,int akty)
{
    {
      int16 hoehe=gethoehe(aktx,akty);
      int bestx=0,besty=0;
      int bestdif=0;
      for (int rely=-1;rely<2;rely++)
	for (int relx=-1;relx<2;relx++)
	  {
	    if (relx||rely)
	      {
		int16 ohoehe=gethoehe(aktx+relx,akty+rely);
		if (ohoehe!=-1)
		  {
		    // Im sprite
		    int16 dif=hoehe-ohoehe;
		    if (dif>bestdif)
		      {
			bestx=relx;
			besty=rely;
			bestdif=dif;
		      }
		  }
	      }
	  }
      if (bestdif>=2)
	{
	  incwasser(bestx+aktx,besty+akty,bestdif>>1);
	  decwasser(aktx,akty,bestdif>>1);
	  //dechoehe(aktx,akty);
	  inchoehe(bestx+aktx,besty+akty);
	}
    }
}



int main()
{
  init_allsprites_kette("flusspal.ppm");
  // Landschaft sollt keine Flussfabren enthalten !!
  iotype *ioptr=make_file_to_io_check("fluss.spr");
  spritetype *neues=spritetype::create(ioptr,CFG_TEXT_MODE);
  delete ioptr;
  if (strcmp(neues->getheaderstring(),"sprite_linear_nontransparenttype"))
    fatalfehler("fluss.spr muss ein sprite_linear_nontransparenttype sein");
  spriteptr=(sprite_linear_nontransparenttype *)neues;
  spriteptr->mx=0;
  spriteptr->my=0;

  // Hoehen zw. 0 und 255 muss ein sprite_linear_nontransparenttype sein !!
  ioptr=make_file_to_io_check("fluss_hoehen.spr");
  neues=spritetype::create(ioptr,CFG_TEXT_MODE);
  delete ioptr;
  if (strcmp(neues->getheaderstring(),"sprite_linear_nontransparenttype"))
    fatalfehler("fluss_hoehen.spr muss ein sprite_linear_nontransparenttype sein");
  hoehenptr=(sprite_linear_nontransparenttype *)neues;
  hoehenptr->mx=0;
  hoehenptr->my=0;
  if ((hoehenptr->sx!=spriteptr->sx)||(hoehenptr->sy!=spriteptr->sy))
    fatalfehler("fluss.spr und fluss_hoehe.spr muessen die selbe groesse haben");

  // Wasserstand zw. 0 und 255
  wasserptr=new sprite_linear_nontransparenttype(spriteptr->sx,spriteptr->sy,0,0,0);

  screenptr=new sprite_linear_nontransparent_screentype(0,0,spriteptr->sx,spriteptr->sy,0,0,"flusspal.ppm","Fluss");
  screen2ptr=new sprite_linear_nontransparent_screentype(0,0,spriteptr->sx,spriteptr->sy,0,0,"hoehenpal.ppm","Hoehen");
  spriteptr->copysprite_clip(0,0,screenptr);
  screenptr->map();
  hoehenptr->copysprite_clip(0,0,screen2ptr);
  screen2ptr->map();
  int k;
  cin >>k;
  while (1)
    {
      incwasser(128,128,10);
      for (int hoehen=255;hoehen;hoehen--)
	{
	  for (int akty=0;akty<spriteptr->sy;akty++)
	    for (int aktx=0;aktx<spriteptr->sx;aktx++)
		if (hoehen==(uint8)hoehenptr->getpixel(aktx,akty))
		  {		  
		    if (hoehen>250)
		      incwasser(aktx,akty,1);
		    if (wasserptr->getpixel(aktx,akty))

		  //		if (gethoehe(aktx,akty)==hoehen)
		      tryflow(aktx,akty);
		  }
	  screenptr->map();
	  hoehenptr->copysprite_clip(0,0,screen2ptr);
	  screen2ptr->map();
	}
    }
  delete screenptr;
  delete screen2ptr;
  delete wasserptr;
  delete hoehenptr;
  delete spriteptr;
  deinit_allsprites_kette();
  return 0;
}

