#!/usr/bin/env ruby
# $Id: audio.rb,v 1.10 2007/10/13 23:25:41 rocky Exp $
#
# A program to show use of audio controls. See cdda-player from the
# libcdio distribution for a more complete program.

#
#    Copyright (C) 2006 Rocky Bernstein <rocky@gnu.org>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
mypath = File.dirname(__FILE__)
if(File::exists?(mypath + "/../ext/cdio/rubycdio.so"))
  $: << File.dirname(__FILE__) + '/../ext/cdio'
  $: << File.dirname(__FILE__) + '/../lib'
else
  require 'rubygems'
end
require "cdio"
require 'getoptlong'

OPTIONS = [
           ['--help',        '-h', GetoptLong::NO_ARGUMENT,
            "Display this help message."],
           ['--close',       '-c', GetoptLong::REQUIRED_ARGUMENT,
            "close CD tray."],
           ['--play',        '-p', GetoptLong::NO_ARGUMENT,
            "Play entire CD."],
           ['--pause',       '-P', GetoptLong::NO_ARGUMENT,
            "pause playing."],
           ['--eject',       '-E', GetoptLong::NO_ARGUMENT,
            "Eject CD."],
           ['--resume',      '-r', GetoptLong::NO_ARGUMENT,
            "resume playing."],
           ['--stop',        '-s', GetoptLong::NO_ARGUMENT,
            "stop playing."],
           ['--track',       '-t', GetoptLong::REQUIRED_ARGUMENT,
            "play a single track."]
         ]

# Print short help - command form and a one-line description
def usage()
  puts "%s [options] [device]
    Issue analog audio CD controls - like playing" % $0
end

# Print help (includes usage), option descriptions, and then exit
def help
  usage
  puts
  puts "Options are ..."
  puts
  OPTIONS.sort.each do |long, short, mode, desc|
    if mode == GetoptLong::REQUIRED_ARGUMENT
      if desc =~ /\b([A-Z]{2,})\b/
        long = long + "=#{$1}"
      end
    end
    printf "  %-20s (%s)\n", long, short
    printf "      %s\n", desc
  end
  exit 100
end

# Return a list of the command line options supported by the
# program.
def command_line_options
  OPTIONS.collect { |lst| lst[0..-2] }
end

options={}
opts = GetoptLong.new(*command_line_options)
begin
  opts.each { |opt, value| options[opt]=value }
rescue GetoptLong::InvalidOption
  exit 3
end
help if options["--help"]

# Handle closing the CD-ROM tray if that was specified.
if options['--close']
    begin
        device_name = options['--close']
        Cdio::close_tray(device_name)
    rescue DeviceException
        puts "Closing tray of CD-ROM drive %s failed" % drive_name
    end
end
        
if ARGV.length() > 0
    begin
        d = Cdio::Device.new(ARGV.first)
    rescue IOError
        puts "Problem opening CD-ROM: %s" % device_name
        exit(1)
    end
else
    begin
        d = Cdio::Device.new(nil, Rubycdio::DRIVER_UNKNOWN)
    rescue IOError
        puts "Problem finding a CD-ROM"
        exit(1)
    end
end

device_name=d.device()
if options["--play"]:
    if d.disc_mode() != 'CD-DA':
        puts "The disc on %s I found was not CD-DA, but %s" \
              % [device_name, d.disc_mode()]
        puts "I have bad feeling about trying to play this..."
    end
    begin 
        start_lsn = d.first_track().lsn()
        end_lsn=d.disc_last_lsn()
        puts "Playing entire CD on %s"  % device_name
        d.audio_play_lsn(start_lsn, end_lsn)
    rescue Rubycdio::TrackError:
    end

elsif options.keys().member?("--track"):
    begin
        track_num = options["--track"].to_i
        if  track_num > d.last_track().track:
            puts "Requested track %d but CD only has %d tracks" \
                  % [opts.track, d.last_track().track]
            exit(2)
        end
        if track_num < d.first_track().track:
            puts "Requested track %d but first track on CD is %d" \
                  % [opts.track, d.first_track().track]
            exit(2)
        end
        puts "Playing track %d on %s"  % [track_num, device_name]
        start_lsn = d.track(track_num).lsn()
        end_lsn = d.track(track_num+1).lsn()
        d.audio_play_lsn(start_lsn, end_lsn)
    rescue TrackError
    end
        
elsif options["--pause"]:
    begin
        puts "Pausing playing in drive %s" % device_name
        d.audio_pause()
    rescue Cdio::DeviceException
        puts "Pause failed on drive %s" % device_name
    end
elsif options["--resume"]:
    begin
        puts "Resuming playing in drive %s" % device_name
        d.audio_resume()
    rescue Cdio::DeviceException
        puts "Resume failed on drive %s" % device_name
    end
elsif options["--stop"]:
    begin
        puts "Stopping playing in drive %s" % device_name
        d.audio_stop()
    rescue Cdio::DeviceException
        puts "Stopping failed on drive %s" % device_name
    end
elsif options["--eject"]:
    begin
        puts "Ejecting CD in drive %s" % device_name
        d.eject_media()
    rescue Cdio::DriverUnsupportedError
        puts "Eject not supported for %s" % device_name
    rescue DeviceException
        puts "Eject of CD-ROM drive %s failed" % device_name
    end
end
        
d.close()
