
// global vars ////////////////////////////////////////////////////////////////

// 情報パネル文字列
// 角度：angle, 距離：distance, 方位：direction, 自宅：home
var mapinfo = new Object();

// 赤道半径(m)
var er = 6378.137;

var ua = new Object(); // UserAgent

var cookie = new Array();

var geocode; // ジオコーディング

var init; // true, false

var map;

var pointCenter; // @point

var pointMyhome; // @point

// マーカー
var markerCenter = new Object();
var marker_list = new Object();

// 追っかけ線カラー
var lineHome2Center = {color:'#666666', weight:2, opacity:0.5, points:[]};

// センターアイコン
var icnCenter = {src:'./img/gmap/cp.png', width:12, height:12, anchor_x:6, anchor_y:6};

// 自宅アイコン
var icnHome = {src:'./img/gmap/cp.png', width:16, height:16, anchor_x:8, anchor_y:8, transparent:'home.png'};

// 方位線
var lineHoi3060 = {degree:[15, 75, 105, 165, 195, 255, 285, 345], color:"#1b1f79", size:5, opacity:0.5, polylines:[], points:[]};
var lineHoi45 = {degree:[45, 135, 225, 315], color:"#1b1f79", size:2, opacity:0.5, polylines:[], points:[]};
var lineEhou = {degree:[85, 175, 265, 355], color:"#ff0000", size:2, opacity:0.5, polylines:[], points:[]};

// global vars // end /////////////////////////////////////////////////////////

// GMap Control ///////////////////////////////////////////////////////////////

/** 
	方位線を表示
	@notes    call from UI
 */
function UI_drawHoiLine() {
//GLog.write('UI_drawHoiLine()');
	if($("disp_line360").checked) {
		clearHoiLine();
		drawHoiLine(lineHoi3060);
		drawHoiLine(lineHoi45);
		drawHoiLine(lineEhou);
	}else{
		clearHoiLine();
	}
	reloadMapinfo();
}

function drawHoiLine(line) {
	var deg = line.degree;
	for (i=0; i<deg.length; i++) {
		_drawHoiLine(i, deg[i], line);
	}
}
function _drawHoiLine(idx, deg, line){
	line.points = [];
	setPoints360(0, deg, line);
	for(var i=1; i<100; i++){
		setPoints360(er*Math.PI/100*i, deg, line);
	}
	line.polylines[idx] = new GPolyline(line.points, line.color, line.size, line.opacity);
	map.addOverlay(line.polylines[idx]);
}

function clearHoiLine(){
	_clearHoiLine(lineHoi3060);
	_clearHoiLine(lineHoi45);
	_clearHoiLine(lineEhou);
}
function _clearHoiLine(line) {
	for (var i=0; i<line.polylines.length; i++) {
		map.removeOverlay(line.polylines[i]);
	}
}


function drawCenterPoint() {
	var tmp_str = "";
	var vflg = (ua.Opera != true) ? "display: none;" : "visibility: hidden;";
	var opt = "position: absolute; z-index:101; width:12px; height:12px; " + vflg + " ";
	if(ua.MSIE && ua.MSIE < 7.0){
		//GLog.write("ie:"+ua.MSIE);
		opt    += " filter :progid:DXImageTransform.Microsoft.AlphaImageLoader(src='./img/gmap/cp.png',sizingmethod=image);"
		tmp_str = "<div id=\"cpicon\" style=\"" + opt + "\"></div>\n";
	} else {
		//GLog.write("ie:"+ua.MSIE);
		tmp_str = "<img id=\"cpicon\" src=\"./img/gmap/cp.png\" width=12 height=12 alt=\"\" style=\"" + opt + "\" />\n";
	}
	$('cptmp').innerHTML = tmp_str;
}

function redrawCenterPoint() {
	var x = String($('map').offsetLeft + (($('map').offsetWidth  - 98) / 2)) + "px";
	var y = String($('map').offsetTop  + (($('map').offsetHeight - 98) / 2)) + "px";
	$('cpicon').style.left = x;
	$('cpicon').style.top = y;
	$('cpicon').style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='./img/gmap/cp.png',sizingmethod=image)";
	$('map').focus();
}

function removeMarker(id) {
	map.removeOverlay(marker_list[id]);
}

/** 
	追っかけ線を表示する
	@notes    call from UI
 */
function UI_drawLineHome2Center() {
	var line = lineHome2Center;
	if(line.polylines){map.removeOverlay(line.polylines);}
	line.points = [];
	line.polylines = new GPolyline([pointCenter, pointMyhome], line.color, line.weight, line.opacity);
	map.addOverlay(line.polylines);
}

/** 
	自宅を描画
 */
function drawHome(){
	if(marker_list['myhome'] && !init){map.removeOverlay(marker_list['myhome']);}
	// custom icon settings
	var icn = new GIcon();
	icn.image = icnHome.src;
	icn.iconSize = new GSize(icnHome.width, icnHome.height);
	icn.iconAnchor = new GPoint(icnHome.anchor_x, icnHome.anchor_y);
	icn.transparent = icnHome.transparent;

	// show marker
	marker_list['myhome'] = new GMarker(pointCenter, icn);
	map.addOverlay(marker_list['myhome']);

	// reload UI
	reloadHome();
}

/** 
	自宅へ移動
	@notes    call from UI
 */
function UI_panHome() {
	map.panTo(pointMyhome);
}

/** 
	住所に移動
	@notes    call from UI
 */
function UI_pan(id) {
	//alert("UI_pan("+id+")");
	// 住所から座標へ変換
	geocode.getLatLng($(id).value, function(point) {
		if (point != null) {map.panTo(point);}
		else {alert('指定の住所が見つかりませんでした。');}
	});
}

/** 
	住所の位置にマーカーを置く
	@notes    call from UI
 */
function UI_putMarker(id) {
	geocode.getLatLng($(id).value, function(point) {
		if (point != null) {
			marker_list[id] = new GMarker(point);
			map.addOverlay(marker_list[id]);
		} else {alert('指定の住所が見つかりませんでした。');}
	});
}

/** 
	センターアイコンを表示
 */
function drawIcnCenter(){
	if(markerCenter) map.removeOverlay(markerCenter);
	var icn = new GIcon();
	icn.image = icnCenter.src;
	icn.iconSize = new GSize(icnCenter.width, icnCenter.height);
	icn.iconAnchor = new GPoint(icnCenter.anchor_x, icnCenter.anchor_y);
	markerCenter = new GMarker(map.getCenter(), icn);
	map.addOverlay(markerCenter);
}

/** 
	自宅とセンターの位置関係を解析
	方位と距離を算出
	@p1    point
	@p2    point
 */
function analizeCenter(p1, p2) {
	var rad, angle, x, y;

	// ラジアン値に変換
	ido = deg2rad(p1.lat());
	keido = deg2rad(p1.lng());
	ido2 = deg2rad(p2.lat());
	keido2 = deg2rad(p2.lng());

	rad = keido2 - keido;
	y = Math.cos(ido2)*Math.sin(rad);
	x =( Math.cos(ido)*Math.sin(ido2) ) - ( Math.sin(ido) * Math.cos(ido2)* Math.cos(rad) );

	// ラジアン値から度数へ
	angle = rad2deg(Math.atan2(y, x));

	if (angle < 0) {angle = angle + 360;}
	angle = round3(angle);
	chkDirection(angle);

	mapinfo['distance'] = pointCenter.distanceFrom(pointMyhome);
}

/** 
	方位を調べる
 */
function chkDirection(angle){
	//GLog.write('angle = '+angle);
	var hoi, eto;
	switch (true) {
		case (0 <= angle) && (angle < 15):
		case (345 <= angle) && (angle <= 360):
			hoi = '北'; eto = '子'; break;
		case (15 <= angle) && (angle < 45):
			hoi = '北東'; eto = '丑'; break;
		case (45 <= angle) && (angle < 75):
			hoi = '北東'; eto = '寅'; break;
		case (75 <= angle) && (angle < 105):
			hoi = '東'; eto = '卯'; break;
		case (105 <= angle) && (angle < 135):
			hoi = '南東'; eto = '辰'; break;
		case (135 <= angle) && (angle < 165):
			hoi = '南東'; eto = '巳'; break;
		case (165 <= angle) && (angle < 195):
			hoi = '南'; eto = '午'; break;
		case (195 <= angle) && (angle < 225):
			hoi = '南西'; eto = '未'; break;
		case (225 <= angle) && (angle < 255):
			hoi = '南西'; eto = '申'; break;
		case (255 <= angle) && (angle < 285):
			hoi = '西'; eto = '酉'; break;
		case (285 <= angle) && (angle < 315):
			hoi = '北西'; eto = '戌'; break;
		case (315 <= angle) && (angle < 345):
			hoi = '北西'; eto = '亥'; break;
		default: hoi=''; eto='';
	}
	// 方位
	mapinfo['direction'] = hoi +"["+ eto +"]";
	// 角度
	angle = round1(angle);
	mapinfo['angle'] = angle;
}

/*
	球面三角法で自宅からの距離＆方位で点を決める(位置と距離と方位を指定して目的位置を求める)
	len[距離(km)] deg [方角(度)] 方位は0-359.99 北-0/東-90/南-180/西-270となる。
*/
function setPoints360(len, deg, line){
	var hmpy = pointMyhome.lat();
	var hmpx = pointMyhome.lng();
	var pox,poy,tmp_lat,tmp_lon;
	var cb,sb,clc,c,xx;
	tmp_lat = (90-hmpy)*(Math.atan(1)*4)/180;
	c = len / er;
	if(c > (Math.atan(1)*4)* 2) c=c-(Math.atan(1)*4)*2;
	cb = Math.cos(c) * Math.cos(tmp_lat) + Math.sin(c) * Math.sin(tmp_lat) * Math.cos(deg * Math.atan(1)/45);
	if(cb==1){sb = 0;}else{sb = Math.sqrt(1 - cb * cb);}
	if(Math.sin(tmp_lat)*sb == 0){
		clc = 0;
	}else{
		clc = (Math.cos(c) - Math.cos(tmp_lat) * cb) / (Math.sin(tmp_lat) * sb);
		if(clc > 1) clc = 1;
		if(clc <-1) clc = -1;
	}
	xx = cb;
    if(Math.sqrt(-1*xx * xx + 1) == 0){
		tmp_lat = Math.atan(1) * 2;
    }else{
		tmp_lat = Math.atan(-xx / Math.sqrt(-xx * xx + 1)) + 2 * Math.atan(1);
    }
	poy = 90 - tmp_lat * 180 / (Math.atan(1) * 4);
	xx = clc;
	if(xx == 1){
		tmp_lon = 0;
	}else if(xx == -1){
	    tmp_lon = Math.atan(1) * 4;
	}else{
		if(Math.sin(deg * Math.atan(1)/45) >= 0){
			tmp_lon = Math.atan(-1*xx / Math.sqrt(-1*xx * xx + 1)) + 2 * Math.atan(1);
		}else{
			tmp_lon = -1*(Math.atan(-1*xx / Math.sqrt(-1*xx * xx + 1)) + 2 * Math.atan(1));
		}
	}
	if(c > Math.atan(1) * 4) tmp_lon = -tmp_lon;
	tmp_lon = tmp_lon * 180 / (Math.atan(1) * 4);
	pox = eval(hmpx) + tmp_lon;

	line.points.push(new GLatLng(poy, pox, false));
}

/** 
	画面中央を自宅に設定
	@notes    call from UI
 */
function UI_saveHome() {
	pointMyhome = pointCenter  = map.getCenter();
	saveCookie("mylat", pointCenter.lat());
	saveCookie("mylng", pointCenter.lng());
	if ($('home_address').value) {
		saveCookie("address", $('home_address').value);
	}
	parseCookie();
	drawHome();
	UI_drawHoiLine();
}

// event ----------------------------------------

function GMap_OnMove(){	//Moveイベント
	drawIcnCenter();
	pointCenter = map.getCenter();
	//if($("disp_cpline").checked) UI_drawLineHome2Center(); // 追っかけ線を表示する
	analizeCenter(pointMyhome, pointCenter);
	reloadMapinfo();
	$('map').focus();
}

function GMap_OnMoveEnd(){	//MoveEndイベント
	//alert("GMap_OnMoveEnd()");
	drawIcnCenter();
	reloadMapinfo();
	if($("disp_cpline").checked) UI_drawLineHome2Center(); // 追っかけ線を表示する
	$('map').focus();
}

function resize(){
	//GLog.write('resize()');
	var map_obj = $("map");
	var disp = getDispSize();
	map_obj.style.width = (disp.width-270) +"px";
	map_obj.style.height = (disp.height-80) +"px";
	if( map ){
		map.checkResize();
		map.panTo(pointCenter);
	}
}



// Library --------------------------------------

/** 
	少数第3位を四捨五入
 */
function round3(n){
	n = n*1000;
	n = Math.round(n);
	return (n/1000);
}

/** 
	少数第1位を四捨五入
 */
function round1(n){
	n = n*10;
	n = Math.round(n);
	return (n/10);
}

/** 
	度数からラジアン値へ
 */
function deg2rad(deg) {
	var radian = deg * Math.PI / 180;
	return radian;
}

/** 
	ラジアン値から度数へ
 */
function rad2deg(rad) {
	var degree = rad * 180 / Math.PI;
	return degree;
}

/** 
	クッキー文字列を解析
 */
function parseCookie() {
	if (document.cookie=='') {return false;}
	//alert("document.cookie = "+document.cookie);
	var c = document.cookie +"; ";
	var ary = $A(c.split("; "));
	ary.each(function(value, i) {
		var v = value.split("=");
		cookie[v[0]] = unescape(v[1]);
	});
	return cookie;
}

/** 
	クッキーに保存
 */
function saveCookie(key, val){
//alert("saveCookie("+key+", "+val+")");
	document.cookie= key+"="+escape(val)+"; expires=Fri, 31-Dec-2030 23:59:59;";
}

/** 
	@todo    ua に入っているデータを使って分岐
 */
function getDispSize(){
	if(document.all){
		if(window.opera){
			return {width:document.body.clientWidth, height:document.body.clientHeight};
		}else{
			return {width:document.documentElement.clientWidth, height:document.documentElement.clientHeight};
		}
	}
	else if(document.layers || document.getElementById){
		return {width:window.innerWidth, height:window.innerHeight};
	}
}

function getUA(){
	var tua = navigator.userAgent;
	if( tua.match( /Opera[\/\s]([0-9]\.[0-9]+)/ )			){ ua.Opera		= parseFloat( RegExp.$1 ); } else { ua.Opera	= 0; }
	if( tua.match( /MSIE ([0-9]\.[0-9]+)/ ) && !ua.Opera	){ ua.MSIE		= parseFloat( RegExp.$1 ); } else { ua.MSIE		= 0; }
	if( tua.match( /Firefox[\/\s]([0-9]\.[0-9]+)/ )			){ ua.Firefox	= parseFloat( RegExp.$1 ); } else { ua.Firefox	= 0; }
	if( tua.match( /Netscape[0-9]?[\/\s]([0-9]\.[0-9]+)/ )	){ ua.Netscape	= parseFloat( RegExp.$1 ); } else { ua.Netscape	= 0; }
	if( tua.match( /Safari/ )								){ ua.Safari	= 1;					   } else { ua.Safari	= 0; }
	ua.Gecko = ( tua.match( /Netscape|Firefox/ ) ? true : false );
	for (i in ua) {
		//alert(i+' = '+ua[i]);
	}
}


// UI Controll ////////////////////////////////////////////////////////////////

/** 
	情報パネルの表示を更新
 */
function reloadMapinfo() {
	// 方位を確認
	$('direction').innerHTML = mapinfo['direction'];
	// 現在位置
	$("now_lng").innerHTML = pointCenter.lng() + ' 度';
	$("now_lat").innerHTML = pointCenter.lat() + ' 度';
	// 現在位置と自宅
	$('angle').innerHTML = mapinfo['angle'] + ' 度';
	$('distance').innerHTML = mapinfo['distance'] + ' m';
}

/** 
	自宅座標の更新
 */
function reloadHome() {
	$("home_lng").innerHTML = pointMyhome.lng() + ' 度';
	$("home_lat").innerHTML = pointMyhome.lat() + ' 度';
	$('home_address').value = (cookie["address"]!=null) ? cookie["address"] : '';
}



// Main ///////////////////////////////////////////////////////////////////////

/** 
	初期設定
 */
function load() {
//alert('1');
	init = true;
	if( typeof(GBrowserIsCompatible)=="function" ){
//alert('2');
		if (GBrowserIsCompatible()) {
//alert('3');
			getUA();
//alert('4');
			$("maperr").innerHTML ="初期化中・・・";
			//IEのキャッシュ破損エラー用
			if(typeof(GMap2) == 'undefined'){
				//alert("ブラウザのキャッシュが壊れてるかも(^^; \n手動でキャッシュクリアしてブラウザを再起動してみてね。");
				return;
			}
//alert('5');
			map = new GMap2($("map"));
			//Cookie読出し
			//alert("document.cookie = "+unescape(document.cookie));
			cookie = parseCookie();
//alert('6');
			if (cookie["mylat"]!=null && cookie["mylng"]!=null) {
				var mylat = cookie["mylat"];
				var mylng = cookie["mylng"];
			} else {
				var mylat = 35.68096912819847;
				var mylng = 139.7670578956604;
			}
//alert('7');
			pointMyhome = new GLatLng(mylat, mylng);
			map.setCenter(pointMyhome, 13);
			pointCenter = map.getCenter();
//alert('8');
			//コントロール追加
			map.enableDragging();
			map.enableScrollWheelZoom();
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());
			map.addControl(new GScaleControl());
			map.addControl(new GOverviewMapControl());
			// ジオコーディング
			geocode = new GClientGeocoder();

//alert('a0');
			//初期動作
			drawHome();
//alert('a1');
			UI_drawHoiLine();
//alert('a2');
			resize();
//alert('a3');
			map.setCenter(pointMyhome, 13);
//alert('a4');
			drawCenterPoint();
//alert('a5');
			GMap_OnMove();
//alert('a6');

			initEvent();
//alert('a7');
		}
	}else{
		$("maperr").innerHTML ="GoogleMapsに接続できませんでした('A`)";
	}
	init = false;
}

/** 
	イベント登録
 */
function initEvent() {
	// Gmap events
	GEvent.addListener(map, 'moveend'  ,  GMap_OnMoveEnd);	//MoveEndイベント
	GEvent.addListener(map, 'move',  GMap_OnMove);			//Moveイベント

	// browser events
	window.onresize = resize;
	window.onunload = GUnload;
	document.observe('keydown', keydown);
	function keydown(e) {
		e = (e || window.event);
		var code = (e.keyCode || e.which);
		if (e.keyCode==13) {
			var id = Event.element(e).id;
			switch(id) {
				case 'home_address':
				case 'des01':
				case 'des02':
				case 'des03':
					 UI_pan(id); return false;break;
			}
		}
	}
}


window.onload = load;
