
// Numero de casas decimais
var CD = 4;

/* ****
 * Fonte: http://www.labeee.ufsc.br/software/declinacao.html 
 */

/* *
 * Constantes relacionadas com o calculo do norte.
 */
var arrCD = Array();
arrCD[1] = -13.980939607;
arrCD[2] = -0.175285632;
arrCD[3] = -0.740830748;
arrCD[4] = -0.158459871;
arrCD[5] = 0.008965292;
arrCD[6] = 0.011727728;
arrCD[7] = 0.003645211;
arrCD[8] = 0.005581527;
arrCD[9] = 0.000675021;
arrCD[10] = 0.000367361;
arrCD[11] = 0.000258494;
arrCD[12] = 0.000149880;
arrCD[13] = 0.000172536;
arrCD[14] = 0.000110381;
arrCD[15] = 0.000134196;
arrCD[16] = 0.000044786;
arrCD[17] = -0.000067400;
arrCD[18] = 0.000115397;
arrCD[19] = 0.000008926;
arrCD[20] = -0.000002207;
arrCD[21] = -0.000004936;
arrCD[22] = -0.000002633;
arrCD[23] = 0.000000523;
arrCD[24] = -0.000000763;
arrCD[25] = 0.000000509;
arrCD[26] = -0.000002715;
arrCD[27] = 0.000000287;
arrCD[28] = -0.000000809;
arrCD[29] = 0.000000404;
arrCD[30] = 0.000000171;
arrCD[31] = 0.000002088;

function azmagUD(satlong,eslat,eslon) {
	var data = '2005.364'; // A data foi fixada em dezembro de 2005

	var xlat = eslat + 15.0;
	var xlon = eslon + 55.0;
	var epoc = data - 1990.0;
	// ----------------------------------------
	return elemen(xlat, xlon, arrCD, epoc);
}

function elemen(Y, X, c, T) {
	/*
	ELEMEN e' um polinomio do quarto grau --> P{ Y,X,T }**4 
	Variavel [ Y ] representa a latitude  reduzida
	Variavel [ X ] representa a longitude reduzida
	Variavel [ T ] representa a epoca     reduzida
	Array    [ C ] eh a array com os dados
	*/

	P1=c[1]+c[2]*Y+c[3]*X+c[4]*T+c[5]*X*X+c[6]*X*Y+c[7]*X*T+c[8]*Y*Y;
	P2=c[9]*Y*T+c[10]*T*T+c[11]*X*X*X+c[12]*X*X*Y+c[13]*X*X*T;
	P3=c[14]*X*Y*Y+c[15]*X*Y*T+c[16]*X*T*T+c[17]*Y*Y*Y+c[18]*Y*Y*T;
	P4=c[19]*Y*T*T+c[20]*X*X*X*X+c[21]*X*X*X*Y+c[22]*X*X*X*T;
	P5=c[23]*X*X*Y*Y+c[24]*X*X*Y*T+c[25]*X*X*T*T+c[26]*X*Y*Y*Y;
	P6=c[27]*X*Y*Y*T+c[28]*Y*Y*Y*T+c[29]*X*Y*T*T;
	P7=c[30]*Y*Y*Y*Y+c[31]*Y*Y*T*T;
	return P1 + P2 + P3 + P4 + P5 + P6 + P7;
}

// -- Source: http://www.satsig.net/degrees-minutes-seconds-calculator.htm
// "Atalho" para aredondamento
function round(number,n) {
	return Math.round(number*Math.pow(10,n))/Math.pow(10,n);
}

// Funcao para converter da notacao tradicional para a decimal
function convToDecimal(my_form, campo) {
	var dec, deg, min, sec, ref;

	deg = eval('my_form.'+campo+'_g.value');
	min = eval('my_form.'+campo+'_m.value');
	ref = eval('my_form.'+campo+'_ref.value');

	dec = (1.0 * deg) + (1.0 * min/60.0);

	if (eval('my_form.'+campo+'_s') != null) {
		sec = eval('my_form.'+campo+'_s.value');
		dec = dec + 1.0 * (sec/3600.0);
	}
	dec = ref * dec;

	if (isNaN(dec)) {
		alert('Valores invalidos!');
		return ;
	}

	if (eval('my_form.'+campo) != null) {
		eval('my_form.'+campo+'.value = round(dec,CD);');
	}
	return dec;
}

// Funcao para converter da notacao decimal para a tradicional
function convToDMS(my_form, campo) {
	var dec, deg, min, min_t, sec, ref;

	dec = eval('my_form.'+campo+'.value');

	// Graus
	deg = parseInt(Math.abs(dec));

	// Minutos
	min_t = (Math.abs(dec) - deg) * 60;
	min = parseInt(min_t);

	// Segundos
	sec = parseInt((min_t - min) * 60);

	// Referencia
	ref = (dec <= 0) ? '-1' : '1';

	eval('my_form.'+campo+'_g.value = deg');
	eval('my_form.'+campo+'_m.value = min');
	if (eval('my_form.'+campo+'_s') != null) {
		eval('my_form.'+campo+'_s.value = sec');
	}
	
	if (eval('my_form.'+campo+'_ref') != null) {
	 	alterarReferencia(eval('my_form.'+campo+'_ref'), ref);
	}
}

// -- Source: http://www.giangrandi.ch/electronics/satcalc/satcalc.shtml
function calcularOld(my_form) {
	var rx_lon, rx_lat, sat_lon, rx_az, rx_el;
	var delta_lon, num, den;	// Temporary values
	var R0 = 6370;		// Earth's radius: 6370 km
	var h = 35800;		// Satellite height: 35800 km

	rx_lon = parseFloat(my_form.loc_longitude.value);
	//rx_lon = parseFloat(convToDecimal(my_form,'loc_lon'));
	if (isNaN(rx_lon) || (rx_lon < -180) || (rx_lon > 180)) {
		//my_form.rx_lon.value = "";
		window.alert("Faltando 'longitude' da localizacao!");
		return(0);
	}

	rx_lat = parseFloat(my_form.loc_latitude.value);
	//rx_lat = parseFloat(convToDecimal(my_form,'loc_lat'));
	if (isNaN(rx_lat) || (rx_lat < -90) || (rx_lat > 90)) {
		//my_form.rx_lat.value = "";
		window.alert("Faltando 'latitude' da localizacao!");
		return(0);
	}

	sat_lon = parseFloat(my_form.sat_longitude.value);
	//sat_lon = parseFloat(convToDecimal(my_form,'sat_lon'));
	if (isNaN(sat_lon) || (sat_lon < -180) || (sat_lon > 180)) {
		//my_form.sat_lon.value = "";
		window.alert("Faltando 'longitude' do satelite!");
		return(0);
	}

	delta_lon = rx_lon - sat_lon;
	rx_az = Math.atan((Math.tan((Math.PI/180)*delta_lon)/Math.sin((Math.PI/180)*rx_lat)))*(180/Math.PI)+180;
	num = Math.cos(rx_lat*(Math.PI/180))*Math.cos(delta_lon*(Math.PI/180))-R0/(R0+h);
	den = Math.sqrt(1-Math.pow(Math.cos(rx_lat*(Math.PI/180))*Math.cos(delta_lon*(Math.PI/180)),2));
	rx_el = (180/Math.PI)*Math.atan(num/den);

		my_form.usr_az_verdadeiro.value = round(rx_az,CD) + ' ?';
	my_form.usr_inclinacao.value = round(rx_el,CD);
	return(1);
}
// -- Source: http://www.satsig.net/ssazelm.htm

function azimuth(satlong,eslat,eslong) {
	longdiffr=(eslong-satlong)/57.29578;
	esazimuth=180+57.29578*Math.atan(Math.tan(longdiffr)/Math.sin((eslat/57.29578)));
	if (eslat<0) esazimuth=esazimuth-180; 
	if (esazimuth<0) esazimuth=esazimuth+360.0;
	return esazimuth;
}

function azmag(satlong,eslat,eslong) {
	var longdiffr, esazimuth, latit, longi, a,b,c,pl,pr,u1,u2, um,esazimuthm;
	longdiffr=(eslong-satlong)/57.29578;
	esazimuth=180+57.29578*Math.atan(Math.tan(longdiffr)/Math.sin((eslat/57.29578)));
	if (eslat<0) esazimuth=esazimuth-180; 
	if (esazimuth<0) esazimuth=esazimuth+360.0;
	//magnetic field model
	//table below updated 25 Apr 2004, needs updating in Apr 2005 to keep errors under 0.2 deg
	//error fixed; dev[16] changed from -0.6 to 0.6
	dev = new Array(65);
	dev[0]=4.7;     dev[1]=7.2;    dev[2]=9.5;    dev[3]=16.3;   dev[4]=45.7;
	dev[5]=20.6;    dev[6]=12.3;   dev[7]=9.1;    dev[8]=17.2;   dev[9]=42.6;
	dev[10]=23.6;   dev[11]=12.9;  dev[12]=9.5;   dev[13]=17;    dev[14]=39.1;
	dev[15]=-8.5;   dev[16]=0.58;  dev[17]=4.7;   dev[18]=14;    dev[19]=29.1;
	dev[20]=-30.1;  dev[21]=-16.3; dev[22]=-14.35;dev[23]=-7.6;  dev[24]=10.8;
	dev[25]=-19.75; dev[26]=-12.06;dev[27]=-19.15;dev[28]=-24.1; dev[29]=-5.5;
	dev[30]=-4.3;   dev[31]=-1.5;  dev[32]=-6.75; dev[33]=-23.6; dev[34]=-19.2;
	dev[35]=8.75;   dev[36]=3.05;  dev[37]=-0.58; dev[38]=-23;   dev[39]=-39.4;
	dev[40]=16.3;   dev[41]=1.92;  dev[42]=-4.43; dev[43]=-32.5; dev[44]=-60.2;
	dev[45]=8.75;   dev[46]=0.45;  dev[47]=-2.15; dev[48]=-18.95;dev[49]=-73.8;
	dev[50]=-12.75; dev[51]=-4.5;  dev[52]=1.2;   dev[53]=-0.75; dev[54]=-63.1;
	dev[55]=-11.9;  dev[56]=-2.9;  dev[57]=5.7;   dev[58]=11;    dev[59]=38.5;
	dev[60]=4.7;    dev[61]=7.2;   dev[62]=9.5;   dev[63]=16.3;  dev[64]=45.7;
	latit=1.0*eslat;
	longi=1.0*eslong;
	if (latit==60.0) latit=59.99999;
	if (latit >59.999999) return "n/a";
	if (latit <-60) return "n/a";
	if (longi==180.0) longi=179.99999;
	if (longi>179.999999) longi=longi-360;
	if (longi<-180) longi=longi+360;
	a = Math.round(((1.0*longi + 180)/30)-0.5);
	//document.write("<P>top left long index is ", a);  
	b = 3- Math.round(((1.0*latit + 60)/30)-0.5);
	//document.write("top lat index is    ", b);   
	c=a * 5 + b;
	//calculate left proportion up to 30.
	if (latit>=30) pl=latit-30;
	else
	if(latit>=0) pl=latit;
	else
	if (latit>=-30) pl=30+latit;
	else
	pl = 60+latit;
	//return pl;
	//calculate hoziz proportion up to 30.
	pr=longi +180 - a*30;
	//return pr;   ok to here
	u1=dev[c+1]+(dev[c]-dev[c+1])*pl/30;
	u2=dev[c+6]+(dev[c+5]-dev[c+6])*pl/30;
	um=u1+(u2-u1)*pr/30;
	//return um;
	esazimuthm=esazimuth-um;
	if (esazimuthm<-180) esazimuthm=esazimuthm+360; 
	if (esazimuthm>360) esazimuthm=esazimuthm-360.0;
	return esazimuthm;
}

function elevation(satlong,eslat,eslong) {
	longdiffr=(eslong-satlong)/57.29578;
	eslatr=eslat/57.29578;
	r1=1+35786/6378.16;
	v1=r1*Math.cos(eslatr)*Math.cos(longdiffr)-1;
	v2=r1*Math.sqrt(1-Math.cos(eslatr)*Math.cos(eslatr)*Math.cos(longdiffr)*Math.cos(longdiffr));
	eselevation=57.29578*Math.atan(v1/v2);
	if (eselevation<30)
	   eselrefracted=(eselevation+Math.sqrt(eselevation*eselevation+4.132))/2
	else
	   eselrefracted=eselevation;
	if (eselrefracted<1)   
	   // added 18 Oct 1998
	   // refraction correction makes satellites below horizon
	   // appear to be marginally visible so to avoid this anomaly
	   // results under 1 deg are displayed as " < 1 ".  Attempts at
	   // very low elevation under 5deg will be subject to severe scintillation
	   eselrefracted="< 1";
	return eselrefracted;
}

function range(satlong,eslat,eslong) {
	longdiffr=(eslong-satlong)/57.29578;
	p1=35786*35786;
	p2=2*6378.16*(35786+6378.16);
	p3=1-Math.cos(eslat/57.29578)*Math.cos(-longdiffr);
	slantrange = Math.sqrt(p1+p2*p3);
	return slantrange;
}

function tilt(satlong,eslat,eslong) {
	longdiffr=(satlong-eslong)/57.29578;
	eslatr=eslat/57.29578;
	poltilt=-57.29578*Math.atan(Math.sin(longdiffr)/Math.tan(eslatr));
	return poltilt;
}

function pmountangle(eslat){
	// amended 19 nov 98 to use different local variable meslat always+ve
	meslat=eslat;
	if (eslat<0) meslat=-eslat;
	polaraxis=meslat-(meslat-43.0)*(meslat-43.0)/(51.3*51.3)+0.000556*meslat+0.68;
	// display truncated to 1 dec place, accuracy 0.1 deg
	if (meslat>80.0) return "lat!"
	else 
	return polaraxis;
}

function pmountoffset(eslat){
	// amended 19 nov 98 to use different local variable meslat always+ve
	meslat=eslat;
	if (eslat<0) meslat=-eslat;
	offset=7.6-(meslat-96.8)* (meslat-96.8)/(35.0*35.0)+meslat/69.0- 0.1*Math.sin(meslat/12.0);
	// display truncated to 1 dec place, accuracy 0.1 deg
	if (meslat>80.0) return "lat!"
	else 
	return offset;
}

function calcular(form) {
	if (checkform(form)) {
		eselevation = elevation(form.sat_longitude.value,form.loc_latitude.value,form.loc_longitude.value);
		esazimuth   = azimuth  (form.sat_longitude.value,form.loc_latitude.value,form.loc_longitude.value);
		esazimuthm  = azmag   (form.sat_longitude.value,form.loc_latitude.value,form.loc_longitude.value);
		slantrange  = range    (form.sat_longitude.value,form.loc_latitude.value,form.loc_longitude.value);
		poltilt     = tilt     (form.sat_longitude.value,form.loc_latitude.value,form.loc_longitude.value);
		pmangle  = pmountangle   (form.loc_latitude.value);
		pmoffset  = pmountoffset   (form.loc_latitude.value);

		inc_antena = form.antena.options[form.antena.selectedIndex].value;

		// Sua configuracao
		form.usr_distancia.value =round(slantrange,CD);


		// Azimuth
		form.usr_az_verdadeiro.value  =round(esazimuth,CD);
		
		// Elevacao
		form.usr_elevacao.value=round(eselevation - inc_antena,CD);

		// Inclinometro
		//form.usr_clinometro_central.value = round(pmangle,CD);
		//form.usr_clinometro_offset.value = round(pmoffset - inc_antena,CD);
		form.usr_clinometro.value = round(90 - (eselevation - inc_antena),CD);

		// Inclinacao LNB
		form.usr_inclinacao.value    =round(poltilt,CD);

		// Completar os campos em GMS tambem
		convToDMS(form,'usr_inclinacao');
		convToDMS(form,'usr_az_verdadeiro');
		convToDMS(form,'usr_elevacao');
	}
	return;
}

function checkform(form) {
	if (form.loc_latitude.value==null  ||form.loc_latitude.value.length==0  ||
	    form.loc_longitude.value==null ||form.loc_longitude.value.length==0 ||
	    form.sat_longitude.value==null||form.sat_longitude.value.length==0){
	
		alert("\nEntre com a Longitude do satelite e com a Latitude e Longitude da sua localizacao"); return false;
		return false;
	}
	return true;
}

// -- Manipular formularios
function alterarReferencia(select, val) {
	for (i = 0; i < select.options.length; i++) {
		if (select.options[i].text == val || select.options[i].value == val) {
			select.options.selectedIndex = i;
			return;
		}
	}
	select.options.selectedIndex = 0;
}

function alterarEstado(my_form) {
	my_form.action = my_form.estado.options[my_form.estado.selectedIndex].value;
	my_form.submit();
}

function alterarCidade(my_form,type) {
	var coord, arr, latitude, longitude;
        if (type == 'h'){
          coord = my_form.cidade.value; 
        }
        else {
	  coord = my_form.cidade.options[my_form.cidade.selectedIndex].value; 
        }
	arr = coord.split('@');
	latitude = arr[0].split(':');
	longitude =  arr[1].split(':');

	// Sinal de referencia
        var expr = /^-{0,1}(\d{1,2})$/;
  	var lat = latitude[0].match(expr);
  	var long = longitude[0].match(expr);

        if(expr.test(latitude[0])) {
          lat_ref = 'S'; }
        else {
          lat_ref = 'N'; }

        if(expr.test(longitude[0])) {
          long_ref = 'O'; }
        else {
          long_ref = 'L'; }

	// Latitude
	my_form.loc_latitude_g.value = lat[1];
	my_form.loc_latitude_m.value = latitude[1];
	my_form.loc_latitude_s.value = latitude[2];
	alterarReferencia(my_form.loc_latitude_ref,lat_ref);
	
	// Longitude
	my_form.loc_longitude_g.value = long[1];
	my_form.loc_longitude_m.value = longitude[1];
	my_form.loc_longitude_s.value = longitude[2];
	alterarReferencia(my_form.loc_longitude_ref,long_ref);

	convToDecimal(my_form,'loc_latitude');
	convToDecimal(my_form,'loc_longitude');
}

function alterarSatelite(my_form) {
	my_form.sat_longitude.value = my_form.satelite.options[my_form.satelite.selectedIndex].value;
	convToDMS(my_form,'sat_longitude');
}

