/* FROM: http://imaginatorium.org/stuff/photocalc.js
 * 
 * Functions for photographic calculations
 * Copyright (c) 2001 Brian Chandler <chandler [at] yomogi.or.jp>
 *
 * This software is copylefted: you may use it freely, or redistribute it 
 * and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation. I do not guarantee 
 * anything about it other than that I did my best. Please send me
 * comments or corrections.
 * 
 * Each calculator operates in a form. If you want to include just one
 * calculator in a page, snip out the form, and the relevant functions
 * from this file (sorry, you'll have to work out which those are) and put 
 * them in the html head. Then please include an acknowledgement on
 * the same page with a link to http://imaginatorium.org/stuff/photo.htm
 * See http://imaginatorium.org/info.htm for terms and stuff.
 */

// ****** 1/u + 1/v = 1/f calculator (lensx, x=u, v, f; lensclear)******

function lensuinf(form) { 	// infinity button
form.u.value = Infinity;
lensclear(form);
}

function lensu(form) {	// Calculate u

var v = form.v.value;
var f = form.f.value;

var u = 1 / (1/f - 1/v);

if (isNaN(u) || u==0)
{   form.u.value="";
    return;
}

if (u < 0)
{   form.u.value="";
    alert("Impossible! (Negative value)");
    return;
}

form.u.value=Math.round(u);
form.mag.value=magstring(v/u);
bulb('lensbulb', 'on')
return 0;
}

function lensv(form) {	// Calculate v

var u = form.u.value;
var f = form.f.value;

var v = 1 / (1/f - 1/u);

if (isNaN(v) || v==0)
{   form.v.value="";
    return;
}

if (v < 0)
{   form.v.value="";
    alert("Impossible! (Negative value)");
    return;
}
form.v.value=Math.round(v);
form.mag.value=magstring(v/u);
bulb('lensbulb', 'on')
return 0;
}

function lensf(form) {	// Calculate f

var u = form.u.value;
var v = form.v.value;

var f = 1 / (1/u + 1/v);
if (isNaN(f) || f==0)
{   form.f.value="";
    return;
}

form.f.value=Math.round(f);
form.mag.value=magstring(v/u);
bulb('lensbulb', 'on');
return 0;
}

function lensclear(form) {		// Called when any value set
if (badno(form.f.value)) form.f.value="";
if (isNaN(form.u.value) || form.u.value<=0) form.u.value="";
if (isNaN(form.v.value) || form.v.value<=0) form.v.value="";
form.mag.value = "";
bulb('lensbulb', 'off');
}

// **** end lensx functions (1/u+1/v=1/f) ****

// ****** Dioptre calculator (1/f1 + 1/f2 = 1/ff) ******
// Also converts in and out of dioptres (d1, d2, dd)
// Allows negative values.
// Sorry - the four cases all written out seems inelegant <g>

function diopf1(form) {	// Called when f1 pressed
var f1 = form.f1.value;
if (isNaN(f1/f1))	// invalid
{   if (form.f1.value=='-')	// leave minus sign!
	form.d1.value='-';
    else
    {	form.f1.value='';
	form.d1.value='';
    }
    form.ff.value='';
    form.dd.value='';
    return;
}

var d1 = Math.round(100000/f1) / 100;
form.d1.value=d1;

var f2 = form.f2.value;
if (isNaN(f2/f2)) return;

form.ff.value = Math.round(1 / (1/f1 + 1/f2));
form.dd.value = Number(form.d1.value) + Number(form.d2.value);
}	// End diopf1()

function diopf2(form) {	// Called when f2 pressed
var f2 = form.f2.value;
if (isNaN(f2/f2))	// invalid
{   if (form.f2.value=='-')	// leave minus sign!
	form.d2.value='-';
    else
    {	form.f2.value='';
	form.d2.value='';
    }
    form.ff.value='';
    form.dd.value='';
    return;
}

var d2 = Math.round(100000/f2) / 100;
form.d2.value=d2;

var f1 = form.f1.value;
if (isNaN(f1/f1)) return;

form.ff.value = Math.round(1 / (1/f1 + 1/f2));
form.dd.value = Number(form.d1.value) + Number(form.d2.value);
}	// End diopf2()

function diopd1(form) {	// Called when d1 pressed
var d1 = form.d1.value;
if (isNaN(d1/d1))	// invalid
{   if (form.d1.value=='-')	// copy minus sign!
	form.f1.value='-';
    else
    {	form.f1.value='';
	if (!(Number(d1) == 0 || d1=='.'))	// Leave 0 . 0. &c
	    form.d1.value='';		// else clear
    }
    form.ff.value='';
    form.dd.value='';
    return;
}

var f1 = Math.round(1000/d1);
form.f1.value=f1;

var f2 = form.f2.value;
if (isNaN(f2/f2)) return;

form.ff.value = Math.round(1 / (1/f1 + 1/f2));
form.dd.value = Number(form.d1.value) + Number(form.d2.value);
}	// End diopd1()

function diopd2(form) {	// Called when d2 pressed
var d2 = form.d2.value;
if (isNaN(d2/d2))	// invalid
{   if (form.d2.value=='-')	// copy minus sign!
	form.f2.value='-';
    else
    {	form.f2.value='';
	if (!(Number(d2) == 0 || d2=='.'))	// Leave 0 . 0. &c
	    form.d2.value='';		// else clear
    }
    form.ff.value='';
    form.dd.value='';
    return;
}

var f2 = Math.round(1000/d2);
form.f2.value=f2;

var f1 = form.f1.value;
if (isNaN(f1/f1)) return;

form.ff.value = Math.round(1 / (1/f1 + 1/f2));
form.dd.value = Number(form.d1.value) + Number(form.d2.value);
}	// End diopd2()


// ==========================================

// **** Utilities

// **** Lightbulb (on/off)
// For image Name, bulb(Name, on/off);

// Preload images
if (document.images) {
    lightoff = new Image();
    lightoff.src  = "../graphics/bulboff.png";
    lighton = new Image();
    lighton.src  = "../graphics/bulbon.png";
}

function bulb(Name,Which) {
    if (document.images)
	document [Name].src = eval("light" + Which + ".src");
}


// **** magstring(mag) - neat magnification value string ****
// assumes arg is valid (a non-negative number or infinity)
function magstring(mag) {

if (mag > 10) return "x "+Math.round(mag);

if (mag < 0.05) return "x 1/" + Math.round(1/mag);

return "x " + Math.round(100*mag) / 100;

} // end magstring


function badno(x) {   // returns true unless a non-negative proper number
return (isNaN(x/x) || x < 0);
}


