/******************************************************************************
 * program:     rasimg library                                                *
 * function:    File formats module handling.                                 *
 * modul:       filehnd.cc                                                    *
 * licency:     GPL or LGPL                                                   *
 ******************************************************************************/
#include<string.h>

#include "common.h"
#include "image.h"


/** This class is a container for loader modules. */
TImageFileHandler *TImageFileHandler::First=NULL;
TImageFileHandler::TImageFileHandler(const char *NewExtension, TLoadPicture LoadPicture_XXX, TSavePicture SavePicture_XXX, const char *NewDescription, const uint32_t NewFlags):
	Flags(NewFlags)
{
 Extension=NewExtension;
 Description=NewDescription;

 LoadPicture=LoadPicture_XXX;
 SavePicture=SavePicture_XXX;

 Next=First;
 Previous=NULL;
 First=this;
 if(Next!=NULL) Next->Previous=this;
}


TImageFileHandler::~TImageFileHandler(void)
{
 if(First==this)
	{
	First=Next;
	if(Next!=NULL) Next->Previous=NULL;
	return;
	}
 if(Next!=NULL) Next->Previous=Previous;
 if(Previous==NULL) return; //Error
 Previous->Next=Next;
}



/** Extract extension from a file name. */
const char *ReadExt(const char *FileName)
{
const char *c;

 if(FileName==NULL) return NULL;
 const size_t LastPos = strlen(FileName);
 c = FileName + LastPos;
 while (c!=FileName)
      {
      if(*c=='.') return(++c);
      if((*c=='/') || (*c=='\\') || (*c==':')) break;	//file has No Ext
      c--;
      }
return(FileName+LastPos);	// 0
}



/////////////////////////////////////////////////////////////////////


/** Main procedure for loading images. This should be called preferably. */
Image LoadPicture(const char *Name)
{
Image Img;
TImageFileHandler *LoadPicture_XXX;
const char *ext,*ext2;

  if(Name==NULL) return NULL;

       //Load image that matches extension
  ext = ReadExt(Name);
  if(ext!=NULL)
    for(LoadPicture_XXX=TImageFileHandler::first();LoadPicture_XXX!=NULL;LoadPicture_XXX=LoadPicture_XXX->next())
      {
      if(LoadPicture_XXX->LoadPicture!=NULL)
	{
	ext2 = LoadPicture_XXX->extension();
	if(ext2!=NULL)
	  {
	  if(*ext2=='.') ext2++;
	  if(!stricmp(ext2,ext))
	    {
	    Img=LoadPicture_XXX->LoadPicture(Name);
	    if(!Img.isEmpty()) return(Img);
	    }
	  }
	}
      }

	//Try to load any images that loader could process
  for(LoadPicture_XXX=TImageFileHandler::first();LoadPicture_XXX!=NULL;LoadPicture_XXX=LoadPicture_XXX->next())
    {
    if(LoadPicture_XXX->LoadPicture!=NULL)
	{
	Img = LoadPicture_XXX->LoadPicture(Name);
	if(!Img.isEmpty()) return(Img);
	}
    }

return(Img);
}


/** Main procedure for saving images. This should be called preferably. */
int SavePicture(const char *Name, const Image &Img)
{
TImageFileHandler *SavePicture_XXX;
const char *ext,*ext2;

  ext = ReadExt(Name);
  for(SavePicture_XXX=TImageFileHandler::first();SavePicture_XXX!=NULL;SavePicture_XXX=SavePicture_XXX->next())
    {
    if(SavePicture_XXX->SavePicture!=NULL)
     {
     ext2=SavePicture_XXX->extension();
     if(ext2!=NULL)
      {
      if(*ext2=='.') ext2++;
      if(!stricmp(ext2,ext))
	 {
	 return(SavePicture_XXX->SavePicture(Name,Img));
	 }
      }
     }
    }

return(-1);
}
