// Dtpic Class
// (C)opyright by Stefan Stuntz
// Modified by Dirk Holtwick, 1997

/// Includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/icon_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/utility_protos.h>
#include <clib/datatypes_protos.h>
#include <clib/muimaster_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/datatypes_pragmas.h>
#include <pragmas/muimaster_pragmas.h>

#include <dos/dos.h>
#include <libraries/mui.h>
#include <datatypes/pictureclass.h>
#include <datatypes/pictureclassext.h>
#include <graphics/gfxmacros.h>

#include "dtpic.h"

extern struct Library *DataTypesBase;
extern struct Library *UtilityBase;
extern struct Library *IntuitionBase;
extern struct Library *GfxBase;
///
/// New
ULONG _mNew(struct IClass *cl,Object *obj,Msg msg)
{
   struct DtpicData *data;
   char   *name;

   if (!(obj=(Object *)DoSuperMethodA(cl,obj,msg)))
      return(0);

   data = INST_DATA(cl,obj);

   memset(data, 0, sizeof(struct DtpicData));

   name = (char *)GetTagData(MUIA_Dtpic_Name,NULL,((struct opSet *)msg)->ops_AttrList);

   if(name)
   {
      if(data->name = AllocVec(strlen(name)+1,0))
         strcpy(data->name, name);
   }

   set(obj,MUIA_FillArea,FALSE);

   return((ULONG)obj);
}
///
/// Dispose
ULONG _mDispose(struct IClass *cl, Object *obj, Msg msg)
{
   struct DtpicData *data = INST_DATA(cl, obj);

   if(data->name)
   {
      FreeVec(data->name);
      data->name = 0;
   }

   return(DoSuperMethodA(cl,obj,msg));
}
///
/// freedto
static VOID freedto(struct DtpicData *data)
{
   data->bitmap = NULL;
   data->bmhd = NULL;

   if (data->dto)
   {
      DisposeDTObject(data->dto);
      data->dto = NULL;
   }
}
///
/// Setup
ULONG _mSetup(struct IClass *cl,Object *obj,Msg msg)
{
   struct DtpicData *data = INST_DATA(cl,obj);

   if (!DoSuperMethodA(cl,obj,msg))
      return(FALSE);

   if (data->name)
   {
      /* tell DOS not to bother us with requesters */
      struct Process *myproc = (struct Process *)FindTask(NULL);
      APTR oldwindowptr = myproc->pr_WindowPtr;
      myproc->pr_WindowPtr = (APTR)-1;

      /* create the datatypes object */
      data->dto = NewDTObject(data->name,
         DTA_GroupID          , GID_PICTURE,
         OBP_Precision        , PRECISION_IMAGE,
         PDTA_Screen          , _screen(obj),
         PDTA_FreeSourceBitMap, TRUE,
         PDTA_DestMode        , MODE_V43,
         PDTA_UseFriendBitMap , TRUE,
         TAG_DONE);

      myproc->pr_WindowPtr = oldwindowptr;

      /* do all the setup/layout stuff that's necessary to get a bitmap from the dto    */
      /* note that when using V43 datatypes, this might not be a real "struct BitMap *" */

      if (data->dto)
      {
         struct FrameInfo fri = {NULL};

         DoMethod(data->dto,DTM_FRAMEBOX,NULL,&fri,&fri,sizeof(struct FrameInfo),0);

         if (fri.fri_Dimensions.Depth>0)
         {
            if (DoMethod(data->dto,DTM_PROCLAYOUT,NULL,1))
            {
               get(data->dto,PDTA_BitMapHeader,&data->bmhd);

               if (data->bmhd)
               {
                  GetDTAttrs(data->dto,PDTA_DestBitMap,&data->bitmap,TAG_DONE);

                  if (!data->bitmap)
                     GetDTAttrs(data->dto,PDTA_BitMap,&data->bitmap,TAG_DONE);

                  if (data->bitmap)
                  {
                     return(TRUE);
                  }
               }
            }
         }
      }
   }
   freedto(data);
   return(TRUE);
}
///
/// Cleanup
ULONG _mCleanup(struct IClass *cl,Object *obj,Msg msg)
{
   struct DtpicData *data = INST_DATA(cl,obj);
   freedto(data);
   return(DoSuperMethodA(cl,obj,msg));
}
///
/// AskMinMax
ULONG _mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg)
{
   struct DtpicData *data = INST_DATA(cl,obj);
   struct MUI_MinMax *mi;

   DoSuperMethodA(cl,obj,(void *)msg);

   mi = msg->MinMaxInfo;

   if (data->bitmap)
   {
      mi->MinWidth  += data->bmhd->bmh_Width ;
      mi->MinHeight += data->bmhd->bmh_Height;
      mi->DefWidth  += data->bmhd->bmh_Width ;
      mi->DefHeight += data->bmhd->bmh_Height;
      mi->MaxWidth  += data->bmhd->bmh_Width ;
      mi->MaxHeight += data->bmhd->bmh_Height;
   }

   /* if we have no bitmap, our object's size will be 0 */

   return(0);
}
///
/// Draw
ULONG _mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
{
   struct DtpicData *data = INST_DATA(cl,obj);

   DoSuperMethodA(cl,obj,(void *)msg);

   if (msg->flags & MADF_DRAWOBJECT)
   {
      if (data->bitmap)
      {
         BltBitMapRastPort(data->bitmap,0,0,_rp(obj),_mleft(obj),_mtop(obj),_mwidth(obj),_mheight(obj),0xc0);
      }
   }

   return(0);
}
///
/// Dispatcher
ULONG __saveds __asm DtpicDispatcher(register __a0 struct IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
{
   switch (msg->MethodID)
   {
      case OM_NEW        : return(_mNew      (cl,obj,(APTR)msg));
      case OM_DISPOSE    : return(_mDispose  (cl,obj,(APTR)msg));
      case MUIM_Setup    : return(_mSetup    (cl,obj,(APTR)msg));
      case MUIM_Cleanup  : return(_mCleanup  (cl,obj,(APTR)msg));
      case MUIM_AskMinMax: return(_mAskMinMax(cl,obj,(APTR)msg));
      case MUIM_Draw     : return(_mDraw     (cl,obj,(APTR)msg));
   }

   return(DoSuperMethodA(cl,obj,msg));
}
///

