=begin
 ******************************************************************************
 * Copyright 1990-2010 MBARI
 * MBARI Proprietary Information. All rights reserved.
 ******************************************************************************
 * Summary  : Implemetation of the Move Carousel behavior
 * Filename : move_carousel.rb
 * Author   : Virrey
 * Project  : Sedimentaion Event Sensor
 * Version  : 1
 * Created  : Aug 10
 * Modified :
 ******************************************************************************
=end

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

require "utils/misc"
require "control/behavior"
require "control/supervisor"
require "device/ezstepper"

##########
# Move Carousel class.
# Move carousel to a desired position

#
class HomeClean < Behavior

  #####
  # Accept a behavior element and extract parameters
  #
  def initialize(p_behavior_element)
    super
    @tar_zip = false
    @velocity = $NORM

    load_attrs(p_behavior_element)
  end
  #####


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

    # Keep for later use
    #
    attrs = p_behavior_element.attributes
    attrs.keys.each do |k|
      case k
        when "tar_zip"
          @tar_zip = attrs[k].to_s.downcase == "true"
          syslog("_ home_clean tar_zip = #{@tar_zip}")

        #  velocity of the move
        when "speed"
          speed = attrs[k].downcase
          case speed

            when "fast"
              @velocity = $FAST

            when "normal"
              @velocity = $NORM

            when "slow"
              @velocity = $SLOW

            else
              puts("Unrecognized speed: #{loc}")

        when "velocity"
          @velocity = attrs[k].to_i

       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")

    # Perform initialization procedures
    @state = READY
  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

    #
    # Perform the behavior
    #
    begin

      Rover.instance.relay.stepperOn
      sleep(2)

      #
      ez = Rover.instance.motors
      ez.reinit

      bt = nil
      # Backup the data from this plan if requested
      #
      backup = Supervisor.instance.deployment.current_plan.backup
      if (backup || @tar_zip)
        begin
          bt = RoverThread.new do
            if (@tar_zip)
              Supervisor.instance.deployment.current_plan.tar_and_zip_plan_data()
            end
            if (backup)
              syslog("_ backup images...")
              syslog("_ #{DataLog.plan_data_home} => #{DataLog.deployment_data_backup_home}")
              syslog(DataLog.backup_plan(DataLog.plan_data_home))
              syslog("_ backup fluorometer data...")
              syslog(DataLog.backup_fluoro())
              syslog("_ backup syslog...")
              syslog(DataLog.backup_logs())
            end
          end
        rescue Exception => e
          syslog(e.to_s)
        end
      end

      # Send the slide throught the brushes a few times first
      #
      pos = 158000
      ez.move_abs(pos)
      ez.save_position_for_startup(pos)

      pos = 117000
      ez.move_abs(pos)
      ez.save_position_for_startup(pos)

      pos = 200000
      ez.move_abs(pos)
      ez.save_position_for_startup(pos)

      # Now, find the home switch
      #
      ez.go_home

      syslog("_ wait for zip and backup to complete")
      n = 0
      if (bt)
        while(bt.alive?) do
          # syslog("_ waiting for backup #{n}...")
          sleep(1)
          n += 1
          bt.exit if (n > 600)
        end
        bt.join
      end
      syslog("_ waited an extra #{n} seconds for zip and backup")

      # Set the position to zero
      #
      ez.reset_position

      # Done with homing, store zero in the controller startup script
      #
      ez.save_position_for_startup

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


  #####
  def clean_up
    Rover.instance.relay.stepperOff

  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.
  #
=begin
  def MoveCarousel.test
    require 'rexml/document'
    # require 'device/ses'

    # Test code here
    move_xml = REXML::Document.new(File.new(Misc.find_plan("test_carousel.xml")))
    lc = MoveCarousel.new(move_xml.root)
    lc.init
    lc.execute
    puts("Done")
  end
  #####
=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
  MoveCarousel.test
end
