### /conv/object.py

space = " "
program_version = \
"""
% written by ig2m - *alpha 1 version*
% http://ig2m.sourceforge.jp
"""

class voice:
	def __init__(self, grid, time = [4,4], pitch = (0, 127), midi = 0):
		self.grid  = grid
		self.time  = time
		self.pitch = pitch
		self.midi = midi	

class score:
	def __init__(self):
		self.voices = []
		self.voicetable = []
		self.tempo  = 42
		self.length = 1
		self.times = [4, 4]		# main times
		self.filename = 'hoge.ly'
		self.selectConv = []
	def SetTempo(self, tempo):
		self.tempo = tempo
	def SetTimes(self, times):
		self.times = times
	def SetLength(self, length):
		self.length = length
	def SetFileN(self, filename):
		self.filename = filename
	def SetVoiceTable(self, voicetable):
		self.voicetable = voicetable
	def AppendVoice(self, voice):
		self.voices.append(voice)
	def SetConv(self, conv):
		conv.sort()
		self.selectConv = conv

### preferences
### [times, pitch, midi, noteNumber, [note's properties]]

def turnTable(table):
	newTable = []
	w = len(table[0])
	h = len(table)
	for i in range(w):
		newTable.append([])
		for j in range(h):
			newTable[i].append(table[j][i])
	return newTable

connected    = 1
disconnected = 0
centerC = 60

def convert_databond_melody(data, bond, pitch):     # numerical conversion
	def pop_note(table, i, j):
		r = table[i][j]
		table[i][j] = ()
		return r
	def isnot_note_connected(table, i, j):
		if table[i][j][-1] == disconnected:
			if i == 0:
				return True
			else:
				if   len(table[i - 1][j]) == 0:	# ()
					return True
				elif table[i - 1][j][-1] == disconnected:
					return True
		return False
	def is_table_empty(table):
		w, h = len(table), len(table[0])
		for i in range(w):
			for j in range(h):
				if len(table[i][j]) <> 0: return False
		return True
		
	if pitch[0] > pitch[1]: 
		pitch[0], pitch[1] = pitch[1], pitch[0]	
	w, h = data.size[0], data.size[1]
	table = []
	melodies = []
	
	#--- 1.
	# make table
	for j in range(h):
		#-- make line
		line = []
		for i in range(w):
			dynamic = data.getpixel((i,j)) / 255.0
			if   dynamic < 0.25:						# No Sound
				if len(line) > 0 and line[-1] <> ():
					if line[-1][-1] == connected:
						line[-1][-1] = disconnected 	# disconnect
				line.append(())							# empty tuple
			else:
				p = 127 - (j + pitch[0])
				if bond.getpixel((i,j)) == 255:
					line.append([p, dynamic, connected])	# connected
				else:
					line.append([p, dynamic, disconnected])	# not connected
		# delete connected if terminal
		if bond.getpixel((w - 1, j)) == 255:
			if len(line) <> 0 and line[-1] <> ():
				if line[-1][-1] == connected:
					line[-1][-1] = disconnected
		#-- add table
		table.append(line)
	# turn table
	table = turnTable(table)
	
	#--- 2.
	# make melody with chord
	melody = []
	for i in range(w):
		chord = []
		for j in range(h):
			if len(table[i][j]) <> 0:	# not ()
				if isnot_note_connected(table, i, j):
					chord.append(pop_note(table, i, j))
		melody.append(chord)
	if melody.count([]) <> len(melody):
		melodies.append(melody)
	
	# make melody
	k = 0
	while not is_table_empty(table):
		k += 1
		melody = []
		tmp = None
		for i in range(w):
			m = len(melody)
			if tmp == None:
				for j in range(h):
					if len(table[i][j]) <> 0:	# not ()
						if table[i][j][-1] == disconnected:
							if isnot_note_connected(table, i, j):
								melody.append([pop_note(table, i, j)])
								break
						else:	# connected
							# if the note is connected and the start point
							if i == 0:
								melody.append([pop_note(table, i, j)])
								tmp = j
								break
							else:
								if len(table[i - 1][j]) == 0:
									melody.append([pop_note(table, i, j)])
									tmp = j
									break
								elif table[i - 1][j][-1] == disconnected:
									melody.append([pop_note(table, i, j)])
									tmp = j
									break
				mnow = len(melody)
				if m == mnow:
					melody.append([])
			else:
				if len(table[i][tmp]) <> 0:
					melody.append([pop_note(table, i, j)])
				else:
					tmp = None
					# restart searching tmp
					for j in range(h):
						if len(table[i][j]) <> 0:	# not ()
							if table[i][j][-1] == disconnected:
								if isnot_note_connected(table, i, j):
									melody.append([pop_note(table, i, j)])
									break
							else:
								# if the note is connected and the start point
								if i == 0:
									melody.append([pop_note(table, i, j)])
									tmp = j
									break
								else:
									if len(table[i - 1][j]) == 0:
										melody.append([pop_note(table, i, j)])
										tmp = j
										break
									elif table[i - 1][j][-1] == disconnected:
										melody.append([pop_note(table, i, j)])
										tmp = j
										break
					mnow = len(melody)
					if m == mnow:
						melody.append([])
		if melody.count([]) <> len(melody):
			melodies.append(melody)
	#--- 3.
	return melodies