/*
 * Googlemaps Plugin for FCKeditor
 * Based on version 1.98 by Alfonso Martinez de Lizarrondo
 *
 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
 *
 * @package    Magic3 Framework
 * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
 * @copyright  Copyright 2006-2012 Magic3 Project.
 * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
 * @version    SVN: $Id: googleMaps.js 4793 2012-03-25 13:21:44Z fishbone $
 * @link       http://www.magic3.org
 */
// Rounds a number to just "precission" decimals
Number.prototype.RoundTo = function(precission)
{
	var base = Math.pow(10, precission);
	return Math.round(this * base) / base;
};

function Import(aSrc)
{
   document.write('<scr'+'ipt type="text/javascript" src="' + aSrc + '"></sc' + 'ript>');
}

var oEditor		= window.parent.InnerDialogLoaded();
var FCK			= oEditor.FCK;
var FCKLang		= oEditor.FCKLang;
var FCKConfig	= oEditor.FCKConfig;
var FCKTools = oEditor.FCKTools;

Import(FCKConfig.FullBasePath + 'dialog/common/fck_dialog_common.js');

//Import('http://maps.google.com/maps?file=api&v=2&key=' + FCKConfig.GoogleMaps_Key);
Import('http://maps.google.com/maps/api/js?sensor=false');

Import('polyline.js');

window.parent.AddTab('Map', FCKLang.GMapsMap);
window.parent.AddTab('Search', FCKLang.GMapsSearch);
window.parent.AddTab('Marker', FCKLang.GMapsMarker);
window.parent.AddTab('Line', FCKLang.GMapsLine);

var ActiveTab;

// Function called when a dialog tag is selected.
function OnDialogTabChange(tabCode)
{
	ActiveTab = tabCode;

	ShowE('MapInfo',	(tabCode == 'Map'));
	ShowE('SearchInfo',	(tabCode == 'Search'));
	ShowE('MarkerInfo',	(tabCode == 'Marker'));
	ShowE('LineInfo',	(tabCode == 'Line'));

	if (tabCode == 'Line'){
		ShowLinePoints()
	} else {
		HideLinePoints();
	}

	if (tabCode != 'Marker') FinishAddMarker();

	ResizeParent();
}
// Get the selected map (if available).
var oFakeImage = FCK.Selection.GetSelectedElement();
var oParsedMap;

if (oFakeImage)
{
	if (oFakeImage.getAttribute('MapNumber'))
	{
		oParsedMap = FCK.GoogleMapsHandler.getMap(oFakeImage.getAttribute('MapNumber'));
		oParsedMap.updateDimensions(oFakeImage);
	} else {
		oFakeImage = null;
	}
}
if (!oParsedMap) oParsedMap = FCK.GoogleMapsHandler.createNew();

window.onload = function()
{
	// Garbage collection. The imported function won't be available inmediately.
//	window.onunload = GUnload;

	// Translate the dialog box texts.
	oEditor.FCKLanguageManager.TranslatePage(document);
	var btn = GetE('btnAddNewMarker');
	btn.alt = btn.title = FCKLang.GMapsAddMarker;

	// Load the selected element information (if any).
	LoadSelection();

	ConfigureEvents();

	// Activate the "OK" button.
	SetupHelpButton(oEditor.FCKPlugins.Items['googlemaps'].Path + 'docs/' + FCKLang.GMapsUserHelpFile);
	window.parent.SetOkButton(true);
//2.6
	if (window.parent.Sizer) window.parent.SetAutoSize(true);
};

function ConfigureEvents()
{
	GetE('txtWidth').onblur = UpdateDimensions;
	GetE('txtHeight').onblur = UpdateDimensions;

	GetE('cmbZoom').onchange  = UpdatePreview;

	GetE('btnAddNewMarker').onclick = function (){AddMarker(); return false;};

	FCKTools.AddEventListener(GetE('searchDirection') , 'keydown', searchDirection_keydown);
	GetE('searchButton').onclick = function (){doSearch(); return false;};
}

function searchDirection_keydown(e)
{
	if (!e) e = window.event;
	if (e.keyCode == 13)
	{
		doSearch();
		if (e.preventDefault) e.preventDefault();
		if (e.stopPropagation) e.stopPropagation();
		return false;
	}
}
// 選択されているマップの設定値の読み込み
function LoadSelection()
{
	GetE('txtWidth').value  = oParsedMap.width;
	GetE('txtHeight').value = oParsedMap.height;

	GetE('cmbZoom').value  = oParsedMap.zoom;
	GetE('txtCenterLatitude').value  = oParsedMap.centerLat;
	GetE('txtCenterLongitude').value = oParsedMap.centerLon;

	var markerPoints = oParsedMap.markerPoints;
	
	GetE('encodedPolyline').value = oParsedMap.LinePoints;
	GetE('encodedLevels').value = oParsedMap.LineLevels;

	SetPreviewElement(oParsedMap.mapType);
	UpdatePreview();
	// Only after we have set the center.
	//map.setMapType( allMapTypes[ oParsedMap.mapType ] );

	for (var i = 0; i < markerPoints.length; i++)
	{
		//var point = new GLatLng(parseFloat(markerPoints[i].lat), parseFloat(markerPoints[i].lon))
		var point = new google.maps.LatLng(parseFloat(markerPoints[i].lat), parseFloat(markerPoints[i].lon));
		AddMarkerAtPoint(point, markerPoints[i].text, false);
	}
	
	decodePolyline();
}

//#### The OK button was hit.
function Ok()
{
	oEditor.FCKUndo.SaveUndoStep();

	oParsedMap.width = GetE('txtWidth').value;
	oParsedMap.height = GetE('txtHeight').value;

	oParsedMap.zoom = GetE('cmbZoom').value;
	oParsedMap.centerLat = GetE('txtCenterLatitude').value;
	oParsedMap.centerLon = GetE('txtCenterLongitude').value;

	oParsedMap.mapType = GetMapTypeIndex(map);

	var markerPoints = [];
	for (var i=0; i < markers.length; i++)
	{
		//var point = markers[i].getPoint();
		//markerPoints.push({lat: point.lat().RoundTo(5), lon:point.lng().RoundTo(5), text:markers[i].text});
		var point = markers[i].getPosition();
		markerPoints.push({ lat:point.lat().RoundTo(5), lon:point.lng().RoundTo(5), text:markers[i].getTitle() });
	}
	oParsedMap.markerPoints = markerPoints;

	oParsedMap.LinePoints = GetE('encodedPolyline').value;
	oParsedMap.LineLevels = GetE('encodedLevels').value;

	var script = oParsedMap.BuildScript();

	if (!oFakeImage) oFakeImage = oParsedMap.createHtmlElement();

	oParsedMap.updateHTMLElement(oFakeImage);
	
	return true;
}
function GetMapTypeIndex(m)
{
	/*
	var name = m.getCurrentMapType().getName();
	for (var i=0; i < allMapTypes.length; i++)
	{
		if ( name == allMapTypes[i].getName() )
			return i;
	}*/
	var mapType = m.getMapTypeId();
	for (var i = 0; i < allMapTypes.length; i++)
	{
		if (mapType == allMapTypes[i]) return i;
	}
	return 0;
}

var map;
var mapDiv;
var geocoder;
var markers = [];
var activeMarker = null;
var Mode = '';
var infoWindow;

var allMapTypes;

function SetPreviewElement(mapType)
{
	mapDiv = document.getElementById("GMapPreview");
	UpdateDimensions();

//	if(!GBrowserIsCompatible())
//		return;

//	allMapTypes = [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP];
//	map = new GMap2(mapDiv, {mapTypes:allMapTypes});
//	map.addControl(new GSmallMapControl());
//	map.addControl(new GMapTypeControl());
	
	allMapTypes = [	google.maps.MapTypeId.ROADMAP,
					google.maps.MapTypeId.SATELLITE,
					google.maps.MapTypeId.HYBRID,
					google.maps.MapTypeId.TERRAIN	];
	var opts = { 	mapTypeId:allMapTypes[mapType],
					mapTypeControlOptions:{	mapTypeIds:allMapTypes } };
	map = new google.maps.Map(mapDiv, opts);
/*
	GEvent.addListener(map, "zoomend", Map_ZoomEnd); 
	GEvent.addListener(map, "drag", Map_Drag); 
//	GEvent.addListener(map, "moveend", Map_MoveEnd); 
	GEvent.addListener(map, "click", Map_Click);
	GEvent.addDomListener(mapDiv, "keydown", DomMap_KeyDown);
	   */
	google.maps.event.addListener(map, 'zoom_changed', function(){
		GetE('cmbZoom').value = map.getZoom();
	});
	google.maps.event.addListener(map, 'drag', function(){
		var point = map.getCenter();
		GetE("txtCenterLatitude").value = point.lat().RoundTo(5);
		GetE("txtCenterLongitude").value = point.lng().RoundTo(5);
	});
	google.maps.event.addListener(map, 'click', function(e){
		var point = e.latLng;
//		if (!overlay)
//		{
			switch (ActiveTab){
				case 'Map':
					//Nothing
					break;
				case 'Marker':
					if (Mode == 'AddMarker') AddMarkerAtPoint(point, FCKConfig.GoogleMaps_MarkerText || FCKLang.GMapsMarkerDefaultText, true);
					break;
				case 'Line':
					createPoint(point.lat(), point.lng(), 3);
					createEncodings(false);
					break;
			}
//		}
	
		// To get Keyboard events, the map must be focused.
//		if (!overlay || overlay.focusable)
//		{
			mapDiv.focus();
//		}
	});
	google.maps.event.addDomListener(mapDiv, 'keydown', function(e){
		if (!e) e = window.event;

		var iCode = (e.keyCode || e.charCode);

		// Delete: remove current point in the line
		if (iCode == 46){
			switch(ActiveTab){
				case 'Map':
					//Nothing
					break;
				case 'Marker':
					//Nothing
					break;
				case 'Line':
					deletePoint();
					break;
			}
		}
	});
}
function UpdatePreview()
{
	if (!map) return;

//	var zoom = parseInt(GetE('cmbZoom').value, 10);
//	map.setCenter(new GLatLng(GetE('txtCenterLatitude').value, GetE('txtCenterLongitude').value), zoom);
	
	map.setCenter(new google.maps.LatLng(GetE('txtCenterLatitude').value, GetE('txtCenterLongitude').value));
	map.setZoom(parseInt(GetE('cmbZoom').value, 10));
}

function UpdateDimensions()
{
	mapDiv.style.width = GetE('txtWidth').value + 'px';
	mapDiv.style.height = GetE('txtHeight').value + 'px';

	ResizeParent();
}

function createMarker(point, html) 
{
/*	var marker = new GMarker(point, {draggable: true});
	marker.text = html;

	GEvent.addListener(marker, "click", function(){
		EditMarker(this);
	});*/
	/*
	GEvent.addListener(marker, "drag", function(){
		Marker_Drag(this.getPoint());
	});
	*/
	var marker = new google.maps.Marker({ position:point, title:html, draggable:true });
	google.maps.event.addListener(marker, "click", function(){
		EditMarker(this);
	});
	return marker;
}

function generateEditPopupString(text)
{
	return '<div style="width:250px; height:7em;">' +
			'<label for="txtMarkerText">' + FCKLang.GMapsMarkerText + '</label><br>' +
			'<textarea id="txtMarkerText" style="width:250px; height:4em;">' + text.replace(/<br>/g, '\n') + '</textarea><br>' +
			'<div style="float:left"><input type="button" id="btnDeleteMarker" onclick="DeleteCurrentMarker()" value="' + FCKLang.GMapsDeleteMarker + '"></div>' +
			'<div style="float:right"><input type="button" id="btnOK2" onclick="UpdateCurrentMarker()" value="' + FCKLang.DlgBtnOK + '">' +
			'<input type="button" id="btnCancel2" onclick="CloseInfoWindow()" value="' + FCKLang.DlgBtnCancel + '"></div>' +
		'</div>';
}

function doSearch()
{
	//if (!geocoder) geocoder = new GClientGeocoder();
	if (!geocoder) geocoder = new google.maps.Geocoder();
	
	function processPoint(point)
	{
		if (point) 
		{
			GetE("txtCenterLatitude").value = point.lat().RoundTo(5);
			GetE("txtCenterLongitude").value = point.lng().RoundTo(5);

			// Create a marker at that direction
			AddMarkerAtPoint(point, GetE('searchDirection').value);

			UpdatePreview();
		} else {
			alert(FCKLang.GMapsNotFound.replace("%s", GetE('searchDirection').value));
		}
	}

	//geocoder.getLatLng ( GetE('searchDirection').value, processPoint );
	geocoder.geocode({ 'address':GetE('searchDirection').value }, function(results, status){
		if (status == google.maps.GeocoderStatus.OK){
			processPoint(results[0].geometry.location);
		} else {
			alert(FCKLang.GMapsNotFound.replace("%s", GetE('searchDirection').value));
		}
	});
}

// Change mode to enable addition of a new marker.
function AddMarker()
{
	if (Mode == 'AddMarker')
	{
		FinishAddMarker();
		return;
	}

	GetE('btnAddNewMarker').src = '../images/AddMarkerDown.png';
	GetE('instructions').innerHTML = FCKLang.GMapsClickToAddMarker;
	Mode = 'AddMarker';
	// Change cursor type
	//mapDiv.firstChild.firstChild.style.cursor = "crosshair";
	map.setOptions({ draggableCursor:'crosshair' });
}

function AddMarkerAtPoint(point, text, interactive)
{
	var marker = createMarker(point, text);
//	map.addOverlay( marker );
	marker.setMap(map);
	markers.push(marker);
	FinishAddMarker();

	if (interactive) EditMarker(marker);
}

function FinishAddMarker()
{
	Mode = '';
	GetE('btnAddNewMarker').src = '../images/AddMarker.png';
	GetE('instructions').innerHTML = '';
	// Change cursor type
	//mapDiv.firstChild.firstChild.style.cursor = "default";
	map.setOptions({ draggableCursor:'default' });
}


function EditMarker(obj)
{
	if (ActiveTab != 'Marker')
	{
		//obj.openInfoWindowHtml(obj.text);
		if (infoWindow) infoWindow.close();
		infoWindow = new google.maps.InfoWindow({ content:obj.getTitle() });
		infoWindow.open(map, obj);
		return;
	}
	// We are really editing.
	activeMarker = obj;
	Mode = 'EditMarker';
	//obj.openInfoWindowHtml(generateEditPopupString(obj.text));
	if (infoWindow) infoWindow.close();
	infoWindow = new google.maps.InfoWindow({ content:generateEditPopupString(obj.getTitle()) });
	infoWindow.open(map, obj);
}

function CloseInfoWindow()
{
	Mode = '';

	//map.closeInfoWindow();
	if (infoWindow) infoWindow.close();
	infoWindow = null;
	activeMarker = null;
}

function UpdateCurrentMarker()
{
	//activeMarker.text = GetE( 'txtMarkerText' ).value.replace(/\n/g, '<br>');
	if (activeMarker) activeMarker.setTitle(GetE('txtMarkerText').value.replace(/\n/g, '<br>'));
	CloseInfoWindow();
}

function DeleteCurrentMarker()
{
	// Remove it from the global array
	for (var j = 0; j < markers.length; j++)
	{
		if (markers[j] == activeMarker)
		{
			markers.splice(j, 1);
			break;
		}
	}
	var tmp = activeMarker;
	CloseInfoWindow();

	// Remove it from the map
	//map.removeOverlay(tmp);
	tmp.setMap(null);
}

// Full resize in x and y and centering
function ResizeParent()
{
	var oParentWindow = window.parent;
//2.6
	if (window.parent.Sizer){
		oParentWindow.Sizer.RefreshSize();
		return;
	}
	var oInnerWindow = window;
	var oInnerDoc = oInnerWindow.document;
	var iDiff, iFrameHeight, iFrameWidth;

	if (document.all){
		iFrameHeight = oInnerDoc.body.offsetHeight;
	} else {
		iFrameHeight = oInnerWindow.innerHeight;
	}

	var iInnerHeight = oInnerDoc.body.scrollHeight;
	iDiff = iInnerHeight - iFrameHeight;

	if (iDiff !== 0)
	{
		if (document.all){
			oParentWindow.dialogHeight = (parseInt(oParentWindow.dialogHeight, 10) + iDiff) + 'px';
		} else {
			oParentWindow.resizeBy(0, iDiff);
		}
	}

	// Width:
	if (document.all){
		iFrameWidth = oInnerDoc.body.offsetWidth;
	} else {
		iFrameWidth = oInnerWindow.innerWidth;
	}

	var iInnerWidth = oInnerDoc.body.scrollWidth;
	iDiff = iInnerWidth - iFrameWidth;

	if (iDiff !== 0)
	{
		if (document.all){
			oParentWindow.dialogWidth = (parseInt(oParentWindow.dialogWidth, 10) + iDiff) + 'px';
		} else {
			oParentWindow.resizeBy(iDiff, 0);
		}
	}
}

// Adds a Help button to the parent dialog pointing to the provided url
function SetupHelpButton(url)
{
	var doc = window.parent.document;
	var helpButton = doc.createElement('INPUT');
	helpButton.type = 'button';
	helpButton.value = FCKLang.Help;
	helpButton.className = 'Button';
	helpButton.onclick = function (){ window.open(url); return false; };

	var okButton = doc.getElementById('btnOk');
	var cell = okButton.parentNode.previousSibling;
	if (cell.nodeName != 'TD') cell = cell.previousSibling;
	cell.appendChild(helpButton);
}