/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : bdoc.cc                                                       */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdio.h>
#include "LayeredControl.h"
#include "Behavior.h"
#include "BehaviorFactory.h"

// Include individual Behavior header files to get symbolic names
// needed by BehaviorFactory
#include "Ascend.h"
#include "BuoyLaunch.h"
#include "ChirpFin.h"
#include "DepthEnvelope.h"
#include "Descend.h"
#include "DownloadData.h"
#include "GetGPS.h"
#include "Launch.h"
#include "MissionTimer.h"
#include "RotateBuoy.h"
#include "RotateCarousel.h"
#include "RotateToLaunchPosition.h"
#include "SetElevator.h"
#include "SetRudder.h"
#include "Setpoint.h"
#include "Waypoint.h"
#include "Yoyo.h"
#include "Zigzag.h"

  // Instantiate Behavior object of each subclass, and print out
  // info about it.

  char *behaviorName[] = {
    AscendBehaviorName,
    BuoyLaunchBehaviorName,
    ChirpFinBehaviorName,
    DepthEnvelopeBehaviorName,
    DescendBehaviorName,
    DownloadDataBehaviorName,
    GetGPSBehaviorName,
    LaunchBehaviorName,
    MissionTimerBehaviorName,
    RotateBuoyBehaviorName,
    RotateCarouselBehaviorName,
    RotateToLaunchPositionBehaviorName,
    SetElevatorBehaviorName,
    SetRudderBehaviorName,
    SetpointBehaviorName,
    WaypointBehaviorName,
    YoyoBehaviorName,
    ZigzagBehaviorName,
    0
  };
  //
  // Find the number of behaviors, excluding the terminating "0".
  //
  int nBehaviors = sizeof(behaviorName) / sizeof(behaviorName[0]) - 1;

int main(int argc, char **argv)
{

  BehaviorFactory *factory = BehaviorFactory::instanceOf();

  Behavior *behavior;

  Boolean printSpecific = False;
  //
  // help() prints out behaviorName[].
  //
  void help();
  int nprinted = 0;
  //
  // Don't try to document every behavior if an argument isn't supplied.
  // Just list the behavior names.
  //
  if( argc == 1 )
  {
    printf(" Please supply a behavior name.\n");
    help();
    return 0;
  }

  if (argc > 1) {
    printSpecific = True;
  }
  //
  // bdoc works with more than one argument.  The entire argument list is
  // checked against behaviorName[i] before incrementing i.
  //
  for (int i = 0; behaviorName[i] != 0; i++) {

    if (printSpecific) {
      // Check if this behavior was specified
      Boolean printIt = False;
      for (int j = 1; j  < argc; j++) {
	if (!strcmp(behaviorName[i], argv[j])) {
	  printIt = True;
	  nprinted++;
	}
      }
      if (!printIt)
      {
	//
	// Not on list of requested behaviors. Go to the next one.  If the 
	// argument isn't found in behaviorName[] give the user help.
	//
	if( i == nBehaviors - 1 && j == argc && nprinted != argc-1 )
        {
	  printf(" %s is an invalid behavior name.\n\n", argv[j-1]);
	  help();
	}
	continue;
      }
    }

    if ((behavior = factory->create(behaviorName[i])) == 0) {
      // Invalid behavior name!
      fprintf(stderr, "Invalid behavior name: \"%s\"\n", behaviorName[i]);
      return 1;
    }
    printf("--------------------------------------------------------\n");
    printf("Behavior: %s    ", behavior->name());

    if (behavior->sequential())
      printf("Sequential\n");
    else
      printf("Nonsequential\n");

    printf("\nValid attributes:\n\n");

    Attribute *attribute;

    for (int i = 0; i < behavior->attributes.list.size(); i++) {

      behavior->attributes.list.get(i, &attribute);

      printf("%s - %s\n", attribute->name(), attribute->description());
      printf("Attribute type: %s\n", attribute->typeMnem());

      if (attribute->hasDefault()) {
	printf("Default value: %s\n", attribute->valueString());
      }
      else {
	printf("Default value: none - input is mandatory\n");
      }

      printf("\n");
    }

    printf("\n");

    // Causes seg violation!
    // delete behavior;
  }

  return 0;
}

void help()
{
  printf(" Valid behaviors are:\n");
  for( int i = 0; i < nBehaviors; i++ )
  {
    printf("   %s\n", behaviorName[i]);
  }
  printf(" \n");
}
