﻿var latitudi,longitudi,tzr;

function dms(x) {
  // convert decimal fraction of degrees to minutes // 
  var m,i,f;
  x = Math.abs(x);	// minutes always > 0
  i = Math.floor(x);
  f = x - i;
  m = Math.round(60.0*f);
  return m;
}

// Function library
var timeStamp = "XX.XX.XXXX";
var Result="location xxx";
var hs,ms = "XX";
var ydays,hh,mm,jday = 0;
var inday = false,dlstime=false;
var lat = 65.85;
var lon = 24.12;
var pi = Math.PI;
var rads = pi/180.0;
var daylen, ha=0.0;
var eqtime, cosfi, altit;
var utct,loctime,tzone = 2.0;
var SummerTime = 0.0;
var SunDia = 0.53;     // Sunradius degrees //
var AirRefr = 35.0/60.0, Refr2=0.0,Ta=0.0;	
var Nousu,fo,fi,dfo,dfi,twidev,twib,twie,delta,kork,noont,powers, csha = 0.0;
var fi2,twidev2,twib2,twie2,x,theta;
var wkday = 0;
var now,inkuu,inpv,invuos, hr, mn, sc;

function range(x) {
  var b = x /pi/2.0;
  var a = 2*pi * (b - Math.round(b));
  if (a < 0) a = 2*pi + a;
  return a;
}

function aika() {
  var y2k = new Date(2000,0,1,0);
  now = new Date();
  hr = now.getHours();
  mn = now.getMinutes();
  sc = now.getSeconds();
  utct = now.getUTCHours();
  tzone = hr-utct;
  var yearNow = now.getYear();
  //   Get the days to J2000, daynumber Y2K-bug fixed
  //   jday = day number since Y2K
  if (inday) now = new Date(invuos,inkuu,inpv+1,11);
  if (inday) yearNow = invuos;
  if (yearNow<1000) yearNow+= 1900;
  // Time in milliseconds at noontime
  var timeNow = now.getTime()/1000.0;

  jday = Math.round((now.getTime() - y2k.getTime())/(24*3600*1000));

  //   Find the ecliptic longitude of the Sun
  //   mean longitude of the Sun
  var L = range(280.461 * rads + .9856474 * rads * jday);

  //   mean anomaly of the Sun
  var g = range(357.528 * rads + .9856003 * rads * jday);

  //   Ecliptic longitude of the Sun
  var lambda = range(L + 1.915 * rads * Math.sin(g) + 0.02 * rads * Math.sin(2 * g));

  //   Obliquity of the ecliptic
  var obliq = 23.439 * rads - .0000004 * rads * jday;

  //   Find the RA and DEC of the Sun

  var alpha = Math.atan2(Math.cos(obliq) * Math.sin(lambda), Math.cos(lambda));
  delta = Math.asin(Math.sin(obliq) * Math.sin(lambda));
  eqtime = 1440.0 -720.0 *(L - alpha)/pi;
  if (eqtime>1440.0) eqtime-= 1440.0;
  var uusi = new Date(yearNow,0,1,12,0,0);
  var NewYear = uusi.getTime()/1000.0;
  ydays = Math.round((timeNow-NewYear)/3600/24)+1;
  SummerTime = 1.0; if ((ydays<90) || (ydays>300)) SummerTime=0.0;
  if (!dlstime) SummerTime = 0.0; 
  dekl = 180*delta/pi;

  wkday =  now.getDay();

  var timeStamp = ""+yearNow +"-"+fillzero(now.getMonth()+1)+"-"+now.getDate();
  return timeStamp;
}

function makeArray(numElements) {
  this.length = numElements
  for (count = 1; count <= numElements; count++)
     this[count] = 0;
  return (this);
}

var WkDays = new makeArray(14);
WkDays[0] = "Sunday"; WkDays[7] = "Sunnuntai";
WkDays[1] = "Monday"; WkDays[8] = "Maanantai";
WkDays[2] = "Tuesday"; WkDays[9] = "Tiistai";
WkDays[3] = "Wednesday"; WkDays[10] = "Keskiviikko";
WkDays[4] = "Thursday";  WkDays[11] = "Torstai";
WkDays[5] = "Friday"; WkDays[12] = "Perjantai";
WkDays[6] = "Saturday"; WkDays[13] = "Lauantai";

var tulokset = "";
var lastitem = 41;
var tzr=0.0;
var inlat = false;
var pvm = "xx-xx-xx";

function hourAngle(zenith,latitude,declination) {
  var cosha,ha;
  var deg2rad = pi/180.0;
  cosha = Math.cos(zenith)/Math.cos(deg2rad*latitude)/Math.cos(deg2rad *declination) - 
    Math.tan(deg2rad *latitude)*Math.tan(deg2rad *declination);
  if (cosha<-1.0) cosha= -1.0; // no darkness
  ha = Math.acos(cosha)/deg2rad; // Hour angle for given zenith angle [degr]
  return ha;
}

function DoCalc(latitude, longitude, timezone) {
  inday = false;
  inlat = true;
  Item = lastitem;

  // invuos = "2008";
  // inkuu = "1";
  // inpv = "20";
  dlstime = false; // Day light saving
  tzone = timezone;
  pvm =  aika();
	
  var yearNow = now.getYear();
  if (yearNow<1000) yearNow+= 1900;

  // hr = 12; 
  // mn = 0;

  lat = latitude;
  lon = longitude;
  tzr = timezone;

  dgmn(parseFloat(lon)+0.00001);

    Ta = 0; // temperature
    AirRefr = 159.4/(273.0+1.0*Ta);
    dgmn(AirRefr); 
    // Northern hemisphere   //
    kork = 90-lat+dekl; 
    // Southern hemisphere	//
    if (dekl > lat ) kork=90+lat-dekl;
    if (kork < 15.0) Refr2 = 1000.0*(0.1594+0.0196*kork+kork*kork* 2.0E-05)/(1.0+0.505*kork+0.0845*kork*kork)/(273.0+1.0*Ta);
    if (kork < 15.0) kork+= Refr2;

    // Calculating the hourangle //
    dfo = 0.5*SunDia+AirRefr;
    fo = hourAngle(rads*(90.0+dfo),lat,dekl);
    // Calculating the hourangle for the twilight //
    // Conversion of angle to hours and minutes //
    daylen = fo/7.5; 
    if (daylen<0.01) {daylen = 0.0;}     // arctic winter     //
    fi = hourAngle(1.675516,lat,dekl);
    twidev = fi - fo; 
    fi2 = hourAngle(1.780236,lat,dekl);
    twidev2 = fi2 - fo; 
    hrmn(daylen);
    tulokset = "";
    tulokset = "Päivän pituus:  "+hs+":"+ms+"<br>";

    ha = 15.0*(hr-tzr-SummerTime) +0.25*(mn + eqtime) +1.0*lon -180.0;
    if (ha>360.0) ha-=360.0;
    if (ha>180.0) ha-=360.0;
    cosfi = Math.sin(rads*lat)*Math.sin(rads*dekl) + Math.cos(rads*lat)*Math.cos(rads*dekl)*Math.cos(rads*ha);
    altit = 90.0 - Math.acos(cosfi)/rads; // altitude degrees
    if (altit < 6.0) altit+= AirRefr;

  // Azimuth theta:
  x = Math.sin(rads*dekl)/Math.cos(rads*lat);
  x = x/Math.cos(rads*altit);
  x-= Math.tan(rads*lat)*Math.tan(rads*altit);
  theta = Math.acos(x)/rads; // morning azimuth

  loctime = hr + mn/60.0;
  utct = loctime-tzr-SummerTime; if (utct<0.0) utct+=24.0;
  Nousu = 12.0 + eqtime/60.0 - fo/15.0 + tzr - lon/15.0 + SummerTime;
  Lasku = 12.0 + eqtime/60.0 + fo/15.0 + tzr - lon/15.0 + SummerTime; 
  // noont =  Nousu + fo/15.0; hrmn(noont);
  noont = 12.0 + eqtime/60.0  + tzr - lon/15.0 + SummerTime;
  if (loctime>noont) theta = 360.0 - theta; // afternoon azimuth
  if (loctime<(noont-12)) theta = 360.0 - theta; // short before midnite 
  twib = Nousu - twidev/15.0;	// Begin civil twilight
  twie = Lasku + twidev/15.0;	// End civil twilight
  twib2 = Nousu - twidev2/15.0;	// Begin nautical twilight
  twie2 = Lasku + twidev2/15.0;	// End nautical twilight
  if (twie>25.0) twie-= 24.0;  // it may overflow with DLS
  if (twie2>25.0) twie2-= 24.0;  // it may overflow with DLS

  if (fi2 < 180.0) {
    hrmn(twib2);
  }

  if (fi < 180.0) {
    hrmn(twib);
  } else tulokset = tulokset + "  Ei yötä! \r";
  if ((daylen<23.95) && (daylen>0.05)) {
    hrmn(Nousu);
    tulokset = tulokset + "<br>Aurinko nousee:  " + hs+":"+ms + "<br>";
    hrmn(Lasku);
    tulokset = tulokset + "Aurinko laskee:  " + hs+":"+ms + "<br>";
  } 
  hrmn(twie);

  // Solar radiation power at noon for extinction 0.9 //
  if (kork>0.0) powers = 1370.0*Math.sin(rads*kork)*Math.exp(Math.log(0.9)/Math.sin(rads*kork));
  else  powers = 0.0;

  dgmn(kork);
  return tulokset;

}

function fillzero(x) {
  var s="x";
  var snull = "0";
  if (x<10) s = snull+x; else s=x;
  return s
}

function dgmn(x) {
  var sign = 1; if (x<0.0) {sign = -1; x = Math.abs(x);}
  hh = Math.round(x + 0.0002);
  mm = Math.round((x - hh)*60 + 0.0002);
  if (mm<0.0) {mm+=60; hh-=1;}
  hs =  hh; if (sign<0) hs = "-"+hh;
  ms = fillzero(mm); 
}

function hrmn(x) {
  hs="00"; ms="00";
  if (x>0.0001) { 
  hh = Math.round(x + 0.001);
  mm = Math.round((x - hh)*60 + 0.001);
  if (mm<0.0) {mm+=60; hh-=1;}
  // normalize times to max 24 hours	//
  if (hh>24.0) {hh-= 24};
  if ((hh==24)&&(mm>10)) {hh-= 24};
  hs = fillzero(hh);
  ms = fillzero(mm);}
}