#--
#******************************************************************************
#* Copyright 1990-2007 MBARI
#* MBARI Proprietary Information. All rights reserved.
#******************************************************************************
#* Summary  : Interface to video server (real and simulated)
#* Filename : video.rb
#* Author   : Henthorn
#* Project  : Benthic Rover
#* Version  : V1.1
#* Created  : Nov-06   Basic functionality
#* Modified : Feb-07   Trap system calls for testing purposes
#*            Oct-07   Integrate SimVideo
#******************************************************************************

require 'monitor'
require 'rover_environment'
require 'rover_utils'
require 'configman'

class Video < Monitor
  include LogHelper
  
  # Define cameras by name: NAME = channel_number
  #
  $STBD_CAMERA = 2
  $PORT_CAMERA = 1
  
  # Default configuration - video server at 192.168.0.90
  # New configuration - video server at 134.89.12.147
  #
  def initialize ip = '134.89.12.147'
    super()
    
    @ip = ip
    syslog("_ Video object instantiated to addr #{@ip}")
  end

  # Capture image and place the image file in the images directory.
  # The target filename is constructed using the given prefix
  # supplmented with a suffix that virtually guarantees a unique
  # filename.
  #
  # Thread syncronization is implemented here via MonitorMixin
  #
  # camera_id - video channel number (1 to 4)
  # prefix - use to label the file (e.g., "measurement_site")
  #
  def capture_image(camera_id, prefix)
    self.synchronize do
  
      # Take an image. If successful copy file to image directory
      #
      if (frame_grab(camera_id))
        return move_image(prefix)
      end
      
      return false
    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 == $PORT_CAMERA || camera_id == $STBD_CAMERA)
      syslog("! Video Fault: 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 (send_system_call(getcmd))
      syslog("! Fault: failed to retrieve frame grab on camera #{camera_id}")
      return false
    end
    
    true
  end

  # Trap system calls 
  #
  def send_system_call(cmd)
    return system(cmd)
  end
 
  # Move latest image file from local to the images directory. 
  # The target filename is constructed using the given prefix
  # supplmented with a suffix that virtually guarantees a unique
  # filename.
  #
  def move_image(prefix)
    
    # Create a unique suffix from the current time down to 1/100 of a second,
    # then copy the image to the log directory
    # 
    suffix = Time.now
    cpcmd = "cp image.jpg " + LogDir.instance.datalog_dir + 
            "#{prefix}_#{\"%10.2f\" % suffix.to_f}.jpg"
    syslog(cpcmd)
    
    # On error, log it and return false
    #
    unless (send_system_call(cpcmd))
      syslog("! Fault: failed to move image")
      return false
    end
    
    true
  end
 
end   # class Video


# SimVideo class implements public Video interface. Logs calls, no action
#
class SimVideo < Video
  include LogHelper
  
  # Simply log the command that would be executed
  #
  def send_system_call(cmd)
    syslog("_ #{cmd}")
    true
  end
end
