=begin
 ******************************************************************************
 * Copyright 1990-2009 MBARI
 * MBARI Proprietary Information. All rights reserved.
 ******************************************************************************
 * Summary  : Factory class for creating Behavior objects
 * Filename : factory.rb
 * Author   : Henthorn
 * Project  : Benthic Rover
 * Version  :
 * Created  : Dec 2008
 * Modified :
 ******************************************************************************
=end

##
# Refer to Rover-code home directory as base
#
require "#{ENV['ROVER_HOME']}/utils/rover_environment"
#

require 'utils/misc'
require 'control/sample_behavior'
require 'control/launch'
require 'control/favorable_current'
require 'control/insert_chambers'
require 'control/home_chambers'
require 'control/chamber_images'
require 'control/fluoro_image'
require 'control/transit_image'
require 'control/make_heading'
require 'control/move_forward'
require 'control/optode_measure'
require 'control/vehicle_checkup'
require 'control/report'
require 'control/move_carousel'
require 'control/home_clean'
require 'control/pause'
require 'control/sedevent'
require 'control/measure_fluorometry'

##########
# Factory class for Behavior subtypes.
#
class Factory

  #####
  # Behavior method.
  # Pass in the xml element containing the behavior definition.
  # The factory will determine which Behavior to construct and return
  # by inspecting the xml element.
  #
  def Factory.behavior(p_behavior_element)

    ##
    # Gotta be a proper element
    #
    return nil unless (p_behavior_element)

    unless (p_behavior_element.class.to_s == "REXML::Element")
      puts("! Parameter must be an Element", p_behavior_element.class)
      return nil
    end

    ##
    # Take a look at the element name and construct the corresponding
    # behavior. We'll do the name comparison with all lowercase, no need
    # to be an interCap stickler.
    #
    l_type = p_behavior_element.name
    l_name = p_behavior_element.attributes['name']
    puts("_ Factory making #{l_type}  #{l_name}")

    case l_type.downcase

    when "samplebehavior"
      return SampleBehavior.new(p_behavior_element)

    when "launch"
      return Launch.new(p_behavior_element)

    when "favorablecurrent"
      return FavorableCurrent.new(p_behavior_element)

    when "insertchambers"
      return InsertChambers.new(p_behavior_element)

    when "homechambers"
      return HomeChambers.new(p_behavior_element)

    when "chamberimages"
      return ChamberImages.new(p_behavior_element)

    when "fluoroimage"
      return FluoroImage.new(p_behavior_element)

    when "transitimage"
      return TransitImage.new(p_behavior_element)

    when "makeheading"
      return MakeHeading.new(p_behavior_element)

    when "moveforward"
      return MoveForward.new(p_behavior_element)

    when "optodemeasure"
      return OptodeMeasure.new(p_behavior_element)

    when "vehiclecheckup"
      return VehicleCheckup.new(p_behavior_element)

    when "report"
      return Report.new(p_behavior_element)
      
    when "movecarousel"
      return MoveCarousel.new(p_behavior_element)

    when "homeclean"
      return HomeClean.new(p_behavior_element)

    when "measurefluorometry"
      return MeasureFluorometry.new(p_behavior_element)

    when "pause"
      return Pause.new(p_behavior_element)

    when "sedevent"
      return SEDEvent.new(p_behavior_element)


#    when "yourBehavior"
#      return YourBehavior.new(p_behavior_element)

    else
      puts("! Sorry. Don't know how to make a #{l_type} behavior")
      return nil
    end
  end

end


##
# Standalone unit test (recommended)
#
if __FILE__ == $0
  require 'rexml/document'
  require 'utils/misc'
  require 'control/behavior'

  bogus = REXML::Element.new
  bogus.name = "Bogus"
  puts("Request for Bogus behavior should fail") if Factory.behavior(bogus)

  # Test code here
  # Typical subclassed behavior usage
  sample_file = File.new(Misc.find_plan("/test_sample.xml"))
  doc = REXML::Document.new(sample_file)

  # Use the factory to make the appropriate kind of behavior
  puts("Typical subclassed behavior usage")
  b = Factory.behavior(doc.elements[1])

  # Treat as a generic behavior. Don't need to know what kind it is.
  b.init
  b.execute
  b.abort
  sleep(1)
  
  puts("Done")
end
