/******************************************************************************
**
**  Coded by Dino Papararo 23-Apr-2001
**
**  Based on NewIff package relased by Commodore
**
**  FUNCTION
**
**    QueryMandPic -- Examine an IFF picture.
**
**  SYNOPSIS
**
**    LONG QueryMandPic (struct ILBMInfo *,struct MandelChunk *,UBYTE *);
**
**  DESCRIPTION
**
**    Passed an initialized ILBMInfo with a not-in-use IFFHandle, a MandelChunk
**
**    structure and a filename, will open an ILBM, fill in ilbm->camg and
**
**    ilbm->bmhd, and close the ILBM.
**
**    This allows you to determine if the ILBM is a size and
**
**    type you want to deal with.
**
**    For succes is necessary the ID_MAND into the iff file !
**
**    Returns 0 for success or an IFFERR (libraries/iffparse.h).
**
**
**  FUNCTION
**
**    LoadMandPic -- Load an IFF picture.
**
**  SYNOPSIS
**
**    LONG LoadMandPic (struct ILBMInfo *,UBYTE *);
**
**  DESCRIPTION
**
**    Function uses a ILBMInfo struct with record ParseInfo.iff initialized
**
**    with AllocIFF() function, and a pointer to a FileName.
**
**    It's necessary a valid Window RPort and ViewPort initialized in the passed
**
**    ILBM Structure for the BODY and COLORS, at end all memory will be freed.
**
**
**  FUNCTION
**
**    SaveMandPic -- save a screen as IFF picture.
**
**  SYNOPSIS
**
**    LONG SaveMandPic (struct ILBMInfo *,struct Chunk *,struct Chunk *,UBYTE *);
**
**  DESCRIPTION
**
**    Function uses a ILBMInfo struct with record ParseInfo.iff initialized
**
**    with AllocIFF() function, two custom chunks, and a pointer to a FileName.
**
**    In the 1st custom chunk I put the copyright infos and in the 2nd the
**
**    special chunk MAND used for window limits, fractal limits, iterations
**
**    type...
**
**    Function will save the icon file too with support for NewIcons.
**
******************************************************************************/

/* Modified for ARexx-support by E. Schwan 23.1.2002 */
/* Modified for StormC-GCC-support by E. Schwan 08.06.2002 */

#include <exec/types.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <graphics/gfxbase.h>

#include <iffp/ilbmapp.h>
#include <iffp/ilbm.h>
#include <iffp/packer.h>

#ifndef __STORM__
#include <proto/exec.h>
#include <proto/iffparse.h>
#define __NOLIBBASE__
#include <proto/intuition.h>
#include <proto/graphics.h>
#else /*__STORM__*/
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/iffparse_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/iffparse_pragmas.h>
#endif /*__STORM__*/

#include "FlashMandel.h"

#define NOMAND 115L
#define MANDERR 116L

#define FROMBLACK 0

/* local function prototypes */

//IMPORT BOOL Fade (struct Window *,ULONG *,ULONG,ULONG,BOOL);

//LONG QueryMandPic (struct ILBMInfo *,struct MandelChunk *,UBYTE *filename);

//LONG LoadMandPic (struct ILBMInfo *,UBYTE *,BOOL);

//LONG SaveMandPic (struct ILBMInfo *,struct Chunk *,struct Chunk *,UBYTE *);

//LONG SavePalette (struct ILBMInfo *,struct Chunk *,UBYTE *);

//LONG LoadPalette (struct ILBMInfo *,UBYTE *,BOOL);

/*----------------------------------------------------------------------*/

/* queryilbm
 *
 * Passed an initilized ILBMInfo with a not-in-use IFFHandle,
 *   and a filename,
 *   will open an ILBM, fill in ilbm->camg and ilbm->bmhd,
 *   and close the ILBM.
 *
 * This allows you to determine if the ILBM is a size and
 *   type you want to deal with.
 *
 * Returns 0 for success or an IFFERR (libraries/iffparse.h)
 */

LONG QueryMandPic (struct ILBMInfo *ilbm,struct MandelChunk *ManChk,UBYTE *filename)
{
LONG error;

BitMapHeader *bmhd;

struct MandelChunk *TmpManChk;

  if (! (ilbm->ParseInfo.iff)) return (CLIENT_ERROR);

  error = openifile (&(ilbm->ParseInfo),filename,IFFF_READ);

  if (! error)
  {
     error = parseifile (&(ilbm->ParseInfo),ID_FORM,ID_ILBM,ilbm->ParseInfo.propchks,ilbm->ParseInfo.collectchks,ilbm->ParseInfo.stopchks);

     if ((error == NULL) || (error == IFFERR_EOC) || (error == IFFERR_EOF))
     {
        if (contextis (ilbm->ParseInfo.iff,ID_ILBM,ID_FORM))
        {
           if (TmpManChk = (struct MandelChunk *) findpropdata (ilbm->ParseInfo.iff,ID_ILBM,ID_MAND))
           {           
              CopyMem (TmpManChk,ManChk,sizeof (struct MandelChunk));
              
              if (bmhd = (BitMapHeader *) findpropdata (ilbm->ParseInfo.iff,ID_ILBM,ID_BMHD))
              {
                 CopyMem (bmhd,&ilbm->Bmhd,sizeof (BitMapHeader));

                 ilbm->camg = getcamg (ilbm);
              }
                          
              else error = NOFILE;             
            }

           else error = NOMAND;
        }

        else error = NOFILE;
     }

     closeifile (&(ilbm->ParseInfo));
  }

  return (error);
}

/* LoadMandPic
 *
 * Passed a not-in-use IFFHandle, an initialized ILBMInfo, and filename,
 *   will load an ILBM into your already opened ilbm->scr, setting up
 *   ilbm->Bmhd, ilbm->camg, ilbm->colortable, and ilbm->ncolors
 *   and loading the colors into the screen's viewport
 *
 *   Note that ncolors may be more colors than you can LoadRGB4.
 *   Use MIN(ilbm->ncolors,vp->ColorMap->Count) for color count if
 *   you change the colors yourself using 1.3/2.0 functions.
 *
 * V39 - unless ilbm->IFFPFlags & IFFPF_NOCOLOR32, will do 32-bit
 *   color load under V39 and higher
 *
 * Returns 0 for success or an IFFERR (libraries/iffparse.h)
 *
 * NOTE - LoadMandPic () keeps the IFFHandle open so you can copy
 *   or examine other chunks.  You must call closeifile(iff,ilbm)
 *   to close the file and deallocate the parsed context
 *
 */

LONG LoadMandPic (struct ILBMInfo *ilbm,UBYTE *filename,BOOL fade)
{
struct BitMap *TmpBM;

LONG error;

  if (! (ilbm->ParseInfo.iff)) return (CLIENT_ERROR);

  if (! ilbm->scr) return (CLIENT_ERROR);

  if (! (ilbm->vp)) ilbm->vp = &ilbm->scr->ViewPort;

  error = openifile (&ilbm->ParseInfo,filename,IFFF_READ);

  if (! error)
  {
     error = parseifile (&ilbm->ParseInfo,ID_FORM,ID_ILBM,ilbm->ParseInfo.propchks,ilbm->ParseInfo.collectchks,ilbm->ParseInfo.stopchks);

     if ((! error) || (error == IFFERR_EOC) || (error == IFFERR_EOF))
     {
        if (contextis (ilbm->ParseInfo.iff,ID_ILBM,ID_FORM))
        {
           if (TmpBM = AllocBitMap ((ULONG) ilbm->win->Width,(ULONG) ilbm->win->Height,(ULONG) ilbm->wrp->BitMap->Depth,BMF_INTERLEAVED | BMF_CLEAR | BMF_MINPLANES,NULL))
           {
              if (! (error = loadbody (ilbm->ParseInfo.iff,TmpBM,&ilbm->Bmhd)))

                 BltBitMapRastPort (TmpBM,(LONG) ilbm->win->LeftEdge,(LONG) ilbm->win->TopEdge,ilbm->wrp,(LONG) ilbm->win->LeftEdge,(LONG) ilbm->win->TopEdge,(LONG) ilbm->win->Width,(LONG) ilbm->win->Height,0xC0);

              FreeBitMap (TmpBM);
           }

           if (! (getcolors (ilbm)))
           {

              if (fade != FALSE) Fade (ilbm->win,(ULONG *) (ilbm->colorrecord),25L,1L,FROMBLACK);

              else setcolors (ilbm,ilbm->vp);

              freecolors (ilbm);
           }
        }

        else error = NOFILE;
     }

     closeifile (&(ilbm->ParseInfo));
  }

  return (error);
}

LONG SaveMandPic (struct ILBMInfo *ilbm,struct Chunk *chunklist1,struct Chunk *chunklist2,UBYTE *filename)
{
struct BitMap *TmpBM;

Color32 *colortable32;

UWORD count;

ULONG modeid;

LONG error = IFFERR_NOMEM;

  modeid = GetVPModeID (ilbm->vp);

  count = ilbm->vp->ColorMap->Count;

  if (colortable32 = (Color32 *) AllocVec ((ULONG) (sizeof (Color32) * count),MEMF_CLEAR))
  {    
     if (TmpBM = AllocBitMap ((ULONG) ilbm->win->Width,(ULONG) ilbm->win->Height,(ULONG) ilbm->wrp->BitMap->Depth,BMF_INTERLEAVED | BMF_CLEAR | BMF_MINPLANES,NULL))
     {
        GetRGB32 (ilbm->vp->ColorMap,0L,(ULONG) count,(ULONG *) colortable32);

        BltBitMap (ilbm->wrp->BitMap,(LONG) ilbm->win->LeftEdge,(LONG) ilbm->win->TopEdge,TmpBM,(LONG) ilbm->win->LeftEdge,(LONG) ilbm->win->TopEdge,(LONG) ilbm->win->Width,(LONG) ilbm->win->Height,0xC0,0xFF,NULL);

        error = saveilbm (ilbm,TmpBM,modeid,ilbm->win->Width,ilbm->win->Height,ilbm->win->Width,ilbm->win->Height,colortable32,count,32,mskNone,0,chunklist1,chunklist2,filename);

        FreeBitMap (TmpBM);
     }

     FreeVec (colortable32);
  }

  return (error);
}

LONG LoadPalette (struct ILBMInfo *ilbm,UBYTE *filename, BOOL fade)
{
LONG error;

  error = openifile (&(ilbm->ParseInfo),filename,IFFF_READ);

  if (! error)
  {
     error = parseifile (&(ilbm->ParseInfo),ID_FORM,ID_ILBM,ilbm->ParseInfo.propchks,ilbm->ParseInfo.collectchks,ilbm->ParseInfo.stopchks);

     if ((! error) || (error == IFFERR_EOC) || (error == IFFERR_EOF))
     {
        if (! (error = getcolors (ilbm)))
        {

          if (fade != FALSE) Fade (ilbm->win,(ULONG *) (ilbm->colorrecord),25L,1L,FROMBLACK);

          else setcolors (ilbm,ilbm->vp);

           freecolors (ilbm);
        }
     }

     closeifile (&(ilbm->ParseInfo));
  }

  return (error);
}

LONG SavePalette (struct ILBMInfo *ilbm,struct Chunk *chunklist,UBYTE *filename)
{
struct IFFHandle *iff;

struct Chunk *chunk;

Color32 *colortable32;

UWORD ncolors;

LONG size,error;

ULONG chunkID;

  iff = ilbm->ParseInfo.iff;

  ncolors = ilbm->vp->ColorMap->Count;

  error = openifile (&(ilbm->ParseInfo),filename,IFFF_WRITE);

  if (! error)
  {
    error = PushChunk (iff,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN);

    if (colortable32 = (Color32 *) AllocVec ((ULONG) (sizeof (Color32) * ncolors),MEMF_CLEAR))
    {
       GetRGB32 (ilbm->vp->ColorMap,0L,(ULONG) ncolors,(ULONG *) colortable32);

       CkErr (putcmap (iff,colortable32,ncolors,32));

       FreeVec (colortable32);
    }

    for (chunk = chunklist; chunk; chunk = chunk->ch_Next)
    {
      chunkID = chunk->ch_ID;

      if ((chunkID != ID_BMHD) && (chunkID != ID_CMAP) && (chunkID != ID_CAMG))
      {
        size = ((chunk->ch_Size == IFFSIZE_UNKNOWN) ? strlen (chunk->ch_Data) : chunk->ch_Size);

        CkErr (PutCk (iff,chunkID,size,chunk->ch_Data));
      }
    }

    CkErr (PopChunk (iff)); /* close out the FORM */

    closeifile (&(ilbm->ParseInfo));    /* and the file */
  }

  return (error);
}

