#include <cstdlib>
#include <cassert>
#include "note.h"
using namespace std;

const int note::subscript = ios_base::xalloc();

//Return the distance from it2 to it1 (the integer you'd have to add to it2 to
//get to it1, or note::n if there is no such integer.

note::const_iterator::difference_type
note::const_iterator::distance(const const_iterator& it1,
                               const const_iterator& it2)
{
	assert(it1.stride == it2.stride);
	difference_type d = 0;

	for (const_iterator it = it2; it != it1 && d < note::n; ++it, ++d) {
	}

	return d;
}

note::const_iterator::difference_type operator-(const note::const_iterator& it1,
                                                const note::const_iterator& it2)
{
	const note::const_iterator::difference_type d =
		note::const_iterator::distance(it1, it2);

	if (d >= note::n) {
		cerr << *it1 << " is inaccessible from " << *it2
			<< " via a stride of " << it1.stride << ".\n";
		exit(EXIT_FAILURE);
	}

	return d;
}

ostream& operator<<(ostream& os, const note& no)
{
	static const char *const a[][12] = {
		{"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"},
		{"C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"}
	};

	assert(no.i < note::n);
	const int s = os.iword(note::subscript);
	assert(0 <= s && s < 2);
	return os << a[s][no.i];
}