// name - name of the cookie
// value - value of the cookie
// [expires] - expiration date of the cookie
// (defaults to end of current session)
// [path] - path for which the cookie is valid
// (defaults to path of calling document)
// [domain] - domain for which the cookie is valid
// (defaults to domain of calling document)
// [secure] - Boolean value indicating if
// the cookie transmission requires a secure transmission
// * an argument defaults when it is assigned null as a placeholder
// * a null placeholder is not required for trailing omitted arguments

function setCookie(name, value, expires, path, domain, secure) {
    var curCookie = name + "=" + escape(value) +
         ((expires) ? "; expires=" + expires.toGMTString() : "") +
         ((path) ? "; path=" + path : "") +
         ((domain) ? "; domain=" + domain : "") +
         ((secure) ? "; secure" : "")
    if ((name + "=" + escape(value)).length <= 4000)
        document.cookie = curCookie
    else if (confirm("Cookie exceeds 4KB and will be cut!"))
        document.cookie = curCookie
}

// name - name of the cookie
// * return string containing value
// of specified cookie or null if cookie
// does not exist
function getCookie(name,defaultvalue) {
    var prefix = name + "="
    var cookieStartIndex = document.cookie.indexOf(prefix)
    if (cookieStartIndex == -1)
        return defaultvalue
    var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex +
        prefix.length)
    if (cookieEndIndex == -1)
        cookieEndIndex = document.cookie.length
    return unescape(document.cookie.substring(cookieStartIndex +
        prefix.length,cookieEndIndex))
}

// name - name of the cookie
// [path] - path of the cookie
// (must be same as path used to create cookie)
// [domain] - domain of the cookie
// (must be same as domain used to create cookie)
// * path and domain default if assigned
// null or omitted if no explicit argument proceeds
function deleteCookie(name, path, domain) {
    if (getCookie(name)) {
	document.cookie = name + "=" +
	 ((path) ? "; path=" + path : "") +
         ((domain) ? "; domain=" + domain : "") +
         "; expires=Thu, 01-Jan-70 00:00:01 GMT"
    }
}

// date - any instance of the Date object
// * you should hand all instances of the
// Date object to this function for "repairs"
// * this function is taken from
// Chapter 14, "Time and Date in JavaScript", in
// "Learn Advanced JavaScript Programming"
function fixDate(date) {
var base = new Date(0)
    var skew = base.getTime()
    if (skew > 0)
       	date.setTime(date.getTime() - skew)
}

AccelUnit = new Array( "G", "m/s^2", "cm/s^2", "mm/s^2", "in/s^2", "ft/s^2" );
AccelConv = new Array( 1.0, 9.80665, 980.665, 9806.65, 386.0886, 32.1740486 );
VelUnit = new Array( "m/s", "cm/s", "mm/s", "in/s", "ft/s", "km/hour", "mile/hour" );
VelConv = new Array( 1.0, 100.0, 1000.0, 39.37, 3.28084, 3.6, 2.236936 );
DispUnit = new Array( "m", "cm", "mm", "in", "ft", "km", "mile" );
DispConv = new Array( 1.0, 100.0, 1000.0, 39.37, 3.28084, 0.001, 0.0006213712 );
ForceUnit = new Array( "N", "dynes", "lbs" );
ForceConv = new Array( 1.0, 100000.0, 0.2248089431 );
MassUnit = new Array( "kg", "g", "lb-mass", "oz-mass", "slug" );
MassConv = new Array( 1.0, 1000.0, 2.20462262185, 35.27, 0.06852 );

function SetForceUnit(f)
{
    conv=ForceConv[f.forceunit.selectedIndex];
    f.force.value *= conv/f.CurrentForceUnit.value;
    f.CurrentForceUnit.value=conv;
}

function SetAccelUnit(f)
{
    conv=AccelConv[f.accelunit.selectedIndex];
    f.accel.value *= conv/f.CurrentAccelUnit.value;
    f.CurrentAccelUnit.value=conv;
}

function SetVelUnit(f)
{
    conv=VelConv[f.velunit.selectedIndex];
    f.vel.value *= conv/f.CurrentVelUnit.value;
    f.CurrentVelUnit.value=conv;
}

function SetDispUnit(f)
{
    conv=DispConv[f.dispunit.selectedIndex];
    f.disp.value *= conv/f.CurrentDispUnit.value;
    f.CurrentDispUnit.value=conv;
}

function SetMassUnit(f)
{
    conv=MassConv[f.massunit.selectedIndex];
    f.mass.value *= conv/f.CurrentMassUnit.value;
    f.CurrentMassUnit.value=conv;
}


function ComputeForce(f)
{
    f.force.value = f.accel.value / f.CurrentAccelUnit.value * 9.80665
                     * f.mass.value / f.CurrentMassUnit.value
                     * f.CurrentForceUnit.value;
}

function ComputeMass(f)
{
    f.mass.value = f.force.value / f.CurrentForceUnit.value
		    / f.accel.value * f.CurrentAccelUnit.value / 9.80665
                    * f.CurrentMassUnit.value;
}

function ComputeAccel(f)
{
    f.accel.value = f.force.value / f.CurrentForceUnit.value
		    / f.mass.value * f.CurrentMassUnit.value
                    * f.CurrentAccelUnit.value / 9.80665;
}

function InitializeForms()
{
	table_fma = document.getElementById('fma');
	table_random = document.getElementById('random');

    table_fma.forceunit.length=ForceUnit.length;
    for(i=0 ; i < ForceUnit.length ; i++) {
	table_fma.forceunit.options[i].text = ForceUnit[i];
    }
    table_fma.forceunit.selectedIndex=getCookie("forceunit",0);
    table_fma.CurrentForceUnit.value=ForceConv[table_fma.forceunit.selectedIndex];

    table_fma.accelunit.length=AccelUnit.length;
    for(i=0 ; i < AccelUnit.length ; i++) {
	table_fma.accelunit.options[i].text = AccelUnit[i];
    }
    table_fma.accelunit.selectedIndex=getCookie("accelunit",0);
    table_fma.CurrentAccelUnit.value=AccelConv[table_fma.accelunit.selectedIndex];

    table_fma.massunit.length=MassUnit.length;
    for(i=0 ; i < MassUnit.length ; i++) {
	table_fma.massunit.options[i].text = MassUnit[i];
    }
    table_fma.massunit.selectedIndex=getCookie("massunit",0);
    table_fma.CurrentMassUnit.value=MassConv[table_fma.massunit.selectedIndex];

    table_random.accelunit.length=AccelUnit.length;
    for(i=0 ; i < AccelUnit.length ; i++) {
	table_random.accelunit.options[i].text = AccelUnit[i];
    }
    table_random.accelunit.selectedIndex=getCookie("accelunit2",0);
    table_random.CurrentAccelUnit.value=AccelConv[table_random.accelunit.selectedIndex];

    table_random.velunit.length=VelUnit.length;
    for(i=0 ; i < VelUnit.length ; i++) {
	table_random.velunit.options[i].text = VelUnit[i];
    }
    table_random.velunit.selectedIndex=getCookie("velunit",0);
    table_random.CurrentVelUnit.value=VelConv[table_random.velunit.selectedIndex];

    table_random.dispunit.length=DispUnit.length;
    for(i=0 ; i < DispUnit.length ; i++) {
	table_random.dispunit.options[i].text = DispUnit[i];
    }
    table_random.dispunit.selectedIndex=getCookie("dispunit",0);
    table_random.CurrentDispUnit.value=DispConv[table_random.dispunit.selectedIndex];
}

function SaveUnits()
{
    var now = new Date()
    fixDate(now)
    now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000)
    setCookie("massunit",table_fma.massunit.selectedIndex,now);
    setCookie("accelunit",table_fma.accelunit.selectedIndex,now);
    setCookie("forceunit",table_fma.forceunit.selectedIndex,now);
    setCookie("accelunit2",table_random.accelunit.selectedIndex,now);
    setCookie("velunit",table_random.velunit.selectedIndex,now);
    setCookie("dispunit",table_random.dispunit.selectedIndex,now);
}

function ComputeSpectrum(f)
{
    with(Math) {
    Accel=0;
    Vel=0;
    Disp=0;

    // First frequency element is #10
    for(i=10 ; (i+2) < (f.elements.length) ; i+=2) {
   	f1=parseFloat(f.elements[i].value);
	a1=parseFloat(f.elements[i+1].value);
	f2=parseFloat(f.elements[i+2].value);
	a2=parseFloat(f.elements[i+3].value);
//alert("i="+i + ", f1="+f1 + ", f2="+f2 + ", a1="+a1 + ", a2="+a2);
	if((f1>0) && (f2>f1) && (a1>0) && (a2>0)) {
	    k2 = (log(a2) - log(a1)) / (log(f2) - log(f1));
	    k1 = a1 / exp(log(f1)*k2);
//alert("k2="+k2);
	    Accel += k1/(k2+1) * (pow(f2,(k2+1)) - pow(f1,(k2+1)));
	    if(k2 != 3.0) {
		Disp += k1/(k2-3) * (pow(f2,(k2-3)) - pow(f1,(k2-3))) / 1558.545457;
	    } else {
		Disp += k1 * (log(f2) - log(f1)) / 1558.545457;
	    }
	    if(k2 != 1.0) {
		Vel += k1/(k2-1) * (pow(f2,(k2-1)) - pow(f1,(k2-1))) / 39.47841760435743;
	    } else {
		Vel += k1 * (log(f2) - log(f1)) / 39.47841760435743;
	    }
	}
    }
    f.accel.value=sqrt(Accel) * f.CurrentAccelUnit.value;
    f.vel.value=sqrt(Vel) * 9.80665 * f.CurrentVelUnit.value;
    f.disp.value=sqrt(Disp) * 6 * 9.80665 * f.CurrentDispUnit.value;
    }
}

function ScaleProfile(f)
{
    original=f.accel.value;
    ComputeSpectrum(f);
    if((original>0) && (f.accel.value>0)) {
	factor=(original * original) / (f.accel.value * f.accel.value);
        // First G^2/Hz element is #8
	for(i=8 ; i < (f.elements.length) ; i+=2) {
	    f.elements[i].value *= factor;
	}
	ComputeSpectrum(f);
    }
}