/*****************************************************************************
 * File:  A_ROW_object.c
 *
 * Object:     row  (ROW)
 * Subsystem:  autosampler
 * Domain:     A
 * Repository: as2.ooa
 *
 * Notice:
 *   (C) Copyright 1999, 2000 ROX Software, Inc.
 *   All rights reserved.
 *
 * Model Compiler:  MC3020 V1.3.0
 *
 * Warnings:
 *   !!! THIS IS AN AUTO-GENERATED FILE. PLEASE DO NOT EDIT. !!!
 ****************************************************************************/

#include "A_objects.h"
#include "A_ROW_object.h"
#include "A_ROW_events.h"
#include "A_CAR_object.h"
#include "A_SP_object.h"
#include "A_PAA_object.h"
    
/*****************************************************************************
 * Statically allocate space for the instance population for this object.
 * Allocate space for the object and its attributes.
 * Depending on the collection scheme, allocate containoids (collection
 * nodes) for gathering instances into free and active extents.
 ****************************************************************************/
static A_ROW_s A_ROW_ObjectPool_s[ A_ROW_MAX_EXTENT_SIZE ];
static Escher_ObjectSet_s A_ROW_ActiveExtent_s; /* set container */
Escher_ObjectSet_s * pG_A_ROW_extent;
static Escher_ObjectSet_s * p_A_ROW_inanimate;

/*****************************************************************************
 * Initialize object factory services.
 ****************************************************************************/
void
A_ROW_FactoryInit()
{
  unsigned int i;
  Escher_ObjectSet_s s;
  Escher_InitSet( &s );

  /* Initialize object instance storage free pool (inanimate list)
   * by linking the containoids into a linear, null-terminated,
   * singly linked list.  */
  for ( i = 0; i < A_ROW_MAX_EXTENT_SIZE; i++ )
  {
    Escher_SetInsertElement( &s, &A_ROW_ObjectPool_s[ i ] );
  }
  p_A_ROW_inanimate = s.next; /* free list head */

  /* Initialize object class extent (animate list) to empty.  */
  Escher_InitSet( &A_ROW_ActiveExtent_s );
  pG_A_ROW_extent = &A_ROW_ActiveExtent_s;
}


/*****************************************************************************
 * Object Creation Accessor
 ****************************************************************************/
A_ROW_s *
A_ROW_Create()
{
  Escher_ObjectSet_s * node;
  A_ROW_s * self;

  /* Check if object pool is empty.  */
  if ( !p_A_ROW_inanimate ) {
    UserObjectPoolEmptyCallout( "as2", "row" );
    return (A_ROW_s *) 0;
  }

  /* Acquire instance storage from object free pool.  */
  node = p_A_ROW_inanimate;
  p_A_ROW_inanimate = p_A_ROW_inanimate->next;
  self = (A_ROW_s *) node->object;

  /* Initialize application analysis object attributes.  */
  self->m_radius = 0;
  self->m_current_sampling_position = 0;
  self->m_next_sampling_position = 0;
  self->m_maximum_sampling_positions = 0;
  self->m_sampling_time = 0;
  self->m_needs_probe = false;

  /* Initialize relationship storage */
  self->mc_CAR_R1 = 0;
  self->mc_PAA_R2 = 0;

  self->mc_current_state = A_ROW_STATE_1;

  /* Insert instance into active extent (animate).  */
  node->next = pG_A_ROW_extent->next;
  pG_A_ROW_extent->next = node;

  return self;
}


/*****************************************************************************
 * A_ROW_AnyWhere1
 ****************************************************************************/
A_ROW_s *
A_ROW_AnyWhere1( const int w_radius )
{
  A_ROW_s * w; 
  Escher_Iterator_s iter_ROW;
  Escher_IteratorReset( &iter_ROW, pG_A_ROW_extent );

  while ( (w = (A_ROW_s *)Escher_IteratorNext( &iter_ROW )) != 0 )
  {
    if ( w->m_radius == w_radius )
    {
      return w;
    }
  }

  return (A_ROW_s *)0;
}

/*****************************************************************************
 * RELATE CAR TO ROW ACROSS R1
 ****************************************************************************/
void
A_ROW_R1_Link( A_CAR_s * part, A_ROW_s * form )
{
  if ( !part || !form )
  {
    return;
  }
  form->mc_CAR_R1 = part;
  part->mc_ROW_R1 = form;
}


/*****************************************************************************
 * State-Event Matrix (SEM)
 * Row Index is object's current (MC enumerated) current state.
 * Row zero is the unitialized state (e.g., for creation event transitions).
 * Column Index is (MC enumerated) state machine events.
 *****************************************************************************/
static const Escher_StateNumber_t
A_ROW_StateEventMatrix[6][6] =
{
  /* Row 0: 'Unitialized' */
  { EVENT_CANT_HAPPEN, EVENT_CANT_HAPPEN, EVENT_CANT_HAPPEN, EVENT_CANT_HAPPEN, EVENT_CANT_HAPPEN, EVENT_CANT_HAPPEN },
  /* Row 1: A_ROW_STATE_1 'idle' */
  { A_ROW_STATE_2, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED },
  /* Row 2: A_ROW_STATE_2 'waiting' */
  { EVENT_IS_IGNORED, A_ROW_STATE_3, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED },
  /* Row 3: A_ROW_STATE_3 'positioning' */
  { EVENT_IS_IGNORED, EVENT_IS_IGNORED, A_ROW_STATE_4, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED },
  /* Row 4: A_ROW_STATE_4 'sampling' */
  { EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED, A_ROW_STATE_5, EVENT_IS_IGNORED, EVENT_IS_IGNORED },
  /* Row 5: A_ROW_STATE_5 'checking' */
  { EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED, EVENT_IS_IGNORED, A_ROW_STATE_3, A_ROW_STATE_1 }
};

/*****************************************************************************
 * Array of pointers to the object's state action methods.
 * Index is the (MC enumerated) number of the state action method to execute.
 ****************************************************************************/
static const StateAction_t
A_ROW_Actions[6] =
{
  (StateAction_t) 0,
  (StateAction_t) A_ROW_Action_1,  /* 'idle' */
  (StateAction_t) A_ROW_Action_2,  /* 'waiting' */
  (StateAction_t) A_ROW_Action_3,  /* 'positioning' */
  (StateAction_t) A_ROW_Action_4,  /* 'sampling' */
  (StateAction_t) A_ROW_Action_5   /* 'checking' */
};

/*****************************************************************************
 * A_ROW_Dispatch - State model level event dispatching.
 ****************************************************************************/
void
A_ROW_Dispatch( const OoaEvent_t * const event )
{
  A_ROW_s * instance = (A_ROW_s *)GetEventTargetInstance( event );
  Escher_EventNumber_t event_number = GetOoaEventNumber( event );
  Escher_StateNumber_t current_state;
  Escher_StateNumber_t next_state;

  if ( instance )
  {
    current_state = instance->mc_current_state;
    if ( current_state > 5 )
    {
      /* Instance validation failure (deleted while event in flight) - TBD */
    }
    else
    {
      next_state = A_ROW_StateEventMatrix[ current_state ][ event_number ];
      if ( next_state <= 5 )
      {
        /* Execute the state action and update 'current state' */
        ( *A_ROW_Actions[ next_state ] )( instance, event );
        instance->mc_current_state = next_state;
      }
      else
      {
        if ( next_state == EVENT_CANT_HAPPEN )
        {
          /* Event can't happen */
          UserEventCantHappenCallout( current_state, next_state, event_number );
        }
        else if ( next_state == EVENT_IS_IGNORED )
        {
          /* Event ignored */
        }
        else
        {
          /* Translation/memory/stack error, etc - TBD */
        }
      }
    }
  }
}