/***************************************************************************
 * Unit:    raster            release 0.25                                 *
 * Purpose: Prototypes for general manipulation n dimensional matrices     *
 * Modul:   raster.cc                                                      *
 * Licency: GPL or LGPL                                                    *
 * Copyright: (c) 1998-2023 Jaroslav Fojtik                                *
 ***************************************************************************/
#ifndef __IMAGE_H__
#define __IMAGE_H__

#include "raster.h"


/* ---------- Global class Image --------- */
#include "stringa.h"


#define RAS_IMG_VERSION (0x200 | 62)

/*Definition of errors while Loading/Saving File(s)*/
#define ErrOK		  0
#define ErrOpenFile	 -1
#define ErrReadFile	 -2
#define ErrWriteFile	 -3
#define ErrBadFileFormat -4

#define ErrNoMem	-10



#ifndef RGBQuad_DEFINED
#define RGBQuad_DEFINED
typedef struct
	{
	unsigned R,G,B,O;
	} RGBQuad;
#endif


struct RGB_Record
   {
   uint8_t Red;
   uint8_t Green;
   uint8_t Blue;
   };



class VectorImage;


class PropertyItem
{
public:
  PropertyItem(void) {Data=NULL;DataSize=0;UsageCount=0;}
  virtual ~PropertyItem();

  mutable short UsageCount;
  void *Data;
  unsigned DataSize;
  string Name;
};


class PropertyList
{
public:
  PropertyList(void) {pProperties=NULL;PropCount=0;};
  ~PropertyList();

  void AddProp(PropertyItem *NewProp);
  bool isEmpty(void) const {return PropCount==0 || pProperties==NULL;}

  int PropCount;
  PropertyItem **pProperties;
};


class Image
	{
public: Raster2DAbstract *Raster;
	APalette *Palette;
	Image *Next;
	float x,y,dx,dy,RotAngle;
	VectorImage *VecImage;
	PropertyList Properties;

	Image(void): VecImage(NULL)  {RotAngle=x=y=dx=dy=0;Raster=NULL;Next=NULL;Palette=NULL;};
	Image(const Image & I, bool AllFrames=true);
	Image(Raster2DAbstract *NewRaster): VecImage(NULL) {RotAngle=x=y=dx=dy=0;Next=NULL;Palette=NULL;if((Raster=NewRaster)!=NULL) Raster->UsageCount++;};
	~Image(void) {Erase();};
	IMAGE_TYPE ImageType(void) const;   // 0-none, 1-gray, 2-palette, 3-true color

	Raster2DAbstract *operator=(Raster2DAbstract *NewRaster);
	Image &operator=(const Image & I);

	uint32_t GetPixel(unsigned Offset1D, unsigned Offset2D) const {return(Raster==NULL?0:Raster->GetValue2D(Offset1D,Offset2D));};
	uint32_t GetPixelRGB(unsigned Offset1D, unsigned Offset2D) const;
	
	void SetPixel(unsigned SizeX, unsigned SizeY, uint32_t x) {if(Raster) Raster->SetValue2D(SizeX,SizeY,x);};

	void Create(unsigned SizeX, unsigned SizeY, int Planes);
	void Erase(void);
	void AttachRaster(Raster2DAbstract *NewRaster);
	void AttachPalette(APalette *NewPalette);
	void AttachVecImg(VectorImage *NewVecImg);
	void AttachProperty(PropertyItem *NewProp);
	};



int ReducePalette(Image *Img, unsigned maxColors);


/* -----File format loader dynamical list------ */
typedef Image (* TLoadPicture)(const char *Name);
typedef int (*TSavePicture)(const char *Name, const Image &Img);

class TImageFileHandler
	{
private:static TImageFileHandler *First;
	TImageFileHandler *Previous;
	TImageFileHandler *Next;

	const char *Extension;
        const char *Description;

public: TImageFileHandler(const char *NewShortKey, TLoadPicture LoadPicture_XXX = NULL, TSavePicture SavePicture_XXX=NULL, const char *NewDescription=NULL);
	~TImageFileHandler();

	TLoadPicture LoadPicture;
	TSavePicture SavePicture;
	const char *extension() {return(Extension);}
	const char *description() {return(Description);}

	static TImageFileHandler *first() {return(First);}
	TImageFileHandler *next() {return(Next);}
	};

int SavePicture(const char *Name,const Image &Img);
Image LoadPicture(const char *Name);



#endif // __IMAGE_H__
