/******************************************************************************
 *
 *    $Source: apphome:APlusPlus/RCS/TESTPRGS/intuition/BoopsiGadget_test.cxx,v $
 *
 *    Demo for the A++ Library
 *    Copyright (C) 1994 by Armin Vogt, EMail: armin@uni-paderborn.de
 *
 *	   $Revision: 1.5 $
 *	   $Date: 1994/05/09 21:27:51 $
 *	   $Author: Armin_Vogt $
 *
 ******************************************************************************/

#include <APlusPlus/exec/SignalResponder.h>
#include <APlusPlus/intuition/GWindow.h>
#include <APlusPlus/intuition/BoopsiGadget.h>
#include <APlusPlus/intuition/StdGadget.h>

extern "C" {
#include <dos/dos.h>
}


volatile static char rcs_id[] = "$Id: BoopsiGadget_test.cxx,v 1.5 1994/05/09 21:27:51 Armin_Vogt Exp Armin_Vogt $";


class MyProp : public BoopsiGadget
{
   public:
      MyProp(GOB_OWNER,AttrList& attrs)
      : BoopsiGadget(gob_owner,(UBYTE*)"propgclass",attrs) {}
   	~MyProp() {}
};



BOOL running = TRUE;
BOOL close2 = FALSE;
GWindow *stop_window;


class MySRSP : public SignalResponder
{
   public:
      MySRSP(BYTE signal) : SignalResponder(signal,0) {}

      void actionCallback();
};

// overload the virtual 'signal received' action callback method.
void MySRSP::actionCallback()
{
   cout << "**Break\n";
   running = FALSE;
}

class MyWindow : public GWindow
{
   private:
      void init();

   public:
      MyWindow(OWNER,AttrList& attrs) : GWindow(owner,attrs) { init(); }
      void On_CLOSEWINDOW(const IntuiMessageC *msg);
      void On_ACTIVEWINDOW(const IntuiMessageC *msg);
      void On_SIZEVERIFY(const IntuiMessageC *msg);
      void handleIntuiMsg(const IntuiMessageC* imsg);
};


void MyWindow::init()
{
  modifyIDCMP(CLASS_NEWSIZE|CLASS_CLOSEWINDOW|CLASS_ACTIVEWINDOW|CLASS_SIZEVERIFY);
}

void MyWindow::On_CLOSEWINDOW(const IntuiMessageC *msg)
      {
         cout << "CLOSEWINDOW.\n";
         if (this == stop_window) running = FALSE;
         delete this;
      }
void MyWindow::On_ACTIVEWINDOW(const IntuiMessageC *msg)
      {
         cout << title() << " is ACTIVE.\n";
      }
void MyWindow::On_SIZEVERIFY(const IntuiMessageC *msg)
      {
         cout << "SIZEVERIFY. \n";
      }
void MyWindow::handleIntuiMsg(const IntuiMessageC* imsg)
      {
         switch (imsg->getClass())
         {
            case CLASS_CLOSEWINDOW :
               On_CLOSEWINDOW(imsg); break;
            case CLASS_ACTIVEWINDOW :
               On_ACTIVEWINDOW(imsg); break;
            case CLASS_SIZEVERIFY :
               On_SIZEVERIFY(imsg); break;
         }
         GWindow::handleIntuiMsg(imsg);
}

// This ITransponder multiplies received PGA_Top values with a given factor.
class PropScalarITP : public ITransponder
{
	private:
		FLOAT factor;

		void sendNotification(AttrList& attrs)
		{
			AttrManipulator next(attrs);
			_dout("MyITP :: received notification stream = "<<attrs<<endl);
			if (next.findTagItem(PGA_Top) )
			{
				next.writeData((LONG)((FLOAT)next.data()*factor));
			   _dout("forwarding n.s. = "<<attrs<<endl);
				if (APPOK(receiver1)) receiver1->setAttributes(attrs);
			}
		}
	public:
		PropScalarITP(FLOAT f,IntuiObject *receiver=NULL) { factor = f; receiver1 = receiver; }	  
};		  



void APPmain()
{
	ULONG l=0;     // dummy variable needed for a getAttribute() call
   MySRSP sr(SIGBREAKB_CTRL_C);
   
	PropScalarITP prop2to1_itp(0.5);
   PropScalarITP prop1to2_itp(2);

	NeXTBorder border;

	
   MyWindow *little = new MyWindow(OWNER_NULL,
      AttrList( WA_Title,(ULONG)"Window - close this to stop.",
		WA_Left,200,
		WA_Top,50,
      WA_Width,300,
      WA_Height,150,
      WA_MinHeight,100,
		WA_MinWidth,100,
      WA_MaxHeight,1600,
      WA_MaxWidth,1600,
      WA_DragBar,TRUE,
      WA_SizeGadget,TRUE,
      WA_DepthGadget,TRUE,
      WA_CloseGadget,TRUE,
      TAG_END) );


   MyWindow *small = new MyWindow(little,
      AttrList( WCV_SharePortWithWindowObj(little),
      WA_Title,(ULONG)"Window sharing userport",
      WA_Left,200,
		WA_Top,200,
      WA_Width,200,
      WA_Height,150,
      WA_MinHeight,100,
		WA_MinWidth,100,
		WA_MaxHeight,1600,
      WA_MaxWidth,1600,
      WA_DragBar,TRUE,
		WA_SizeGadget,TRUE,
		WA_DepthGadget,TRUE,
      WA_CloseGadget,TRUE,
      TAG_END) );


   MyProp *prop1 = new MyProp(small,
      AttrList( GOB_LeftFromRightOfParent,-30,
      GOB_TopFromTopOfParent,0,
      GOB_RightFromRightOfParent,-1,
      GOB_BottomFromBottomOfParent,0,
      GA_Immediate,TRUE,
      GA_RelVerify,TRUE,
      PGA_Freedom,FREEVERT,
      PGA_Top,100,
      PGA_Total,1000,
      PGA_Visible,500,
      ICA_TARGET,ICTARGET_IDCMP,
      PGA_NewLook,TRUE,
		ITRANSPONDER(&prop1to2_itp),
		GOB_BorderObj(&border),
      TAG_END) );

		
   MyProp *prop2 = new MyProp(little,
		AttrList(
		GOB_LeftFromLeftOfParent,2,
      GOB_TopFromTopOfParent,2,
		GOB_RightFromLeftOfParent,35,
      GOB_BottomFromBottomOfParent,-10,
      GA_Immediate,TRUE,
      GA_RelVerify,TRUE,
      PGA_Freedom,FREEVERT,
      PGA_Top, prop1->getAttribute(PGA_Top,l)*2,	// initialise from the ITP source
      PGA_Total,2000,
      PGA_Visible,1000,
      ICA_TARGET,ICTARGET_IDCMP,
      PGA_NewLook,TRUE,
		GOB_BorderObj(&border),
		ITRANSPONDER(&prop2to1_itp),
      TAG_END) );

   if (! APPOK(prop2) )
      cerr << " APPOK() on "<<(APTR)prop2<<" failed, status "<<(LONG)prop2->status()<<"\n";
   if (! APPOK(prop1) )
      cerr << "prop1 invalid\n";

   prop1to2_itp.setReceiver(prop2);
   prop2to1_itp.setReceiver(prop1);
	
   cout << "ITransponders at "<<(APTR)&prop1to2_itp<<" and "<<(APTR)&prop2to1_itp<<endl;

   stop_window = little;
   cout << little << endl;
   cout << "sizeof( )"<<"\nBoopsigadget\t"<<sizeof(MyProp)<<endl<<"\nGWindow\t"<<sizeof(GWindow)<<endl;

	little->refreshGList();
	small->refreshGList();

   while (running)
   {
      SignalResponder::WaitSignal();
   }

   cout << "cleaned up. goodbye.\n";
}