/* Simple datatype picture loader
 * If you don't use sas/c, you will have to open the libraries by hand.
 * intuition.library, graphics.library, datatypes.library, dos.lib
 * And it uses the latest picture.datatype V43. The header files are
 * in the archive on aminet.
 */
#include <proto/intuition.h>
#include <proto/datatypes.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/dos.h>

#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <datatypes/pictureclassExt.h>
#include <exec/memory.h>

#include <stdio.h>
#include <stdlib.h>


/* Prototypes */
struct Window *createwin(struct Screen *scr);
struct Pic *LoadPic(char *filename, struct Screen *scr);
void error(char *errstr);

/* Globals */
struct Pic
{
   Object *dto;
   struct BitMap *bitmap;
   int width, height;
   int depth;
};
struct Pic *gpic;
struct Window *gwin;
struct Screen *gscreen;

///S main(int argc, char **argv)
main(int argc, char **argv)
{
   char title[200];
   ULONG class;
   struct IntuiMessage *intmess;

   gscreen=NULL;
   gwin=NULL;

   if(argc!=2)
      error("Usage: pdto <file>");

   if(!(gscreen = LockPubScreen(NULL)))
      error("error: LockPucScreen");
   if(!(gwin = createwin(gscreen)))
      error("error: CreateWindow");

   if(!(gpic = LoadPic(argv[1], gscreen)))
      error("pic not loaded");

   /* Not so good, since the mem could be trashed */
   sprintf(title,"%s - %ldx%ldx%ld", argv[1], gpic->width, gpic->height, gpic->depth);

   ChangeWindowBox(gwin,gwin->LeftEdge,gwin->TopEdge,gpic->width+gwin->BorderLeft, gpic->height+gwin->BorderTop);
   SetWindowTitles(gwin,argv[1], title);

   /* Wait for CloseWindow, or refresh. if refresh blit it */
   while(1)
   {
      WaitPort(gwin->UserPort);
      while( (intmess = (struct IntuiMessage *)GetMsg(gwin->UserPort)))
      {
         class = intmess->Class;
         ReplyMsg((struct Message *)intmess);

         if(class==IDCMP_CLOSEWINDOW)
            error("");
         /* Blit when sizewin is finished */
         else
            BltBitMapRastPort(gpic->bitmap,0,0,gwin->RPort,gwin->BorderLeft,gwin->BorderTop,gpic->width,gpic->height,0xC0);
      }
   }
}
///E

///S struct Pic *LoadPic(char *filename, struct Screen *scr)
struct Pic *LoadPic(char *filename, struct Screen *screen)
{
   struct Pic *pic;
   struct BitMapHeader *BitMapHeader;

   if(pic=(struct Pic *)AllocVec(sizeof(struct Pic),MEMF_PUBLIC))
   {
      if(pic->dto = NewDTObject(filename,
            DTA_SourceType,         DTST_FILE,
            DTA_GroupID,            GID_PICTURE,
            PDTA_Remap,             TRUE,
            PDTA_Screen,            screen,
            PDTA_FreeSourceBitMap,  TRUE,
            PDTA_DestMode,          MODE_V43,
            PDTA_UseFriendBitMap,   TRUE,
            OBP_Precision,          PRECISION_IMAGE,
            TAG_DONE))
      {
         if(DoMethod(pic->dto,DTM_PROCLAYOUT,NULL,1))
         {
            if((GetDTAttrs(pic->dto, PDTA_BitMapHeader, &BitMapHeader, PDTA_DestBitMap, &pic->bitmap, TAG_DONE))==2)
            {
               /* Store picture info */
               pic->width = BitMapHeader->bmh_Width;
               pic->height = BitMapHeader->bmh_Height;
               pic->depth = BitMapHeader->bmh_Depth;
               return(pic);
            }
         }
         DisposeDTObject(pic->dto);
         pic->dto=NULL;
      }
      FreeVec(pic);
      pic=NULL;
   }
   return(NULL);
}
///E

///S error(string)
void error(char *errstr)
{
   if(*errstr)
      Printf("%s\n",errstr);

   if(gpic)
   {
      if(gpic->dto) DisposeDTObject(gpic->dto);
      FreeVec(gpic);
   }
   if(gwin) CloseWindow(gwin);
   if(gscreen) UnlockPubScreen(NULL, gscreen);
   exit(0);
}
///E

///S win = createwin(screen)
struct Window *createwin(struct Screen *screen)
{
   struct Window *crwin;

   if(!(crwin = OpenWindowTags(NULL,
         WA_Width, 200,
         WA_Height, 20,
         WA_DragBar, TRUE,
         WA_DepthGadget, TRUE,
         WA_CloseGadget, TRUE,
         WA_SimpleRefresh, TRUE ,
         WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW,
         WA_PubScreen, screen,
         WA_Title, "Loading",
         WA_ScreenTitle, "Loading",
         TAG_END)))
   {
      Printf("Could not open window");
      return(FALSE);
   }
   return(crwin);
}
///E

