//---------------------------------------------------------
/* 
QiblaLocator v0.8.10

Original code 
By: ibnMasud

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 ipcity = geoip_city();
//var ipregion = geoip_region();
//var ipcountry = geoip_country_name();


var addrEmptyMsg = 'Enter address, zipcode, country or lat,lon';
var map, geocoder, centerMarker;
var kaba = new GLatLng(qiblaLat, qiblaLng);


//--------------------------- Initialize -----------------------------


// initialization function
function init(startAddr, startLat, startLng, startZoom)
{
	if (!GBrowserIsCompatible())
		return;

	//new Accordian('accordian',3,'selected');
	if (!startAddr) startAddr = '';
	if (!startLat) startLat = 30.6186;
	if (!startLng) startLng = -96.3361;
	if (!startZoom) startZoom = 11;

	//startLat = geoip_latitude();
	//startLng = geoip_longitude();

        startLng = parseFloat(geoip_longitude());
        startLat = parseFloat(geoip_latitude());


	var params = {};
	try 
	{
		var paramsArr = String(document.location).split('?')[1].split('&');
		for (var i = 0; i < paramsArr.length; ++i) {
			var p = paramsArr[i].split('=');
			params[p[0]] = p[1];
		}
	}
	catch (e) {}				

				
	startLat = (params['latitude'] ? parseFloat(params['latitude']) : startLat);
	startLng = (params['longitude'] ? parseFloat(params['longitude']) : startLng);
	startZoom = (params['zoom'] ? parseInt(params['zoom']) : startZoom);
	startAddr = (params['address'] ? params['address'] : startAddr);

	initSize();
	map = new GMap2(document.getElementById('map'));
	geocoder = new GClientGeocoder();
	var home = new GLatLng(startLat, startLng);

//	map.addControl(new GLargeMapControl());
//	map.addControl(new GMenuMapTypeControl());
//	map.addMapType(G_PHYSICAL_MAP); 
//	map.addMapType(G_SATELLITE_3D_MAP);
//	map.addControl(new GScaleControl());
	addMapControls();
	map.setCenter(home, startZoom);

	var xhair = new GIcon(null, 'http://apps.qiblalocator.com/images/crosshair.gif');
	xhair.iconSize = new GSize(17, 17);
	xhair.iconAnchor = new GPoint(8, 8);
	centerMarker = new GMarker(home, {icon: xhair, clickable: false});


	GEvent.addListener(map, 'move', mapDraw);
	document.getElementById('roundRect').value = startAddr;
	leaveAddressBar();
	mapDraw();
	//GEvent.addDomListener(map, 'resize', checkResize());

}


//------------------------- Map Functions -----------------------------

// adds map controls. To add: map control size based on window size.
function addMapControls()
{
	map.addControl(new GSmallMapControl());
	map.addControl(new GMenuMapTypeControl());
	map.addMapType(G_PHYSICAL_MAP); 
	map.addMapType(G_SATELLITE_3D_MAP);
	//map.addControl(new GScaleControl());
}

// update map 
function mapDraw()
{
	var center = map.getCenter();
	//var zoom = map.getZoom();
	var lng = center.lng();
	var lat = center.lat();
	var qiblaDir = -getDirection(lat, lng, qiblaLat, qiblaLng);
	//map.setCenter(center, zoom);
	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)
{
	if (qiblaDir < 0) qiblaDir += 360;
        var long = center.lng();
        var lati = center.lat();
        var longf = long.toFixed(4);
        var latif = lati.toFixed(4);
			
	writeItem('direction', qiblaDir.toFixed(2)+ '&deg ');	
	/*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');	
	}*/
}



//update a data item
function writeItem(itemID, value)
{
	document.getElementById(itemID).innerHTML = value;
}


// create a direction line
function getLine(lat, lng, angle)
{
	var factor = 7;
	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;
}

// called when window is resized
// initial map size
function initSize()	
{
		var h = getEDim("header").height+ getEDim("footer").height;
		height = getWinDim().height- h;
		$("map").style.height = height+ 'px';
		$("footer").style.width = getWinDim().width+ 'px';
		return height;
}


// called to reset map size on window resize
function checkResize()	
{	
		initSize();
		mapDraw();
}


function getWinDim() 
{
	var myWidth = 0, myHeight = 0;

	if( typeof( window.innerWidth ) == 'number' ) 
	{ 	//Non-IE
		myWidth = window.innerWidth;
		myHeight = window.innerHeight;
	} 
	else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) 
	{	//IE 6+ in 'standards compliant mode'
		myWidth = document.documentElement.clientWidth;
		myHeight = document.documentElement.clientHeight;
	} 
	else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) 
	{	//IE 4 compatible
		myWidth = document.body.clientWidth;
		myHeight = document.body.clientHeight;
	}
//	alert('width: '+myWidth +', height: '+ myHeight);
	return {width: myWidth, height: myHeight};
}

function getEDim(element)
{
	element = $(element);
	var display = element.style.display;
	if (display != 'none' && display != null) // Safari bug
		return {width: element.offsetWidth, height: element.offsetHeight};
	var els = element.style;
	var originalVisibility = els.visibility;
	var originalPosition = els.position;
	var originalDisplay = els.display;
	els.visibility = 'hidden';
	els.position = 'absolute';
	els.display = 'block';
	var originalWidth = element.clientWidth;
	var originalHeight = element.clientHeight;
	els.display = originalDisplay;
	els.position = originalPosition;
	els.visibility = originalVisibility;
	return {width: originalWidth, height: originalHeight};
}

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1) 
      return element;

    elements.push(element);
  }

  return elements;
}

//-------------------------- 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('roundRect').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('roundRect');

	address.style.color = '#000000';
	if (address.value == addrEmptyMsg)
		address.value = '';
}


// called when address bar lose focus
function leaveAddressBar()
{
	var address = document.getElementById('roundRect');

	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";
    }
   }
}

// generate share-able link
function shareLink()

{
	var center = map.getCenter();
	var lng = center.lng().toFixed(4);
	var lat = center.lat().toFixed(4);
	var zoom = map.getZoom();

	var link = document.getElementById('sharelink');
	link.value = 'http://www.qiblalocator.com/?latitude=' + lat + '&longitude=' + lng + '&zoom=' + zoom;
}
