import pickle, database, string, gdbm, sys, whrandom 
import struct, commands, thread, signal, os, FCNTL
def print_amount(db):
    "print the sizes of the songs"
    one = []             #make the data structures to store the numbers in
    two = []
    three = []
    four = []
    five = []
    six = []
    seven = []
    eight = []
    nine = []
    ten = []
    k = db.firstkey()
    while k != None:
	value = db[k]                   #get each song's rating
	songname = string.lstrip(k)     #from the database
	if value == '1':
	    one.append(songname)
	elif value == '2':
	    two.append(songname)
	elif value == '3':
	    three.append(songname)
	elif value == '4':
	    four.append(songname)
	elif value == '5':
	    five.append(songname)
	elif value == '6':
	    six.append(songname)
	elif value == '7':
	    seven.append(songname)
	elif value == '8':
	    eight.append(songname)
	elif value == '9':
	    nine.append(songname)
	elif value == '10':
	    ten.append(songname)
	k = db.nextkey(k)
    
    print "1:", len(one)
    print "2:", len(two)
    print "3:", len(three)
    print "4:", len(four)
    print "5:", len(five)
    print "6:", len(six)
    print "7:", len(seven)
    print "8:", len(eight)
    print "9:", len(nine)
    print "10:", len(ten)
    print "total:", len(one) + len(two) + len(three) + len(four) + len(five) + len(six) + len(seven) + len(eight) + len(nine) + len(ten)
def change_value(db, value):
    "change the value of the song that is currently playing"
    name = db['currentsong']
    if(db.has_key(name)):
	del db[name]
	value = database.int_to_string(value)
	db[name] = value
def next(db, playfrom):
    if(db.has_key('halt')):
	del db['halt']
	db['halt'] = 'a'
    else:
	db['halt'] = 'a'
    command = 'killall -9 mpg123'            #kill mpg123
    output = commands.getstatusoutput(command)
    name = db['currentsong']
    print 'songvalue reduced by 1'
    songvalue = db[name]                    #skip to the next song and decrese the song's rating
    del db[name]
    songvalue = database.subfromstr(songvalue)
    db[name] = songvalue
    #prevents next from exiting from next before play is dead.
    while 1:
	if db['playlock'] == 'locked':
	    pass
	else:
	    break
    thread.start_new_thread(playsongs, (db, playfrom, 0))

def prev(db, playfrom):
    try:
	del db['halt']
	db['halt'] = 'a'
    except:
	db['halt'] = 'a'
    command = 'killall -9 mpg123'            #kill mpg123
    output = commands.getstatusoutput(command)
    if(db.has_key('prevsong')):
	name = db['prevsong']
	print 'songvalue raised by 1'
	songvalue = db[name]                    #skip to the next song and decrese the song's rating
	del db[name]
	songvalue = database.addtostr(songvalue)
	db[name] = songvalue
    #prevents prev from exiting from prev before play is dead.
    while 1:
	if db['playlock'] == 'locked':
	    pass
	else:
	    break
    thread.start_new_thread(playsongs, (db, playfrom, 1))
    
def end_thread(db):
    "this prevents the program from looping in it's thread"
    #this uses the halt key to kill a playsongs() loop in progress
    #this is nescessary for skipping or playing a previous song
    x = 0
    try:
	haltvalue = db['halt']
	haltvalue = string.strip(haltvalue)
	del db['halt']
	if haltvalue == 'a':
	    db['halt'] = 'b'
	    x = 1
	else:
	    db['halt'] = 'b'
    except:
	print 'halt key not in db'
	db['halt'] = 'b'
	x = 0
    return x

def playsongs(db, playfrom, play_prev):
    #this is my semi-random song player thingy
    #get a random integer between 1 and 5, play a song of that value,
    #then subtract one from that values place holder, so that there are
    #fives songs of the value 5 played, 4 of four, etc.
    
    if(db.has_key('playlock')):       #lock so that no other play functions can be started
	if db['playlock'] == 'locked':
	    print 'crimeny it\'s locked'
	    thread.exit()
	else:
	    del db['playlock']
	    db['playlock'] = 'locked'
    else:
	db['playlock'] = 'locked'
    if(db.has_key('playvalues') == 0):
	count = 1
	playvalues = {}
	while count <= 10:
	    playvalues[count] = count
	    count = count + 1
	valuesfile= os.environ['HOME'] + "/.pimp3.values"
	f = open(valuesfile, 'w')
	p = pickle.Pickler(f)
	p.dump(playvalues)
	del f
	db['playvalues'] = 'yes'
    playto = 10   #initialize playto
    while 1:
	k = db.firstkey()
	one = []             #make the data structures to store the numbers in
	two = []
	three = []
	four = []
	five = []
	six = []
	seven = []
	eight = []
	nine = []
	ten = []
	while k != None:
	    value = db[k]                   #get each song's rating
	    songname = k     #from the database
	    if ((songname == 'halt')|(songname == 'song playing')|
	    (songname == 'playlock')|(songname == 'g1')|
	    (songname == 'g2')|(songname == 'g3')|
	    (songname == 'g4')|(songname == 'g5')|
	    (songname == 'g6')|(songname == 'g7')|
	    (songname == 'g8')|(songname == 'g9')|
	    (songname == 'g10')|(songname == 'playvalues')|
	    (songname == 'oldsong')|(songname == 'prevsong')|
	    (songname == 'currentsong')):
		ko = k
		k = db.nextkey(k)
		if k == ko:
		    break
		else:
		    continue
	    value = string.atoi(value)
	    if value == 1:
		one.append(songname)
	    elif value == 2:
		two.append(songname)
	    elif value == 3:
		three.append(songname)
	    elif value == 4:
		four.append(songname)
	    elif value == 5:
		five.append(songname)
	    elif value == 6:
		six.append(songname)
	    elif value == 7:
		seven.append(songname)
	    elif value == 8:
		eight.append(songname)
	    elif value == 9:
		nine.append(songname)
	    elif value == 10:
		ten.append(songname)
	    k = db.nextkey(k)
	songplayed = ' '
	oldplayfrom = playfrom   #save the old playfrom value so that
				 #playto can be reinitialized later
	whole_song_played = 0
	quit_or_not = end_thread(db)
	if quit_or_not == 1:
	    break
	#get the playvalues
	valuesfile = os.environ['HOME'] + "/.pimp3.values"
	f = open(valuesfile, 'r')
	p = pickle.Unpickler(f)
	playvalues = p.load()
	del f
	
	#this is ment to slightly speed up the random generator
	#it stops from generating numbers for depleted values
	count = 1
	while count <= 10:
	    key = count
	    if ((count == playfrom)&(playvalues[key] == 0)):
		playfrom = count + 1
	    if ((count == playto)&(playvalues[key] == 0)):
		playfrom = count - 1
	    count = count + 1
	    
	#generate the random number    
	if(playfrom != playto):           #accomodate the option to play only songs of the value 5
	    random = whrandom.randint(playfrom, playto)
	else:
	    random = playto
	
	#this handles the database and makes sure that 5 songs of the value
	#5, 4 of 4, and etc are played in each loop.
	    
	count = 1
	while count <= 10:
	    if ((count == random)&(playvalues[count] != 0)):
		songplayed = play(db, one, two, three, four, five, six, seven, eight, nine, ten, count, play_prev)
		value = playvalues[count]
		playvalues[count] = value - 1
	    count = count + 1
	    
	#reset values when nescessary
	count = oldplayfrom
	stop = 0
	while count <= 10:
	    if((playvalues[count] == 0) & (stop != 1)):
		stop = 0
	    else:
		stop = 1
	    count = count + 1
	    
	if stop != 1:
	    count = 1
	    playvalues = {}
	    while count <= 10:
		playvalues[count] = count
		count = count + 1
	    playfrom = oldplayfrom
	    playto = 5
		
	quit_or_not = end_thread(db)
	f = open(valuesfile, 'w')
	p = pickle.Pickler(f)
	p.dump(playvalues)
	del f
	if (quit_or_not == 0) & (songplayed != ' ') & (songplayed != None):
	    if(db.has_key(songplayed)):
		songvalue = db[songplayed]
	    else:
		print 'songname not in database'
		continue
	    print songvalue
	    del db[songplayed]
	    #print 'old value:', songvalue,
	    print 'songvalue upgraded by 1'
	    songvalue = database.addtostr(songvalue)
	    db[songplayed] = songvalue
	elif quit_or_not == 1:
	    break
	del one, two, three, four, five
    if(db.has_key('halt')):
	del db['halt']
	db['halt'] = 'b'
    else:
	db['halt'] = 'b'	
    if(db.has_key('playlock')):       #lock so that no other play functions can be started
	if db['playlock'] == 'locked':
	    del db['playlock']
	    db['playlock'] = 'unlocked'
    else:
	db['playlock'] = 'unlocked'
    thread.exit()
def play(db, one, two, three, four, five, six, seven, eight, nine, ten, value, play_prev):
    "play the assigned song"
    if value == 1:
	list = one
    elif value == 2:
	list = two
    elif value == 3:
	list = three
    elif value == 4:
	list = four
    elif value == 5:
	list = five
    elif value == 6:
	list = six
    elif value == 7:
	list = seven
    elif value == 8:
	list = eight
    elif value == 9:
	list = nine
    elif value == 10:
	list = ten
	
    length = len(list)
    if length > 0:
	random = whrandom.randint(0, length)
	random = random - 1
	songname = list[random]
	if play_prev == 1:
	    if(db.has_key('prevsong')):
		songname = db['prevsong']
	    else:
		db['prevsong'] = songname
		
	if(db.has_key('currentsong')):
	    del db['currentsong']
	    db['currentsong'] = songname
	else:
	    db['currentsong'] = songname
	filename = string.replace(songname, '\000', '')
	mp3name = '\"' + filename + '\"'
	command = "mpg123 " + mp3name
	filename = string.split(filename, '/') #strip off the directory heading
	length = len(filename)
	length = length - 1
	filename = filename[length]
	print filename, " : ", db[songname]
	print ":",
	if(db.has_key('oldsong')&db.has_key('prevsong')):
	    temp = db['oldsong']
	    del db['oldsong']
	    db['oldsong'] = songname
	    del db['prevsong']
	    db['prevsong'] = temp
	else:
	    db['oldsong'] = songname
	    db['prevsong'] = songname
	trash = commands.getstatusoutput(command)
	return songname
def play_help():
    print
    print 'help -this help message'
    print 'n    -play the next song'
    print 'v    -play the previous song'
    print '1-5  -change the current mp3\'s value to the number entered'
    print 'p    -start playing the music'
    print 'q    -quit'
    print
    
def randomplay(db, playfrom, versionnumber):
    "playsongs in random order"
    #used to make sure two instances of play are not running at the same time
    print 'Welcome to the pimp3 ',versionnumber,'!'
    if(db.has_key('playlock')):
	del db['playlock']   #remove the playlock
	db['playlock'] = 'unlocked'
    #start the menu loop
    play_help()
    #thread.start_new_thread(playsongs, (db, playfrom, 0))
    print ':',
    while 1:
	input = raw_input('')
	input = string.strip(input)
	if input == 'n':
	    next(db, playfrom)
	elif input == 'v':
	    prev(db, playfrom)
	elif input == 'p':
	    thread.start_new_thread(playsongs, (db, playfrom, 0))
	elif input == '1':
	    change_value(db, 1)
	elif input == '2':
	    change_value(db, 2)
	elif input == '3':
	    change_value(db, 3)
	elif input == '4':
	    change_value(db, 4)
	elif input == '5':
	    change_value(db, 5)
	elif input == 'q':
	    print 'Goodbye'
	    command = 'killall -9 mpg123'
	    try:
		del db['halt']
		db['halt'] = 'a'
	    except:
		db['halt'] = 'a'
	    commands.getstatusoutput(command)
	    thread.exit()
	    sys.exit()
	elif input == 'help':
	    play_help()
	else:
	    play_help()
	del input
















































