/*
   PasteGadgets - code for a utility that loads or saves system-gadget
                  images.
   (c) 1990  Olaf Leimann
             Dorpsstraat 77
  NL-2211 GD Noordwijkerhout
*/

#include <exec/types.h>
#include <exec/memory.h>
#define  INTUITIONPRIVATE 1
#include <intuition/intuitionbase.h>
#include <workbench/startup.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <string.h>
#include <stdio.h>

struct IntuitionBase *IntuitionBase ;

extern void LoadImages(struct Window *,char *);
extern void SaveImages(struct Window *,char *);

struct NewWindow GWindow = {
   0,11,100,50,-1,-1,0L,
   WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|WINDOWSIZING|NOCAREREFRESH,
   NULL,NULL,(UBYTE *)"HI!",NULL,NULL,
   100,50,640,256,WBENCHSCREEN
};

#define NUMGADGETS  6

char *ImageIDs[NUMGADGETS] = {
   "CLSE","BACK","FRNT","SIZE","SBCK","SFNT"
};
USHORT ImageBits[NUMGADGETS] = {
   CLOSE, WDOWNBACK, WUPFRONT, SIZING, SDOWNBACK, SUPFRONT
};

void main(argc,argv)
   int   argc ;
   char *argv[] ;
/*#FOLD:*/
{
   struct Window *win ;
   int i,show=0 ;
   char *s ;

   if(argc > 1){
      if(strcmp(argv[1],"?")==0) show = 1 ;
      IntuitionBase =(struct IntuitionBase *)OpenLibrary(
         "intuition.library",0L);
      if(IntuitionBase){
         win = OpenWindow(&GWindow);
         if(win){
            for(i=1;i<argc;i++){
               s = argv[i] ;
               if(stricmp(s,"LOAD")==0 && i<argc-1)
                  LoadImages(win,argv[++i]);
               else if(stricmp(s,"SAVE")==0 && i<argc-1)
                  SaveImages(win,argv[++i]);
               else
                  LoadImages(win,argv[i]);
            }
            CloseWindow(win);
         }
         CloseLibrary((struct Library *)IntuitionBase);
      }
   }
   else show = 1 ;
   if(show){
      printf("PasteGadgets (c) 1990  Olaf Leimann\n");
      printf("Loads or saves a set of systemgadgets.\n");
      printf("Gadgets supported are:\n");
      printf("Window DEPTH CLOSE DRAG and SIZE gadgets and\n");
      printf("Screen DEPTH gadgets.\n");
      printf("Usage: %s [LOAD] filename | [SAVE filename]\n",argv[0]);
   }
}
/*#ENDFD*/

struct Gadget *FindGadget(win,bits)
   struct Window *win ;
   USHORT         bits ;
/*#FOLD:*/
{
   struct Gadget *gad=NULL ;
   struct Screen *scr ;
   int            found = 0 ;

   if(win){
      gad = win->FirstGadget ;
      while(gad !=NULL && found==0){
         if((gad->GadgetType & 0x00F0) == bits)
            found = 1 ;
         else
            gad = gad->NextGadget ;
      }
      if(gad==NULL){
         scr = win->WScreen ;
         if(scr){
            gad = scr->FirstGadget ;
            while(gad !=NULL && found==0){
               if((gad->GadgetType & 0x00F0) == bits)
                  found = 1 ;
               else
                  gad = gad->NextGadget ;
            }
         }
      }
   }
   return(gad);
}
/*#ENDFD*/

long CalcImageSize(im)
   struct Image *im ;
/*#FOLD:*/
{
   UBYTE planes=0,i;
   UBYTE planepick;
   long  size=0 ;

   if(im){
      planepick = im->PlanePick ;
      for(i=0;i<im->Depth;i++,planepick >>= 1){
         if(planepick & 0x01) planes++ ;
      }
      size = planes * im->Height * ((im->Width + 0x000F) >> 4) ;
   }
   return(size);
}
/*#ENDFD*/

void TakeImage(from,to)
   struct Image *from,*to ;
/*#FOLD:*/
{
   long    size1,size2 ;
   USHORT *Data ;

   size1 = CalcImageSize(from);
   size2 = CalcImageSize(to);
   if(size1 != size2)
      Data = (USHORT *)AllocMem(size1 << 1,MEMF_CLEAR|MEMF_CHIP);
   else
      Data = to->ImageData ;

   Forbid();

   if(size1 != size2 && size2 > 0 && to->ImageData!=NULL)
      FreeMem(to->ImageData,size2 << 1);

   memcpy((char *)to,(char *)from,sizeof(struct Image));
   to->ImageData = Data ;
   to->NextImage = NULL ;

   if(Data!=NULL && from->ImageData != NULL && size1 > 0){
      memcpy((char *)to->ImageData,(char *)from->ImageData,size1 << 1);
      Permit();
   }
   else{
      Permit();
      printf("--> err: No Data\n");
   }
}
/*#ENDFD*/

char buffer[8] ;

void LoadImages(win,name)
   struct Window *win ;
   char          *name ;
/*#FOLD:*/
{
   struct Image im ;
   struct Gadget *gad ;
   USHORT *Data ;
   BPTR   file ;
   short  l,ok=1 ;
   long   size ;

   if(win!=NULL && name !=NULL){
      file = Open(name,MODE_OLDFILE);
      if(file){
         do{
            l = Read(file,(UBYTE *)&buffer[0],4L);
            buffer[4] = 0 ;
            if(l == 4){
               ok=0;
               while(ok < NUMGADGETS && strcmp(buffer,ImageIDs[ok])!=0)
                   ok++ ;
               if(ok < NUMGADGETS){

                  size = CalcImageSize(&im);
                  Data = im.ImageData ;
                  Read(file,(UBYTE *)&im,sizeof(struct Image));
                  im.ImageData = Data ;

                  if(im.ImageData!=NULL && size>0)
                     FreeMem((UBYTE *)im.ImageData,size << 1);

                  size = CalcImageSize(&im);
                  if(size > 0){
                     im.ImageData = (USHORT *)AllocMem(size << 1,
                        MEMF_CLEAR|MEMF_CHIP);
                     if(im.ImageData)
                        Read(file,(UBYTE *)im.ImageData,size << 1);
                  }
                  else im.ImageData = NULL ;

                  gad=FindGadget(win,ImageBits[ok]);
                  if(gad){
                     if((gad->Flags & GADGIMAGE) &&
                         gad->GadgetRender!=NULL){
                        TakeImage(&im,(struct Image *)gad->GadgetRender);
                     }
                  }
               }
            }
         }while(l==4 && ok<NUMGADGETS) ;
         if(im.ImageData!=NULL && size>0)
            FreeMem((UBYTE *)im.ImageData,size << 1);
         Close(file);
         RefreshGadgets(win->FirstGadget,win,NULL);
         Delay(100);
      }
   }
}
/*#ENDFD*/

void SaveImages(win,name)
   struct Window *win ;
   char          *name ;
/*#FOLD:*/
{
   struct Gadget *gad ;
   BPTR           file ;
   long           size ;
   int            i ;

   if(win!=NULL && name !=NULL){
      file = Open(name,MODE_NEWFILE);
      if(file){
         for(i=0;i<NUMGADGETS;i++){
            gad = FindGadget(win,ImageBits[i]);
            if(gad){
               if((gad->Flags & GADGIMAGE) && gad->GadgetRender!=NULL){
                  Write(file,(UBYTE *)ImageIDs[i],4L);
                  Write(file,(UBYTE *)gad->GadgetRender,
                     sizeof(struct Image));
                  size = CalcImageSize((struct Image *)gad->GadgetRender);
                  if(size > 0)
                     Write(file,
            (UBYTE *)((struct Image *)gad->GadgetRender)->ImageData,
                     size << 1);
               }
            }
         }
         Close(file);
      }
   }
}
/*#ENDFD*/

