#!/usr/bin/env python
'''The Python soundmixer using smixer and curses

Yes, it's lame depending on non-standard packages,
but I had it installed and didn't whan't to lern how to 
program the soundmixer under linux.
-TheZulk

How to use:
up and down to change volume
right and left to change device to control
q to exit (quit)
0 through 9 sets volume 0% through 90% of volume

'''
import curses
from os import system,popen,popen4
from sys import exit
volume = {}
vols = []

if __name__ == '__main__':
	# Load all mixer devices from smixer
	for a in popen('smixer -p').readlines():
		if a[:2] == 'ID': continue
		if a[:2] == '--':continue
		vols.append(a.split()[1])
		volume[a.split()[1]] =  int(a.split()[-1][:-1])

	## I only need vol and pcm in my mixer :)
	vols = ['Vol','Pcm','Line','Mic']

	## Therefor I have to check that they are valid :(
	for a in vols:
		if not volume.has_key(a):
			print 'error: ' + a + ' is not a device in your sound mixer'
			print volume.keys()
			exit(1)

	curvol = vols[0]
	# Open smixer and hook up it's stdin to mixer[0]
	mixer = popen4('smixer -s -')


def val(name, x,y,value):
	'''Puts one volume-meter on the screen'''
	val=value/2
	if val < 0:
		val = 0
	if val > 50:
		val = 50
	nlen = len(name)
	if nlen > 10:
		name = name[:10]
	screen.addstr(y,x,name+' '*(12-nlen)+' ['+'#'*val+' '*(50-val)+'] '+str(value)+'%')
	screen.clrtoeol()

def setVol(dev):
	'''I'm lazy, so this funktion sets the volume of a device'''
	mixer[0].write('vol '+dev+' '+str(volume[dev])+'\n')
	mixer[0].flush()

def up_pressed():
	'''I rather have this for it self than in the main loop'''
        global curvol
	volume[curvol] += 5
	if volume[curvol] > 100:
		volume[curvol] = 100
	setVol(curvol)

def down_pressed():
	'''I rather have this for it self than in the main loop'''
        global curvol
        volume[curvol] -= 5
        if volume[curvol] < 0:
                volume[curvol] = 0
	setVol(curvol)

def left_pressed():
	'''I rather have this for it self than in the main loop'''
	global curvol
	vols.append(vols.pop(0))
	curvol = vols[0]

def right_pressed():
	'''I rather have this for it self than in the main loop'''
        global curvol
	vols.insert(0,vols.pop())
	curvol=vols[0]

if __name__ == '__main__':
	# Initiaze curses
	screen = curses.initscr()
	curses.noecho()
	curses.cbreak()
	screen.keypad(1)

	try:
		screen.addstr(3,1,''' This program is made by TheZulk!
	Buttons used are:
	up and down    - change volume
	left and right - change device to be controlled
	0 -> 9         - change volume to number * 10
	q              - quit''')	
		quit = 0
		while not quit:
			screen.addstr(1,1,'Current control: '+curvol)
			screen.clrtoeol()
			# Put the volume meters on the screen
			b = 10
			for a in vols:
				val(a, 2,b,volume[a])
				b += 1
			screen.box()
			screen.refresh()
	
			# Check for a keypress
			c = screen.getch()
	
			# Quit if q is pressed
			if c == ord('q'): quit = 1
			if c == ord('w'):
				screen.clear()
		                screen.addstr(3,1,''' This program is made by TheZulk!
        Buttons used are:
        up and down    - change volume
        left and right - change device to be controlled
        0 -> 9         - change volume to number * 10
        q              - quit''')
	
			# Check the arrow keys
			elif c == curses.KEY_UP: up_pressed()
			elif c == curses.KEY_DOWN: down_pressed()
			elif c == curses.KEY_LEFT: left_pressed()
			elif c == curses.KEY_RIGHT: right_pressed()

			# Fast keys for when you don't have time to what for
			# the lazy incresing and decresing with the arrow keys
			elif c >= ord('0'):
				if c <= ord('9'):
					volume[curvol]=int(chr(c))*10
					setVol(curvol)

			## I want to control xmms aswell :)
			if c == ord('z'): system('xmms -r')
			elif c == ord('x'): system('xmms -p')
			elif c == ord('c'): system('xmms -u')
			elif c == ord('v'): system('xmms -s')
			elif c == ord('b'): system('xmms -f')

	finally:	
		# Deinitialize curses
		screen.keypad(0)
		curses.nocbreak()
		curses.echo()
		curses.endwin()
