=begin
 ******************************************************************************
 * Copyright 1990-2009 MBARI
 * MBARI Proprietary Information. All rights reserved.
 ******************************************************************************
 * Summary  : Interface to Axis video server
 * Filename : axis.rb
 * Author   : Henthorn
 * Project  : Benthic Rover
 * Version  : 1
 * Created  : Nov 08
 * Modified : 
 ******************************************************************************
=end

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

require 'utils/datalog'

class Video
  Stbd = 1
  Port = 2
end

##########
# Axis driver implements interface to Axis video server for capturing
# and saving images.
#
class Axis
  include SyslogWriter
  include RoverTime

  ##
  # Default configuration - video server at 134.89.12.147
  #
  def initialize(ip = "134.89.12.147")
    @ip = ip
    syslog("_ Axis object instantiated with ip #{@ip}")
  end

  ##
  # Capture image and place the image file in the images directory.
  # The target filename is passed in.
  # supplmented with a suffix that virtually guarantees a unique
  # filename.
  #
  # camera_id - video channel number (1 to 4)
  # target - use to label the file (e.g., "/data/measurement_site/port_before")
  #
  def capture_image(camera_id, target=nil)
    # Take an image. If successful copy file to image directory
    #
    if (frame_grab(camera_id))
      return move_image(target) if target
      true
    end
    return false
  end

  CheckupFailed = "failed check-up"

  #####
  # Basic health check-up. Perform a frame grab. If successful, we passed.
  #
  def check_up
    sleep(35)   # Assume power just turned on, wait for server to boot-up
    if (frame_grab(Video::Port))
      return nil
    else
      return CheckupFailed
    end
  end
  #####
#~~~~~~~~~~~~~~~~~~~~~~ PRIVATE METHODS ~~~~~~~~~~~~~~~~~~~~~~~~~

private

  ##
  # Capture image from camera. The image file is placed in the
  # current directory and named image.jpg
  #
  # camera_id - video channel number (1 to 4)
  #
  def frame_grab(camera_id)

    unless (camera_id == Video::Port || camera_id == Video::Stbd)
      syslog("! bad camera id: #{camera_id}")
      return false
    end

    getcmd = "wget -q http://#{@ip}/jpg/#{camera_id}/image.jpg"
    syslog("_ " + getcmd)

    # On error, log it and return false
    #
    unless (system(getcmd))
      syslog("! failed to retrieve frame grab on camera #{camera_id}")
      return false
    end
    true
  end

  ##
  # Move latest image file from local to the images directory. 
  # The target filename is constructed using the given target name
  # supplmented with a suffix that virtually guarantees a unique
  # filename.
  #
  def move_image(target)

    # Create a unique suffix from the current time down to 1/100 of a second,
    # then copy the image to the log directory
    # 
    t = Time.now
    suffix = sprintf("%d%02d%02d-%02d%02d%02d",
                     t.year%2000, t.mon, t.day, t.hour, t.min, t.sec)

    cpcmd = "cp image.jpg " + "#{target}_" + suffix + ".jpg"
    syslog(cpcmd)

    # On error, log it and return false
    #
    unless (retval = system(cpcmd))
      syslog("! failed to move image")
    end
    system("rm -f image.jpg")

    retval
  end

end
##########


##########
# SimVideo class implements public Video interface. Logs calls, no action
#
class SimAxis < Axis
  ##
  # Capture image from camera. The image file is placed in the
  # current directory and named image.jpg
  #
  # camera_id - video channel number (1 to 4)
  #
  def frame_grab(camera_id)

    unless (camera_id == Video::Port || camera_id == Video::Stbd)
      syslog("! bad camera id: #{camera_id}")
      return false
    end

    getcmd = "wget -q http://#{@ip}/jpg/#{camera_id}/image.jpg"
    syslog("_ " + getcmd)

    # Make a fake image.jpg file
    #
    system("echo \"axis image\" > image.jpg")
    true
  end

end


def Axis.test
  require 'device/relay_board'

  if (ARGV.length > 0)
    axis = SimAxis.new
    rm = SimRelayMan.new
  else
    axis = Axis.new
    rm = RelayMan.new
  end

  puts("Booting the axis video server...")
  rm.videoOn
  sleep(30)
  puts("Capturing image")
  axis.capture_image(1, "#{DataLog.behavior_data_home}/test_image")
  rm.videoOff

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 (e.g., "$ ruby  my_class.rb")
#
if __FILE__ == $0
  # Test code here
  Axis.test
end
