//  First time example.
//
//   This example demonstrates:
//
// - how to use the object communication mechanism with
//   classes not derived from TQObject, e.g. interpreted classes
// - how to create signals
// - how to connect signals to slots, e.g class methods
// - how to activate signals
//
//*******************************************************************
//
//  1. Run ROOT
//  2. Type .L rqfirst.C
//  3. Type rqfirst()
//
//*******************************************************************


class A {

RQ_OBJECT("A")  // for classes not derived from TQObject
                // RQ_OBJECT macro should be used

private:
   Int_t       fValue;
   Int_t       fValues[3];
   const char *fText;
public:

   A() : fValue(0) { }
   ~A() { }

   void  SetValue(Int_t value);  //*SIGNAL*
   void  SetValues(Int_t*);      //*SIGNAL*
   void  SetText(const char*);   //*SIGNAL*
   void  SetValues(Int_t v1, Int_t v2, Int_t v3);   //*SIGNAL*
   void  PrintValue() const;
   void  PrintValues() const;
   void  PrintText() const;
};


//___________________________________________________________________
void A::PrintValue() const
{
   printf("value=%d\n",fValue);
}

//___________________________________________________________________
void A::PrintValues() const
{
   for(int i=0; i<3; i++ ) {
      printf("value[%d] = %d\n", i, fValues[i]);
   }
}

//___________________________________________________________________
void A::PrintText() const
{
   printf("\ntext:\t%s\n", fText);
}

//___________________________________________________________________
void A::SetValue(Int_t value)
{
   // Set new value.
   // Emit signal "SetValue(Int_t)" with a single parameter.


   if (value != fValue) {
      fValue = value;
      Emit("SetValue(Int_t)", fValue);
   }
}

//___________________________________________________________________
void A::SetValues(Int_t *values)
{
   // Set new values.
   // Emit signal  "SetValues(Int_t*)" with pointer
   // to Int_t as parameter.

   if (values != fValues) {
      for (int i = 0; i < 3; i++) fValues[i] = values[i];
      Emit("SetValues(Int_t*)", (long)fValues);
   }
}

//___________________________________________________________________
void  A::SetValues(Int_t v0, Int_t v1, Int_t v2)
{
   // Set new values.
   // Emit signal "SetValues(Int_t,Int_t,Int_t)"
   // with three parameters.

   long args[3];

   if (v0 != fValues[0] ||
       v1 != fValues[1] ||
       v2 != fValues[2]) {

      args[0] = fValues[0] = v0;
      args[1] = fValues[1] = v1;
      args[2] = fValues[2] = v2;
      Emit("SetValues(Int_t,Int_t,Int_t)", args);
   }

}

//___________________________________________________________________
void A::SetText(const char *text)
{
   // Set new text.
   // Emit signal "SetText(char*)".

   if(text!=fText) {
      fText=text;
      Emit("SetText(char*)", fText);
   }
}

/////////////////////////////////////////////////////////////////////
A *a;    // a,b objects are available from ROOT session
A *b;

//___________________________________________________________________
void rqfirst()
{
   // Simple tests on signals, slots and connections

   a = new A();
   b = new A();

   a->Connect("SetValue(Int_t)", "A", b, "SetValue(Int_t)");
   a->Connect("SetValues(Int_t,Int_t,Int_t)", "A",
               b, "SetValues(Int_t,Int_t,Int_t)");

   a->Connect("SetValues(Int_t*)", "A", b, "SetValues(Int_t*)");
   a->Connect("SetText(Text_t*)", "A", b, "SetText(char*)");

   printf("\n******* Test of SetValue(Int_t) signal *******\n");
   b->SetValue(10);
   printf("\n\t***** b fValue before ******\n");
   b->PrintValue();
   a->SetValue(20);
   printf("\n\t***** b fValue after a->SetValue(20) ******\n");
   b->PrintValue();

   printf("\n******** Test of SetValues(Int_t,Int_t,Int_t) signal ");
   printf("********\n");

   b->SetValues(10,20,30);
   printf("\n\t***** b fValues before ******\n");
   b->PrintValues();
   a->SetValues(1,2,3);
   printf("\n\t***** b fValues after a->SetValues(1,2,3) ******\n");
   b->PrintValues();

   Int_t qq[3] = { 40,50,60 };

   printf("\n******** Test of SetValues(Int_t*) signal *******\n");

   a->SetValues(qq);
   printf("\n\t***** b fValues after a->SetValues(Int_t*) ******\n");
   b->PrintValues();

   printf("\n******* Test of SetText(char*) signal *******\n");

   b->SetText("this is b text before\n");
   b->PrintText();
   a->SetText("now it is something different\n");
   b->PrintText();
}

