/******************************************************************************
 **
 **	C++ Class Library for the Amiga© system software.
 **
 **	Copyright (C) 1994 by Armin Vogt  **  EMail: armin@uni-paderborn.de
 **	All Rights Reserved.
 **
 **	$Source: apphome:APlusPlus/RCS/libsource/BoopsiGadget.cxx,v $
 **	$Revision: 1.6 $
 **	$Date: 1994/04/23 21:00:43 $
 **	$Author: Armin_Vogt $
 **
 ******************************************************************************/

extern "C" {
#ifdef __GNUG__
#include <inline/intuition.h>
#endif

#ifdef __SASC
#include <proto/intuition.h>
#endif
}
#include <APlusPlus/intuition/BoopsiGadget.h>


volatile static char rcs_id[] = "$Id: BoopsiGadget.cxx,v 1.6 1994/04/23 21:00:43 Armin_Vogt Exp Armin_Vogt $";


void BoopsiGadget::create(Class *privClass,UBYTE *pubClass)
{
   if (Ok()) 
	{
	   privateClass = privClass;
   	publicClass  = pubClass;

	   intuiAttrs().addAttrs(AttrList(GA_Left,0, GA_Top,0, GA_Width,0, GA_Height,0, TAG_END));
   
   	getHomeWindow()->modifyIDCMP(CLASS_IDCMPUPDATE|CLASS_GADGETDOWN|CLASS_GADGETUP);
   
	   setIOType(IOTYPE_BOOPSIGADGET);
	}
  	_dout("Boopsigadget "<<(APTR)this<<" initialised. status = "<<(isKindOfIntuiObject()?"OK":"ERROR")<<"\n");
   _dout("status = "<<status()<<endl);
}


APTR BoopsiGadget::redrawSelf(GWindow *homeWindow,ULONG& returnType)
{
   _dout("Boopsigadget::redrawSelf()\n");
   
   GadgetCV::redrawSelf(homeWindow,returnType);
   
   // destroy old Boopsigadget
   if (gadgetPtr()!=NULL)
   {
      _dout("DisposeObject()\n");
      DisposeObject(gadgetPtr());
      _dout("\tdone\n");
   }
   
   // copy GraphicObject rectangle to gadget taglist
   intuiAttrs().updateAttrs(AttrList(GA_Left,iLeft(),GA_Top,iTop(),GA_Width,iWidth(),GA_Height,iHeight(),TAG_END));

   // create new Boopsigadget
   if ( storeGadget((struct Gadget*)NewObjectA(privateClass,publicClass,intuiAttrs()) ) )
   {
      gadgetPtr()->NextGadget = NULL; // important for AddGList() in GWindow::On_NEWSIZE()
      returnType = IOTYPE_BOOPSIGADGET;
   }
   else
   {
      returnType = NULL;
      _ierror(BOOPSIGADGET_NEWOBJECT_FAILED);
   }
   
   _dout("\tdone\n");
   return gadgetPtr();
}

void BoopsiGadget::callback(const IntuiMessageC *imsg)
   /* Boopsigadgets receive IDCMPUPDATE messages in case they have ICA_TARGET set to ICTARGET_IDCMP.
      Each IDCMPUPDATE message contains a taglist of changed attributes in the IAddress field.
      This taglist is used to change the IntuiObject attribute tags, spreading changes through the
      ITransponder in the process.
   */
{
   if (imsg && imsg->getIAddress())
   {
        _dout("BoopsiGadget::callback\n");

      switch(imsg->getClass())
      {
         case CLASS_IDCMPUPDATE :
            setAttrs( AttrList((struct TagItem*)imsg->getIAddress()) );
            break;
      }
   }
   else _dout("BoopsiGadget::callback() received imsg==null!!\n");
}

ULONG BoopsiGadget::setAttributes(AttrList& attrs)
{
	if (notificationLoop()) return 0L;

   _dout("BoopsiGadget("<<(APTR)this<<")::setAttributes("<<attrs<<")\n");
   
   if (gadgetPtr())
   {
      SetGadgetAttrsA(gadgetPtr(),(Window*)getHomeWindow()->windowPtr(),NULL,attrs);
   }
	
   return GadgetCV::setAttributes(attrs);
}

ULONG BoopsiGadget::getAttribute(Tag attrID,ULONG& dataStore)
   /* read a specific BOOPSI attribute. If the attribute is recognized by the BOOPSI object
      0L is being returned and dataStore is undefined, otherwise the attribute's value is
      stored in dataStore, a reference to a ULONG variable.
   */
{
	if (gadgetPtr() && GetAttr(attrID,gadgetPtr(),&dataStore))
		return dataStore;
	else
		return GadgetCV::getAttribute(attrID,dataStore);
}

BoopsiGadget::~BoopsiGadget()
   /* Dispose the Boopsi object.
   */
{
   _dout("BoopsiGadget::~\n");
   if (gadgetPtr()!=NULL)
   {  _dout("DisposeObject()\n");
      DisposeObject(gadgetPtr());
   }
   _dout("done\n");
}