
//======================================================================================
// script file	: GoogleMap生成スクリプト( GoogleMap Version 3 対応 )
// file path	: /common/library/js
// comment		: 
// history		: 2010.05.21. y.yaguma	new
// 				  2010.06.08. y.yaguma	変更可能メンバに oMapOptionsを追加
//										mapをクリックした場合にInfoWindowを消す処理削除
//										(IE6/IE7にてInfoWindowを地図と誤判断される不具合あり)
// 				  2010.06.26. y.yaguma	GetPos：インタフェース修正
//										AddPointMarkerの追加
//======================================================================================


//==========================================================
// class name : CGoogleMap
//----------------------------------------------------------
// description: GoogleMapを生成するクラス
//==========================================================

var CGoogleMap	= function(){};					// 変更不可！



//==========================================================
// 変更可能 メンバ変数
//==========================================================

// 変更可能範囲 ここから -----------------------------------

// Mapを描画するキャンバス設定

CGoogleMap.szMapCanvas		=	"map";


// Mapの初期位置に設定する緯度・経度
// ※先に緯度と経度を取得して設定してください

CGoogleMap.nInitLat			=	34.720195;	
CGoogleMap.nInitLng			=	135.265463;	

// Mapを表示する場合のオプションを設定します
// 設定内容については公式のリファレンスを参照ください。
CGoogleMap.oMapOptions		=	{	
									// ズームイン/ズームアウトの設定 - ZoomOut(0) ～ ZoomIn(20)
									zoom					: 12,

									// マップコントロール(地図/航空地図 etc)の使用有無
									mapTypeControl			: true,

									// マップコントロールのオプション設定
									mapTypeControlOptions	: {	mapTypeIds	: new Array(google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID ),
																position	: google.maps.ControlPosition.TOP_RIGHT,
																style		: google.maps.MapTypeControlStyle.DROPDOWN_MENU
															  },

									// マップの初期表示方法(地図/航空地図 etc)
									mapTypeId				: google.maps.MapTypeId.ROADMAP

								};							// GoogleMapオプション

// 変更可能範囲 ここまで -----------------------------------




//==========================================================
// 変更不可 メンバ変数
//==========================================================
CGoogleMap.oMap				=	null;						// GoogleMapオブジェクト
CGoogleMap.oGeo				=	new google.maps.Geocoder();	// ジオコーディングする場合のオブジェクト

CGoogleMap.oMarker			=	new Array();				// マーカーオブジェクトリスト
CGoogleMap.oCurrentPopUp	=	null;						// 表示中ポップアップオブジェクト(InfoWindow)



//==========================================================
// 公開メソッド
//==========================================================

//==========================================================
// func_name	: CGoogleMap::Initialize
// access		: public
// arg_value	: なし
// rtn_value	: なし
// account		: GoogleMapを生成するための処理を行う。
// comment		: szInitAddr, szInitPlaceが有効出ない場合は
//				  ImgLinkの所在地を初期位置として生成します。
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
// 				  2010.06.09	y.yaguma	MapクリックでInfoWindowを削除する処理無効化
//==========================================================
CGoogleMap.Initialize		=	function()
{
	var oPos = null;
	var i;

		// 住所, 場所ともに登録が無い場合
		if( !CGoogleMap.nInitLat || !CGoogleMap.nInitLng )
		{
			// イメージリンク所在地に設定
			oPos = new google.maps.LatLng( 34.68951, 135.19381 )
			CGoogleMap.oMapOptions.center = oPos;
			CGoogleMap.oMap = new google.maps.Map( document.getElementById( CGoogleMap.szMapCanvas ), CGoogleMap.oMapOptions );
		}
		else
		{
			// 指定された場所を初期位置に設定
			oPos = new google.maps.LatLng( CGoogleMap.nInitLat, CGoogleMap.nInitLng )
			CGoogleMap.oMapOptions.center = oPos;
			CGoogleMap.oMap = new google.maps.Map( document.getElementById( CGoogleMap.szMapCanvas ), CGoogleMap.oMapOptions );
		}

		// PopUpの表示を削除するためのリスナー登録
		// 本機能はIE6/IE7でInfoWindowの一部が地図と誤判断される不具合があるため削除する。
		if( 0 )
		{
			google.maps.event.addListener
			(	CGoogleMap.oMap , 'click',
				function()
				{
						if( CGoogleMap.oCurrentPopUp )
						{
							CGoogleMap.oCurrentPopUp.close();
						}
						CGoogleMap.oCurrentPopUp = null;

					return;
				}
			);
		}

		// Initialize前にマーカーが追加されて表示できていないものは
		// 全て表示する。(ただしGeoCode中のマーカー以外)
		for( i = 0; i < CGoogleMap.oMarker.length; i++ )
		{
			if( !CGoogleMap.oMarker[i].IsShow() )
			{
				CGoogleMap.oMarker[i].Show();
			}
		}

	return;
}


//==========================================================
// func_name	: CGoogleMap::SetZoom
// access		: public
// arg_value	: zoom - Zoom値(0～20)
// rtn_value	: なし
// account		: ズームの値を再設定する
// comment		: 0がズームアウトした位置で、値を大きくするとズームインする。
//----------------------------------------------------------
// history		: 2010.05.31	y.yaguma	新規
//==========================================================
CGoogleMap.SetZoom				=	function( zoom )
{
		// エラーチェック
		if( typeof(zoom) != 'number' )
		{
			return;
		}

		if( (0 > zoom) && (20 < zoom) )
		{
			return;
		}

		// ズームの再設定
		if( CGoogleMap.oMap )
		{
			// オブジェクトがある場合には関数で変更する
			CGoogleMap.oMap.setZoom( zoom );
		}
		else
		{
			// オブジェクトがない場合にはオプションを再設定
			CGoogleMap.oMapOptions.zoom = zoom;
		}

	return;
}



//==========================================================
// func_name	: CGoogleMap::GetPos
// access		: public
// arg_value	: oLatElmID		- 緯度を表示するエレメントID
//				  oLngElmID		- 経度を表示するエレメントID
//				  szAddr		- 住所
//				  bSetMarker	- マーカーを表示するかどうか(true/false)
//				  bCentering	- 中央にあわせるかどうか(true/false)
// rtn_value	: true	- 要求成功
//				: false	- 要求失敗
// account		: 住所から緯度と経度を取得する
// comment		: 取得できたら指定されたエレメントへに格納します。
//				  検索できない住所・場所が指定された場合は無視されます。
//				  マーカー表示・中央寄せは地図表示中かつ検索できた場合に
//				  のみ有効です。
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
//				  2010.06.15	y.yaguma	latlngを取得できなかった場合には空文字を設定するよう修正
//				  2010.06.26	y.yaguma	インタフェース修正
//==========================================================
CGoogleMap.GetPos				=	function( oLatElmID, oLngElmID, szAddr, bSetMarker, bCentering )
{
		if( (!CGoogleMap.oGeo) || (!szAddr) )
		{
			return false;
		}

		CGoogleMap.oGeo.geocode(	{address: szAddr},
									function( oResults, eStatus )
									{
											if( eStatus == google.maps.GeocoderStatus.OK )
											{
												//マーカー設定する必要がある場合はマーカー追加
												if( CGoogleMap.oMap && bSetMarker )
												{
													CGoogleMap.AddMarker( oResults[0].geometry.location.lat(), oResults[0].geometry.location.lng(), bCentering, "", "", "", "");
												}

												//センタリングする必要がある場合は中央をセンタリング
												if( CGoogleMap.oMap && bCentering )
												{
													CGoogleMap.oMap.setCenter( oResults[0].geometry.location );
												}

												oLatElmID.value = oResults[0].geometry.location.lat();
												oLngElmID.value = oResults[0].geometry.location.lng();
											}
											else
											{
												oLatElmID.value = "";
												oLngElmID.value = "";
											}

										return;
									}
								);

	return true;
}


//==========================================================
// func_name	: CGoogleMap::SetMapCenter
// access		: public
// arg_value	: szAddr		- 住所・場所
// rtn_value	: なし
// account		: 住所より緯度・経度を取得しMapの中心位置を更新します。
// comment		: 検索できない住所・場所が指定された場合は無視されます。
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
//==========================================================
CGoogleMap.SetMapCenter		=	function( szAddr )
{
		if( (!CGoogleMap.oGeo) || (!szAddr) )
		{
			return;
		}

		CGoogleMap.oGeo.geocode(	{address: szAddr},
									function( oResults, eStatus )
									{
											if( eStatus == google.maps.GeocoderStatus.OK )
											{
												if( CGoogleMap.oMap )
												{
													CGoogleMap.oMap.setCenter( oResults[0].geometry.location );
												}
											}

										return;
									}
								);

	return;
}


//==========================================================
// func_name	: CGoogleMap::AddMarker
// access		: public
// arg_value	: dLat			- 緯度
//				  dLng			- 経度
//				  bCenterUpdate	- 指定した位置で中央位置を更新するかどうか
//				  szTitle		- マーカータイトル(MarkerToolTips用)
//				  szInfo		- マーカー情報    (吹き出し用/HTMLタグ可)
//				  szIcon		- マーカー画像    (指定無し可)
//				  szIconShadow	- マーカー影画像  (指定無し可)
// rtn_value	: なし
// account		: マーカー情報を追加する
// comment		: 他のマーカーを消去後にMarkarを表示する場合には
//				  先にClearMarkerをコールし消去が確認できた時点で
//				  追加してください。
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
//==========================================================
CGoogleMap.AddMarker		=	function( dLat, dLng, bCenterUpdate, szTitle, szInfo, szIcon, szIconShadow )
{
	var nIdx = CGoogleMap.oMarker.length;
	var oPos = null;

		// マーカーオブジェクト生成
		CGoogleMap.oMarker[nIdx] = new CGoogleMapMarker( szTitle, szInfo, szIcon, szIconShadow );
		if( CGoogleMap.oMarker[nIdx] )
		{
			oPos = new google.maps.LatLng( dLat, dLng )
			CGoogleMap.oMarker[nIdx].SetPos( oPos );
			CGoogleMap.oMarker[nIdx].SetCenterUpdate( bCenterUpdate );

			// oMapが生成されていない(onloadされていない)場合には初期化の段階で処理する
			if( CGoogleMap.oMap )
			{
				CGoogleMap.oMarker[nIdx].Show();
			}
		}

	return;
}


//==========================================================
// func_name	: CGoogleMap::AddMarkerEx
// access		: public
// arg_value	: szAddr		- 住所
//				  bCenterUpdate	- 指定した位置で中央位置を更新するかどうか
//				  szTitle		- マーカータイトル(MarkerToolTips用)
//				  szInfo		- マーカー情報    (吹き出し用/HTMLタグ可)
//				  szIcon		- マーカー画像    (指定無し可)
//				  szIconShadow	- マーカー影画像  (指定無し可)
// rtn_value	: なし
// account		: マーカー情報を追加する
// comment		: GeoCoderを使用し住所からLatLngを取得します。
//				  !!注意-1!!
//				  無償GoogleMapではGeoCoderに制限があり連続し
//				  たマーカー追加はパフォーマンス的に問題があり
//				  ます。無償GoogleMapを利用する場合には、
//				  CGoogleMap::AddMarkerを利用してください。
//				  現在この関数では200msの待ちを入れてからジオ
//				  コーダを実行しています。
//
//				  !!注意-2!!
//				  他のマーカーを消去後にMarkarを表示する場合には
//				  先にClearMarkerをコールし消去が確認できた時点で
//				  追加してください。
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
//==========================================================
CGoogleMap.AddMarkerEx		=	function( szAddr, bCenterUpdate, szTitle, szInfo, szIcon, szIconShadow )
{
	var nIdx = CGoogleMap.oMarker.length;

		CGoogleMap.oMarker[nIdx] = new CGoogleMapMarker( szTitle, szInfo, szIcon, szIconShadow );
		if( CGoogleMap.oMarker[nIdx] )
		{
			CGoogleMap.searchMarkerPos( nIdx, szAddr, bCenterUpdate );
		}

	return;
}


//==========================================================
// func_name	: CGoogleMap::AddPointMarker
// access		: public
// arg_value	: oLocation		- マウスでポイントされた位置情報
//				  bCentering	- 中央にあわせるかどうか(true/false)
// rtn_value	: true	- 要求成功
//				: false	- 要求失敗
// account		: マウスでポイントされた位置にマーカーを追加します。
// comment		: 本関数を使用するためにはマップに対してイベントリスナーを
//				  登録する必要があります。以下は使用例です。
//
//				  google.maps.event.addListener( CGoogleMap.oMap, 'click', function( event ) {
//					CGoogleMap.AddPointMarker( event.LatLng, true );
//				  });
//
//				  以上のようなソースコードを必ず使用するソース側で定義してください。
//				  本スクリプトでは定義しません。
//
//----------------------------------------------------------
// history		: 2010.06.26	y.yaguma	新規
//==========================================================
CGoogleMap.AddPointMarker	=	function( oLocation, bCentering )
{
		CGoogleMap.AddMarker( oLocation.lat(), oLocation.lng(), bCentering, "", "", "", "" );

	return;
}


//==========================================================
// func_name	: CGoogleMap::ClearMarker
// access		: public
// arg_value	: なし
// rtn_value	: true	- マーカー全消去完了
//				  false	- 消去できない状態。
// account		: マーカーに関連する表示を消去します。
// comment		: 
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
//==========================================================
CGoogleMap.ClearMarker			=	function()
{
	var i;

		// 既に全て表示されているか確認
		for( i = 0; i < CGoogleMap.oMarker.length; i++ )
		{
			// ひとつでも位置が初期化されていなければ
			// Location要求中なのでクリアは保留する。
			if( !CGoogleMap.oMarker[i].IsSetPos() )
			{
				return false;
			}
		}

		for( i = 0; i < CGoogleMap.oMarker.length; i++ )
		{
			CGoogleMap.oMarker[i].Hide();
			delete CGoogleMap.oMarker[i];
			CGoogleMap.oMarker[i] = null;
		}

		CGoogleMap.oCurrentPopUp = null;
		CGoogleMap.oMarker.length = 0;

	return true;
}





//==========================================================
// func_name	: CGoogleMap::searchMarkerPos
// access		: private
// arg_value	: nIdx			- 検索対象マーカーindex
//				  szAddr		- 検索住所
//				  bCenterUpdate	- 指定した位置で中央位置を更新するかどうか
// rtn_value	: なし
// account		: 住所から緯度と経度を取得する
// comment		: 取得できたら指定されたエレメントへに格納します。
//----------------------------------------------------------
// history		: 2010.05.21	y.yaguma	新規
//==========================================================
CGoogleMap.searchMarkerPos	=	function( nIdx, szAddr, bCenterUpdate )
{
		if( szAddr )
		{
			setTimeout( function()
						{
							if( !CGoogleMap.oGeo )
							{
								return;
							}

							CGoogleMap.oGeo.geocode
							(	{address: szAddr},
								function( oResults, eStatus )
								{
										if( eStatus == google.maps.GeocoderStatus.OK )
										{
											if( CGoogleMap.oMarker[nIdx] )
											{
												CGoogleMap.oMarker[nIdx].SetPos( oResults[0].geometry.location );
												CGoogleMap.oMarker[nIdx].SetCenterUpdate( bCenterUpdate );

												// oMapが生成されていない(onloadされていない)場合には初期化の段階で処理する
												if( CGoogleMap.oMap )
												{
													CGoogleMap.oMarker[nIdx].Show();
												}
											}
										}
										else
										{
											CGoogleMap.searchMarkerPos(nIdx, szAddr);
										}

									return;
								}
							);
						},
						200
					);
		}

	return;
}




//==========================================================
// class name : CGoogleMapMarker
//----------------------------------------------------------
// description: マーカー情報管理クラス
//==========================================================

var CGoogleMapMarker = function( szTitle, szInfo, szIcon, szIconShadow )
{
		this.szTitle		= szTitle;			// タイトル(マーカーツールチップ用)
		this.szInfo			= szInfo;			// 吹き出し表示データ(HTML形式)
		this.szIcon			= szIcon;			// アイコン画像パス
		this.szIconShadow	= szIconShadow;		// アイコン影画像パス

		this.oMarker		= null;				// マーカーオブジェクト
		this.oPopUp			= null;				// 吹き出しオブジェクト
		this.oPopUpOpen		= null;				// 吹き出しオープンイベントリスナーオブジェクト
		this.oPopUpClose	= null;				// 吹き出しクローズイベントリスナーオブジェクト	

		this.oPos			= null;				// マーカー位置
		this.bCenterUpdate	= false;			// センタリングフラグ
		this.bShow			= false;			// 表示フラグ


		//==========================================================
		// func_name	: CGoogleMapMarker::SetPos
		// access		: public
		// arg_value	: oPos	- マーカー表示位置
		// rtn_value	: なし
		// account		: マーカー表示位置を設定する
		// comment		: 
		//----------------------------------------------------------
		// history		: 2010.05.21	y.yaguma	新規
		//==========================================================
		this.SetPos			= function( oPos )
		{
				if( oPos )
				{
					this.oPos = oPos;
				}

			return;
		}


		//==========================================================
		// func_name	: CGoogleMapMarker::IsSetPos
		// access		: public
		// arg_value	: なし
		// rtn_value	: なし
		// account		: マーカー表示位置が設定されているかを応答する
		// comment		: 
		//----------------------------------------------------------
		// history		: 2010.05.25	y.yaguma	新規
		//==========================================================
		this.IsSetPos		= function()
		{
			var bRet = false;

				if( this.oPos )
				{
					bRet = true;
				}

			return bRet;
		}


		//==========================================================
		// func_name	: CGoogleMapMarker::SetCenterUpdate
		// access		: public
		// arg_value	: bUpdate	- 中心位置更新有無
		// rtn_value	: なし
		// account		: 中心位置更新マーカーであるかを設定する
		// comment		: 
		//----------------------------------------------------------
		// history		: 2010.05.21	y.yaguma	新規
		//==========================================================
		this.SetCenterUpdate= function( bUpdate )
		{
				this.bCenterUpdate = bUpdate;

			return;
		}


		//==========================================================
		// func_name	: CGoogleMapMarker::IsShow
		// access		: public
		// arg_value	: なし
		// rtn_value	: なし
		// account		: マーカーが表示中かの状態を応答する
		// comment		: 
		//----------------------------------------------------------
		// history		: 2010.05.21	y.yaguma	新規
		//==========================================================
		this.IsShow			= function()
		{
			return this.bShow;
		}


		//==========================================================
		// func_name	: CGoogleMapMarker::Show
		// access		: public
		// arg_value	: なし
		// rtn_value	: なし
		// account		: マーカーを表示する
		// comment		: 各オプションは内部状態により自動生成する。
		//----------------------------------------------------------
		// history		: 2010.05.21	y.yaguma	新規
		//==========================================================
		this.Show			= function()
		{
			var oMarkerOpt = new Array();
			var oPopUpOpt  = new Array();

				// 位置が設定されていない場合は処理しない
				if( !this.oPos )
				{
					return;
				}

				// タイトルの設定
				if( this.szTitle )
				{
					oMarkerOpt['title'] = this.szTitle;
				}

				// アイコン情報の設定
				if( this.szIcon )
				{
					oMarkerOpt['icon'] = this.szIcon;
					// アイコンがある場合にのみ影アイコンの設定を行う
					if( this.szIconShadow )
					{
						oMarkerOpt['shadow'] = this.szIconShadow;
					}
				}

				oMarkerOpt['map'] = CGoogleMap.oMap;
				oMarkerOpt['position'] = this.oPos;

				// 吹き出し用の情報が指定されている場合
				if( this.szInfo )
				{
					oPopUpOpt['content'] = this.szInfo;
					oPopUpOpt['position'] = this.oPos;
					oMarkerOpt['clickable'] = true;
				}

				this.oMarker = new google.maps.Marker( oMarkerOpt );
				if( this.szInfo )
				{
					this.oPopUp = new google.maps.InfoWindow( oPopUpOpt );
					this.createListener( this.oMarker, this.oPopUp );
				}

				// マーカー位置へのセンタリング判定
				if( this.bCenterUpdate )
				{
					CGoogleMap.oMap.setCenter( this.oPos );
				}

				this.bShow = true;

			return;
		};


		//==========================================================
		// func_name	: CGoogleMapMarker::Hide
		// access		: public
		// arg_value	: なし
		// rtn_value	: なし
		// account		: マーカーを非表示にし関連オブジェクトを初期化する
		// comment		: 
		//----------------------------------------------------------
		// history		: 2010.05.21	y.yaguma	新規
		//==========================================================
		this.Hide			= function()
		{
				// 吹き出しオープン用イベントを設定している場合
				if( this.oPopUpOpen )
				{
					google.maps.event.removeListener( this.oPopUpOpen );
					delete this.oPopUpOpen;
					this.oPopUpOpen = null;
				}

				// 吹き出しクローズ用イベントを設定している場合
				if( this.oPopUpClose )
				{
					google.maps.event.removeListener( this.oPopUpClose );
					delete this.oPopUpClose;
					this.oPopUpClose = null;
				}

				// 吹き出し用オブジェクトを所有している場合
				if( this.oPopUp )
				{
					this.oPopUp.close();
					delete this.oPopUp;
					this.oPopUp = null;
				}

				// マーカーオブジェクトを所有している場合
				if( this.oMarker )
				{
					this.oMarker.setMap();
					delete this.oMarker;
					this.oMarker = null;
				}

				this.bShow = false;

			return;
		};


		//==========================================================
		// func_name	: CGoogleMapMarker::createListener
		// access		: private
		// arg_value	: なし
		// rtn_value	: なし
		// account		: イベントリスナーを生成する
		// comment		: 
		//----------------------------------------------------------
		// history		: 2010.05.21	y.yaguma	新規
		// 				  2010.06.26	y.yaguma	イベントコールバックの引数修正
		//==========================================================
		this.createListener	= function( marker, popup )
		{
				// マーカーをクリックした場合、PopUpを表示するためのリスナー
				this.oPopUpOpen = google.maps.event.addListener
				(	marker ,'click',
					function( event )
					{
							if( CGoogleMap.oCurrentPopUp )
							{
								CGoogleMap.oCurrentPopUp.close();
							}
							popup.open( CGoogleMap.oMap, marker )
							CGoogleMap.oCurrentPopUp = popup;
					}
				);

				// PopUpの閉じるボタンを押下した場合のイベントリスナー
				this.oPopUpClose = google.maps.event.addListener
				(	popup , 'closeclick',
					function( event )
					{
							CGoogleMap.oCurrentPopUp = null;
					}
				);

			return;
		};

	return;
}


