import sys
sys.path.append('pys60-compat')

import e32
import e32dbm
import appuifw
import audio
import os
import random
import time
import stat

# config
fade_step = 10
fade_interval = 10

# global app lock
app_lock = e32.Ao_lock()
alarm_timer = e32.Ao_timer()
fade_timer = None
snd = None

def quit():
	global snd, fade_timer, alarm_timer

	try:
		if snd != None:
			snd.close()
		if alarm_timer != None:
			alarm_timer.cancel()
		if fade_timer != None:
			fade_timer.cancel()
	finally:
		app_lock.signal()

appuifw.app.exit_key_handler = quit

def gen_songs_list():
	global songs_list
	global songs_path

	songs_list = []

	for dir in os.walk(songs_path):
		songs_list.extend( \
			map(lambda x,base=dir[0]:os.path.join(base,x), \
			filter(lambda x:x[-3:]=='mp3', dir[2]) \
			) )

def play_rand_song():
	global songs_list
	global snd

	song = songs_list[random.randint(0,len(songs_list)-1)]

	try:
		snd = audio.Sound.open(song)
	except:
		#print 'Could not open file: %s' % song
		pass

	snd.set_volume(0)
	snd.play(audio.KMdaRepeatForever)

def fade_in():
	global fade_timer, fade_step, fade_interval
	global snd
	
	vol = snd.current_volume()
	max_vol = snd.max_volume()

	if vol < max_vol:
		snd.set_volume(vol+max_vol/fade_step)
		fade_timer.after(fade_interval, fade_in) 

def do_alarm():
	global fade_timer
	fade_timer = e32.Ao_timer()

	play_rand_song()
	fade_in()

def check_alarm():
	global target_time
	global alarm_timer

	if time.localtime()[3:5] == target_time:
		#print 'alarm'
		do_alarm()
		alarm_timer.after(60, check_alarm)
	else:
		alarm_timer.after(30, check_alarm)

base_drives = ['c:','d:','e:','z:']
def filter_dirs(lst, path=''):
	full_lst = map(lambda x:os.path.join(path, x), lst)
	return [ lst[i] for i in xrange(len(full_lst)) if os.path.isdir(full_lst[i]) ]

def query_path(path_list=None,this_path='',is_base=False):
	global base_drives

	if is_base:
		path_list = filter_dirs(base_drives)
	
	if not path_list:
		path_list = []

	try:
		if not is_base:
			chces = [u'[Choose Current Dir]']
			path_list = ['..'] + path_list
		else:
			chces = []

		chces.extend(map(unicode, path_list))
		r = appuifw.selection_list(choices=chces, search_field=1)
	except:
		#print path_list
		return ''	

	if not is_base and r == 0: # choose this path
		return this_path
	elif not is_base:
		selected_path = os.path.join(this_path,path_list[r-1])
		p_list = os.listdir(selected_path)
		p_list = filter_dirs(p_list, selected_path)
		return query_path(p_list, selected_path )
	elif r != None: #is_base = True
		selected_path = path_list[r] + '\\'
		p_list = os.listdir(selected_path)
		p_list = filter_dirs(p_list, selected_path)
		return query_path(p_list, selected_path)
	
def main_menu():
	global target_time
	global data_store
	global songs_path
	global alarm_timer

	menu = [u'Set Alarm', u'Change Songs Path', u'Disable Alarm']
	r = appuifw.selection_list(choices=menu, search_field=1)
	
	if r == 2:
		quit()
	elif r == 0: #Set Alarm
		if songs_path == '':
			appuifw.note(u'Please choose songs path')
			main_menu()
			return

		initial_time = list(time.gmtime(0))
		initial_time[3] = (initial_time[3]+target_time[0])%23
		initial_time[4] = (initial_time[4]+target_time[1])%60
		if initial_time[3] < 2:
			initial_time[2] += 1
		 
		#print initial_time
		t = appuifw.query(u'Alarm Time:','time', time.mktime(initial_time))
		target_time = time.gmtime(t)[3:5] 
		data_store['target_time'] = ':'.join(map(str,target_time))

		alarm_timer.cancel()
		check_alarm()
		appuifw.note(u'Please click the menu button to hide this window')
		main_menu()

	elif r == 1: #Change Songs Path
		r = os.path.normpath(query_path(is_base=True))
		if r:
			songs_path = r
			data_store['songs_path'] = songs_path
			appuifw.note(u'Importing Songs...')
			gen_songs_list()

		main_menu()

	elif r == 3: #Hide
		return
		
def data_store_init():
	global data_store
	global songs_path
	global data_store
	global target_time

	data_store = e32dbm.open('e:\\alarmconf.db','c')
	if not data_store.has_key('songs_path'):
		data_store['songs_path'] = ''
		songs_path = ''
	else:
		songs_path = data_store['songs_path']

	if not data_store.has_key('target_time'):
		data_store['target_time'] = '0:0' 
		target_time = (0,0)
	else:
		target_time = tuple(map(int,data_store['target_time'].split(':')))

	#print target_time
	#print songs_path

def main():
	global songs_path
	global target_time

	data_store_init()

	if songs_path != '':
		gen_songs_list()
	main_menu()

def myexitfunc():
	global data_store

	s = appuifw.app.screen
	appuifw.app.screen = 'large'
	appuifw.app.screen = s
	app_lock.wait()
	data_store.close()
	
if __name__ == '__main__':
	sys.exitfunc = myexitfunc
	main()

