/loaders/SMloader.py
import pygame
import os.path
import re
from bmevent import *
from keyfile import *

# Required information for a loader module. If this isn't here, the game
# will crash and burn and it will be ALL YOUR FAULT.
name = "StepMania"
version = 0.0

def detect(file):
	res = [re.compile("^#SUBTITLE"), re.compile("^#BANNER"),
	       re.compile("^#BACKGROUND"),re.compile("^#NOTES")]
	match = [0,0,0,0]

	f = open(file)
	for line in f:
		for n in range(0,len(res)):
			if res[n].match(line):
				match[n] = 1
	return sum(match) / float(len(match))

def info(file):
	return {}

def load(file,status=lambda x,y:None):
	keymapping = {0:1, 1:2, 2:3, 3:4, 4:5, 5:0, 7:6, 8:7}
	kf = KeyFile()
	kf.numkeys = len(keymapping)
	dir = os.path.dirname(file)
	f = open(file,'r')
	kf.track = -1
	matcher = re.compile("#([A-Z]+):(.*);",re.DOTALL)
	kf.stoplist = []
	buf = ''
	for line in f:
		line = line.split('//')[0];
		line = line.strip()
		if len(line) == 0:
			continue
		buf += line
		m = matcher.match(buf)
		if m:
			buf = '';
			cmd = m.group(1)
			arg = m.group(2).split(':')
		else:
			continue

		if cmd == "TITLE":
			kf.title = arg[0]
		elif cmd == "SUBTITLE":
			kf.subtitle = arg[0]
		elif cmd == "ARTIST":
			kf.artist = arg[0]
		elif cmd == "BPMS":
			bpmlist = map(lambda x: x.split('='),arg[0].split(','))
			kf.bpm = bpmlist[0][1]
			for b in bpmlist:
				kf.add(BMEvent(float(b[0]), BME_TEMPO, None, float(b[1])))
		elif cmd == "STOPS":
			if arg[0]:
				stoplist = map(lambda x: x.split('='),arg[0].split(','))
				for s in stoplist:
					print s[0]
					kf.add(BMEvent(float(s[0]), BME_STOP, None, int(float(s[1])*1000)))
		elif cmd == "BACKGROUND":
			if arg[0]:
				try:
					kf.stagefile = pygame.image.load(os.path.join(dir,arg[0]))
					kf.stagefile = kf.stagefile.convert()
					status("STAGEFILE",kf.stagefile)
				except pygame.error:
					pass
		elif cmd == "OFFSET":
			kf.offset = float(arg[0])
			kf.add(BMEvent(int(kf.offset * 1000), BME_BGM, None, 255))
		elif cmd == "MUSIC":
			print os.path.join(dir,arg[0])
			try:
				pygame.mixer.music.load(os.path.join(dir,arg[0]))
                        except pygame.error:
				pygame.mixer.music.load(os.path.join(dir,arg[0].lower()))
			kf.wavs[255] = pygame.mixer.music
		elif cmd == "NOTES":
			if arg[0] == 'dance-single' and arg[2].lower() == 'challenge':
				parse_notes(arg[5],kf)
		else:
			print "Unknown command:",cmd
	kf.sort()
	f.close()

	return kf

# BUGS! This assumes a four-column chart.
def parse_notes(str,kf):
	tracks = str.split(',')
	track = 0

	for t in tracks:
		l = len(t) / 4
		for n in range(0,l):
			for m in range(0,4):
				k = t[n*4+m]
				if k == 'M':	# Freaking mines...
					continue
				k = int(k)
				if k > 0:
					beat = 4 * (track + (float(n)/l))
					# Add note filter here?
					kf.add(BMEvent(beat, BME_NOTE1, m*2+1, 1))
		track += 1