/***********************************************************************/
/* Open Visualization Data Explorer                                    */
/* (C) Copyright IBM Corp. 1989,1999                                   */
/* ALL RIGHTS RESERVED                                                 */
/* This code licensed under the                                        */
/*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
/***********************************************************************/

#include <dxconfig.h>


/*---------------------------------------------------------------------------*\
 $Source: /home/gda/dxcvs/dx/src/exec/hwrender/hwGroupInteractor.c,v $
  Author: Mark Hood

  A Group interactor is an interactor that mutates itself into a copy of
  one of three other interactors, depending upon which mouse button is used
  when starting a stroke.

  There is no echo associated with a group interactor.  To refresh a group
  interactor's display, its component interactors' echo methods must be
  invoked explicitly.

\*---------------------------------------------------------------------------*/

#include <stdio.h>
#include <math.h>

#include "hwDeclarations.h"

#ifdef STANDALONE
#include <X11/Xlib.h>
#else
#include "hwMemory.h"
#include <X11/Xlib.h>
#endif

#include "hwPortLayer.h"

#include "hwDebug.h"

/*
 *  Forward references
 */

static void StartStroke (tdmInteractor I, int x, int y, int btn, int s) ;
static void Destroy (tdmInteractor I) ;

/*
 *  Null functions
 */
static void 
NullStrokePoint (tdmInteractor I, int a, int b, int type, int s)
{
}

static void
NullEndStroke (tdmInteractor I, tdmInteractorReturnP R)
{
  R->change = 0 ;
}

static void
NullDoubleClick (tdmInteractor I, int x, int y, tdmInteractorReturnP R)
{
  R->change = 0 ;
}

static void
NullResumeEcho (tdmInteractor I, tdmInteractorRedrawMode redraw_mode)
{
}


tdmInteractor
_dxfCreateInteractorGroup (tdmInteractorWin W,
			   tdmInteractor btn1,
			   tdmInteractor btn2,
			   tdmInteractor btn3) 
{
  /*
   *  Initialize and return a handle to an interactor group.  
   */

  register tdmInteractor I ;

  ENTRY(("_dxfCreateInteractorGroup(0x%x, 0x%x, 0x%x, 0x%x)",
	 W, btn1, btn2, btn3));

  if (W && (I = _dxfAllocateInteractor(W, 0)))
    {
      /* instance initial interactor methods */
      FUNC(I, StartStroke) = StartStroke ;
      FUNC(I, StrokePoint) = NullStrokePoint ;
      FUNC(I, EndStroke) = NullEndStroke ;
      FUNC(I, DoubleClick) = NullDoubleClick ;
      FUNC(I, ResumeEcho) = NullResumeEcho ;
      FUNC(I, Destroy) = Destroy ;
      FUNC(I, KeyStruck) = _dxfNullKeyStruck;

      
      /* init data */
      BTN1(I) = btn1 ;
      BTN2(I) = btn2 ;
      BTN3(I) = btn3 ;
      IS_GROUP(I) = 1 ;

      EXIT(("I = 0x%x", I));
      return I ;
    }
  else
    {
      EXIT(("ERROR"));
      return 0 ;
    }
}


void
_dxfUpdateInteractorGroup (tdmInteractor I,
			  tdmInteractor btn1,
			  tdmInteractor btn2,
			  tdmInteractor btn3) 
{
  ENTRY(("_dxfUpdateInteractorGroup(0x%x, 0x%x, 0x%x, 0x%x)",
	 I, btn1, btn2, btn3));
  
  if (I)
    {
      BTN1(I) = btn1 ;
      BTN2(I) = btn2 ;
      BTN3(I) = btn3 ;
      EXIT((""));
    }
  else
    EXIT(("ERROR: bad group"));
}
      

static void 
StartStroke (tdmInteractor I, int x, int y, int btn, int s)
{
  tdmInteractor btn1, btn2, btn3 ;

  ENTRY(("StartStroke(0x%x, %d, %d, %d)",
	 I, x, y, btn));
  
  /* save button interactors */
  btn1 = BTN1(I) ;
  btn2 = BTN2(I) ;
  btn3 = BTN3(I) ;

  /* copy interactor info */
  switch(btn)
    {
    case 1:
      *I = *BTN1(I) ;
      break ;
    case 2:
      *I = *BTN2(I) ;
      break ;
    case 3:
      *I = *BTN3(I) ;
      break ;
    }

  /* call new start stroke method */
  tdmStartStroke (I, x, y, btn, s) ;

  /* restore group info */
  BTN1(I) = btn1 ;
  BTN2(I) = btn2 ;
  BTN3(I) = btn3 ;
  IS_GROUP(I) = 1 ;

  FUNC(I, StartStroke) = StartStroke ;
  FUNC(I, Destroy) = Destroy ;

  EXIT((""));
}

static void
Destroy (tdmInteractor I)
{
  ENTRY(("Destroy(0x%x)", I));
  
  if (!I) {
    EXIT(("I = NULL"));
    return ;
  }

  PRIVATE(I) = (void *)0 ;
  _dxfDeallocateInteractor(I) ;

  EXIT((""));
}
