--[[
Lua Music Sequencer - v1.0
Written by Knifa.
Default Samples by modcase.

Every new array added to the Score variable for Songs is 
like a new insturment, for playing chords and drums
and the like.

Songs are processed in HALF-BEATS, not one full beat.
]]

--------------------------------------------

function DoMenu()
	files = System.listDirectory()
	filen = table.getn( files );
	filecur = 1;
	lastmove = 0;
	
	while ( true ) do
		for i = 1, filen do
			if ( i == filecur ) then
				color = Color.new( 255, 255, 0 );
			else
				color = Color.new( 255, 255, 255 );
			end
			
			screen:print( 0, i*10-10, files[i].name, color );
		end
		
		pad = Controls.read();
		if ( tmTime:time() > lastmove+100 ) then
			if ( pad:down() ) then
				filecur = filecur + 1;
			end
			if ( pad:up() ) then
				filecur = filecur - 1;
			end
			if ( pad:cross() ) then
				return files[filecur].name;
			end
			
			if ( filecur < 1 ) then
				filecur = filen;
			end
			if ( filecur > filen ) then
				filecur = 1;
			end
			
			lastmove = tmTime:time();
		end
		
		screen:print( 0, 252, "Music Sequencer v1.0 by Knifa", colWhite );
		screen:print( 0, 262, "Default Samples by modcase", colWhite );
		screen.waitVblankStart();
		screen.flip()
		screen:clear()
	end
end

function AddSample( file )
	screen:print( 0, 0, "Loading " .. file, Color.new( 255, 255, 0 ) );
	screen.flip();
	screen:clear();
	
	table.insert( Samples, Sound.load( file ) );
	return table.getn( Samples );
end

--------------------------------------------

-- Default notes, AddSamples returned value is the number you should use for adding the sample in your music.
-- Samples can also be loaded in the song files.

Samples = { };

V_DRUM1		= AddSample( "bass1.wav" );
V_HIHAT1	= AddSample( "hihat1.wav" );
V_C1		= AddSample( "c1.wav" );
V_C1_SHARP	= AddSample( "c1_sharp.wav" );
V_D1		= AddSample( "d1.wav" );
V_D1_SHARP	= AddSample( "d1_sharp.wav" );
V_E1		= AddSample( "e1.wav" );
V_F1		= AddSample( "f1.wav" );
V_F1_SHARP	= AddSample( "f1_sharp.wav" );
V_G1		= AddSample( "g1.wav" );
V_G1_SHARP	= AddSample( "g1_sharp.wav" );
V_A1		= AddSample( "a1.wav" );
V_A1_SHARP	= AddSample( "a1_sharp.wav" );
V_B1		= AddSample( "b1.wav" );
V_SNARE1	= AddSample( "snare1.wav" );

--------------------------------------------

System.usbDiskModeActivate()

tmTime = Timer.new();
tmTime:start();

dofile("song3.lua");
iOneBeat = (1/(Song.iBPM/60))*1000;
iTracks = table.getn( Song.Score );

iLastBeat = 0;
iCurBeat = 1;
iCurHalfBeat = 1
iTime = 0;

colWhite = Color.new(255, 255, 255);

--------------------------------------------

while ( true ) do
	iTime = tmTime:time();
	cPad = Controls.read();
	
	--------------------------------------------
	
	if ( iTime >= iLastBeat+iOneBeat/2 ) then -- Plays per HALF-BEAT
		for i = 1, iTracks do
			iVoice = Song.Score[i][iCurHalfBeat]
			
			if ( iVoice > 0 ) then
				Samples[iVoice]:play();
			end
		end
		
		iCurBeat = iCurBeat + 0.5;
		iCurHalfBeat = iCurHalfBeat + 1;
		if ( iCurBeat > Song.iLength*2 ) then
			iCurBeat = 1;
		end
		if ( iCurHalfBeat > Song.iLength ) then
			iCurHalfBeat = 1;
		end
		
		screen:print( 0, 80, "BEAT", colWhite );
		iLastBeat = iTime;
	end
	
	--------------------------------------------
	
	if ( cPad:start() ) then
		dofile(DoMenu());
		
		iOneBeat = (1/(Song.iBPM/60))*1000;
		iTracks = table.getn( Song.Score );
		
		iLastBeat = 0;
		iCurBeat = 1;
		iCurHalfBeat = 1;
		iTime = 0;
	end
	
	if ( cPad:select() ) then
		break;
	end
	
	--------------------------------------------
	
	screen:print( 0, 0, "BPM: " .. Song.iBPM, colWhite );
	screen:print( 0, 10, "One Beat: " .. iOneBeat .. "ms", colWhite );
	screen:print( 0, 20, "Tracks: " .. iTracks, colWhite );
	screen:print( 0, 40, "Current Beat: " .. math.floor(iCurBeat) .. " (" .. iCurHalfBeat .. " half)", colWhite );
	screen:print( 0, 50, "Running Time: " .. iTime, colWhite );
	screen:print( 0, 60, "Last Beat Time: " .. iLastBeat, colWhite );
	
	screen:print( 0, 254, "Press START to go to the song selector.", colWhite );
	screen:print( 0, 264, "Press SELECT to exit.", colWhite )
	
	--------------------------------------------
	
	screen.waitVblankStart();
	screen.flip();
	screen:clear();

end