#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <cstdlib>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "brikx.h"

char DIR_SAVE[1024];

char *configdir()
{
	char *confdirtemp;                                                                                             
                                                                                                                              
#if defined(WIN32) || defined(_WIN32) || defined(WINDOWS)                                                                     
	confdirtemp=getenv("USERPROFILE");                                                                                    
	if (confdirtemp) strcpy(DIR_SAVE,confdirtemp);                                                                        
	else strcpy(DIR_SAVE,"c:\\windows\\");                                                                                  
#else                                                                                                                         
	confdirtemp=getenv("HOME");                                                                                           
	if (confdirtemp) strcpy(DIR_SAVE,confdirtemp);                                                                        
	else strcpy(DIR_SAVE,"~");                                                                                            
	strcat(DIR_SAVE,"/.brikx/");                                                                                           
	mkdir(DIR_SAVE,0755);                                                                                                 
#endif         
	return DIR_SAVE;
}

int strcmpi(const char *a1, const char *a2)
{
    	char c1, c2;
		while((c1=*a1) | (c2=*a2))
        {
			if (!c1 || !c2 || (islower(c1) ? toupper(c1) : c1) != (islower(c2) ? toupper(c2) : c2))
			  return (c1 - c2);
			a1++;
			a2++;
		}
		return 0;
}

SDL_Surface *LoadImage(char *fname,int Rkey,int Gkey,int Bkey)
{
    SDL_Surface *loaded,*optimized=NULL;
    if (loaded=IMG_Load(fname))
      {
        if ((optimized=SDL_DisplayFormat(loaded)) && Rkey>-1)
            SDL_SetColorKey(optimized,SDL_RLEACCEL | SDL_SRCCOLORKEY,SDL_MapRGB(optimized->format,Rkey,Gkey,Bkey));
        if (!optimized) return loaded;
        SDL_FreeSurface(loaded);
      }
    else return NULL;
    return optimized;
}

void PutSurface(SDL_Surface *src,SDL_Surface *dest,SDL_Rect pos,int clipx,int clipy,int width,int height)
{
     if (!src || !dest) return;
     SDL_Rect clip;
     clip.x=clipx;
     clip.y=clipy;
     clip.w=width;
     clip.h=height;
     SDL_BlitSurface(src,clipx==-1?NULL:&clip,dest,&pos);
}

void PutSurface(SDL_Surface *src,SDL_Surface *dest,int x,int y,int clipx,int clipy,int width,int height)
{
     SDL_Rect pos;
     pos.x=x;
     pos.y=y;
     PutSurface(src,dest,pos,clipx,clipy,width,height);
}

int LoadLevel(char *fname,level &t,maxes &m,char *text)
{
      FILE *f=fopen(fname,"r");
      if (!f) return 0;
      char s[140];
      int i,j,timelimit;
      fgets(s,130,f);
      timelimit=atoi(s);
      for (i=0; i<=7 && !feof(f); i++)
        {
          fgets(s,130,f);
          for (j=0; j<=7; j++)
            t[j][i]=(s[j*2]-'0')*10+s[j*2+1]-'0';
        }
      for (i=0; i<MODES; i++)
        {
          m[i]=-1;
          if (!feof(f))
            {
              fgets(s,130,f);
              if (*s) m[i]=atoi(s);
            }
        }
      if (fgets(text,1024,f))
        while (text[strlen(text)]=='\n' || text[strlen(text)]=='\r')
          text[strlen(text)-1]=0;
      else *text=0;
      fclose(f);
      return timelimit;
}

int SaveLevel(char *fname,level t,int timelimit,maxes m,char *text)
{
    FILE *f=fopen(fname,"w+");
    if (!f) return 0;
    int i,j;
    fprintf(f,"%d\n",timelimit);
    for (i=0; i<=7; i++)
      {
        for (j=0; j<=7; j++)
          fprintf(f,"%02d",t[j][i]);
        fprintf(f,"\n");
      }
    for (i=0; i<MODES; i++)
      fprintf(f,"%d\n",m[i]);
    if (text) fprintf(f,text);
    fclose(f);
    return 1;
}

int Input(SDL_Surface *screen,TTF_Font *font,SDL_Color color,int x,int y,char *s,int maxlen)
{
    SDL_Surface *text=NULL,*save=NULL;
    SDL_Event event; 
    bool end=false;
    char t[maxlen+1],ss[strlen(s)+maxlen+2];
    *t=0;
    if (!(save=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL,WIDTH,HEIGHT,BPP,rmask,gmask,bmask,amask))) return 0;
    SDL_LockSurface(save);
    SDL_LockSurface(screen);
    memcpy(save->pixels,screen->pixels,WIDTH*HEIGHT*BPP/8);
    SDL_UnlockSurface(save);
    SDL_UnlockSurface(screen);
    SDL_EnableUNICODE(SDL_ENABLE);
    while (!end)
      {
        SDL_Delay(DELAY);
        sprintf(ss,"%s%s.",s,t);
        if (text) SDL_FreeSurface(text);
        text=TTF_RenderText_Solid(font,ss,color);
        SDL_LockSurface(save);
        SDL_LockSurface(screen);
        memcpy(screen->pixels,save->pixels,WIDTH*HEIGHT*BPP/8);
        SDL_UnlockSurface(save);
        SDL_UnlockSurface(screen);
        PutSurface(text,screen,x,y);
        SDL_Flip(screen);
        while (SDL_PollEvent(&event))
          if (event.type==SDL_KEYDOWN)
	     switch (event.key.keysym.unicode)
	       {
		      case SDLK_BACKSPACE:
		        if (*t) t[strlen(t)-1]=0;
		      break;
		      case SDLK_ESCAPE:
			       *t=0;
		      case SDLK_RETURN:
			       end=true;
		      break;
		 default:
		      if (isprint(event.key.keysym.unicode) && strlen(t)<maxlen) sprintf(t,"%s%c",t,event.key.keysym.unicode);
	       }
    }
    SDL_EnableUNICODE(SDL_DISABLE);
    SDL_FreeSurface(text);
    SDL_FreeSurface(save);
    strcpy(s,t);
    return strlen(t);
}

int SaveHigh(long score,int level,int difficulty,char *name)
{
    int i,j;
    high h;
    char s[NAME_MAXLEN+2];
    FILE *f=fopen(FILE_HIGH,"r");
    if (f)
      {
        for (i=0; !feof(f); i++)
          {
            fgets(s,NAME_MAXLEN,f);
            h[i].score=atoi(s);
            fgets(s,NAME_MAXLEN,f);
            h[i].level=atoi(s);
            fgets(s,NAME_MAXLEN,f);
            h[i].difficulty=atoi(s);
            fgets(h[i].name,NAME_MAXLEN,f);
            h[i].name[strlen(h[i].name)-1]=s[strlen(s)-1]=0;
          }
        fclose(f);
        while (i<MAX_HIGHENTRIES)
          {
            h[i].score=h[i].level=h[i].difficulty=h[i].name[0]=0;
            i++;
          }
      }
    else
      for (i=0; i<MAX_HIGHENTRIES; i++)
        h[i].score=h[i].level=h[i].difficulty=h[i].name[0]=0;
    for (i=0; i<MAX_HIGHENTRIES && level<=h[i].level && score<h[i].score; i++)
      ;
    if (i<MAX_HIGHENTRIES)
      {
        for (j=MAX_HIGHENTRIES-1; j>i; j--)
          {
            h[j].score=h[j-1].score;
            h[j].level=h[j-1].level;
            h[j].difficulty=h[j-1].difficulty;
            strcpy(h[j].name,h[j-1].name);
          }
        h[i].score=score;
        h[i].level=level;
        h[i].difficulty=difficulty;
        strcpy(h[i].name,name);
        if (!(f=fopen(FILE_HIGH,"w+"))) return -1;
        for (j=0; j<MAX_HIGHENTRIES; j++)
          fprintf(f,"%d\n%d\n%d\n%s\n",h[j].score,h[j].level,h[j].difficulty,h[j].name);
        fclose(f);
      }
    return i;
}

int SaveGame(level table,long score,int levnum,long timer,int timelimit,int diff,maxes m,char *name,char *leveltext)
{
    char s[1024];
    sprintf(s,"%s%s.save",configdir(),name);
    FILE *f=fopen(s,"w+");
    int i,j;
    if (!f)
      {
         fprintf(stderr,"ERROR: cannot write savegame file %s",s);
         return -1;
      }
    fprintf(f,"%d\n%ld\n%ld\n%d\n",levnum,score,timer,timelimit);
    for (i=0; i<=7; i++)
      {
        for (j=0; j<=7; j++)
          fprintf(f,"%02d",table[j][i]);
        fprintf(f,"\n");
      }
    fprintf(f,"%d\n",diff);
    for (i=0; i<MODES; i++)
      fprintf(f,"%d\n",m[i]);
    if (leveltext) fprintf(f,"%s\n",leveltext);
    fclose(f);   
    return 0;
}

int LoadGame(level &table,long &score,int &levnum,long &timer,int &timelimit,int &diff,maxes &m,char *name,char *leveltext)
{
    char s[1024];
    sprintf(s,"%s%s.save",configdir(),name);
    FILE *f=fopen(s,"r");
	if (!f)
	{
		fprintf(stderr,"cannot load savegame from %s\n",s);
		return -1;
	}
    int i,j;
    fgets(s,130,f);
    levnum=atoi(s);
    fgets(s,130,f);
    score=atoi(s);
    fgets(s,130,f);
    timer=atoi(s);
    fgets(s,130,f);
    timelimit=atoi(s);
    for (i=0; i<=7 && !feof(f); i++)
      {
        fgets(s,130,f);
        for (j=0; j<=7; j++)
		{
		  SDL_Delay(5);
          table[j][i]=(s[j*2]-'0')*10+s[j*2+1]-'0';
		}
      }
    fgets(s,130,f);
    diff=atoi(s);
    for (i=0; i<MODES; i++)
      {
        fgets(s,130,f);
        m[i]=atoi(s);
      }
    if (leveltext) fgets(leveltext,130,f);
    while (leveltext[strlen(leveltext)-1]=='\n' || leveltext[strlen(leveltext)-1]=='\r')
	leveltext[strlen(leveltext)-1]=0;
    fclose(f);
    return 0;
}

void GetNextSet(char *name)
{
    DIR *D=opendir(DIR_TILESET);
    dirent *d;
    while ((d=readdir(D)) && strcmpi(d->d_name,name))
      ;
    if (d)
      {
        if (!(d=readdir(D)))
          {
            rewinddir(D);
            d=readdir(D);
          }
        while (d && (d->d_name[0]=='.'))
		{
          d=readdir(D);
		  if (!d)
		  {
			  rewinddir(D);
			  d=readdir(D);
		  }
		}
        if (d) strcpy(name,d->d_name);
      }
    closedir(D);
}

int LoadShinePos(char *fname,int &dx,int &dy)
{
    FILE *f=fopen(fname,"r");
    if (!f) return -1;
    char s[32];
    if (fgets(s,31,f)) dx=atoi(s);
    else return -1;
    if (fgets(s,31,f)) dy=atoi(s);
    else return -1;
    fclose(f);
    return 0;
}
