"use strict";

var DATA_CHIPTUNES = {
	testsong : {
		chip: "testsquare",
		bpm: 120, // beats per minute
		priority: 1, // baseline nonzero for BGM
		songdata : {
			sq0:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note; dur=0 applies envelope over length of note played
						data: {start: 1.0, end: 0.0, dur: 0.5}
					},
					{command: "sweep", // set linear frequency sweep applied to every note (start and end multiply base note frequency); dur=0 applies sweep over length of note played
						data: {start: 1.0, end: 1.0, dur: 0}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					{command: "pan", // linearly-divided fraction of the audio going to the right channel, with the remainder going to the left
						data: {position: 1.0}
					},
					{command: "tempo", // change tempo mid-tune
						data: {bpm: 120}
					},
					{command: "detune", // detune in cents to be applied to the oscillator (for "richer" cound when 2 similar frequencies overlap)
						data: {cents: 0}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn2 1",
							"Dn2 1",
							"En2 1",
							"Fn2 1",
							"Gn2 1",
							"An2 1",
							"Bn2 1",
							"Cn3 1",
						]
					},
					{command: "pan", // linearly-divided fraction of the audio going to the right channel, with the remainder going to the left
						data: {position: 0.0}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn3 1",
							"Bn2 1",
							"An2 1",
							"Gn2 1",
							"Fn2 1",
							"En2 1",
							"Dn2 1",
							"Cn2 1",
						]
					},
				],
			sq1:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note
						data: {start: 1.0, end: 0.0, dur: 0.5}
					},
					{command: "sweep", // set linear frequency sweep applied to every note (start and end multiply base note frequency)
						data: {start: 1.0, end: 1.0, dur: 0}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					{command: "tempo", // change tempo mid-tune
						data: {bpm: 240}
					},
					{command: "detune", // detune in cents to be applied to the oscillator (for "richer" cound when 2 similar frequencies overlap)
						data: {cents: 2}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn3 1",
							"Cn3 1",
							"Dn3 1",
							"Dn3 1",
							"En3 1",
							"Cn3 1",
							"Fn3 1",
							"Fn3 1",
							"Gn3 1",
							"Cn3 1",
							"An3 1",
							"An3 1",
							"Bn3 1",
							"Bn3 1",
							"Cn4 1",
							"Cn3 1",
						]
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn4 1",
							"Cn3 1",
							"Bn3 1",
							"Bn3 1",
							"An3 1",
							"An3 1",
							"Gn3 1",
							"Cn3 1",
							"Fn3 1",
							"Fn3 1",
							"En3 1",
							"Cn3 1",
							"Dn3 1",
							"Dn3 1",
							"Cn3 1",
							"Cn3 1",
						]
					},
				],
		}
	},
	testsongDX : {
		chip: "oneofeach",
		bpm: 120, // beats per minute
		priority: 1, // baseline nonzero for BGM
		songdata : {
			st:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note
						data: {start: 1.0, end: 0.0, dur: 0.5}
					},
					{command: "sweep", // set linear frequency sweep applied to every note (start and end multiply base note frequency)
						data: {start: 1.0, end: 1.0, dur: 0}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					{command: "pan", // linearly-divided fraction of the audio going to the right channel, with the remainder going to the left
						data: {position: 1.0}
					},
					{command: "tempo", // change tempo mid-tune
						data: {bpm: 120}
					},
					{command: "detune", // detune in cents to be applied to the oscillator (for "richer" cound when 2 similar frequencies overlap)
						data: {cents: 0}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn2 1",
							"Dn2 1",
							"En2 1",
							"Fn2 1",
							"Gn2 1",
							"An2 1",
							"Bn2 1",
							"Cn3 1",
						]
					},
					{command: "pan", // linearly-divided fraction of the audio going to the right channel, with the remainder going to the left
						data: {position: 0.0}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
						]
					},
				],
			tri:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note
						data: {start: 1.0, end: 0.0, dur: 0.5}
					},
					{command: "sweep", // set linear frequency sweep applied to every note (start and end multiply base note frequency)
						data: {start: 1.0, end: 1.0, dur: 0}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					{command: "pan", // linearly-divided fraction of the audio going to the right channel, with the remainder going to the left
						data: {position: 1.0}
					},
					{command: "tempo", // change tempo mid-tune
						data: {bpm: 120}
					},
					{command: "detune", // detune in cents to be applied to the oscillator (for "richer" cound when 2 similar frequencies overlap)
						data: {cents: 0}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
							"Rst 1",
						]
					},
					{command: "pan", // linearly-divided fraction of the audio going to the right channel, with the remainder going to the left
						data: {position: 0.0}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn3 1",
							"Bn2 1",
							"An2 1",
							"Gn2 1",
							"Fn2 1",
							"En2 1",
							"Dn2 1",
							"Cn2 1",
						]
					},
				],
			sq:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note
						data: {start: 1.0, end: 0.0, dur: 0.5}
					},
					{command: "sweep", // set linear frequency sweep applied to every note (start and end multiply base note frequency)
						data: {start: 1.0, end: 1.0, dur: 0}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					{command: "tempo", // change tempo mid-tune
						data: {bpm: 240}
					},
					{command: "detune", // detune in cents to be applied to the oscillator (for "richer" cound when 2 similar frequencies overlap)
						data: {cents: 2}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn3 1",
							"Cn3 1",
							"Dn3 1",
							"Dn3 1",
							"En3 1",
							"Cn3 1",
							"Fn3 1",
							"Fn3 1",
							"Gn3 1",
							"Cn3 1",
							"An3 1",
							"An3 1",
							"Bn3 1",
							"Bn3 1",
							"Cn4 1",
							"Cn3 1",
						]
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn4 1",
							"Cn3 1",
							"Bn3 1",
							"Bn3 1",
							"An3 1",
							"An3 1",
							"Gn3 1",
							"Cn3 1",
							"Fn3 1",
							"Fn3 1",
							"En3 1",
							"Cn3 1",
							"Dn3 1",
							"Dn3 1",
							"Cn3 1",
							"Cn3 1",
						]
					},
				],
			sin:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note
						data: {start: 1.0, end: 1.0, dur: 0.0}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn5 1",
							"Bn4 1",
							"Cn5 1",
							"Gn4 1",
							"Cn5 1",
							"Bn4 1",
							"Cn5 1",
							"Rst 1",
						]
					},
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn5 1",
							"Dn5 1",
							"Cn5 1",
							"Gn4 1",
							"Cn5 1",
							"Dn5 1",
							"Cn5 1",
							"Rst 1",
						]
					},
				],
		}
	},
	noisesong : {
		chip: "noisetest",
		bpm: 120, // beats per minute
		priority: 1, // baseline nonzero for BGM
		songdata : {
			nz:	// name of a channel on the chip	
				[
					{command: "env", // set linear ramp envelope applied to every note
						data: {start: 1.0, end: 0.0, dur: 0.5}
					},
					{command: "vol", // set overall volume of channel
						data: {level: 0.1}
					},
					
					{command: "notes", // strings of the form "NnO L" where NnO is the Note-modifier-Octave note to play (from DEF_CHIPTUNE_PITCHES) and L is the length in beats or fractions (can be multiple characters as long as parseFloat will take it)
						data: [
							"Cn2 1",
							"Cn3 1",
							"Cn4 1",
							"Cn5 1",
							"Cn6 1",
							"Cn7 1",
							"Cn8 1",
							"Cn9 1",
						]
					}
				]
		}
	},
	
};


// data organizing when multiple chiptunes form one sequence/playlist/metatune
var DATA_CT_SEQUENCES = {};
DATA_CT_SEQUENCES["Seeking the Darkness Within"] = [
		"Seeking the Darkness I",
		"Seeking the Darkness II",
		"Seeking the Darkness III",
		"Seeking the Darkness IV",
		//"a Breath of Darkness",
	];

// generic sequencer for when the goal is to go
// all the way through the list and maybe repeat.
// Note that because there's no way to detect the
// last item finishing, and queue mode assumes loop
// if no further data, if the idea is to play once
// and stop, the last item in the list should be  
// loopable silence or conclude with the desired 
// jump-loop internally.
// Neither can we differentiate "instances" of a
// track by the time they're queued, so if the same
// track occurs multiple times in the list, the
// index detection will always land on the first
// occurrence when the sequencer is reloaded e.g.
// into a new room.  If the same track name occurs
// consecutively, the SDS/chiptune-side queueing
// logic will assume it's already playing and not
// queue up the repeat, meaning the queues will
// stay consumed and the sequencer will move on to
// the next track.
// If absolutely needed, you could likely work around
// this by setting an alternate-named chiptune equal
// to the one you want to repeat (literally assign
// existing data to a new name; no need to deep-dup
// the data) and bouncing between the two names.
var CT_SEQUENCER = function(seqName, loop){
	return function(mapRoom){
		// build a hack gameobject which will watch the current track name
		// (keep in mind that this will be the last track name QUEUED and
		// may not reflect the actually playing content UNTIL the queue drains)
		// and queue the next movement whenever the current queue is spent.
		var movements = DATA_CT_SEQUENCES[seqName];
		if (!movements) return null;
		var idx = movements.indexOf(SDS.bgmName);
		if (idx===-1){
			idx=0;
			SDS.switchBgm(movements[idx],true);
		}
		if (!loop && idx===movements.length-1) return null;
		
		var dummy = new GameObject(
			new Sprite(
				null,
				"ChiptuneSequencer"
			),
			"ChiptuneSequencer"
		);
		dummy.Update = function(){
			if ((loop || idx!==movements.length-1) && SDS.bgm.dequeued_channels === SDS.bgm.queued_channels){
				idx = (idx+1)%movements.length;
				SDS.queueBgm(movements[idx],true);
			}
		};
		return dummy;
	};
};
// custom sequencers for more advanced effects
var DATA_CT_SEQUENCERS = {};
//DATA_CT_SEQUENCERS.darknessByKey = CT_SEQUENCER("Seeking the Darkness Within",true); // for now.  Update when/if needed

DATA_CT_SEQUENCERS.darknessByKey = function(mapRoom){
	// A custom sequencer that will advance the BGM
	// based on number of keys collected
	var movements = [
		"Seeking the Darkness I",
		"Seeking the Darkness II",
		"Seeking the Darkness III",
		"Seeking the Darkness IV",
		"a Breath of Darkness",
		""
	];
	var keysToMovement = [ // latest movement allowed; increment will be automatic
		0,
		1,
		1,
		1,
		1,
		2,
		2,
		5
	];
	// keys now tracked at the diary level
	//var keys = 0;
	//for (var i=1; i<8; ++i){
	//	if (GLOBAL_DIARY.check(5,"SEALKEY_"+i)) ++keys;
	//}
	//var entries = GLOBAL_DIARY.narrative.length;


	//if (!movements) return null;
	var idx = movements.indexOf(SDS.bgmName);
	if (idx===-1){
		//idx=Math.min(keysToMovement[keys],4);
		////idx = (keys==7) ? 4 : 0;
		idx=Math.min(keysToMovement[GLOBAL_DIARY.key_count],4);
		//idx = (GLOBAL_DIARY.key_count==7) ? 4 : 0;
		
		SDS.switchBgm(movements[idx],idx<4);
	}
	//if (!loop && idx===movements.length-1) return null;
	
	var dummy = new GameObject(
		new Sprite(
			null,
			"ChiptuneSequencer"
		),
		"ChiptuneSequencer"
	);
	dummy.Update = function(){
		// recompute key count only when diary changes
		//if (GLOBAL_DIARY.narrative.length != entries){
		//	if (GLOBAL_DIARY.check(5,"SEALKEY_"+(keys+1))) ++keys;
		//	entries = GLOBAL_DIARY.narrative.length;
		//}

		//if ((idx < keysToMovement[keys]) && SDS.bgm.dequeued_channels === SDS.bgm.queued_channels){
		if ((idx < keysToMovement[GLOBAL_DIARY.key_count]) && SDS.bgm.dequeued_channels === SDS.bgm.queued_channels){
			idx = (idx+1)%movements.length;
			SDS.queueBgm(movements[idx],true);
		}
	};
	return dummy;
};
