#define PIXMAP

#include <sys/stat.h>
#include "main.h"
#include "setup.h"
#include "ex.h"
#include "pixmap.h"
#include "chara.h"

/* file size を得る */
int get_fs( char *file_name )
{
  struct stat st;

  stat(file_name,&st);
  return st.st_size;
}

/* 星をランダムに置く */
void make_default_bg()
{
  int i,j;
  XPoint st_pos[1000];

  set_col(Back);
  XFillRectangle(disp,background,gc,0,0,w1attr.width,w1attr.height);

  set_col(Star1);
  for(j=0;j<6;j++)
  {
    for(i=0;i<1000;i++)
    {
      st_pos[i].x=random()%w1attr.width;
      st_pos[i].y=random()%w1attr.height;
    }
    XDrawPoints(disp,background,gc,st_pos,1000,CoordModeOrigin);
  }

  set_col(Star2);
  for(j=0;j<1;j++)
  {
    for(i=0;i<1000;i++)
    {
      st_pos[i].x=random()%w1attr.width;
      st_pos[i].y=random()%w1attr.height;
    }
    XDrawPoints(disp,background,gc,st_pos,1000,CoordModeOrigin);
  }

  set_col(Star3);
  for(i=0;i<40;i++)
  {
    XFillRectangle(disp,background,gc,
		   random()%w1attr.width,random()%w1attr.height,2,2);
  }
}

/* tiff Image を読み込み、size が小さい場合は並べる */
void load_image()
{
  FILE *fp;
  char *data;
  int fsize;
  int backw,backh;
  int backx,backy;

  set_col(Back);
  XFillRectangle(disp,background,gc,0,0,w1attr.width,w1attr.height);

  if(bgfn[0]=='\0') { make_default_bg(); return; }

  data=(char *)calloc(1,fsize=get_fs(bgfn));
  if( (fp=fopen(bgfn,"r")) == NULL )
  {
    fprintf(stderr,"%s: Can't open '%s'\n",av[0],bgfn);
    make_default_bg();
    return;
  }
  fread(data,fsize,1,fp);
  fclose(fp);

  if(link_tiff(disp,background,0,gc,cmap,data,0,0,&backw,&backh)!=-1)
  {
    backy=0;
    while(backy<w1attr.height)
    {
      backx=0;
      while(backx<w1attr.width)
      {
	if(backx!=0||backy!=0)
	  XCopyArea(disp,background,background,gc,0,0,backw,backh,backx,backy);
	backx+=backw;
      }
      backy+=backh;
    }
  }
  else make_default_bg();

  free(data);
}

static void set_chara_values(int i,int x,int y,int width,int height)
{
  sp[i].x=x;
  sp[i].y=y;
  sp[i].width=width;
  sp[i].height=height;
}

/* キャラクタを定義する */
void set_charas()
{
/* characters */
  set_chara_values(COSMO    ,SIZE* 0,SIZE* 0,SIZE   ,SIZE   );
  set_chara_values(COSMO1   ,SIZE* 1,SIZE* 0,SIZE   ,SIZE   );
  set_chara_values(COSMO2   ,SIZE* 2,SIZE* 0,SIZE   ,SIZE   );
  set_chara_values(COSMO3   ,SIZE* 3,SIZE* 0,SIZE   ,SIZE   );
  set_chara_values(COSMO4   ,SIZE* 4,SIZE* 0,SIZE   ,SIZE   );
  set_chara_values(COSMO5   ,SIZE* 5,SIZE* 0,SIZE   ,SIZE   );
  set_chara_values(BLOCK    ,SIZE* 0,SIZE* 1,SIZE   ,SIZE   );
  set_chara_values(BLOCK_BW ,SIZE* 0,SIZE* 3,SIZE   ,SIZE   );
  set_chara_values(BALL_L   ,SIZE* 1,SIZE* 1,SIZE   ,SIZE   );
  set_chara_values(BALL_R   ,SIZE* 2,SIZE* 1,SIZE   ,SIZE   );
  set_chara_values(BALL     ,SIZE* 3,SIZE* 1,SIZE   ,SIZE   );
  set_chara_values(BALL_L_BW,SIZE* 1,SIZE* 3,SIZE   ,SIZE   );
  set_chara_values(BALL_R_BW,SIZE* 2,SIZE* 3,SIZE   ,SIZE   );
  set_chara_values(PA       ,SIZE* 4,SIZE* 1,SIZE   ,SIZE   );
  set_chara_values(STAR     ,SIZE* 5,SIZE* 1,SIZE   ,SIZE   );
  set_chara_values(STAR_BW  ,SIZE* 3,SIZE* 3,SIZE   ,SIZE   );
  set_chara_values(CURTAIN1 ,SIZE* 0,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN2 ,SIZE* 1,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN3 ,SIZE* 2,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN4 ,SIZE* 3,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN5 ,SIZE* 4,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN6 ,SIZE* 5,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN6 ,SIZE* 6,SIZE* 2,SIZE   ,SIZE   );
  set_chara_values(CURTAIN7 ,SIZE* 7,SIZE* 2,SIZE   ,SIZE   );

/* numbers */
  set_chara_values(B0,24*0,SIZE*4,24,32);
  set_chara_values(B1,24*1,SIZE*4,24,32);
  set_chara_values(B2,24*2,SIZE*4,24,32);
  set_chara_values(B3,24*3,SIZE*4,24,32);
  set_chara_values(B4,24*4,SIZE*4,24,32);
  set_chara_values(B5,24*5,SIZE*4,24,32);
  set_chara_values(B6,24*6,SIZE*4,24,32);
  set_chara_values(B7,24*7,SIZE*4,24,32);
  set_chara_values(B8,24*8,SIZE*4,24,32);
  set_chara_values(B9,24*9,SIZE*4,24,32);

  set_chara_values(S0,24*0,SIZE*5   ,24,16);
  set_chara_values(S1,24*1,SIZE*5   ,24,16);
  set_chara_values(S2,24*2,SIZE*5   ,24,16);
  set_chara_values(S3,24*3,SIZE*5   ,24,16);
  set_chara_values(S4,24*4,SIZE*5   ,24,16);
  set_chara_values(S5,24*0,SIZE*5+16,24,16);
  set_chara_values(S6,24*1,SIZE*5+16,24,16);
  set_chara_values(S7,24*2,SIZE*5+16,24,16);
  set_chara_values(S8,24*3,SIZE*5+16,24,16);
  set_chara_values(S9,24*4,SIZE*5+16,24,16);
  set_chara_values(Sx,24*5,SIZE*5+16,24,16);

  set_chara_values(SCORE,0,SIZE*6,1,32);

  set_chara_values(D0,SIZE*5+16*0,SIZE*5   ,16,16);
  set_chara_values(D1,SIZE*5+16*1,SIZE*5   ,16,16);
  set_chara_values(D2,SIZE*5+16*2,SIZE*5   ,16,16);
  set_chara_values(D3,SIZE*5+16*3,SIZE*5   ,16,16);
  set_chara_values(D4,SIZE*5+16*4,SIZE*5   ,16,16);
  set_chara_values(D5,SIZE*5+16*0,SIZE*5+16,16,16);
  set_chara_values(D6,SIZE*5+16*1,SIZE*5+16,16,16);
  set_chara_values(D7,SIZE*5+16*2,SIZE*5+16,16,16);
  set_chara_values(D8,SIZE*5+16*3,SIZE*5+16,16,16);
  set_chara_values(D9,SIZE*5+16*4,SIZE*5+16,16,16);
}

/* 裏ウィンドウ(pixmap)を作成 */
void make_pixmaps()
{
  int csize;
  int i,j,k;
  unsigned char *data;
  unsigned char c;

  background =
    XCreatePixmap(disp,w1attr.win,
		  w1attr.width,w1attr.height,XDefaultDepth(disp,0));
  mwintmp = 
    XCreatePixmap(disp,w2attr.win,
		  w2attr.width,w2attr.height,XDefaultDepth(disp,0));
  chara = XCreatePixmap(disp,mwin,SIZE*16,SIZE*8,XDefaultDepth(disp,0));
  mask  = XCreatePixmap(disp,mwin,SIZE*16,SIZE*8,XDefaultDepth(disp,0));
  scr   = XCreatePixmap(disp,mwin,w2attr.width,16,XDefaultDepth(disp,0));
  scrm  = XCreatePixmap(disp,mwin,w2attr.width,16,XDefaultDepth(disp,0));
  tmp   = XCreatePixmap(disp,mwin,TMP_WIDTH,SIZE*2,XDefaultDepth(disp,0));

  XSetForeground(disp,gc,0xffffffff);
  XFillRectangle(disp,mask ,gc,0,0,SIZE*16,SIZE*8);
  XSetForeground(disp,gc,0);
  XFillRectangle(disp,chara,gc,0,0,SIZE*16,SIZE*8);

  /* 圧縮されたデータを展開 */
  csize=cdata[0]+cdata[1]*0x100+cdata[2]*0x10000+cdata[3]*0x1000000;
  data=malloc(csize);
  j=4; k=0;
  for(;;)
  {
    c=cdata[j++];
    for(i=0;i<cdata[j];i++) data[k++]=c;
    j++;
    if(k==csize) break;
  }
  link_tiff(disp,chara,mask,gc,cmap,data,0,0,NULL,NULL);
  free(data);

  load_image();

  set_charas();
}

/* テンポラリ領域をクリア */
void init_tmp()
{
  int i;

  init_stack(&tmp_stack);
  for(i=0;i<MAXTMP;i++) push(&tmp_stack,i);
}

/* キャラクタを合成 */
int put_sp(Window win,int c,int x,int y,int ty)
{
  int n;

  if( (n=pop(&tmp_stack))==-1 )
  {
    fprintf(stderr,"No more temporaries!\n");
    return 0;
  }

  if(ty==0) { sppos[n].tx=n*SIZE; sppos[n].ty=0;  }
       else { sppos[n].tx=0;      sppos[n].ty=ty; }

  sppos[n].x=x; sppos[n].y=y;
  sppos[n].width=sp[c].width; sppos[n].height=sp[c].height;
  sppos[n].win=win;

  XCopyArea(disp,sppos[n].win,tmp,gc,
	    sppos[n].x,sppos[n].y,sppos[n].width,sppos[n].height,
	    sppos[n].tx,sppos[n].ty);

  place_chara(sppos[n].win,c,sppos[n].x,sppos[n].y);

  if(sppos[n].win==mwin)
  {
    if(sppos[n].x             <minx) minx=sppos[n].x;
    if(sppos[n].x+sp[c].width >maxx) maxx=sppos[n].x+sp[c].width;
    if(sppos[n].y             <miny) miny=sppos[n].y;
    if(sppos[n].y+sp[c].height>maxy) maxy=sppos[n].y+sp[c].height;
  }

  return n;
}

/* キャラの下敷になった部分を元に戻す */
void return_back(int n)
{
  XCopyArea(disp,tmp,sppos[n].win,gc,
	    sppos[n].tx,sppos[n].ty,sppos[n].width,sppos[n].height,
	    sppos[n].x,sppos[n].y);

  if(sppos[n].win==mwin)
  {
    if(sppos[n].x                <minx) minx=sppos[n].x;
    if(sppos[n].x+sppos[n].width >maxx) maxx=sppos[n].x+sppos[n].width;
    if(sppos[n].y                <miny) miny=sppos[n].y;
    if(sppos[n].y+sppos[n].height>maxy) maxy=sppos[n].y+sppos[n].height;
  }

  push(&tmp_stack,n);
}
