function calculatePrayerTimes( longitude, latitude, timeZone, height, gd, gn, J )
{
  //double d, t, r, g, beta, z, u, vd, vn, w;
  //int
  Sh = 1;
  beta = 2 * Math.PI * J / 365;
  d = ( 180 / Math.PI )
      * ( 0.006918 - 0.399912 * Math.cos( beta ) + 0.070257 * Math.sin( beta )
          - 0.006758 * Math.cos( 2 * beta ) + 0.000907 * Math.sin( 2 * beta )
          - 0.002697 * Math.cos( 3 * beta ) + 0.001480 * Math.sin( 3 * beta ) );
  t = 229.18 * ( 0.000075 + 0.001868 * Math.cos( beta ) - 0.032077
      * Math.sin( beta ) - 0.014615 * Math.cos( 2 * beta ) - 0.040849 * Math
      .sin( 2 * beta ) );
  r = 15 * timeZone;
  g = 18;
  z = 12 + ( r - longitude ) / 15 - t / 60;
  u = 180 / ( 15 * Math.PI )
      * Math.acos( ( Math.sin( ( -0.833 - 0.0347 * sign( height )
          * Math.sqrt( height * sign( height ) ) )
          * Math.PI / 180 ) - Math.sin( d * Math.PI / 180 )
          * Math.sin( latitude * Math.PI / 180 ) )
          / ( Math.cos( d * Math.PI / 180 ) * Math.cos( latitude * Math.PI
              / 180 ) ) );
  vd = 180
      / ( 15 * Math.PI )
      * Math.acos( ( -1 * Math.sin( gd * Math.PI / 180 ) - Math.sin( d
          * Math.PI / 180 )
          * Math.sin( latitude * Math.PI / 180 ) )
          / ( Math.cos( d * Math.PI / 180 ) * Math.cos( latitude * Math.PI
              / 180 ) ) );
  vn = 180
      / ( 15 * Math.PI )
      * Math.acos( ( -1 * Math.sin( gn * Math.PI / 180 ) - Math.sin( d
          * Math.PI / 180 )
          * Math.sin( latitude * Math.PI / 180 ) )
          / ( Math.cos( d * Math.PI / 180 ) * Math.cos( latitude * Math.PI
              / 180 ) ) );
  w = 180
      / ( 15 * Math.PI )
      * Math.acos( ( Math.sin( Math.atan( 1 / ( Sh + Math.tan( Math
          .abs( latitude - d )
          * Math.PI / 180 ) ) ) ) - Math.sin( d * Math.PI / 180 )
          * Math.sin( latitude * Math.PI / 180 ) )
          / ( Math.cos( d * Math.PI / 180 ) * Math.cos( latitude * Math.PI
              / 180 ) ) );
 
  var prayerTimes = new Array( 6 );
  prayerTimes[0] = z - vd;
  prayerTimes[1] = z - u;
  prayerTimes[2] = z;
  prayerTimes[3] = z + w;
  prayerTimes[4] = z + u;
  prayerTimes[5] = z + vn;
  return prayerTimes;
}
function sign( number )
{
  if( number < 0 )
    return -1;
 //if( number > 0 )
  return 1;
}
/*
Convert from
1.5 to 1:30
*/
function hourToString( doubleHour )
{
  // Get the hour integer part
  hour = Math.floor( doubleHour );
  doubleHour -= hour;
 
  // Get minutes
  doubleHour *= 60;
  minute = Math.floor( doubleHour );
 
  var ap = "am";
  if( hour   > 11 ) { ap = "pm";             }
  if( hour   > 12 ) { hour = hour - 12;      }
  if( hour   == 0 ) { hour = 12;             }
  if( hour   < 10 ) { hour   = "0" + hour;   }
  if( minute < 10 ) { minute = "0" + minute; }
 
  // Get seconds
  // doubleHour -= minute;
  // doubleHour *= 60;
  // this.second = Math.abs( hour );
  timeString = hour + ":" + minute + ap;
 
  return timeString;
}
var MONTH_DAYS = new Array( 12 );
MONTH_DAYS[0] = 31;
MONTH_DAYS[1] = 28;
MONTH_DAYS[2] = 31;
MONTH_DAYS[3] = 30;
MONTH_DAYS[4] = 31;
MONTH_DAYS[5] = 30;
MONTH_DAYS[6] = 31;
MONTH_DAYS[7] = 31;
MONTH_DAYS[8] = 30;
MONTH_DAYS[9] = 31;
MONTH_DAYS[10] = 30;
MONTH_DAYS[11] = 31;
 
function getYearDay( day )
{
  days = 0;
  for( i=0 ; i<day.getMonth() ; ++i )
  {
    if( i != 2 )
      days += MONTH_DAYS[i];
    else
    {
      // Special check for February
      if( day.getYear() % 4 == 0 )
        days = days + 29;
      else
        days = days + 28;
    }
  }
  days += day.getDate();
  return days;
}

//---------------------------------------------------------
/* 

*/
//--------------------------- Globals -----------------------------
var qiblaLat = 21.42252;
var qiblaLng = 39.82621; 
var addrEmptyMsg = 'Enter address or zipcode';
var map, geocoder, centerMarker;
//--------------------------- Initialize -----------------------------
// initialization function
function init(startAddr, startLat, startLng, startZoom){
	if (!GBrowserIsCompatible())
		return;
	new Accordian('accordian',3,'selected');
	if (!startAddr) startAddr = '';
	if (!startLat) startLat = -6.1698;
	if (!startLng) startLng = 106.8308;
	if (!startZoom) startZoom = 15;
	map = new GMap2(document.getElementById('map'));
	geocoder = new GClientGeocoder();
	var home = new GLatLng(startLat, startLng);
	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
	map.addControl(new GScaleControl());
	map.setCenter(home, startZoom,G_SATELLITE_MAP);
	var icon = new GIcon(null, 'images/crosshair.gif');
	icon.iconSize = new GSize(17, 17);
	icon.iconAnchor = new GPoint(8, 8);
	centerMarker = new GMarker(home, {icon: icon, clickable: false});
	GEvent.addListener(map, 'move', mapDraw);
	document.getElementById('address').value = startAddr;
	leaveAddressBar();
	mapDraw();
}
//------------------------- Map Functions -----------------------------
// update map 
function mapDraw(){
	var center = map.getCenter();
	var lng = center.lng();
	var lat = center.lat();
	var qiblaDir = -getDirection(lat, lng, qiblaLat, qiblaLng);
	map.clearOverlays();
	centerMarker.setPoint(center);
	map.addOverlay(centerMarker);
	var line = getLine(lat, lng, qiblaDir);
	map.addOverlay(line);	
	writeData(center, qiblaDir);
}
//write information
function writeData(center, qiblaDir){
	var kaba = new GLatLng(qiblaLat, qiblaLng);
	//checkunit();
	//var distance = center.distanceFrom(kaba)/ 1000; 
	if (qiblaDir < 0) qiblaDir += 360;
	writeItem('curLng', center.lng().toFixed(4));
	writeItem('curLat', center.lat().toFixed(4));						
	writeItem('direction', qiblaDir.toFixed(2)+ '&deg;&nbsp;N');	
	if (document.getElementById('units').checked)	{
		var converter = 1609.344;   //miles
		var distance = center.distanceFrom(kaba)/ converter; 
		writeItem('distance', distance.toFixed(0)+ '&nbsp;mi');	
	}	else {
		var converter = 1000;     //kilometers
		var distance = center.distanceFrom(kaba)/ converter; 
		writeItem('distance', distance.toFixed(0)+ '&nbsp;km');	
	}
	var timeZone=center.lng()/15;
  var prayerTimesArray = calculatePrayerTimes(center.lng(),center.lat(),timeZone,0,20,18,getYearDay(new Date()));
  writeItem('adzShubuh',hourToString(prayerTimesArray[0]));
  writeItem('adzDhuhur',hourToString(prayerTimesArray[2]));
  writeItem('adzAshar',hourToString(prayerTimesArray[3]));
  writeItem('adzMaghrib',hourToString(prayerTimesArray[4]));
  writeItem('adzIsya',hourToString(prayerTimesArray[5]));
}
//update a data item
function writeItem(itemID, value){
	document.getElementById(itemID).innerHTML = value;
}
// create a direction line
function getLine(lat, lng, angle){
	var factor = 8;
	var zoom = map.getZoom();
	var dLng = factor/ Math.pow(2, zoom- 7);
	if (zoom < 7) dLng = factor;
	dLng = dLng* Math.sin(dtr(angle));
	var from = new GPoint(lng, lat);
	var lat2 = getLat(lat, angle, dLng)
	var to = new GPoint(lng+ dLng, lat2);
	if (Math.abs(dLng) > Math.abs(lng- qiblaLng))
		to = new GPoint(qiblaLng, qiblaLat);
	var line = new GPolyline([ from, to ], '#FF0000', 4);
	return line;
}
//-------------------------- Calculating Functions -----------------------
// definitions:
// point1 = (lat1, lng1), point2 = (lat2, lng2)
// dLng = lng1- lng2
// direction = angle of the line connecting point1 to point2 (CW from North)
// find the direction
function getDirection(lat1, lng1, lat2, lng2){
	var dLng = lng1- lng2;
	return rtd(getDirectionRad(dtr(lat1), dtr(lat2), dtr(dLng)));
}
function getDirectionRad(lat1, lat2, dLng){
	return Math.atan2(Math.sin(dLng), Math.cos(lat1)* Math.tan(lat2)- Math.sin(lat1)* Math.cos(dLng));
}
// find lat2 for a given direction
function getLat(lat1, angle, dLng){
	return rtd(getLatRad(dtr(lat1), dtr(angle), dtr(dLng)));
}
function getLatRad(lat1, angle, dLng){
	return Math.atan((Math.sin(dLng)+ Math.tan(angle)* Math.sin(lat1)* Math.cos(dLng))/ (Math.tan(angle)* Math.cos(lat1)));
}
//-------------------------- Angle Unit Conversion -----------------------
// degree to radian
function dtr(d){
    return (d* Math.PI)/ 180.0;
}
// radian to degree
function rtd(r){
    return (r* 180.0)/ Math.PI;
}
//-------------------------- Geocoder Functions -----------------------
// locate address
function locateAddress() {
	var address = document.getElementById('address').value;
	if (address == '' || address == addrEmptyMsg)
	{
		alert(addrEmptyMsg);
		return;
	}
	geocoder.getLocations(address, showAddressOnMap);
}
// show address on map
function showAddressOnMap(response) {
	if (!response || response.Status.code != 200) 
		alert('Address not found');
	else {
		place = response.Placemark[0];
		point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
		map.setCenter(point, 8+ place.AddressDetails.Accuracy);
		marker = new GMarker(point);
		map.addOverlay(marker);
		marker.openInfoWindowHtml(place.address);
	}
}
//-------------------------- Misc Functions  -----------------------
// called when address bar is focused
function focusAddressBar(){
	var address = document.getElementById('address');
	address.style.color = '#000000';
	if (address.value == addrEmptyMsg)
		address.value = '';
}
// called when address bar lose focus
function leaveAddressBar(){
	var address = document.getElementById('address');
	if (address.value == '' || address.value == addrEmptyMsg)
	{
		address.style.color = '#999999';
		address.value = addrEmptyMsg;
	}
}
//distance mile/km selector
function  checkunit() {
   if (document.dUnit.unit[0].checked==true) converter = 1609.344;   //miles
   if (document.dUnit.unit[1].checked==true) converter = 1000;     //kilometers
}
// toggle hidden element
function toggle( targetId ) {
   if ( document.getElementById ) {
    target = document.getElementById( targetId );
    if ( target.style.display == "none" ) {
     target.style.display = "";
    } else {
     target.style.display = "none";
    }
   }
}
/*
double longitude
double latitude
double timeZone
double height
double gd
double gn
int yearDay;
*/
