/* gmaphz.js
   HZ Specific Google Maps Implementation
   By: Ranqthas Clawfoot
   July, 2008
*/


// this will become the G2map.
var map;
var manager;

// Let's describe our zoom levels
var zoomParams = new Array();

// zoomParams[zoom level]['scale'] = meters/px
// zoomParams[zoom level]['heightpx'] = height of map in px
// zoomParams[zoom level]['tilesx'] = width of map in tiles
// zoomParams[zoom level]['tilesy'] = height of map in tiles

zoomParams[0] = new Array();
zoomParams[0]['scale'] = 125/4.0;
zoomParams[0]['heightpx'] = 880;
zoomParams[0]['tilesx'] = 3;
zoomParams[0]['tilesy'] = 4;
zoomParams[0]['mpp'] = 32;

zoomParams[1] = new Array();
zoomParams[1]['scale'] = 125/8.0;
zoomParams[1]['heightpx'] = 1760;
zoomParams[1]['tilesx'] = 5;
zoomParams[1]['tilesy'] = 7;
zoomParams[1]['mpp'] = 16;

zoomParams[2] = new Array();
zoomParams[2]['scale'] = 125/16.0;
zoomParams[2]['heightpx'] = 3520;
zoomParams[2]['tilesx'] = 9;
zoomParams[2]['tilesy'] = 14;
zoomParams[2]['mpp'] = 8;
 
zoomParams[3] = new Array();
zoomParams[3]['scale'] = 125/32.0;
zoomParams[3]['heightpx'] = 7040;
zoomParams[3]['tilesx'] = 18;
zoomParams[3]['tilesy'] = 28;
zoomParams[3]['mpp'] = 4;
 
zoomParams[4] = new Array();
zoomParams[4]['scale'] = 125/64.0;
zoomParams[4]['heightpx'] = 14080;
zoomParams[4]['tilesx'] = 36;
zoomParams[4]['tilesy'] = 55;
zoomParams[4]['mpp'] = 2;
 
zoomParams[5] = new Array();
zoomParams[5]['scale'] = 125/128.0;
zoomParams[5]['heightpx'] = 28160;
zoomParams[5]['tilesx'] = 72;
zoomParams[5]['tilesy'] = 110;
zoomParams[5]['mpp'] = 1;




// I can't believe theres no printf() function in javascript!!
function zeropad(n){
  r = n.toString();
  dc = r.length;
  while(dc < 4){
    r = '0' + r;
    dc++;
  }
  return r;
}


// make a marker, return it.  
function newmark(userx,usery,detail,title,icon){
  //var form = document.gmcoords;
  //var x = form.xcoord.value;
  //var y = form.ycoord.value;
  var x = userx;
  var y = usery;

  // input checking.
  var errstr = '';

  // is the input a number?
  if(isNaN(x)){ errstr += "X coordinate must be a number\n";}
  if(isNaN(y)){ errstr += "Y coordinate must be a number\n";}

  // is the input in bounds?
  if(!isNaN(x) && !( x >= 13500 && x <= 31500)){
    errstr += "X coordinate is out of bounds [13500,31500]\n";
  }
  if(!isNaN(y) && !( y >= 13000 && y <= 40000)){
    errstr += "Y coordinate is out of bounds [13000,40000]\n";
  }

  // any trouble?
  if(errstr.length > 0){ alert(errstr); return;}

  // now let's make a marker!
  var loc = new GLatLng(y,x,true);
  var mark = new GMarker(loc,{title:title,icon:icon});

  mark.bindInfoWindowHtml(detail);
  return mark;
}

// Plop down a marker.  This will get changed later
function addmark(userx,usery){
  //var form = document.gmcoords;
  //var x = form.xcoord.value;
  //var y = form.ycoord.value;
  var x = userx;
  var y = usery;

  // input checking.
  var errstr = '';

  // is the input a number?
  if(isNaN(x)){ errstr += "X coordinate must be a number\n";}
  if(isNaN(y)){ errstr += "Y coordinate must be a number\n";}

  // is the input in bounds?
  if(!isNaN(x) && !( x >= 13500 && x <= 31500)){
    errstr += "X coordinate is out of bounds [13500,31500]\n";
  }
  if(!isNaN(y) && !( y >= 13000 && y <= 40000)){
    errstr += "Y coordinate is out of bounds [13000,40000]\n";
  }

  // any trouble?
  if(errstr.length > 0){ alert(errstr); return;}

  // now let's make a marker!
  var loc = new GLatLng(y,x,true);
  var mark = new GMarker(loc,{title:"Custom point"});

  map.addOverlay(mark);
  map.setCenter(loc);
  mark.bindInfoWindowHtml("<b>Your Marker</b><br><tt>X: " + x + "<br>Y: " + y + "</tt>");
}



// custom projection
// for now, lets do 8 meters/pixel
// from NW(13500,41000) to SE(31500,13000)
// yes, the N/S direction is flipped :(
// pixel dims are 2250x3500
function HZProjection(){ }
HZProjection.prototype = new GProjection();

HZProjection.prototype.fromLatLngToPixel = function(latlng,zoom){
  var px = 0;
  var py = 0;
  var latadj = latlng.lat() - 13500;
  var lngadj = latlng.lng() - 13500;
  var scalefac = 0;
  var mapheight = 0;
        
  // gah! I f'd up my map.
  if(zoom >= 4) latadj = latlng.lat() - 13000;

  if(zoom > 5) zoom = 5;
  scalefac = zoomParams[zoom]['scale'];
  mapheight = zoomParams[zoom]['heightpx'];
        
  px =  lngadj / scalefac;
  py =  mapheight - (latadj / scalefac);
  //alert("lat/lng -> y/x " + latlng.lat() + "/" + latlng.lng() + "->" + py + "/" +px);
  //return new GPoint(Math.round(px),Math.round(py));
  return new GPoint(Math.floor(px),Math.floor(py));

}


// undo the above
HZProjection.prototype.fromPixelToLatLng = function(pixel,zoom,unbounded){
   
  var lng = 0;
  var lat = 0;

  var scalefac = 0;
  var mapheight = 0;

  if(zoom > 5) zoom = 5;
  scalefac = zoomParams[zoom]['scale'];
  mapheight = zoomParams[zoom]['heightpx'];
        

  lng = (pixel.x * scalefac) + 13500;
  lat = ((mapheight - pixel.y) * scalefac) + 13000;
  //alert("px/py -> lng/lat " + pixel.x + "/" + pixel.y + "->" + lng + "/" + lat);
  return new GLatLng(lat,lng,true);

}


// geezus, i wish these arguments were better documented.
// tilesize is the size of the edge of a tile (they're square), 256
// zoom is the zoom level
// tile.x, tile.y are the indexes (the same used in getTileUrl)
HZProjection.prototype.tileCheckRange = function(tile,zoom,tilesize){
  var maxx = zoomParams[zoom]['tilesx'];
  var maxy = zoomParams[zoom]['tilesy'];
  //alert(tile.x + "/" + tile.y + "? " + maxx + "/" + maxy + " " + zoom);
  if( tile.x >= 0 && tile.x < maxx && tile.y >=0 && tile.y < maxy){
    //  alert(tile.x + "/" + tile.y + " OK");
    return true;
  }
  else return false;

}


HZProjection.prototype.getWrapWidth= function(zoom){
  // docs say Infinity is the right value
  // but that causes the markers to get pushed to the far left of 
  // the viewport.  Buh?!
  return 99999999;
}
 

// now the tile set
var tilelayers = [new GTileLayer(GCopyrightCollection("Test"),0,5)];
tilelayers[0].getTileUrl = function(a,b){

  var i = 0;
  var mpp = 0;
  var reqstr = "http://tiles.bristugo.com/istaria/";

  i = (a.y * zoomParams[b]['tilesx']) + a.x;
  mpp = zoomParams[b]['mpp'];

  reqstr += b + "/Istaria_" + mpp + "_" + zeropad(i) + ".jpg";
  return reqstr;

}


// and to keep you from panning off the side. (broken)
function checkBounds(){
  // crap, GLatLngBounds doesn't work for non-bounded GLatLngs
  
  // doin this manually.  Where's the center?
  var C = map.getCenter();
  var X = C.lng();
  var Y = C.lat() + 500;

  var AmaxX = 31500;
  var AmaxY = 40000;
  var AminX = 13500;
  var AminY = 13000;
        
  if( X <= AmaxX && X >= AminX && Y <= AmaxY && Y >= AminY){ return; }

  if(X < AminX) { X = AminX; }
  if(X > AmaxX) { X = AmaxX; }
  if(Y < AminY) { Y = AminY; }
  if(Y > AmaxY) { Y = AmaxY; }
  map.setCenter(new GLatLng(Y,X,true));

}

// let's define some custom icons here.

// dragon lair
var IconLair = new GIcon(G_DEFAULT_ICON,'http://bristugo.com/local/mapsupp/dragon2.png');
IconLair.shadow = "http://bristugo.com/local/mapsupp/shadow.png";
IconLair.iconSize = new GSize(30,40);
IconLair.shadowSize = IconLair.iconSize;
IconLair.iconAnchor = new GPoint(15,34);
IconLair.infoWindowAnchor = new GPoint(15,34);
IconLair.printImage = IconLair.image;
IconLair.mozPrintImage = IconLair.image;
IconLair.imageMap = [5,5, 25,5, 25,21, 15,35, 5,21, 5,5];

// biped plot
var IconPlot = new GIcon(IconLair,'http://bristugo.com/local/mapsupp/individual.png');

// guild community
var IconGuild = new GIcon(IconLair,'http://bristugo.com/local/mapsupp/guild.png');

// community
var IconCommunity = new GIcon(IconLair,'http://bristugo.com/local/mapsupp/community.png');
