// 
//
//     Mensurinterpolation mit Beziersplines
//
//     Autor: Arndt Brünner
//
//	 Version: 4. 4. 2002 
// 
//     erweitert bis c4 am 8.1.2003


var Wert_= new Array(61);
var PolyBezX= new Array(61),PolyBezY= new Array(61);
var X= new Array(61), Y= new Array(61);
var srx= new Array(61),slx= new Array(61);
var sry= new Array(61),sly= new Array(61);
var n ;
var gen; //Anzahl Dezimalstellen
var sslx=0.0,ssly=0.0,ssrx=0.0,ssry=0.0  
var xMin,xMax;
var ka;
var Log=false;Basis=2/12;LogF=1/Math.log(Basis);

//ReDim Y(n + 1), X(n + 1)
//ReDim Preserve slx(n), sly(n), srx(n), sry(n)


for (var i=0;i<61;i++) Wert_[i]="";


//ub=Ubound(Wert_())

function BezInt()
{
//Wert_[0]=1;Wert_[4]=2;Wert_[10]=1,5;
gen=document.f.ad.selectedIndex;
Log=(document.f.typ.selectedIndex==1);
var mt=document.f.mitTon.selectedIndex;
var ttt =new String('');
NeueWerte();
if (n==1) {alert('Es sind mindestens zwei Werte erforderlich!');return;}
if(xMin==-1) 
{
Wertetransfer(document.f.Eingabe.value,document.f.TiefsterTon.value);
NeueWerte();
if(xMin==-1) {alert('Sie haben keinen Wert eingegeben!');return;} 
}
for(var i=xMin;i<=xMax;i++) eval('document.f.z'+i+'.value="";');
for(var i=xMax+1;i<61;i++) eval('document.f.z'+i+'.value="";');
for(var i=xMin;i<=xMax;i++) 
{
var yyy="";
//if(Log)yyy=String(Math.exp(IY(i))); else 
yyy=String(IY(i));
//alert(IY+"\n"+yyy);
if (yyy=='') return;

if (ka==1) yyy=yyy.replace(/\./g,",");

eval('document.f.z'+i+'.value="'+yyy+'";');
if (mt==0) ttt+=GetTonName(i+1)+"\t";
else if (mt==2) ttt+=i+"\t";
ttt+=yyy+"\n";
}
document.f.Ausgabe.value=ttt;
}



function NeueWerte()
{
var n_0,n_1;
var Abbruch = false;
n = 0;
xMin=-1;xMax=-1;
ka=-1;
for (var i = 0; i<61; i++)
{
if (Wert_[i] != "")
{
    if (xMin==-1) xMin=i;
    xMax=i;		
    n++;
    Y[n] = Number(String(Wert_[i]).replace(/\,/,"."));	
    if (ka==-1){ if (Wert_[i].indexOf(",")>0) ka=1; else if (Wert_[i].indexOf(".")>0) ka=2;}
    X[n] = i;
    if (n == 1) n_0 = i;
    if(Log)Y[n]=Math.log(Y[n])*LogF;
}
}
if (ka==-1) ka=1;
n_1 = X[n];


if (n < 2) Abbruch = true;
if (Abbruch != true)
{
    Bereich();
    Stuetzstellen_berechnen();
//  Zeichnen
//  if (Tabelle.Visible) Tabelle.Form_Activate
}
else
{
//  MAbbruch_Click
//  Exit Sub
}
}

function Bereich()
{
for (var i = 0; i<= (n - 1) * 3; i++) NeuePolybez_ (i);
}


function NeuePolybez_(a)
{
//On Error Resume }
//PolyBezX[a] = ScaleX(PolyBez(a).X - xMin, 0, 3)
//PolyBezY[a] = -ScaleY(yMax - PolyBez(a).Y, 0, 3)
//'-ScaleY(yMax - Yy, 0, 3)
//'MsgBox Str(a) + Chr(10) + Str(PolyBez_(a).x) + Chr(10) + Str(PolyBez_(a).y)
}



function Stuetzstellen_berechnen()
//On Error Resume }
{
var yMax=100, yMin=0;
for (var i = 1; i<= n;i++)
{
if (Y[i] > yMax) yMax = Y[i];
if (Y[i] < yMin) yMin = Y[i];
}
var yd=0.0 , xd=0.0, faktor=0.0 ;
yd = yMax - yMin;
xd = X[n] - X[1];
faktor = yd / xd * 10;
if (faktor < 0.01) faktor = 1;
//faktor=1;

for (var i = 2; i< n; i++)
{
Stuetzstellen3D(X[i-1],Y[i-1]/faktor,X[i],Y[i]/faktor,X[i+1],Y[i+1]/faktor);
ssly = ssly * faktor;
ssry = ssry * faktor;
if (sslx > X[i]) sslx = X[i];
if (ssrx < X[i]) ssrx = X[i];
if (sslx < X[i - 1]) sslx = X[i - 1];
if (ssrx > X[i + 1]) ssrx = X[i + 1];
slx[i] = sslx;
sly[i] = ssly;
srx[i] = ssrx;
sry[i] = ssry;
}

for(var i = 1; i<= n;i++)
{
if ((i == 1) || (X[i - 1] + 1 == X[i]))
{
    srx[i] = Randstuetzstelle(X[i], X[i + 1], slx[i + 1]);
    sry[i] = Randstuetzstelle(Y[i], Y[i + 1], sly[i + 1]);
    slx[i] = 0.7 * X[i] + 0.3 * X[i - 1];
    sly[i] = 0.7 * Y[i] + 0.3 * Y[i - 1];
    if (srx[i] < X[i]) srx[i] = X[i];
}
if ((i == n) || (X[i] + 1 == X[i + 1]))
{
    slx[i] = Randstuetzstelle(X[i], X[i - 1], srx[i - 1]);
    if (slx[i] > X[i]) slx[i] = X[i];
    sly[i] = Randstuetzstelle(Y[i], Y[i - 1], sry[i - 1]);
    srx[i] = 0.7 * X[i] + 0.3 * X[i + 1];
    sry[i] = 0.7 * Y[i] + 0.3 * Y[i + 1];
}
}
if (n == 2)
{
    srx[1] = 0.7 * X[1] + 0.3 * X[2];
    slx[2] = 0.3 * X[1] + 0.7 * X[2];
    sry[1] = 0.7 * Y[1] + 0.3 * Y[2];
    sly[2] = 0.3 * Y[1] + 0.7 * Y[2];
}

var i = 1;
if (X[2] + 1 == X[3])
{
    srx[i] = 0.7 * X[i] + 0.3 * X[i + 1];
    slx[i + 1] = 0.3 * X[i] + 0.7 * X[i + 1];
    sry[i] = 0.7 * Y[i] + 0.3 * Y[i + 1];
    sly[i + 1] = 0.3 * Y[i] + 0.7 * Y[i + 1];
}

for (i = 2;i< n; i++)
{
if ((X[i - 1] + 1 == X[i]) && (X[i] + 1 == X[i + 1]))
{
    srx[i] = 0.7 * X[i] + 0.3 * X[i + 1];
    slx[i + 1] = 0.3 * X[i] + 0.7 * X[i + 1];
    sry[i] = 0.7 * Y[i] + 0.3 * Y[i + 1];
    sly[i + 1] = 0.3 * Y[i] + 0.7 * Y[i + 1];
}
if ((X[i - 1] + 1 == X[i]) && (i + 1 == n))
{
    srx[i] = 0.7 * X[i] + 0.3 * X[i + 1];
    slx[i + 1] = 0.3 * X[i] + 0.7 * X[i + 1];
    sry[i] = 0.7 * Y[i] + 0.3 * Y[i + 1];
    sly[i + 1] = 0.3 * Y[i] + 0.7 * Y[i + 1];
}
}
NeueStuetzstellen()
Bereich()
}



function Stuetzstellen3D(xl, yl, X_, Y_, xr, yr)
{
//On Error GoTo fehler2
//alert(xl+"\n"+yl+"\n"+X_+"\n"+Y_+"\n"+xr+"\n"+yr);

var v=0.0, d1x=0.0, d2x=0.0;
var d1y=0.0, d2y=0.0, dd1=0.0, dd2=0.0;
var Winkel1=0.0, Winkel2=0.0, Winkel3=0.0;

v = 0.3827; //  1/3; // 1/2.718;
d1x = xl - X_; d1y = yl - Y_;
d2x = xr - X_; d2y = yr - Y_;
dd1 = Math.sqrt(d1x*d1x + d1y*d1y);
dd2 = Math.sqrt(d2x*d2x + d2y*d2y);
Winkel1 = Math.atan(Math.abs(d1y / d1x));
if ((d1y > 0) && (d1x < 0)) Winkel1 = Math.PI - Winkel1;
if ((d1y <= 0) && (d1x < 0)) Winkel1 = Math.PI + Winkel1;
if ((d1y < 0) && (d1x > 0)) Winkel1 = 2 * Math.PI - Winkel1;
Winkel2 = Math.atan(Math.abs(d2y / d2x));
if ((d2y > 0) && (d2x < 0)) Winkel2 = Math.PI - Winkel2;
if ((d2y <= 0) && (d2x < 0)) Winkel2 = Math.PI + Winkel2;
if ((d2y < 0) && (d2x > 0)) Winkel2 = 2 * Math.PI - Winkel2;
Winkel3 = (Winkel1 + Winkel2) / 2;
if (Winkel3 < Math.PI) Winkel3 = Winkel3 + Math.PI;

var sw =0.0, cw =0.0, s1 =0.0, s2 =0.0, c1 =0.0, c2 =0.0;
sw = Math.sin(Winkel3 + Math.PI / 2);
cw = Math.cos(Winkel3 + Math.PI / 2);
s1 = Math.sin(Winkel1);
c1 = Math.cos(Winkel1);
s2 = Math.sin(Winkel2);
c2 = Math.cos(Winkel2);

sslx = X_ - cw * dd1 * v;
ssly = Y_ - sw * dd1 * v;
ssrx = X_ + cw * dd2 * v;
ssry = Y_ + sw * dd2 * v;
//alert(sslx+"\n"+ssly+"\n"+ssrx+"\n"+ssry);
}


function Randstuetzstelle(y1, y2, s2)
{
//alert(y1);alert(y2);alert(s2);
var yt2 =0.0, yt1 =0.0;
yt2 = (2 * y2 + y1) / 3;
yt1 = (2 * y1 + y2) / 3;
return yt1 + s2 - yt2;
}



function NeueStuetzstellen()
{
//ReDim PolyBez(n * 3 - 3), PolyBez_(n * 3 - 3)
var i =0;
for (i = 0;i< n - 1;i++)
{
PolyBezX[i * 3] = X[i + 1];
PolyBezY[i * 3] = Y[i + 1];
PolyBezX[i * 3 + 1] = srx[i + 1];
PolyBezY[i * 3 + 1] = sry[i + 1];
PolyBezX[i * 3 + 2] = slx[i + 2];
PolyBezY[i * 3 + 2] = sly[i + 2];
NeuePolybez_ (i * 3);
NeuePolybez_ (i * 3 + 1);
NeuePolybez_ (i * 3 + 2);
}
PolyBezX[i * 3] = X[n];
PolyBezY[i * 3] = Y[n];
NeuePolybez_ (i * 3);

}



function NeuePolybez_(a)
{
}



function Bezier2(y0, y1, y2, y3, t)
{
	var t2=t*t;
	var t3=t2*t;
	var t_2=(1-t)*(1-t);
	var t_3=t_2*(1-t);
	return (y0 * t_3) + (3 * y1 * t * t_2) + (3 * y2 * t2 * (1 - t)) + (y3 * t3);
 //Bezier2 = (y0 * (1 - t) ^ 3) + (3 * y1 * t * (t - 1) ^ 2) + (3 * y2 * t ^ 2 * (1 - t)) + (y3 * t ^ 3)
}



function IY(a)
{
var i=0, j =0.0, k =0.0, br=1;
for (i = 1; i <= n;i++)
{
if (X[i] == a){ if(Log)return Runden(Math.pow(Basis,Y[i]),gen);  return  Y[i];}
if (X[i] > a) {br=0;break;}
}
if (br==1) return '';
for (j = 0; j<= 1; j+= 0.1)
{
var Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], j);
if (Xx >= a) break;
}
for (k = j - 0.1; k<= 1; k+= 0.01)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], k);
if (Xx >= a) break;
}
var l =0.0, l1 =0.0, l2 =0.0, l3=0.0, l4=0.0, l5=0.0, l6=0.0;
for (l = k - 0.01; l<= 1; l+= 0.001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l);
if (Xx >= a) break;
}
for (l1 = l - 0.001; l1<= 1; l1+= 0.0001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l1);
if (Xx >= a) break;
}
for (l2 = l1 - 0.0001; l2<= l1 ; l2 += 0.00001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l2);
if (Xx >= a) break;
}

var LL=l2;

if (gen>4){
for (l3 = l2 - 0.00001; l3<= l2 ; l3 += 0.000001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l3);
LL=l3;
if (Xx >= a) break;
}

if (gen>5){
for (l4 = l3 - 0.000001; l4<= l3 ; l4 += 0.0000001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l4);
LL=l4;
if (Xx >= a) break;
}

if (gen>6){
for (l5 = l4 - 0.0000001; l5<= l4 ; l5 += 0.00000001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l5);
LL=l5;
if (Xx >= a) break;
}

if (gen>7){
for (l6 = l5 - 0.00000001; l6<= l5 ; l6 += 0.000000001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l6);
LL=l6;
if (Xx >= a) break;
}

if (gen>8){
for (l7 = l6 - 0.000000001; l7<= l6 ; l7 += 0.0000000001)
{
Xx = Bezier2(X[i - 1], srx[i - 1], slx[i], X[i], l7);
LL=l7;
if (Xx >= a) break;
}}}}}}


//alert(Y[i-1]+'\n'+sry[i-1]+'\n'+sly[i]+'\n'+Y[i]+'\n'+LL+'\n'+gen);

if(Log)return Runden(Math.pow(Basis,Bezier2(Y[i - 1], sry[i - 1], sly[i], Y[i], LL)), gen);
return Runden(Bezier2(Y[i - 1], sry[i - 1], sly[i], Y[i], LL), gen);
//alert(IY);
}

function Runden(t,i)
{
	var d=Math.pow(10,i);
	return Math.round(t*d)/d;
}


function Wertetransfer(w,tt)
{
	for(var i=0;i<61;i++) Wert_[i]="";
	var n=0;
	var n=GetTonNummer(tt)-1;
	w=w.replace(/\t/g,":").replace(/=/g,":");
	if (w.indexOf(':')>0)
	{
		w=w.replace(/: /g,":");
		w=w.replace(/\n/g," ").replace(/\r/g,"").replace(/;/g," ");
		var ww=w.split(" ")
		for (var i=0;i<61;i++)
			eval('document.f.y'+i+'.value=""');
		for (var i=0;i<ww.length;i++)
		{
			var www=ww[i].split(":");
			var nn=GetTonNummer(www[0])-1;
			if (nn>=0){ eval('document.f.y'+nn+'.value=www[1]');Wert_[nn]=www[1];}
		}
		return;
	}
	w=w.replace(/\r/g,"");
	var ww=w.split("\n");
	for (var i=0;i<61;i++)
	{
		if ((i>=n)&&(i-n<ww.length)) 
		{
			eval('document.f.y'+(i)+'.value=ww[i-n]');
			if (ww[i] !="");
			Wert_[i]=ww[i]
		}
			else {eval('document.f.y'+i+'.value=""');Wert_[i]="";}
	}
}

function GetTonNummer(t)
{
	var i,d=1,l=1;
	if (t.length==0) {return -999;}
	else if (t.indexOf('cis')==0){i=2 ;l=3;}
	else if (t.indexOf('des')==0){i=2 ;l=3;}
	else if (t.indexOf('dis')==0){i=4 ;l=3;}
	else if (t.indexOf('es')==0){i=4 ;l=2;}
	else if (t.indexOf('fis')==0){i=7 ;l=3;}
	else if (t.indexOf('ges')==0){i=7 ;l=3;}
	else if (t.indexOf('gis')==0){i=9 ;l=3;}
	else if (t.indexOf('ais')==0){i=11 ;l=3;}
	else if (t.indexOf('as')==0){i=9 ;l=2;}
	else if (t.indexOf('c')==0){i=1 ;}
	else if (t.indexOf('d')==0){i=3 ;}
	else if (t.indexOf('e')==0){i=5 ;}
	else if (t.indexOf('f')==0){i=6 ;}
	else if (t.indexOf('g')==0){i=8 ;}
	else if (t.indexOf('a')==0){i=10 ;}
	else if (t.indexOf('h')==0){i=12 ;}
	else if (t.indexOf('b')==0){i=11 ;}
	else if (t.indexOf('Cis')==0){i=2 ;d=-1;l=3;}
	else if (t.indexOf('Des')==0){i=2 ;d=-1;l=3;}
	else if (t.indexOf('Dis')==0){i=4 ;d=-1;l=3;}
	else if (t.indexOf('Es')==0){i=4 ;d=-1;l=2;}
	else if (t.indexOf('Fis')==0){i=7 ;d=-1;l=3;}
	else if (t.indexOf('Ges')==0){i=7 ;d=-1;l=3;}
	else if (t.indexOf('Gis')==0){i=9 ;d=-1;l=3;}
	else if (t.indexOf('Ais')==0){i=11 ;d=-1;l=3;}
	else if (t.indexOf('As')==0){i=9 ;d=-1;l=2;}
	else if (t.indexOf('C')==0){i=1 ;d=-1;}
	else if (t.indexOf('D')==0){i=3 ;d=-1;}
	else if (t.indexOf('E')==0){i=5 ;d=-1;}
	else if (t.indexOf('F')==0){i=6 ;d=-1;}
	else if (t.indexOf('G')==0){i=8 ;d=-1;}
	else if (t.indexOf('A')==0){i=10 ;d=-1;}
	else if (t.indexOf('H')==0){i=12 ;d=-1;}
	else if (t.indexOf('B')==0){i=11 ;d=-1;}
	else {alert("Falsche Eingabe der Taste. Bitte Tonbuchstabe(n)+Oktave. Bsp.: C0, fis2, es3");return -999;}
	var o=t.substring(l,t.length);
	if (d==-1) return 12*o*d+i;
	return 12*o*d+i+12;
}

function GetTonName(i)
{
	i=Math.floor(i+0.5);
	var t;
	switch(Math.abs(i*1.0+1200) %12)
	{
		case 0: t = "h";break;
		case 1: t = "c";break;
		case 2: t = "cis";break;
		case 3: t = "d";break;
		case 4: t = "dis";break;
		case 5: t = "e";break;
		case 6: t = "f";break;
		case 7: t = "fis";break;
		case 8: t = "g";break;
		case 9: t = "gis";break;
		case 10: t = "a";break;
		case 11: t = "b";break;
	}
	if (i < 13) t = t.charAt(0).toUpperCase()+t.substring(1,t.length);
	if (i>24) var o = Math.floor((i-1) / 12)-1;
	if ((i<25)&&(i>0)) o=0;
	if (i<1) o=Math.floor((12-i)/12);
//	alert("Tonname("+i+")="+t+o);
	return t+o;
}
