=begin
 ******************************************************************************
 * Copyright 1990-2009 MBARI
 * MBARI Proprietary Information. All rights reserved.
 ******************************************************************************
 * Summary  : Implemetation of the ChamberImages behavior
 * Filename : chamber_images.rb
 * Author   : Henthorn
 * Project  : Benthic Rover
 * Version  : 1
 * Created  : Dec 08
 * Modified : 
 ******************************************************************************
=end

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

require "utils/misc"
require "control/behavior"
require 'device/rover'

##########
# ChamberImages class.
# Capture images from both chamber cameras.
#
class ChamberImages < Behavior
  include RoverTime

  #####
  # Accept a behavior element and extract parameters
  #
  def initialize(p_behavior_element)
    super

    @prefix = ""
    load_attrs(p_behavior_element)
  end
  #####


  #####
  # A crude documentation feature. Each subclass should provide
  # one that begins by calling this method.
  #
  def ChamberImages.usage
    u  = sprintf(Behavior.usage_format, \
                 "prefix","Prepends to image filenames","String","blank")
    u += "\n<ChamberImages name=\"Example\" prefix=\"inserted\" "
    u += "comment=\"Prepends 'inserted' to image filenames\" />\n"
  end


  #####
  # Iterate over attributes in the element, extract parameters.
  #
  def load_attrs(p_behavior_element)
    super

    attrs = p_behavior_element.attributes
    attrs.keys.each do |k|
      case k

        # Get the prefix for these images
        when "prefix"
        @prefix = attrs[k]

#       else
#       puts("Unrecognized attr: #{k}")

      end
    end

    # Option: Throw an exception if there any required attributes
    # missing
    #
  end
  #####


  #####
  # Initialize behavior and make ready for execution.
  # Should be called just before executing the behavior.
  #
  def init(p_seq_number=1)   # Where in the plan behavior sequence I am
    syslog("_ #{@name} init")
    self.data_home = p_seq_number

    # Perform initialization procedures
    @state = READY
  end
  #####


  #####
  # Create directory to hold images
  #
  def data_home=(p_seq_num)
    mn_zero = p_seq_num > 9 ? "" : "0"
    home_prefix = mn_zero + p_seq_num.to_s
    DataLog.behavior_data_home = @data_home = home_prefix + "-chamber_camera/"
  end
  #####


  #####
  # Power-up the video server, give it time to boot up
  #
  def ChamberImages.video_on()
    Rover.instance.ethernet(true)
    Rover.instance.relay.videoOn
    Rover.instance.relay.camerasOn
    sleep(30)
  end
  #####


  #####
  # Power-down the video server
  #
  def ChamberImages.video_off()
    unless (Supervisor.instance.deployment.mars)
      Rover.instance.ethernet(false)
      Rover.instance.relay.videoOff
      Rover.instance.relay.camerasOff
    end
  end
  #####


  #####
  # Capture the images
  #
  def ChamberImages.capture_images(prefix="")
    image_name = DataLog.behavior_data_home + prefix + "_Stbd"
    unless (Rover.instance.video.capture_image(Video::Stbd, image_name))
      syslog("! Unable to capture stbd_#{prefix} image")
    end

    image_name = DataLog.behavior_data_home + "/" + prefix + "_Port"
    unless (Rover.instance.video.capture_image(Video::Port, image_name))
      syslog("! Unable to capture port_#{prefix} image")
    end

  end
  #####


  #####
  # Execute the behavior
  #
  def execute
    # Execute if ready.
    unless (@state == READY)
      syslog("! #{name} not in ready state")
      return
    end

    syslog("_ #{@name} executing")
    @state = EXECUTING

    ##
    # Don't bother running the behavior unless the health
    # of the video server is OK.
    #
    health = Supervisor.instance.dbif.load_component_state(RoverStore::ChamCam)
    if (health[RoverStore::Health])
      @state = FINISHED
      syslog("! Video server health is poor")
      return
    end

    # Perform the behavior
    begin

      ##
      # Power-up the video server, capture
      # the images and move the image files to correct location
      # using the prefix, if any.
      #
      ChamberImages.video_on()

      ChamberImages.capture_images(@prefix)

      ChamberImages.video_off()
      syslog("_ #{@name} complete")
    ensure
      self.clean_up()
    end
  end
  #####


  #####
  def clean_up
    ChamberImages.video_off()
  end
  #####


  #####
  # Abort the behavior
  #
  def abort
    syslog("_ #{@name} abort")
    if (@state == EXECUTING)
      @state = ABORTING 

      # Kill the run thread, clean up
      @my_thread.kill if @my_thread
      clean_up
    else
      syslog("_ #{@name} not executing, aborting...")
    end
  end
  #####


  #####
  # Test method. Use to run standard test of MyClass from
  # a ruby script.
  # 
  def ChamberImages.test
    require 'rexml/document'
    require 'device/rover'

    Rover.instance
    # Test code here
    images_xml = REXML::Document.new(File.new(Misc.find_plan("test_chamber_images.xml")))
    ci = ChamberImages.new(images_xml.root)
    ci.init
    ci.execute
    puts("Done")
  end
  #####

end

#####
# Standalone unit test (recommended)
# Include at the end of the file as a hook to run a unit test of
# the code from the command line including the command line options
# (e.g., "$ ruby my_class.rb --sim").
#
if __FILE__ == $0
  if "usage" == ARGV[0]
    puts(Behavior.usage)
    puts(ChamberImages.usage)
    exit(0)
  end

  ChamberImages.test
end
