<!--
// ======================================================================= 
//	Version 1.0.0
//
//----- 11-08-02, 11-09-02, Began coding
//----- 12-20-03, 12-25-03, Major improvements...
//----- 04-01-04, 04-04-04, Added 45 degree data and single mid-band click
//----- 02-21-07, Band edges fixed: 80, 160
//----- 05-10-07  Optional parse of url command line for frequency 
//----- 05-29-07  Development and fixes, added 1.25m and 70cm bands
//                Also, centimeter converter
//	05-31-07  Can enter a freq, a wire length, or a band
//      06-02-07  For a given length of wire, what is the lowest band?
//
//	Version 1.1.1
//      Code by KBNorton
//
//      Use an associative array here... this is the "master" array
//      All data is stored here for other numeric indexed, faster arrays
//      Added 160m band data
//
//      Program to calculate wire lengths and dimensions for various 
//      size loop antennas and different shapes.  
//
//      Watch upper band edges that end in 0, like 2.0. These have 
//      special coding requirements. Now fixed for 80 and 160m.
//
// =======================================================================

var bandNames    = new Array();

bandNames["1"]   = "160m,1.8,2.0";
bandNames["2"]   = "160m,1.8,2.0";	// OK to do this!
bandNames["3"]   = "80m,3.5,4.0";
bandNames["4"]   = "80m,3.5,4.0";
bandNames["7"]   = "40m,7.0,7.3";
bandNames["10"]  = "30m,10.1,10.15";
bandNames["14"]  = "20m,14.0,14.35";
bandNames["18"]  = "17m,18.068,18.168";
bandNames["21"]  = "15m,21.0,21.45";
bandNames["24"]  = "12m,24.89,24.99";
bandNames["28"]  = "10m,28.0,29.7";
bandNames["29"]  = "10m,28.0,29.7";
bandNames["50"]  = "6m,50.0,54.0";
bandNames["51"]  = "6m,50.0,54.0";
bandNames["52"]  = "6m,50.0,54.0";
bandNames["53"]  = "6m,50.0,54.0";
bandNames["54"]  = "6m,50.0,54.0";
bandNames["144"] = "2m,144.0,148.0";	// Note boundry conditions
bandNames["145"] = "2m,144.0,148.0";
bandNames["146"] = "2m,144.0,148.0";
bandNames["147"] = "2m,144.0,148.0";
bandNames["148"] = "2m,144.0,148.0";
bandNames["222"] = "1.25m,222.0,225.0";
bandNames["223"] = "1.25m,222.0,225.0";
bandNames["224"] = "1.25m,222.0,225.0";
bandNames["225"] = "1.25m,222.0,225.0";
bandNames["420"] = "70cm,420.0,450.0";	// Note: Special case for 440Mhz


//----- Array for the mid band frequencies...
var midBands = new Array();	// Indexed array for mid-freqs
var bandList = new Array();	// Associative array, bandname => index no.
buildMidband();

//----- Array for the random selections...
var theBands = new Array(); 
buildRandom();

//----- Global incrementer for stepBand()
var nextItem = "0";

//----- Global var for a current valid band, out of band is null
var validBand = "";
var myField   = "";

//----- Boolean switch for stepBand
//----- This causes the stepBand buffer to reset after a click from
//----- either random or calculate functions. 
var stepSignal = false;
var signal     = "";

function calculate(signal)
{
//----- Data Inits...
	var metricCon  = 0.3048;	// ft x metricCon = meters
        var fortyFive  = 0.7071;	// 45 degree height conversion
	var myMeasure  = "Feet";
	var mylength   = 0;
	var squareSide = 0;
	var triSide    = 0;
	var idxcnt     = 0;

	var item       = ""
	var myData     = "";
	var calcFreq   = "";
	var lowerEdge  = "";
	var upperEdge  = "";

	var displayBand = "";

//----- Possible calculator inputs, some can be null
	var myFreq     = document.loopdata.frequency.value;
        var mylength   = document.loopdata.antlength.value;
        var mybandname = document.loopdata.bandname.value; 

//----- Set/clear this flag...
	validBand = "";

//----- Check here first for a band name entry
	mybandname = mybandname.replace(/[ ]/g,"");	// Delete all spaces
	mybandname = mybandname.toLowerCase();		// To lower
	if ( mybandname.match(/70/) )
	{
		mybandname = mybandname + "cm";
	}
	else if ( ! mybandname.match(/m$/) )
	{
		mybandname = mybandname + "m";
	}
 
	if ( mybandname && (myField == "bandname") )
	{
		for ( item in bandList )
		{
//----- This could be a broader search
	 		if ( item.search(mybandname) > -1 )
			{
				myFreq = midBands[bandList[item]];
				document.loopdata.frequency.value = myFreq;
				myField = ""; 
				break;
			}

		}
	}

//----- Get the user's input from the form. Assume it is all valid.
//----- This is always the length in feet.
	if ( myFreq && ( (myField != "antlength") || signal ) )
	{
        	mylength = 1005 / Number(myFreq);
    	}

	if ( mylength && (myField == "antlength") )
	{
//----- NOTE: Length must be in feet here
//----- Find out if length is in feet, meters, or centimeters
//----- If in feet, do nothing else convert accordingly
		if ( document.loopdata.dimentype[0].checked )
		{
			mylength = mylength / metricCon; 
		}

		if ( document.loopdata.dimentype[2].checked )
		{
			mylength = mylength / (metricCon * 100 ) 
		}

//----- Used seperate var and Math.round for this result
		calcFreq = Math.round((1005 / mylength) * 1000)/1000;
		myFreq   = calcFreq.toString();

//----- Coming from stepband? If so, get lowest frequency for this wire
//----- length. Stepband can be a one-shot
		if ( signal )
		{
			idxcnt = 0;
			for ( item in midBands )
			{
				if ( Number(midBands[item]) > calcFreq )
				{
					break;
				}
				idxcnt = idxcnt + 1;
			}
// alert("data: " + midBands[idxcnt]+" "+calcFreq);
			if ( idxcnt > -1 && idxcnt < midBands.length )
			{
				myFreq = midBands[idxcnt];
			}
		}

		document.loopdata.frequency.value = myFreq;
		myField  = "";
		signal   = false;	// Not stepping now, reset here
    	}

//----- If nothing then do nothing...	
	if ( !myFreq && !mylength )
	{
		return;
	}

//----- Standard test for numeric value
//----- Have all data by here: freq and length in feet
	if (!isNaN(mylength) &&
        	(mylength != Number.POSITIVE_INFINITY) &&
        	(mylength != Number.NEGATIVE_INFINITY))
    	{

		if ( document.loopdata.dimentype[0].checked || document.loopdata.dimentype[2].checked )
		{
//----- Convert this length to metric...
			mylength = mylength * metricCon;

//----- Only do this if the button is "pushed" 2 is the centimeters slot
			if ( document.loopdata.dimentype[2].checked )
			{
				mylength = mylength * 100;
				document.loopdata.measurement.value = "Centimeters";
			}
			else
			{
				document.loopdata.measurement.value = "Meters";
			}
		}
		else
		{
			document.loopdata.measurement.value = "Feet";
		}

//----- If OK, then round and load into the variable...
	       	document.loopdata.antlength.value   = round(mylength);
       		document.loopdata.oneside.value     = squareSide = round(mylength/4.0);
       		document.loopdata.horizontal.value  = round((mylength/6.0) * 2);
       		document.loopdata.vertical.value    = round(mylength/6.0);
       		document.loopdata.diameter.value    = round(mylength/Math.PI);
       		document.loopdata.triangle.value    = triSide = round(mylength/3.0);
		document.loopdata.squarediag.value  = round(Math.sqrt(squareSide*squareSide + squareSide*squareSide));
		document.loopdata.deltaheight.value = round(Math.sqrt((triSide*triSide) - ((triSide/2)*(triSide/2))));

//----- Compute the vertical heights when sloped at 45 degrees...
		document.loopdata.slopeOneside.value     = round(fortyFive * document.loopdata.oneside.value);
		document.loopdata.slopeVertical.value    = round(fortyFive * document.loopdata.vertical.value);
		document.loopdata.slopeDiameter.value    = round(fortyFive * document.loopdata.diameter.value);
		document.loopdata.slopeSquarediag.value  = round(fortyFive * document.loopdata.squarediag.value);
		document.loopdata.slopeDeltaheight.value = round(fortyFive * document.loopdata.deltaheight.value);

	        document.loopdata.impedance.value  = 102;

//----- Determine the band name... has to be a string?
		myTest = myFreq.split(".");

//-----	Special case for 70cm band, very hardcoded... :(	
		if ( myFreq < 450 && myFreq > 420 )
		{
			myTest[0] = "420";
		}

		if ( bandNames[myTest[0]] )
		{
//----- OK, we have valid data...
			myData    = bandNames[myTest[0]].split(",");
			lowerEdge = Number(myData[1]);  // If empty then null
			upperEdge = Number(myData[2]);
	
			if ( Number(myFreq) > upperEdge )
			{
				displayBand = " >"+myData[0];

			}
			else if ( Number(myFreq) < lowerEdge )
			{
				displayBand = " <"+myData[0];
			}
			else
			{
				displayBand = " "+myData[0];

//----- Use global validBand to update band "status" and for lookup
				validBand  = myData[0];
			}
		}
		else
		{
			displayBand = " ";
		}

//----- This is the band name field
		document.loopdata.bandname.value = displayBand;
    	}
	else
	{
//----- Otherwise, the user's input was probably invalid, so don't
//----- display anything except the alerting error message.

        	document.loopdata.frequency.value   = "";
        	document.loopdata.antlength.value   = "";
        	document.loopdata.impedance.value   = "";
        	document.loopdata.oneside.value     = "";
		document.loopdata.horizontal.value  = "";
		document.loopdata.vertical.value    = "";
		document.loopdata.diameter.value    = "";
		document.loopdata.triangle.value    = "";
		document.loopdata.squarediag.value  = "";
		document.loopdata.deltaheight.value = "";

		document.loopdata.slopeOneside.value     = "";
		document.loopdata.slopeVertical.value    = "";
		document.loopdata.slopeDiameter.value    = "";
		document.loopdata.slopeSquarediag.value  = ""; 
		document.loopdata.slopeDeltaheight.value = "";

	        alert("Computational Error: Divide by zero...");
	}

//----- If nothing in signal, then did not start from stepBand() 
//----- So reset to 0 in stepband, we are not stepping.
//----- But if something, keep stepping, true!
	if ( ! signal )
	{
		stepSignal = false;
	}
}

//----- This method rounds a number to three decimal places.
//----- Then converts to a string here for all values...
function round(x)
{
        var buffer  = 0;
        var mydot   = 0;
        var str_val = "";

        buffer  = Math.round(x * 1000)/1000;
        str_val = buffer.toString();
        mydot   = str_val.indexOf(".", 0);
        mydot   = mydot + 4;
        str_val = str_val.substr(0,mydot);

//----- NOTE: IE does NOT like this! It does it for you...
//----- if ( str_val[0].match(/^\./) ) then str_val = "0" + str_val;

        return str_val;
}

//----- Select a random frequency for a demo...
//----- This function calls calculate!
function randomfreq()
{
	var bandChoice   = 0;
	var count        = 0;
        var spread       = 0;

        var theFreq      = "";
        var bandSpread   = "";

	count      = theBands.length;		// Get array size

	bandChoice = Math.round(Math.random() * (count - 1) );
        spread     = Math.round(Math.random() * 1000);
        bandSpread = spread.toString();
        theFreq    = theBands[bandChoice] + bandSpread;

	document.loopdata.frequency.value = theFreq;
	calculate(true);
}

//----- Populate an array of mid band freqs... 
//----- Store as a "rounded" string
//----- Build associative array: names to indexed numbers
function buildMidband()
{
	var item     = "";
// var myData   = "";		// Data record: "80m,3.5,4.0" i.e.
	var myData   = new Array();

	var midFreq  = 0;
	var last     = 0;
	var freqCnt  = 0;

	for ( item in bandNames )
	{
		myData  = bandNames[item].split(",");
		if ( myData[1] && myData[2] )
		{
			midFreq = Number(myData[1]) + (( Number(myData[2]) - Number(myData[1]) ) / 2); 
			if ( last != midFreq )
			{
				last = midFreq;
				bandList[myData[0]] = freqCnt;
				midBands[freqCnt++] = String(round(midFreq));
			}
		}
	}

	return true;
}

//----- Step thru the bands at mid freq for each band in turn...
//----- Suppose you want to show mid-band for the band you are already in
//----- from a type-in or a random entry, must be within the band!
function stepBand()
{
//----- If in a valid band already and not stepping then
//----- just get the mid value for that band, 
//----- determine the correct nextItem for this band
	if ( validBand && ! stepSignal )
	{
		nextItem   = bandList[validBand];
// validBand  = "";
		stepSignal = true;

	}
	else
	{
//----- Reset the array pointer if true, to start, first time entry...
//----- We are "stepping" thru the buffer, true
		if ( ! stepSignal )
		{
			nextItem = 0;
			stepSignal = true;
		}
	}

//----- Start over if at array end... steps thru a "circular" array
//----- Catches the out-of-bound condition...
	if ( ! midBands[nextItem] )
	{
		nextItem = 0;
	}

//----- Recalled as string data...
//----- Not the best example of good programming...
        if ( myField == "antlength" )
	{
		document.loopdata.frequency.value = "";
	}
	else
	{
		document.loopdata.frequency.value = midBands[nextItem++];
	}

//----- Past this signal "token" to show calculate we are from here...
//----- Either not null or null, true or false
	calculate(stepSignal);
}

//----- Build the array theBands for the random pull... 
function buildRandom()
{
	var item     = "";
	var freqCnt  = 0;

//----- Read data from bandNames array...
//----- Store with "dot" as a string, i.e., 14. later becomes 14.<xxx>
	for ( item in bandNames )
	{
		theBands[freqCnt++] = String(item) + ".";
	}

	return true;
}

//----- The input trigger from the web page, read the URL line
//----- on page load from html page...
function readData()
{
	var key   = "";

//----- Get the URL string data in the URL window after the "?" 	
	var loc   = location.search.substring(1);
	var pairs = loc.split("=");
	key       = pairs[1];

//----- If coming in from outside, then parse url line
//----- Store on page space
	if ( key )
	{
		document.loopdata.frequency.value = key;
		calculate();
	}

	return true;
}

//----- What was changed on the page
//----- myField is a global var
function fromWhere(fieldLoc)
{
	myField = fieldLoc;

}
// -->
