var HuntPitchName = new Array()
var HuntIntervalName = new Array()
var HuntJNDintervalQuality = new Array()

HuntPitchName[0] = 'A'
HuntPitchName[1] = 'super A'
HuntPitchName[2] = 'sub B-flat'
HuntPitchName[3] = 'B-flat'
HuntPitchName[4] = 'super B-flat'
HuntPitchName[5] = 'acute B-flat/grave B'
HuntPitchName[6] = 'sub B'
HuntPitchName[7] = 'B'
HuntPitchName[8] = 'super B'
HuntPitchName[9] = 'sub C'
HuntPitchName[10] = 'C'
HuntPitchName[11] = 'super C'
HuntPitchName[12] = 'acute C/grave C-sharp'
HuntPitchName[13] = 'sub C-sharp'
HuntPitchName[14] = 'C-sharp'
HuntPitchName[15] = 'super C-sharp'
HuntPitchName[16] = 'sub D/acute C-sharp'
HuntPitchName[17] = 'D'
HuntPitchName[18] = 'grave E-flat/super D'
HuntPitchName[19] = 'sub E-flat'
HuntPitchName[20] = 'E-flat'
HuntPitchName[21] = 'super E-flat'
HuntPitchName[22] = 'acute E-flat/grave E'
HuntPitchName[23] = 'sub E'
HuntPitchName[24] = 'E'
HuntPitchName[25] = 'super E'
HuntPitchName[26] = 'sub F'
HuntPitchName[27] = 'F'
HuntPitchName[28] = 'super F'
HuntPitchName[29] = 'acute F/grave F-sharp'
HuntPitchName[30] = 'sub F-sharp'
HuntPitchName[31] = 'F-sharp'
HuntPitchName[32] = 'super F-sharp'
HuntPitchName[33] = 'sub G'
HuntPitchName[34] = 'G'
HuntPitchName[35] = 'super G'
HuntPitchName[36] = 'grave G-sharp/sub A-flat'
HuntPitchName[37] = 'sub G-sharp/A-flat'
HuntPitchName[38] = 'G-sharp/super A-flat'
HuntPitchName[39] = 'super G-sharp/acute A-flat'
HuntPitchName[40] = 'sub A'

HuntIntervalName[0] = 'P1'
HuntIntervalName[1] = 'L1, Nm2'
HuntIntervalName[2] = 'Sm2'
HuntIntervalName[3] = 'm2'
HuntIntervalName[4] = 'Lm2'
HuntIntervalName[5] = 'Wm2, NM2'
HuntIntervalName[6] = 'SM2'
HuntIntervalName[7] = 'M2'
HuntIntervalName[8] = 'LM2'
HuntIntervalName[9] = 'Sm3'
HuntIntervalName[10] = 'm3'
HuntIntervalName[11] = 'Lm3'
HuntIntervalName[12] = 'Wm3,NM3'
HuntIntervalName[13] = 'SM3'
HuntIntervalName[14] = 'M3'
HuntIntervalName[15] = 'LM3'
HuntIntervalName[16] = 'S4,WM3'
HuntIntervalName[17] = 'P4'
HuntIntervalName[18] = 'L4'
HuntIntervalName[19] = 'Sd5,Na4'
HuntIntervalName[20] = 'd5'
HuntIntervalName[21] = 'a4'
HuntIntervalName[22] = 'La4,Wd5'
HuntIntervalName[23] = 'S5'
HuntIntervalName[24] = 'P5'
HuntIntervalName[25] = 'L5,Nm6'
HuntIntervalName[26] = 'Sm6'
HuntIntervalName[27] = 'm6'
HuntIntervalName[28] = 'Lm6'
HuntIntervalName[29] = 'Wm6,NM6'
HuntIntervalName[30] = 'SM6'
HuntIntervalName[31] = 'M6'
HuntIntervalName[32] = 'LM6'
HuntIntervalName[33] = 'Sm7'
HuntIntervalName[34] = 'm7'
HuntIntervalName[35] = 'Lm7'
HuntIntervalName[36] = 'Wm7,NM7'
HuntIntervalName[37] = 'SM7'
HuntIntervalName[38] = 'M7'
HuntIntervalName[39] = 'LM7'
HuntIntervalName[40] = 'S8,WM7'
HuntIntervalName[41] = 'P8'

HuntJNDintervalQuality[0] = '+0'
HuntJNDintervalQuality[1] = '-1,+0'
HuntJNDintervalQuality[2] = '+1'
HuntJNDintervalQuality[3] = '+0'
HuntJNDintervalQuality[4] = '-1'
HuntJNDintervalQuality[5] = '-1,+1'
HuntJNDintervalQuality[6] = '+1'
HuntJNDintervalQuality[7] = '+0'
HuntJNDintervalQuality[8] = '-1'
HuntJNDintervalQuality[9] = '+1'
HuntJNDintervalQuality[10] = '+0'
HuntJNDintervalQuality[11] = '-1'
HuntJNDintervalQuality[12] = '-1,+1'
HuntJNDintervalQuality[13] = '+1'
HuntJNDintervalQuality[14] = '+0'
HuntJNDintervalQuality[15] = '-1'
HuntJNDintervalQuality[16] = '-2,+1'
HuntJNDintervalQuality[17] = '+0'
HuntJNDintervalQuality[18] = '-1'
HuntJNDintervalQuality[19] = '-1,+1'
HuntJNDintervalQuality[20] = '+0'
HuntJNDintervalQuality[21] = '+0'
HuntJNDintervalQuality[22] = '-1,+1'
HuntJNDintervalQuality[23] = '+1'
HuntJNDintervalQuality[24] = '+0'
HuntJNDintervalQuality[25] = '-1,+2'
HuntJNDintervalQuality[26] = '+1'
HuntJNDintervalQuality[27] = '+0'
HuntJNDintervalQuality[28] = '-1'
HuntJNDintervalQuality[29] = '-1,+1'
HuntJNDintervalQuality[30] = '+1'
HuntJNDintervalQuality[31] = '+0'
HuntJNDintervalQuality[32] = '-1'
HuntJNDintervalQuality[33] = '+1'
HuntJNDintervalQuality[34] = '+0'
HuntJNDintervalQuality[35] = '-1'
HuntJNDintervalQuality[36] = '-1,+1'
HuntJNDintervalQuality[37] = '+1'
HuntJNDintervalQuality[38] = '+0'
HuntJNDintervalQuality[39] = '-1'
HuntJNDintervalQuality[40] = '+0,+1'
HuntJNDintervalQuality[41] = '+0'

var HuntJNDInflection = new Array('doubleflat','flat','','sharp','doublesharp')
var HuntJNDquality = new Array('dd','d','P','a','aa')
var HuntIQGrade = new Array('P','A+','A','A-','B+','B','B-','C+','C','C-','D+','D','F')
var HuntIQEval = new Array('Perfect','Excellent','Excellent','Excellent','Good','Good','Good','Fair','Fair','Fair','Poor','Poor','Wrong')

var tab = String.fromCharCode(9)
var lineEnd = String.fromCharCode(13)

function GetCents(theForm, interval) {
	var x = decimalize(interval)
	var c = getCentValue(x)
	theForm.CentSize.value = c
	return false
}

function GetHuntPitchName(theForm, hertz, showList) {
	var x = parseFloat(hertz)/440
	x = justifyX(x)
	var c = getCentValue(x)
	var s = getStep(x, 41)
	var j = (41*Math.log(x)/Math.log(2))-s
	j = 2 + Math.round(10*(j/2))
	j = HuntJNDInflection[j]
	if (j != "") {j += "."}
	var jj = ""
	var p = new Array()
	p[0] = HuntPitchName[s]
	p[1] = ""
	if (p[0].indexOf("/") > -1) {
		p[1] = p[0].split("/")[1]
		p[0] = p[0].split("/")[0]
		theForm.HuntPitchCategory2.value = j+p[1]
	}
	theForm.HuntPitchCategory1.value = j+p[0]
	if (showList) {
		var pitchNames = j+p[0]
		if (p[1] != "") {pitchNames += tab+"or" +tab+j+p[1]}
		theForm.HuntPitchDisplay.value += hertz +tab+"Hz" +tab+pitchNames +lineEnd
	}
	return false
}

function GetHuntIntervalCategory(theForm, interval, showCents, showJND, showCat, showList) {
	var x = decimalize(interval)
	var c = getCentValue(x)
	var s = getStep(x, 41)
	var j = (41*Math.log(x)/Math.log(2))-s
	var q = ""
	var qd = new Array()
	var qi = 0
	var names = new Array()
	var quals = new Array()
	j = Math.round(10*(j/2))
	if (j > -1) {
		j = "+"+j
	}
	theForm.HuntIntervalCategory.value = s
	if (showCents) {theForm.CentSize.value = c}
	if (showJND) {
		var n = HuntIntervalName[s]
		if (n.indexOf(",") > -1) {
			names = n.split(",")
			quals = HuntJNDintervalQuality[s].split(",")
			qd[0] = Math.abs(j-parseInt(quals[0]))
			qd[1] = Math.abs(j-parseInt(quals[1]))
			if (qd[1] <= qd[0]) {
				qi = 1
			}
			n = names[qi]
			q = HuntJNDquality[j-parseInt(quals[qi])+2]
		}
		else {
			q = HuntJNDquality[j-parseInt(HuntJNDintervalQuality[s])+2]
		}
		//if (q != "P") {q += "."} else {q = ""}
		q += "."
		theForm.HuntIntervalCatName.value = q+n
	}
	if (showCat) {theForm.HuntIntervalJNDInflection.value = j}
	if (showList) {
		var theCent = fixLength(c, 2)
		theForm.HuntIntervalDisplay.value += interval +tab+theCent +tab+s +tab+"Commas" +tab+j +tab+"JNDs" +tab+q+n +lineEnd
	}
	return false
}

function GetHuntJNDbyET(theForm, interval) {
	var x = decimalize(interval)
	var c = getStep(x, 205)
	var j = ""+c
	j = j.charAt(j.length-1,1)
	var p = parseInt(j)
	p = p - 5
	if (p > 2) {p = p - 5}
	if (p < -2) {p = p + 5}
	theForm.HuntIntervalCatName.value = c
	theForm.HuntIntervalJNDInflection.value = p
	return false
}

function GetHuntIQGPA(theForm, intervalList, theET) {
	var resultString = ""
	var theInterval = ""
	var tabFields = new Array()
	var scoreTotal = 0
	var rawAverage = 0.0
	var scoreAverage = 0
	var intervalArray = intervalList.split(",")
	for (var i = 0; i < intervalArray.length; i++) {
		while (intervalArray[i].charAt(0) == " ") {intervalArray[i] = intervalArray[i].substring(1,intervalArray[i].length)}
		}
	for (var j = 0; j < intervalArray.length; j++) {
		theInterval = intervalArray[j]
		resultString = GetHuntIQ(theInterval, theET)
		theForm.HuntIQGPAdisplay.value += resultString
		tabFields = resultString.split(tab)
		scoreTotal += 12-parseInt(tabFields[8])
	}
	rawAverage = scoreTotal/(intervalArray.length-1)
	rawAverage = fixLength(rawAverage, 1)
	scoreAverage = Math.round(rawAverage)
	if (scoreAverage > 12) {scoreAverage = 12}
	theForm.HuntIQGPAdisplay.value +="IQGPA"+ tab+(fixLength((12-rawAverage),1))+ tab+HuntIQGrade[scoreAverage] +tab+HuntIQEval[scoreAverage] +lineEnd
	return false
}

function GetHuntIQ(interval, theET) {
	var theResult = ""
	var x = decimalize(interval)
	var c = getCentValue(x)
	var s = getStep(x, theET)
	var m = getCentValue(Math.pow(2,(s/theET)))
	var diff = c-m
	var d = Math.abs(Math.round(diff))
	if (d > 12) {d = 12}
	c = fixLength(c, 2)
	m = fixLength(m, 2)
	diff = fixLength(diff, 1)
	theResult = interval+ tab+c+ tab+s+ tab+" of "+theET+"ET"+ tab+m
	theResult += tab+" error"+ tab+diff+ tab+"Score"+ tab+(12-d)+ tab+HuntIQGrade[d] + lineEnd
	return theResult
}

function getCentValue(x) {
	var theCentValue = 1200*Math.log(x)/Math.log(2)
	return theCentValue
}

function getStep(x, theET) {
	var theStep = Math.round(theET*Math.log(x)/Math.log(2))
	return theStep
}

function decimalize(i) {
	var a = 0
	var r = new Array()
	var d = i.indexOf(".")
	if (d == -1 ) {
		var s = i.indexOf("/")
		if (s > -1 ) {
			r = i.split("/")
			a = r[0] / r[1]
			a = justifyX(a)
			return a
		}
		s = i.indexOf(":")
		if (s > -1 ) {
			r = i.split(":")
			a = r[1] / r[0]
			a = justifyX(a)
			return a
		}
	}
	else {
		a = justifyX(i)
		return a
	}
}


function justifyX(i) {
	while (i < 1) {
		i = i * 2
	}
	while (i > 2) {
		i = i / 2
	}
	return i
}

function fixLength(x, precision) {
	if (x > 8191 && x < 10485) {
		x = x - 5000
		var fixedX = Math.round(x*Math.pow(10,precision))/Math.pow(10,precision)
		fixedX = fixedX + 5000
	} else {
		var fixedX = Math.round(x*Math.pow(10,precision))/Math.pow(10,precision)
	}
	return fixedX
}
