#!/usr/bin/env python

# (C) 2005 Canonical Ltd.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
# License: GNU General Public License, version 2 or any later version

# Configure default output device in ~/.asoundrc.

import sys, re, os.path

conffile = os.path.expanduser('~/.asoundrc')

def help(): 
    print '''Usage: set-default-soundcard <number> | --check-markers
If %s does not exist, or its magic comments are present, 
change the default sound card setting in it to the given number. If
--check-markers is given, the exit code shows whether the configuration file
could be modified, but does not actually change it.
''' % conffile 

def create_conffile(card_num): 
    '''Create a new configuration file with the given card as default.'''

    try:
        f = open(conffile, 'w')
        print >> f, '''### BEGIN set-default-soundcard
# If the "### BEGIN..." and "### END..." comments are intact, then you
# can change your default soundcard with "set-default-soundcard(1)."
# Remove these comments if you want to maintain a custom configuration
# that should not be changed automatically.

# Default soundcard
defaults.pcm.card %s

### END set-default-soundcard
''' % card_num
    except IOError:
        print >> sys.stderr, 'Could not create', conffile
        sys.exit(1)

def change_conffile(card_num):
    '''Change default to given card number an existing configuration file. If
    successful, return true; return false if the file does not exist, cannot be
    written, or does not have the magic comments. If card_num is None, then
    only the markers are checked without actually modifying the file.'''

    try:
        lines = open(conffile).readlines()
    except IOError:
        return False

    # search for the BEGIN marker
    marker = re.compile('### BEGIN set-default-soundcard')
    lineno = 0
    found = 0
    for l in lines:
        lineno = lineno+1
        if marker.match(l):
            found = 1
            break
    if not found:
        return False

    # search for default setting
    marker = re.compile('(defaults.pcm.card\s+)(\d+)(.*)$')
    found = 0
    for l in lines[lineno:]:
        lineno = lineno+1
        m = marker.match(l)
        if m:
            if card_num:
                lines[lineno-1] = m.group(1) + card_num + m.group(3) + '\n'
            found = 1
            break
    if not found:
        return False

    # search for the END marker
    marker = re.compile('### END set-default-soundcard')
    found = 0
    for l in lines[lineno:]:
        lineno = lineno+1
        if marker.match(l):
            found = 1
            break
    if not found:
        return False

    # write back file
    if card_num:
        try:
            open(conffile, 'w').writelines(lines)
        except IOError:
            return False
    return True

if len(sys.argv) < 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
    help()
    sys.exit(0)

check_only = (sys.argv[1] == '--check-markers')

if len(sys.argv) != 2 or not (check_only or sys.argv[1].isdigit()):
    help()
    sys.exit(1)

if not check_only:
    card_num = sys.argv[1]
else:
    card_num = None

# if ~/.asoundrc does not exist, create it
if not os.path.exists(conffile):
    if check_only:
        sys.exit(0)
    create_conffile(card_num)
else:
    if not change_conffile(card_num):
        if not check_only:
            print >> sys.stderr, conffile, \
               'was modified manually, cannot be changed by this program.'
        sys.exit(1)

