
//---------------------------------------------------------
/* 
QiblaLocator v0.8.10

Original code 
By: ibnMasud

Edited with permission:
By: Mutoha Arkanuddin

Code cleanup and bug-fix
By: Hamid Zarrabi-Zadeh

Fixes a critical bug in showing qibla direction line
*/


//--------------------------- Globals -----------------------------

var qiblaLat = 21.42252;
var qiblaLng = 39.82621; 

var addrEmptyMsg = 'Ketik lokasi yang diinginkan..';
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 = -7.77365;
	if (!startLng) startLng = 110.380624;
	if (!startZoom) startZoom = 18;
	


	map = new GMap2(document.getElementById('map'));
	map.setMapType(G_SATELLITE_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);

	var icon = new GIcon(null, 'images/crosshair.gif');
	icon.iconSize = new GSize(200, 200);
	icon.iconAnchor = new GPoint(100, 100);
	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;

	
        var latAbs=Math.abs(Math.round(center.lat()*1000000))
	var lat1= Math.floor(latAbs / 1000000)
	var lat2= Math.floor(((latAbs/1000000) - Math.floor(latAbs/1000000)) * 60)
     	var lat3= (Math.floor(((((latAbs/1000000) - Math.floor(latAbs/1000000)) * 60) - Math.floor(((latAbs/1000000) - Math.floor(latAbs/1000000)) * 60)) * 100000) *60/100000 )
     
        if (center.lat() < 0) 
  	writeItem('curLatdms', lat1+ '&deg;'+lat2+'\''+lat3.toFixed(0)+'&quot;&nbsp;LS');
	else
 	writeItem('curLatdms', lat1+ '&deg;'+lat2+'\''+lat3.toFixed(0)+'&quot;&nbsp;LU'); 


	if (center.lat() < 0) 
  	writeItem('curLatdec', Math.abs(center.lat()).toFixed(5)+ '&deg;&nbsp;LS');
	else  
        writeItem('curLatdec', center.lat().toFixed(5)+ '&deg;&nbsp;LU');
               








        var longAbs=Math.abs(Math.round(center.lng()*1000000))
	var long1= Math.floor(longAbs / 1000000)
	var long2= Math.floor(((longAbs/1000000) - Math.floor(longAbs/1000000)) * 60)
     	var long3= (Math.floor(((((longAbs/1000000) - Math.floor(longAbs/1000000)) * 60) - Math.floor(((longAbs/1000000) - Math.floor(longAbs/1000000)) * 60)) * 100000) *60/100000 )
     
        if (center.lng() < 0) 
  	writeItem('curLngdms', long1+ '&deg;'+long2+'\''+long3.toFixed(0)+'&quot;&nbsp;BB');
	else
 	writeItem('curLngdms', long1+ '&deg;'+long2+'\''+long3.toFixed(0)+'&quot;&nbsp;BT'); 


        if (center.lng() < 0) 
  	writeItem('curLngdec', Math.abs(center.lng().toFixed(5))+ '&deg;&nbsp;BB');
	else  
        writeItem('curLngdec', center.lng().toFixed(5)+ '&deg;&nbsp;BT');
     



				
	writeItem('direction0', qiblaDir.toFixed(2)+ '&deg;');
	
        

	var dirAbs=Math.abs(Math.round(qiblaDir*1000000))
	var dir1= Math.floor(dirAbs / 1000000)
	var dir2= Math.floor(((dirAbs/1000000) - Math.floor(dirAbs/1000000)) * 60)
     	var dir3= (Math.floor(((((dirAbs/1000000) - Math.floor(dirAbs/1000000)) * 60) - Math.floor(((dirAbs/1000000) - Math.floor(dirAbs/1000000)) * 60)) * 100000) *60/100000 )
      	writeItem('direction1', dir1+ '&deg;'+dir2+'\''+dir3.toFixed(0)+'&quot;&nbsp;'); 

	

	

	var qiblaDir2=360-qiblaDir				
	writeItem('direction2', qiblaDir2.toFixed(2)+ '&deg;');


	var qiblaDir3=qiblaDir-270
 if (qiblaDir3 < 0) 
        writeItem('direction3', (qiblaDir3+360).toFixed(2)+ '&deg;');
	else  				
	writeItem('direction3', qiblaDir3.toFixed(2)+ '&deg;');









	if (document.getElementById('units').checked)
	{
		var converter = 1609.344;   //miles
		var distance = center.distanceFrom(kaba)/ converter; 
		writeItem('distance', distance.toFixed(2)+ '&nbsp;mil');	
	}
	else {
		var converter = 1000;     //kilometers
		var distance = center.distanceFrom(kaba)/ converter; 
		writeItem('distance', distance.toFixed(2)+ '&nbsp;km');	
	}



	var simpang=0.017455064*distance
				
	writeItem('simpang', simpang.toFixed(2)+ '&nbsp;km');









}


//update a data item
function writeItem(itemID, value)
{
	document.getElementById(itemID).innerHTML = value;
}


// create a direction line
function getLine(lat, lng, angle)
{
	var factor = 10;
	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 ], '#FF0066', 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('Lokasi tidak ditemukan..!');
	else 
	{
		place = response.Placemark[0];
		point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
		map.setCenter(point, 4+ 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";
    }
   }
}