#include "utils.h"
#include <stdio.h>
#include <malloc.h>

#define MAX_PATH     128
unzFile uf = 0;
IMGLIST *img_list=NULL;
Image *imglist_search(char *name);
void imglist_add(Image *s, char *name);

int unzipReadDir( char* zipfile, char options[][60])
{
  unzFile uf = 0;
  int count=0;	

if ( !uf ) {
  uf = unzOpen( zipfile );
}
  if( !uf )
  {
    printf( "Can not open file '%s' !\n", zipfile );
	return count;
  }
	int rv = unzGoToFirstFile(uf);
	while (rv == UNZ_OK)
	{
		// get zipped file info
		unz_file_info unzfi;
		char fn[MAX_PATH];
		if (unzGetCurrentFileInfo(uf, &unzfi, fn, MAX_PATH, NULL, 0, NULL, 0) != UNZ_OK) break;
		if (fn[0]=='_')
			strcpy(options[count++],fn);

		rv = unzGoToNextFile(uf);

	}

	return count;

}

int unzipFile( char* zipfile, char* filename, char* outfile )
{
  unzFile uf = 0;
  FILE* fout = 0;
  int result, bytes;
  char buffer[1024];

if ( !uf ) {
  uf = unzOpen( zipfile );
}
  if( !uf )
  {
    printf( "Can not open file '%s' !\n", zipfile );
    return UNZIP_ERROPEN;
  }

  if( unzLocateFile( uf, filename, 0 ) != UNZ_OK )
  {
    printf( "Can not find '%s' inside the zipfile !\n", filename );
    unzCloseCurrentFile(uf);
    return UNZIP_ERRNOTFOUND;
  }

  if( unzOpenCurrentFile( uf) != UNZ_OK )
  {
    printf( "Can not open '%s' inside the zipfile !\n", filename );
    unzCloseCurrentFile(uf);
    return UNZIP_ERRNOTFOUND;
  }

  fout = fopen( outfile,"wb" );
  if( !fout )
  {
    printf( "Can not create file '%s' !\n", outfile );
    unzCloseCurrentFile(uf);
    return UNZIP_ERRCREATE;
  }

  result = UNZIP_OK;
  for(;;)
  {
    bytes = unzReadCurrentFile( uf, buffer, sizeof(buffer) );
    if( bytes == 0 ) break;
    if( bytes < 0 )
    {
      printf( "Error reading %s %d!\n", filename, bytes );
      result = UNZIP_ERRREAD;
      break;
    }
    else
      if( fwrite( buffer, 1, bytes, fout )!= bytes )
      {
        printf("error in writing extracted file\n");
        result = UNZIP_ERRWRITE;
        break;
      }
  }

  fclose( fout );
//  unzCloseCurrentFile( uf );

  return result;
}

void closezipfile() {
        if (uf) {
                 unzCloseCurrentFile( uf );
		uf=0;
	}
}

Image *loadfromcache(char *filename)
{
	return imglist_search(filename);
}
		



Image *loadfromzip_check4blank(char *filename, char * zipfile)
{
 
	int  bytes;
  	unsigned char * buffer;
	Image * s1;

	if((s1=imglist_search(filename))!=NULL) {
        	return s1;
       	}

        if ( !uf ) {
    //printf( "Opening file '%s' '%s' !\n", zipfile , filename);
  uf = unzOpen( zipfile );
        }
  if( !uf )
  {
    printf( "Can not open file '%s' !\n", zipfile );
    return NULL;
  }
//      printf ("Locating file\n");
  if( unzLocateFile( uf, filename, 0 ) != UNZ_OK )
  {
    //printf( "Can not find '%s' inside the zipfile !\n", filename );
    unzCloseCurrentFile(uf);
    s1=loadImage("./system/nodata.png");
    if (s1!=NULL)
	imglist_add(s1,filename);
    return s1;
  }

//      printf ("Opening current  file\n");
  if( unzOpenCurrentFile( uf) != UNZ_OK )
  {
    printf( "Can not open '%s' inside the zipfile !\n", filename );
    unzCloseCurrentFile(uf);
    return NULL;
  }
//      printf ("reading current  file\n");
        buffer=(unsigned char *) malloc ( sizeof (unsigned char)*70000);
        bytes = unzReadCurrentFile( uf, buffer, sizeof(unsigned char)*70000);

        if (bytes<0) {
                printf( "Can not read from '%s' !\n", filename );
                return NULL;

        }
        s1=loadImageFromMemory(buffer, bytes);
	if (s1!=NULL)
		imglist_add(s1,filename);
	else {
        	s1=loadImage("./system/nodata.png");
		if (s1!=NULL)
			imglist_add(s1,filename);
	}
        free (buffer);

	return s1;


}


Image *loadfromzip(char *filename, char * zipfile)
{
 
	int  bytes;
  	unsigned char * buffer;
	Image * s1;

	if((s1=imglist_search(filename))!=NULL) {
        	return s1;
       	}

        if ( !uf ) {
    //printf( "Opening file '%s' '%s' !\n", zipfile , filename);
  uf = unzOpen( zipfile );
        }
  if( !uf )
  {
    printf( "Can not open file '%s' !\n", zipfile );
    return NULL;
  }
//      printf ("Locating file\n");
  if( unzLocateFile( uf, filename, 0 ) != UNZ_OK )
  {
    printf( "Can not find '%s' inside the zipfile !\n", filename );
    unzCloseCurrentFile(uf);
    return NULL;
  }

//      printf ("Opening current  file\n");
  if( unzOpenCurrentFile( uf) != UNZ_OK )
  {
    printf( "Can not open '%s' inside the zipfile !\n", filename );
    unzCloseCurrentFile(uf);
    return NULL;
  }
//      printf ("reading current  file\n");
        buffer=(unsigned char *) malloc ( sizeof (unsigned char)*70000);
        bytes = unzReadCurrentFile( uf, buffer, sizeof(unsigned char)*70000);

        if (bytes<0) {
                printf( "Can not read from '%s' !\n", filename );
                return NULL;

        }
        s1=loadImageFromMemory(buffer, bytes);
	if (s1!=NULL)
		imglist_add(s1,filename);
	else
		printf("%s::: is NULL\n", filename);
        free (buffer);

	return s1;


}








Image *loadfromdir(char *filename)
{
 
	Image * s1;

	if((s1=imglist_search(filename))!=NULL) {
        	return s1;
       	}
        s1=loadImage(filename);
	if (s1!=NULL)
		imglist_add(s1,filename);
	return s1;
}

Image *loadfromdir_check4blank(char *filename)
{
 
	Image * s1;

	if((s1=imglist_search(filename))!=NULL) {
        	return s1;
       	}
        s1=loadImage(filename);
	if (s1!=NULL)
		imglist_add(s1,filename);
	else {
        	s1=loadImage("./system/nodata.png");
		if (s1!=NULL)
			imglist_add(s1,filename);
	}
	return s1;


}

void unload_group (int zoom,char * zipfile) {
	char filename[128];
	int cmplen;
        IMGLIST *i=img_list;

	  if (zipfile[strlen(zipfile)-4]=='.') {
		sprintf(filename,"%dx",zoom);
		cmplen=2;
	  } else {
		sprintf(filename,"%s/%dx",zipfile,zoom);
		cmplen=strlen(zipfile)+3;
	}

        while(i!=NULL) {
		//printf("%d:%s:%s:%d\n",zoom, i->name,filename,cmplen);
                if(!strncmp(i->name,filename,cmplen)) {
                        if(i->refcount) {
                                i->refcount=0;
                        }
                }
                i=i->next;
        }
}

void unloadmap(char *name)
{
        IMGLIST *i=img_list;

        while(i!=NULL) {
                if(!strcmp(i->name,name)) {
                        if(i->refcount) {
                                i->refcount=0;
                        }
                        return;
                }
                i=i->next;
        }
}


void imglist_add(Image *s, char *name)
{
        IMGLIST *nu;

        nu=(IMGLIST* )malloc(sizeof(IMGLIST));
        strcpy(nu->name,name);
        nu->refcount=1;
        nu->img=s;

        if(img_list==NULL) {
                img_list=nu;
                nu->next=NULL;
        } else {
                nu->next=img_list;
                img_list=nu;
        }
}

Image *imglist_search(char *name)
{
        IMGLIST *i=img_list;

        while(i!=NULL) {
                if(!strcmp(name,i->name)) {
                        //i->refcount++;
                        return (i->img);
                }
                i=i->next;
        }
        return(NULL);
}


void imglist_garbagecollect()
{
        IMGLIST *s=img_list,*p=NULL,*n=NULL;

        while(s!=NULL) {
                n=s->next;

                if(s->refcount==0) {
                        if(p==NULL) {
                                img_list=n;
                        } else {
                                p->next=n;
                        }
                        freeImage(s->img);
                        free(s);
                } else {
                        p=s;
                }
                s=n;
        }
}


