var startLat = 31.98,startLon = 44.32;//Al-najaf
var selectedCity = 19917;//Al-najaf
var qiblaDir;
var map,centerMarker,kabaMarker;
var geocoder;
var line,qline;//qline Is qibla direction
var qiblaLat = 21.42252;
var qiblaLng = 39.82621;
var noWrite = false;//If don't want to write data in new city page
var segmentSize = 200000;//Segment lines

function load() {
  if (GBrowserIsCompatible()) {
    geocoder = new GClientGeocoder()
    
    map = new GMap2(document.getElementById("map"));

    map.setCenter(new GLatLng(startLat,startLon), 5);
    
    map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT));
    map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT));
    
    map.addMapType(G_PHYSICAL_MAP);
    map.addMapType(G_SATELLITE_3D_MAP);
    map.setMapType(G_NORMAL_MAP);
    
    map.addControl(new GScaleControl(), new GControlPosition(G_ANCHOR_BOTTOM_LEFT));
    map.enableDoubleClickZoom();
    keyboardhandler = new GKeyboardHandler(map);
    
    GEvent.addListener(map, 'move', draw);
    
    qiblaDir = -getDirection(startLat, startLon, qiblaLat, qiblaLng);
    
    line = getLine(startLat, startLon, qiblaDir);
    map.addOverlay(line);    
    //writeData(map.getCenter(), qiblaDir);

    qline = getLine(startLat, startLon, qiblaDir,true);
    map.addOverlay(qline);    
    writeData(map.getCenter(), qiblaDir);

    var icon = new GIcon(null, 'img/crosshair.gif');
    icon.iconSize = new GSize(17, 17);
    icon.iconAnchor = new GPoint(8, 8);
    var point = new GLatLng(startLat,startLon);
    centerMarker = new GMarker(point, {icon: icon});
    map.addOverlay(centerMarker);

    icon = new GIcon(null, 'img/kaba.jpg');
    icon.iconSize = new GSize(20, 20);
    icon.iconAnchor = new GPoint(10, 10);
    point = new GLatLng(qiblaLat,qiblaLng);
    kabaMarker = new GMarker(point, {icon: icon});
    map.addOverlay(kabaMarker);
    
    //Init Objects
    document.getElementById("latbox").innerHTML = myRound(startLat);
    document.getElementById("lonbox").innerHTML = myRound(startLon);
  }
}

function draw(){
    var center = map.getCenter();
    var lng = center.lng();
    var lat = center.lat();
    
    document.getElementById("latbox").innerHTML = myRound(lat);
    document.getElementById("lonbox").innerHTML = myRound(lng);
    
    qiblaDir = -getDirection(lat, lng, qiblaLat, qiblaLng);
    
    map.clearOverlays();

    centerMarker.setPoint(center);
    map.addOverlay(centerMarker);
    map.addOverlay(kabaMarker);
    
    if(onMap){
        gmt = gmtRound((lng / 180) * 12);
        document.getElementById('gmt').value = gmt;
    }
    
    if(onMov){
        onMov = false;
        onMap = false;
    }
    else{
        onMap = true;
        onGsr = false;
    }
    
    line = getLine(lat, lng, qiblaDir);
    map.addOverlay(line);

    qline = getLine(lat, lng, qiblaDir,true);
    map.addOverlay(qline);

    writeData(center, qiblaDir);
}

function getLine(lat, lng, angle,qline){
    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 GLatLng(lat, lng);
    var to = new GLatLng(qiblaLat, qiblaLng);
    
    if(qline){
        var lat2 = getLat(lat, angle, dLng)
        var to = new GLatLng(lat2, lng + dLng);
        
        if (Math.abs(dLng) > Math.abs(lng - qiblaLng))
            to = new GLatLng(qiblaLat, qiblaLng);
        var line = new GPolyline([ from, to ], '#FF3333',4);
    }
    else{
        var is3DMap = (getMapType() == 'e');
        //if (extension) extDraw();
        
        var qiblaSegments = is3DMap ? [from, to] : drawArc(from, to);
        var line = new GPolyline(qiblaSegments, '#3333FF',2, 0.8);
    }
    
    return line;
}

function getMapType(){
    return map.getCurrentMapType().getUrlArg();
}

//-------------------------- Cartesian Point -----------------------

// From: Long Distance Measure Google Maplet
// By: Martin Brock

function drawArc(p1, p2){
    var d = p1.distanceFrom(p2);
    if (d > 2 * segmentSize) {
        var P = cartesian(p1);
        var Q = cartesian(p2);
        var PdotQ = P.scalarProduct(Q);
        var w = Q.difference(P.product(PdotQ));
        var Qp = w.product(1.0/w.euclideanNorm());
        var bigAlpha = Math.acos(PdotQ);
        var nSegments = Math.round(d/ segmentSize);
        var dAlphaMax = bigAlpha/ nSegments;
        var dAlpha = dAlphaMax/64;
        var points = [];
        for (alpha = 0; alpha < bigAlpha; alpha += dAlpha) {
            points.push(P.product(Math.cos(alpha)).sum(Qp.product(Math.sin(alpha))).spherical());
            dAlpha = Math.min(dAlphaMax, dAlpha* 2);
        }
        points.push(p2);
    }
    else
        var points = [p1, p2];
    return points;
}

function CartesianPoint(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
}

CartesianPoint.prototype.sum = function(point) {
    return new CartesianPoint(this.x + point.x, this.y + point.y, this.z + point.z);
}

CartesianPoint.prototype.difference = function(point) {
    return new CartesianPoint(this.x - point.x, this.y - point.y, this.z - point.z);
}

CartesianPoint.prototype.scalarProduct = function(point) {
    return this.x*point.x + this.y*point.y + this.z*point.z;
}

CartesianPoint.prototype.product = function(scalar) {
    return new CartesianPoint(this.x*scalar, this.y*scalar, this.z*scalar);
}

CartesianPoint.prototype.euclideanNorm = function() {
    return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
}

// http://en.wikipedia.org/wiki/Spherical_coordinates
CartesianPoint.prototype.spherical = function() {
    var phi = Math.acos(this.z);
    var sinPhi = Math.sin(phi);
    var theta = Math.atan2(this.y/sinPhi, this.x/sinPhi);
    var degreesPerRadian = 180/Math.PI;
    return new GLatLng(degreesPerRadian*(Math.PI/2 - phi), degreesPerRadian*theta);
}

function cartesian(point) {
    var phi = Math.PI/2 - point.latRadians();
    var theta = point.lngRadians();
    return new CartesianPoint(Math.sin(phi)*Math.cos(theta), Math.sin(phi)*Math.sin(theta), Math.cos(phi));
}

// Draw line codes

function writeData(center, qiblaDir){
    if(noWrite) return;
    
    var kaba = new GLatLng(qiblaLat, qiblaLng);

    if (qiblaDir < 0) qiblaDir += 360;
    document.getElementById("direction").innerHTML = myRound(qiblaDir);
    document.getElementById("distance_km").innerHTML = myRound(center.distanceFrom(kaba,6378137)/ 1000);
    document.getElementById("distance_ml").innerHTML = myRound(center.distanceFrom(kaba,6378137)/ 1609.344);
}

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

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

function dtr(d){
    return (d* Math.PI)/ 180.0;
}

function rtd(r){
    return (r* 180.0)/ Math.PI;
}

function moveToPos(lat, lng)
{
    var home = new GLatLng(lat, lng);
    document.getElementById("latbox").innerHTML = myRound(lat);
    document.getElementById("lonbox").innerHTML = myRound(lng);
    onMov = true;
    
    if(typeof map != "undefined"){
        map.setCenter(home);
    }
}

function moveToCity(cityname) {
  var quds = Array('فلسطين','قدس','القدس','فلسطين','palestine','qods','quds','al-qods','al-quds','بيت المقدس','بيت المقدس','فلسطين, القدس');
  for(i = 0;i < quds.length;i++){
    if(cityname.indexOf(quds[i]) > -1){
      moveToPos(31.7857, 35.2007);
      return;
    }
  }

  geocoder.getLatLng(cityname,
    function(point){
      if(!point){
        alert('' + cityname + ' '+ lang['not_found']);
      }
      else{
        onMap = true;
        onGsr = true;
        moveToPos(point.y, point.x)
      }
    }
  );

}

function myRound(num){
    num *= 10000;
    num = Math.round(num);
    num /= 10000;
    return num;
}
