/*****************************************************************************
* Abstraction of the image format for input and output.		             *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Gershon Elber    		        Ver 0.2, Apr. 1995   *
*****************************************************************************/

#include "program.h"

typedef enum {
    IMAGE_RLE_TYPE,
    IMAGE_PPM_TYPE
} ImageIOType;

static ImageIOType
    IType = IMAGE_PPM_TYPE;

typedef struct LoadedImagesStruct {
    struct LoadedImagesStruct *Pnext;
    char *FileName;
    ImageStruct *Image;
} LoadedImagesStruct;

static LoadedImagesStruct
    *LoadedImagesList = NULL;

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Sets image type.                                                         M
*                                                                            *
* PARAMETERS:                                                                M
*   Image:  A string describing the image type.                              M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   ImageSetImageType                                                        M
*****************************************************************************/
void ImageSetImageType(char *Image)
{
    if (stricmp(Image, "rle") == 0)
        IType = IMAGE_RLE_TYPE;
    else if (stricmp(Image, "ppm") == 0)
        IType = IMAGE_PPM_TYPE;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Opens output image file.                                                 M
*                                                                            *
* PARAMETERS:                                                                M
*   argv:     Pointer to the name of this program.                           M
*   XSize:    X dimension of the image.                                      M
*   YSize:    Y dimension of the image.                                      M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   ImageOpenFile, output image                                              M
*****************************************************************************/
void ImageOpenFile(char **argv, int XSize, int YSize)
{
    switch (IType) {
	default:
	case IMAGE_RLE_TYPE:
	    RLEOpenFile(argv, XSize, YSize);
	    break;
	case IMAGE_PPM_TYPE:
	    PPMOpenFile(argv, XSize, YSize);
	    break;
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Outputs given line of color pixels and alpha correction values to the    M
*   ouput image file.                                                        M
*                                                                            *
* PARAMETERS:                                                                M
*   Alpha:  array of alpha values.                                           M
*   Pixels: array of color pixels.                                           M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   ImagePutLine, output image                                               M
*****************************************************************************/
void ImagePutLine(ByteType *Alpha, PixelStruct *Pixels)
{
    switch (IType) {
	default:
	case IMAGE_RLE_TYPE:
	    RLEPutLine(Alpha, Pixels);
	    break;
	case IMAGE_PPM_TYPE:
	    PPMPutLine(Alpha, Pixels);
	    break;
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Closes output image file.                                                M
*                                                                            *
* PARAMETERS:                                                                M
*   None                                                                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   ImageCloseFile, output image                                             M
*****************************************************************************/
void ImageCloseFile(void)
{
    switch (IType) {
	default:
	case IMAGE_RLE_TYPE:
	    RLECloseFile();
	    break;
	case IMAGE_PPM_TYPE:
	    PPMCloseFile();
	    break;
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Loads image file.     		                                     M
*                                                                            *
* PARAMETERS:                                                                M
*   File: Name of the image file.	                                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   ImageStruct *:  Pointer to dynamicaly created image.                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   ImageLoadImage, texture		                                     M
*****************************************************************************/
ImageStruct *ImageLoadImage(char *File)
{
    LoadedImagesStruct *LoadedImage;
    ImageStruct *Image;

    if (File == NULL)
        return NULL;

    /* Search if we already loaded this image. */
    for (LoadedImage = LoadedImagesList;
	 LoadedImage != NULL;
	 LoadedImage = LoadedImage -> Pnext)
	if (strcmp(File, LoadedImage -> FileName) == 0)
	    return LoadedImage -> Image;

    if (stricmp(&File[strlen(File) - 3], "rle") == 0)
        Image = RLELoadImage(File);
    else if (stricmp(&File[strlen(File) - 3], "ppm") == 0)
        Image = PPMLoadImage(File);
    else {
	fprintf(stderr,
		"Texture file \"%s\" must be image of type 'rle' or 'ppm'\n",
		File);
	Image = NULL;
    }

    if (Image != NULL) {
	/* Add it to global list of loaded images. */
	LoadedImage = (LoadedImagesStruct *)
				    IritMalloc(sizeof(LoadedImagesStruct));
	LoadedImage -> FileName = IritStrdup(File);
	LoadedImage -> Image = Image;
	LoadedImage -> Pnext = LoadedImagesList;
	LoadedImagesList = LoadedImage;
    }

    return Image;
}
