
var map=umap=gmap=ymap=null,_default='GMAP',_latlon='D.d',_perpage=20,_enable_gmap=true,_enable_ymap=_enable_umap=false,_flickr_mode='search',_maplink='yuancc';
var nsid='',auth_token,auth_nsid,auth_username,mode=0,photostream='',_stop=false,logged_in=false,login_username=null,login_userid=null;
var flickr_referrer=false, _seach_text=true;
var geocache_key='', api_key = '4a615b7429317895a6b15a35b3c91603', api_secret='f5ac5b5817ae4d5b';
var photos = new Array();
var users = new Array();
var flickr_users = new Array();
var geocaches = new Array();
var gps_tracks = new Array();
var pager = new Object();
var requestQueue = new Array();
var CK = new Object();
var Flickr = new Object();
Flickr.browse_filter='';
var IE4=(document.all);
var Flickr_Groups = new Array();
Flickr_Groups['94823070@N00'] = {mode:4, id:'94823070@N00', name:'Geotagging Flickr'};
Flickr_Groups['28892259@N00'] = {mode:5, id:'28892259@N00', name:'Geotagged'};
Flickr_Groups['73471210@N00'] = {mode:6, id:'73471210@N00', name:'Geotagged : Berlin'};
Flickr_Groups['42649376@N00'] = {mode:7, id:'42649376@N00', name:'Geotagged : Boston'};
Flickr_Groups['55989636@N00'] = {mode:8, id:'55989636@N00', name:'Geotagged : Brighton'};
Flickr_Groups['94005860@N00'] = {mode:9, id:'94005860@N00', name:'Geotagged : Canada'};
Flickr_Groups['81731410@N00'] = {mode:10, id:'81731410@N00', name:'Geotagged : Canterbury'};
Flickr_Groups['13375983@N00'] = {mode:11, id:'13375983@N00', name:'Geotagged : Denmark'};
Flickr_Groups['67387261@N00'] = {mode:12, id:'67387261@N00', name:'Geotagged : Europe'};
Flickr_Groups['94744248@N00'] = {mode:13, id:'94744248@N00', name:'Geotagged : Germany'};
Flickr_Groups['57827878@N00'] = {mode:14, id:'57827878@N00', name:'Geotagged : Hong Kong'};
Flickr_Groups['94027142@N00'] = {mode:15, id:'94027142@N00', name:'Geotagged : Ireland'};
Flickr_Groups['13557536@N00'] = {mode:16, id:'13557536@N00', name:'Geotagged : Italy'};
Flickr_Groups['15549361@N00'] = {mode:17, id:'15549361@N00', name:'Geotagged : Japan'};
Flickr_Groups['77312356@N00'] = {mode:18, id:'77312356@N00', name:'Geotagged : Kent'};
Flickr_Groups['48986628@N00'] = {mode:19, id:'48986628@N00', name:'Geotagged : London'};
Flickr_Groups['99108089@N00'] = {mode:20, id:'99108089@N00', name:'Geotagged : Mexico'};
Flickr_Groups['16897949@N00'] = {mode:21, id:'16897949@N00', name:'Geotagged : Michigan'};
Flickr_Groups['94306909@N00'] = {mode:22, id:'94306909@N00', name:'Geotagged : New Zealand'};
Flickr_Groups['15172128@N00'] = {mode:23, id:'15172128@N00', name:'Geotagged : Portugal'};
Flickr_Groups['90279179@N00'] = {mode:24, id:'90279179@N00', name:'Geotagged : Spain'};
Flickr_Groups['47922491@N00'] = {mode:25, id:'47922491@N00', name:'Geotagged : Street Art'};
Flickr_Groups['24615541@N00'] = {mode:26, id:'24615541@N00', name:'Geotagged : Switzerland'};
Flickr_Groups['66961499@N00'] = {mode:27, id:'66961499@N00', name:'Geotagged : Taiwan'};
Flickr_Groups['85837265@N00'] = {mode:28, id:'85837265@N00', name:'Geotagged : Travel'};
Flickr_Groups['97173639@N00'] = {mode:29, id:'97173639@N00', name:'Geotagged : Tuscany'};
Flickr_Groups['79212288@N00'] = {mode:30, id:'79212288@N00', name:'Geotagged : UK'};
Flickr_Groups['18146257@N00'] = {mode:31, id:'18146257@N00', name:'Geotagged : Washington State'};
Flickr_Groups['52241207092@N01'] = {mode:32, id:'52241207092@N01', name:'Australian Postcode'};
Flickr_Groups['52241213703@N01'] = {mode:33, id:'52241213703@N01', name:'GeoCaching'};
Flickr_Groups['72706585@N00'] = {mode:34, id:'72706585@N00', name:'Yuan.CC Flickr Tools'};

if(_get_cookie('default_map')) _default=_get_cookie('default_map');
else _default='GMAP';
if(_get_cookie('coord_format')) _latlon=_get_cookie('coord_format');
else _latlon='D.d';
if( _get_cookie('enable_gmap')=='true' ) _enable_gmap = true;
else _enable_gmap = true;
if( _get_cookie('enable_ymap')=='true' ) _enable_ymap = true;
else _enable_ymap = false;
if( _get_cookie('enable_umap')=='true' ) _enable_umap = true;
else _enable_umap = false;
if( _get_cookie('maplink')=='' || _get_cookie('maplink')==null ) _maplink = 'yuancc';
else _maplink = _get_cookie('maplink');

function _gt(e) { return document.getElementsByTagName(e); }
function _gi(e) { return document.getElementById(e); }
function _ce(e) { return document.createElement(e); }
function _ct(e) { return document.createTextNode(e); }

if (typeof DOMParser == "undefined") {
   DOMParser = function () {}

   DOMParser.prototype.parseFromString = function (str, contentType) {
      if (typeof ActiveXObject != "undefined") {
         var d = new ActiveXObject("MSXML.DomDocument");
         d.loadXML(str);
         return d;
      } else if (typeof XMLHttpRequest != "undefined") {
         var req = new XMLHttpRequest;
         req.open("GET", "data:" + (contentType || "application/xml") +
                         ";charset=utf-8," + encodeURIComponent(str), false);
         if (req.overrideMimeType) {
            req.overrideMimeType(contentType);
         }
         req.send(null);
         return req.responseXML;
      }
   }
}

MyAddEventListener = function (target,type,callback,captures) {
    if (target.addEventListener) {
	// EOMB
        target.addEventListener(type,callback,captures);
    } else if (target.detachEvent) {
        // IE
        target.detachEvent('on'+type,callback,captures);
    } else {
    	// IE 5 Mac and some others
    	target['on'+type] = callback;
    }
}

MyRemoveEventListener = function (target,type,callback,captures) {
    if (target.removeEventListener) {
	// EOMB
        target.removeEventListener(type,callback,captures);
    } else if (target.attachEvent) {
        // IE
        target.attachEvent('on'+type,callback,captures);
    } else {
    	// IE 5 Mac and some others
    	target['on'+type] = callback;
    }
}

function init() {

    window_resize();
    initMap(_default);
    switchmap(_default);
    initCursor();
    initSearch();

    var username=photoid='';
    var referrer = '' + document.referrer;
    var flickr_url = /^http:\/\/([w\.]*)flickr.com\/photos\/([^\/]+)\/(\d+)\/?/;
    if( referrer.match(flickr_url) ) {
	flickr_referrer = true;
	var a = flickr_url.exec(referrer);
	username = a[2];
	photoid = a[3];
    }

    if( (_init_service=='' && authenticated) || flickr_referrer || _init_service=='flickr' ) {
	if( _init_nsid != undefined && _init_nsid != '' ) {
	    username = _init_nsid;
	}
	if( _init_photoid != undefined && _init_photoid != '' ) {
	    flickr_referrer = true;
	    photoid = _init_photoid;
	    username = _init_nsid;
	}
	flickr(username, photoid);
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('flickrTab');
	CK.activePage.style.display = 'block';
    } else if( _init_service=='gps' ) {
	GPS.setup();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('gps');
	CK.activePage.style.display = 'block';
    } else if( _init_service=='georss' ) {
	GEORSS.setup();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('georss');
	CK.activePage.style.display = 'block';
	_gi('georss_url').value = _init_georss;
	GEORSS.refresh();
    } else  {
	about();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('about');
	CK.activePage.style.display = 'block';
    }

    if( _init_addr!='' ) CaptureForm();

}

function window_resize() {

    var info = _gi('infoPanel');
    var main = _gi('main');
    var body = _gt('body')[0];
    var umap = _gi('umap');
    var gmap = _gi('gmap');
    var ymap = _gi('ymap');

    main.style.width = body.clientWidth-270-10-14 + 'px';
    main.style.height = body.clientHeight-50-20-30 + 'px';
//    _perpage = (Math.floor((body.clientHeight-190-310)/52))*5;
    _perpage = (Math.floor((body.clientHeight-190-310-32)/52))*5;
    if( _perpage <= 5 ) _perpage = 5;
    umap.style.width = main.style.width;
    umap.style.height = main.style.height;
    umap.style.display = 'none';
    gmap.style.width = main.style.width;
    gmap.style.height = main.style.height;
    gmap.style.display = 'none';
    ymap.style.width = main.style.width;
    ymap.style.height = main.style.height;
    ymap.style.display = 'none';

    if( map ) {
	if( map.mtype =='GMAP' ) gmap.style.display = 'block';
	if( map.mtype =='UMAP' ) umap.style.display = 'block';
	if( map.mtype =='YMAP' ) ymap.style.display = 'block';
	map.checkResize();
    }
    initCursor();
}

function GM_xmlhttpRequest(req) {

//    url = 'http://' + document.location.hostname + document.location.pathname + 'xml_proxy.php?' + req.url;
    url = 'http://' + document.location.hostname + '/xml_proxy.php?' + req.url;
//    var xmlhttp = new XMLHttpRequest();

    if( IE4 ) var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    else var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
	if (xmlhttp.readyState==4) {
	    if (xmlhttp.status==200) req.onload(xmlhttp);
	}
    }
    xmlhttp.open(req.method, url, true);
    if(IE4) xmlhttp.send();
    else xmlhttp.send(null);
}


function initMap(m) {

    if( m == 'UMAP' ) {
	_gi('ymap').style.display = 'none';
	_gi('gmap').style.display = 'none';
	_gi('umap').style.display = 'block';

	umap = new CKMap(m,_gi('umap'));
	umap.addControl(LargeMapControl);
	umap.addControl(MapTypeControl);
//	umap.centerAndZoom(umap.LatLng(25.035405, 121.520255),8);

	umap.style = _gi('umap').style;
	map = umap;
    }

    if( m == 'GMAP' ) {
	_gi('umap').style.display = 'none';
	_gi('ymap').style.display = 'none';
	_gi('gmap').style.display = 'block';

	gmap = new CKMap(m,_gi('gmap'));
	gmap.addControl(LargeMapControl);
	gmap.addControl(OverviewMapControl);
	gmap.addControl(MapTypeControl);
	gmap.addControl(ScaleControl);
//	gmap.setMapType(G_SATELLITE_TYPE);
	gmap.zoomTo(_init_zoom);
//	gmap.centerAndZoom(gmap.LatLng(39, -96),13);
//	gmap.checkResize();
	gmap.refreshMap();

	gmap.style = _gi('gmap').style;
	map = gmap;
    }

    if( m == 'YMAP' ) {
	_gi('gmap').style.display = 'none';
	_gi('umap').style.display = 'none';
	_gi('ymap').style.display = 'block';

	ymap = new CKMap(m,_gi('ymap'));
	ymap.addControl(LargeMapControl);
//	ymap.centerAndZoom(new YGeoPoint(39, -96),13);

	ymap.style = _gi('ymap').style;
	map = ymap;
    }
    map.addListener('moveend', function() {
	var lat = map.getCenterLatLng().lat();
	var lon = map.getCenterLatLng().lng();
	var zoom = map.getZoomLevel();
	_set_cookie('last_lat', lat);
	_set_cookie('last_lon', lon);
	_set_cookie('last_zoom', zoom);

	_gi('coords_lat').value = showLatLon(lat,'lat');
	_gi('coords_lon').value = showLatLon(lon,'lon');
	_gi('gmaplink').href = 'http://maps.google.com/?t=k&q=' + lat +'+'+ lon;
//	_gi('gelink').href = 'http://maps.yuan.cc/makeKML.php?lat=' + lat + '&lon=' + lon + '&src=YuanCC&title=Yuan.CC Maps&url=http://maps.yuan.cc/';
	_gi('gelink').href = 'http://maps.yuan.cc/kml.php?lat=' + lat + '&lon=' + lon;
	_gi('ymaplink').href = 'http://maps.yahoo.com/maps_result?lat=' +lat+ '&lon=' + lon;
	_gi('umaplink').href = 'http://www.urmap.com/SearchEngine/map.jsp?targetName=Yuan.CC Maps Location&lat=' +lat+ '&lon=' + lon;
	if( _gi('permlink') ) _gi('permlink').href = 'http://maps.yuan.cc/?lat=' +lat+ '&lon=' +lon+ '&zoom=' +zoom+ '&service=flickr';
	browsePhotos(1);
	GEOURL.refresh();
	GPS.browseTracks();
    });
    map.enableDragging();
}

function initCursor() {
    if( !_gi('map_cursor') ) {
	var cursor = _ce('div');
	cursor.id = 'map_cursor';
	cursor.style.position = 'absolute';
	cursor.style.width = '41px';
	cursor.style.height = '41px';
	cursor.style.zIndex = 21000;
	cursor.style.top = 0;
	cursor.style.left = 0;
//	cursor.style.border = '0px solid #ff0000';
	cursor.innerHTML = '<div style="position:absolute;width:19px;height:19px;border-right:1px solid #ff0000;border-bottom:1px solid #ff0000;"></div><div style="position:absolute;width:19px;height:19px;top:19px;left:19px;border-left:1px solid #ff0000;border-top:1px solid #ff0000;"></div><div id="cursorphoto" style="position:absolute;width:50px;height:50px;top:-5px;left:-5px;z-index:22000"></div>';
	_gi('main').appendChild(cursor);
    } else var cursor = _gi('map_cursor');
    var showCursor = function() {
        var mh = ''+_gi('main').style.height;
        var mw = ''+_gi('main').style.width;
        mh = 1*mh.replace(/px/,'');
        mw = 1*mw.replace(/px/,'');
        cursor.style.top = Math.round(mh/2-20) + 'px';
        cursor.style.left = Math.round(mw/2-20) + 'px';
//        MyRemoveEventListener(_gi('main'), 'mouseover', showCursor, true);
    }
    showCursor();
//    _gi('main').addEventListener('mouseover', showCursor, true);
    MyAddEventListener(_gi('main'),'mouseover', showCursor, true);
}

function switchmap(maptype) {

    if( map.mtype == maptype ) {
//	map.checkResize();
	map.refreshMap();
	return;
    }
    _gi('umap').style.display = 'none';
    _gi('ymap').style.display = 'none';
    _gi('gmap').style.display = 'none';
    lastmap = map;
    
    if( maptype =='GMAP' ) {
	_gi('gmap').style.display = 'block';
	if( gmap == null ) initMap('GMAP');
	map = gmap;
    }
    if( maptype =='UMAP' && _enable_umap) {
	_gi('umap').style.display = 'block';
	if( umap == null ) initMap('UMAP');
	map = umap;
    }
    if( maptype =='YMAP' && _enable_ymap) {
	_gi('ymap').style.display = 'block';
	if( ymap == null ) initMap('YMAP');
	map = ymap;
    }
    lat = lastmap.getCenterLatLng().lat();
    lon = lastmap.getCenterLatLng().lng();
    map.checkResize();
    map.centerAndZoom(map.LatLng(lat,lon), lastmap.getZoomLevel());
}

function centerMap() {
    var lat,lon;
    if( _latlon == 'D.d' ) {
	lat = 1 * _gi('coords_lat').value;
	lon = 1 * _gi('coords_lon').value;
    } else {
	lat = DMm_to_Dd(_gi('coords_lat').value);
	lon = DMm_to_Dd(_gi('coords_lon').value);
    }
    if( lat!='N/A' && lon!='N/A') map.centerAtLatLng(map.LatLng(lat,lon));
}

function login() {

    var infoPanel = _gi('infoPanel');

    _gi('menu').value= 'select';
    if( ! _gi('login_page') ) {
	loginDiv = _ce('div');
	loginDiv.id = 'login_page';
	loginDiv.style.padding = '5px';
	loginDiv.style.background = '#eeeeef';
	loginDiv.style.lineHeight = '16px';
	infoPanel.appendChild(loginDiv);
    } else loginDiv = _gi('login_page');

    if( !logged_in ) {
	var html = '<h3>LOGIN Yuan.CC Maps</h3>';
	html += '<table>';
	html += '<tr><td align="right">Username:</td><td><input id="login_username" type="text" name="username"></td></tr>';
	html += '<tr><td align="right">Password:</td><td><input id="login_passwd" type="password" name="passwd"></td></tr>';
	html += '</table>';
	html += '<input type="button" value="Login" onclick="login_send()"> ';
	html += '<small>(<a href="javascript:;" onclick="signup();">Not a member?</a>)</small></p>';
	html += showTip('TIP', 'If you are a Flickr member, you can <a href="?login=true">authenticate via Flickr</a>. If none of the above, please <a href="javascript:;" onclick="signup();">sign up</a> first.');
    } else {
	var html = '<h3>Welcome to Yuan.CC Maps</h3>';
	html += '<ul><li><a href="javascript:;" onclick="_gi(\'menu\').value=\'flickr\';selectMenu(_gi(\'menu\'));">Flickr</a></li>';
	html += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'geocache\';selectMenu(_gi(\'menu\'));">Geocaching</a></li>';
	html += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'gps\';selectMenu(_gi(\'menu\'));">GPS Tracks</a></li>';
	html += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'geourl\';selectMenu(_gi(\'menu\'));">GeoURL</a></li>';
	html += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'georss\';selectMenu(_gi(\'menu\'));">GeoRSS</a></li>';
	html += '</ul>';
	html += '<div style="text-align:right;"><form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_s-xclick"> <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit" alt="Make payments with PayPal - it\'s fast, free and secure!"> <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHJwYJKoZIhvcNAQcEoIIHGDCCBxQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYBa+a8SqoqHis26FpBSBVSCFEyQSnq7+eJNIclCtBSF1U2ZM4+JVXxofJ0ZltoY/SZETdVI4IaRSremVBN4nG9AoFo0Ll7FjNfSZME3Av1SPngq5hH26657q0TScOYIn7L0C6blTeg1P1i0DZwwSc4PvYr9+RmbY2R8OxJvPQIXHDELMAkGBSsOAwIaBQAwgaQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIR8VBU7VHbGGAgYBfsu9Gqz+Yw2zTDIxUbkkq/T5obPLXXvLFHiZhhnvSqw8BI5DrSKNhH+pqyhFDGZeEkiWs5T7GKq4VcVfJ+BDU3DFbT9D5mMawfp995K0wIJkxiMGcE7ddCio6oy6O48GyMToP0+wpRJyws7iNRndg+WFR91hdAY8NYEPumIxcu6CCA4cwggODMIIC7KADAgECAgEAMA0GCSqGSIb3DQEBBQUAMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTAeFw0wNDAyMTMxMDEzMTVaFw0zNTAyMTMxMDEzMTVaMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwUdO3fxEzEtcnI7ZKZL412XvZPugoni7i7D7prCe0AtaHTc97CYgm7NsAtJyxNLixmhLV8pyIEaiHXWAh8fPKW+R017+EmXrr9EaquPmsVvTywAAE1PMNOKqo2kl4Gxiz9zZqIajOm1fZGWcGS0f5JQ2kBqNbvbg2/Za+GJ/qwUCAwEAAaOB7jCB6zAdBgNVHQ4EFgQUlp98u8ZvF71ZP1LXChvsENZklGswgbsGA1UdIwSBszCBsIAUlp98u8ZvF71ZP1LXChvsENZklGuhgZSkgZEwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgV86VpqAWuXvX6Oro4qJ1tYVIT5DgWpE692Ag422H7yRIr/9j/iKG4Thia/Oflx4TdL+IFJBAyPK9v6zZNZtBgPBynXb048hsP16l2vi0k5Q2JKiPDsEfBhGI+HnxLXEaUWAcVfCsQFvd2A1sxRr67ip5y2wwBelUecP3AjJ+YcxggGaMIIBlgIBATCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA2MDMwMjEyMDEyNlowIwYJKoZIhvcNAQkEMRYEFDTqh7092owu3m2cOd+LgyX51gbqMA0GCSqGSIb3DQEBAQUABIGASxab1PJ09GiiwbFfS9ysTxvz2pvrJiomY7HFR3al1pRWw6vmNwqM32c94Puvqoo7QQ75typIpHIwWAvVVn2F0Ojt4zCKhpKEpkxfvc6zEjfmCRZEfwMrKE6KbCepQFK/mNbNt2O4ycQKhD1JZkzw2mlH2AzfiDD8kyJlwGo1YUY=-----END PKCS7-----"></form></div>';
    }
    loginDiv.innerHTML = html;

    if(CK.activePage) CK.activePage.style.display = 'none';
    CK.activePage = loginDiv;
    CK.activePage.style.display = 'block';
}

function signup() {

    var loginDiv = _gi('login_page');
    var html = '<h3>Registration</h3>';
    html += '<table>';
    html += '<tr><td align="right">Username:</td><td><input id="signup_username" type="text" name="username" size="16" MAXLENGTH="12"> <small>(Max. 12 chars)</small></td></tr>';
    html += '<tr><td align="right">Password:</td><td><input id="signup_passwd" type="password" name="passwd" size="16" MAXLENGTH="20"> <small>(Max. 20 chars)</small></td></tr>';
    html += '<tr><td align="right">Confirm:</td><td><input id="signup_confirm" type="password" name="passwd" size="16" MAXLENGTH="20"></td></tr>';
    html += '<tr><td align="right">Email:</td><td><input id="signup_email" type="text" name="email" size="24"></td></tr>';
    html += '</table>';
    html += '<input type="button" value="SIGN UP" onclick="signup_send()">';
    loginDiv.innerHTML = html;
}

function login_send() {

    var loginDiv = _gi('login_page');
    var username = _gi('login_username').value;
    var passwd = _gi('login_passwd').value;

    var sql_pattern = /'/;
    if( username.match(sql_pattern) || passwd.match(sql_pattern) ) {
	alert('Username or password contains invalid characters');
	return;
    }
    if( passwd == '' ) {
	alert('Password is blank!');
	return;
    }

    var md5_passwd = hex_md5(passwd);
    if( auth_nsid != undefined ) var fid = auth_nsid;
    else var fid = '';
    var url = 'http://maps.yuan.cc/mapi.php?method=members.login&username=' + username + '&mpw=' + md5_passwd + '&userid='+fid;
    showLoadingMessage('Login Yuan.CC Maps...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var stat = dom.getElementsByTagName('rsp').item(0).getAttribute('stat');
	    var userid = dom.getElementsByTagName('rsp').item(0).getAttribute('userid');
	    if( stat == 'ok' ) {
//		loginDiv.innerHTML += '<p><font color="red">Account created successfully</font></p>';
		showLoadingMessage('Login successfully');
		logged_in = true;
		login_username = username;
		login_userid = userid;
		_gi('login').innerHTML = '<small>Logged in as ' + username + '</small>';
		login();
	    } else {
//		alert( dom.getElementsByTagName('rsp').item(0).firstChild.data );
		alert('Username or password mismatch, please try again.');
		logged_in = false;
	    }
	}
    });
}

function signup_send() {

    var loginDiv = _gi('login_page');
    var username = _gi('signup_username').value;
    var passwd = _gi('signup_passwd').value;
    var confirm = _gi('signup_confirm').value;
    var email = _gi('signup_email').value;

    var sql_pattern = /'/;
    if( username.match(sql_pattern) || passwd.match(sql_pattern) || email.match(sql_pattern) ) {
	alert('Username or password contains invalid characters');
	return;
    }

    if( username.length < 4 ) {
	alert('Please pick a username between 4 and 12 characters');
	return;
    }
    if( passwd != confirm || passwd == '' ) {
	alert('Password not match or blank password');
	return;
    }
    var email_pattern = /^[^@]+@[^\.]+\..+$/;
    if( !email.match(email_pattern) ) {
	alert('Invalid email address');
	return;
    }
    var md5_passwd = hex_md5(passwd);
    if( authenticated ) var flickrmember = '&flickrid=' + auth_nsid;
    else var flickrmember = '';
    var url = 'http://maps.yuan.cc/mapi.php?method=members.signup&username=' + username + '&mpw=' + md5_passwd + '&email=' + email + flickrmember;
    showLoadingMessage('Signup Yuan.CC Maps...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var stat = dom.getElementsByTagName('rsp').item(0).getAttribute('stat');
	    if( stat == 'ok' ) {
//		loginDiv.innerHTML += '<p><font color="red">Account created successfully</font></p>';
		showLoadingMessage('Account created successfully');
		login();
	    } else alert( dom.getElementsByTagName('rsp').item(0).firstChild.data );
	}
    });
}

function selectMenu(sel) {
    if( sel.value == 'select') return;
    if( sel.value == '-') {
	sel.selectedIndex=0;
	return;
    }
    GEOURL.browse = false;
    GPS.browseOnOff(false);
    if( sel.value == 'flickr') {
	if( !_gi('flickrTab') ) flickr();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('flickrTab');
	CK.activePage.style.display = 'block';
	return;
    }
    if( sel.value == 'geocache') {
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('geocache');
	CK.activePage.style.display = 'block';
	geocache();
	return;
    }
    if( sel.value == 'gps') {
	GPS.setup();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('gps');
	CK.activePage.style.display = 'block';
	return;
    }
    if( sel.value == 'geourl') {
	GEOURL.setup();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('geourl');
	CK.activePage.style.display = 'block';
	return;
    }
    if( sel.value == 'georss') {
	GEORSS.setup();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('georss');
	CK.activePage.style.display = 'block';
	return;
    }
    if( sel.value == 'setting') {
	if( !_gi('settings') ) settings();
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('settings');
	CK.activePage.style.display = 'block';
	return;
    }
    if( sel.value == 'about') {
	if(CK.activePage) CK.activePage.style.display = 'none';
	CK.activePage = _gi('about');
	CK.activePage.style.display = 'block';
	about();
	return;
    }
}

FlickrAPI_sign = function(params) {

    params.api_key = api_key;
    if( authenticated ) {
	params.auth_token = auth_token;
    }

    var _11=[], _12='';
    for(var p in params) {
        params[p]=params[p];
        _11.push(p);
        _12+="&"+p+"="+escape_utf8(params[p]);
    }
    _11.sort();
    if(authenticated) {
	var cal=api_secret;
	if(cal!="") {
	    for(var i=0;i<_11.length;i++) cal+=_11[i]+params[_11[i]];
	    cal = hex_md5(cal);
	    _12="api_sig="+cal+_12;
	}
    } 
// else _12 = 'application=yuancc' + _12;
    return _12;
}

function about() {
    str = '<h3>About Yuan.CC Maps</h3>';
    str += '<p>I am a freelance web programmer. I love maps, GIS/GPS, photographing, traveling, and geocaching. Yuan.CC Maps service is my personal project originally developed for own use. Now I\'d like to share my work with you. </p>';
    str += '<p>Yuan.CC Maps currently provides five services: ';
    str += '<ol><li><a href="javascript:;" onclick="_gi(\'menu\').value=\'flickr\';selectMenu(_gi(\'menu\'));">Flickr</a></li>';
    str += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'geocache\';selectMenu(_gi(\'menu\'));">Geocaching</a></li>';
    str += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'gps\';selectMenu(_gi(\'menu\'));">GPS</a> (display GPS track logs)</li>';
    str += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'geourl\';selectMenu(_gi(\'menu\'));">GeoURL</a></li>';
    str += '<li><a href="javascript:;" onclick="_gi(\'menu\').value=\'georss\';selectMenu(_gi(\'menu\'));">GeoRSS</a></li></ol>';
    str += 'You can select from the above pull-down menu.</p>';
//    str += '<p>This service is running on my home server with a DSL connection. I exploit the hot web technologies such as web services and Ajax, but no Java/flash. The performance should be fine. Suggestions and feedbacks are welcome. If you like my work, donate is always appreciated. :)</p>';
    str += '<p>This service is running on my home server with a DSL connection. I exploit the hot web technologies such as web services and Ajax, so the performance should be fine. Suggestions and feedbacks are welcome. If you like my work, donation is always appreciated. :)</p>';
    str += '<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_s-xclick"> <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit" alt="Make payments with PayPal - it\'s fast, free and secure!"> <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----"></form>';
//    str += '<script type="text/javascript" src="http://embed.technorati.com/embed/buyfcm3fa.js"></script>';

//    var google_ads = _gi('googleads');
//    google_ads.style.display = 'none';
//    document.body.appendChild(google_ads);

    _gi('about').innerHTML = str;
//    _gi('about').appendChild(google_ads);
//    google_ads.style.display = 'block';
}

function settings() {

    var m1=m2=m3=m4=m5=m6='';
    var infoPanel = _gi('infoPanel');
    var setting = _ce('div');
//    setting.className = 'tabBody';
    setting.id = 'settings';
    setting.style.display = 'block';
    setting.style.fontFamily = 'Arial';
    setting.style.fontSize = '12px';
    setting.style.padding = '4px';
//    setting.style.textAlign = 'left';

    switch(_maplink) {
	case 'yuancc': m1='selected'; break;
	case 'gmap': m2='selected'; break;
	case 'geotagviewer': m3='selected'; break;
	case 'flickrfly': m4='selected'; break;
	case 'flickr2map': m5='selected'; break;
	case 'none': m6='selected'; break;
	default: m1='selected';
    }

    var str = '<h3><strong>Preferences</strong></h3>';
    str += '<p><b>Enabled Maps</b><br />';
    str += '<input id="enable_gmap" type="checkbox" name="usegmap" checked disabled> Google Maps';
    str += '<input id="enable_ymap" type="checkbox" name="useymap"> Yahoo Maps';
    str += '<input id="enable_umap" type="checkbox" name="useumap"> UrMap';

    str += '<p><b>Default Map</b>: (Coverage)<br />';
    str += '<input id="default_gmap" type="radio" name="dmap" value="GMAP" checked> Google Maps (World) <br />';
    str += '<input id="default_ymap" type="radio" name="dmap" value="YMAP"> Yahoo Maps (US) <br />';
    str += '<input id="default_umap" type="radio" name="dmap" value="UMAP"> UrMap (Taiwan) </p>';

    str += '<p><b>Lat/Lon Format</b><br />';
    str += '<input id="coord_Dd" type="radio" name="coord_format" value="D.d" checked> D.d<br />';
    str += '<input id="coord_DMm" type="radio" name="coord_format" value="DM.m"> DM.m<br /></p>';

    str += '<p><b>Geotagging Flickr Map Link</b><br /><br />';
    str += 'Choose your map link service: <br />';
    str += '<select id="maplink">';
    str += '<option value="yuancc" '+m1+'>Yuan.CC Maps</option>';
    str += '<option value="gmap" '+m2+'>Google Maps</option>';
    str += '<option value="geotagviewer" '+m3+'>GeoTag Viewer</option>';
    str += '<option value="flickrfly" '+m4+'>FlickrFly</option>';
    str += '<option value="flickr2map" '+m5+'>Flickr2Map</option>';
    str += '<option value="localizeus">loc.alize.us</option>';
    str += '<option value="none" '+m6+'>None</option>';
    str += '</select></p>';


    str += '<input type="button" value="Save" onClick="save_settings()">  ';
    str += '<span id="settings_log" style="color:red"></span>';

    setting.innerHTML = str;
    infoPanel.appendChild(setting);

    if(_enable_gmap) _gi('enable_gmap').checked = true;
    if(_enable_ymap) _gi('enable_ymap').checked = true;
    if(_enable_umap) _gi('enable_umap').checked = true;

    switch(_default) {
	case 'GMAP': _gi('default_gmap').checked = true; break;
	case 'YMAP': _gi('default_ymap').checked = true; break;
	case 'UMAP': _gi('default_umap').checked = true; break;
	default: _gi('default_gmap').checked = true;
    }

    switch(_latlon) {
	case 'D.d': _gi('coord_Dd').checked = true; break;
	case 'DM.m': _gi('coord_DMm').checked = true; break;
	default: _gi('coord_Dd').checked = true;
    }
}

function save_settings() {

    if( _gi('enable_gmap').checked ) {
	_enable_gmap = true;
	_set_cookie('enable_gmap', 'true');
    } else {
	_enable_gmap = true;
	_set_cookie('enable_gmap', 'true');
    }
    if( _gi('enable_ymap').checked ) {
	_enable_ymap = true;
	_set_cookie('enable_ymap', 'true');
    } else {
	_enable_ymap = false;
	_set_cookie('enable_ymap', 'false');
    }
    if( _gi('enable_umap').checked ) {
	_enable_umap = true;
	_set_cookie('enable_umap', 'true');
    } else {
	_enable_umap = false;
	_set_cookie('enable_umap', 'false');
    }

//    _gi('msgBar').innerHTML = _gi('default_gmap').checked + ',' + _gi('default_ymap').checked + ',' + _gi('default_umap').checked;
    if( _gi('default_gmap').checked ) _default = 'GMAP'; 
    if( _gi('default_ymap').checked ) _default = 'YMAP';
    if( _gi('default_umap').checked ) _default = 'UMAP';
    _set_cookie('default_map', _default);

    if( _gi('coord_Dd').checked ) _latlon = 'D.d'; 
    if( _gi('coord_DMm').checked ) _latlon = 'DM.m'; 
    _set_cookie('coord_format', _latlon);

    _maplink = _gi('maplink').value;
    _set_cookie('maplink', _maplink);

    _gi('settings_log').innerHTML = 'Settings Saved.';
//    showLoadingMessage('Settings saved.');
}

function flickr(username,photoid) {
    var infoPanel = _gi('infoPanel');

    var flickrBody = _ce('div');
//    CK.activePage = flickrBody;
    flickrBody.className = 'tabBody';
    flickrBody.id = 'flickrTab';
    flickrBody.style.display = 'block';
    flickrBody.style.textAlign = 'center';

    infoPanel.appendChild(flickrBody);

    flickrPanel = _ce('div');
    var flickrSearch = _ce('div');
    flickrPhotos = _ce('div');
    flickrPhoto = _ce('div');
    flickrSync = _ce('div');
    flickrBrowse = _ce('div');
    flickrBody.appendChild(flickrPanel);
    flickrBody.appendChild(flickrSearch);
    flickrBody.appendChild(flickrSync);
    flickrBody.appendChild(flickrBrowse);
    flickrBody.appendChild(flickrPhotos);
    flickrBody.appendChild(flickrPhoto);

    flickrPanel.id = 'flickrPanel'; 
//    flickrPanel.style.background = '#e8f2fd';
//    flickrPanel.style.textAlign = 'left';
//    flickrPanel.style.color = '#0070d7';
//    flickrPanel.style.fontSize = '12px';
//    flickrPanel.style.fontFamily = 'arial';
//    flickrPanel.style.padding = '4px';
//    flickrPanel.style.margin = '5px 5px 1px 5px';

    flickrBrowse.id = 'flickrBrowse';
    flickrBrowse.style.display = 'none';
    if( authenticated ) str = '<br /><input type="checkbox" id="flickrBrowseMode" onChange="browsePhotos(1)"><label for="flickrBrowseMode">Browse my photos only</label>';
    else str = '';
    flickrBrowse.innerHTML = str;

    flickrSync.id = 'flickrSync'; 
    flickrSync.style.display = 'none';
    str = '<h4>Sync Geotagged Photos</h4>';
    str += '<p><b>Yuan.CC Maps</b> can retrieve your geotagged photos to our database in order to support spacial search for photos. Once sync is done, you can browse your geotagged photos in Yuan.CC Maps or in <a href="http://maps.yuan.cc/kml.php?flickr_id=' +auth_nsid+ '">Google Earth</a>.</p>';
    str += '<ul><li>One-Time Sync: Click to <a href="javascript:;" onclick="syncPhotos();">sync</a> now.</li>';
    str += '<li><input id="autosync" type="checkbox" name="autosync" onclick="syncAuto();"> <label for="autosync">Automatic sync in the background.</label></li></ul>';
    str += '<div id="synclog"></div>';
    flickrSync.innerHTML = str;
    _gi('autosync').checked = (auth_sync)? true : false;

    flickrSearch.id = 'flickrSearch'; 
//    flickrSearch.style.background = '#e8f2fd';
//    flickrSearch.style.textAlign = 'left';
    flickrSearch.style.color = '#0070d7';
    flickrSearch.style.fontSize = '10px';
    flickrSearch.style.fontFamily = 'arial';
//    flickrSearch.style.padding = '2px';
//    flickrSearch.style.margin = '0px 5px 5px 5px';
    var html = '<span><input type="checkbox" id="on_the_map" checked> <b>Photos on Flickr Map</b><br />';
    html += '<b>Filter tags: </b>';
    html += '<input type=radio id="flickrtag2" name="flickrtag" value="all" onclick="searchPhotos()"><label for="flickrtag2"> None</label></span>';
    html += '<input type=radio id="flickrtag1" name="flickrtag" checked value="geotagged" onclick="searchPhotos()"><input type="text" id="searchtags" name="tags" value="geotagged" style="font-family:arial;font-size:10px" size="20" onchange="searchPhotos()"><br />';
    html += '<span class="tab" style="float:right;font-family:arial;line-height:12px;margin:2px;padding:2px;"><a href="javascript:;" onclick="searchUser()">Search</a></span>';
    html += '<b>http://flickr.com/photos/';
    html += '<input type=text id="flickruser" style="font-family:arial;font-size:10px" size=10 onchange="searchUser()">/</b><br clear=all><hr>';
//    html += '<input type=button id="flickrsearch" value="Search" onclick="searchUser()"></span><hr />';
    html += '<strong>Photostream: </strong>' + selectGroup(0,false);
    flickrSearch.innerHTML = html;

    flickrPhoto.style.padding = '0px';
    flickrPhoto.style.margin = '5px 0px 0px 0px';

    if(flickr_referrer) {
	photos[photoid] = new Object();
	photos[photoid].title = '';
	photos[photoid].lat = 999;
	photos[photoid].lon = 999;
	photos[photoid].open = true;
	_gi('flickruser').value = username;
	searchUser();
	getLatLon(photoid);
    } else {
	if(username!='' && photoid=='') {
	    _gi('flickruser').value = username;
	    searchUser();
	}
    }
    checkFlickrAuth();
}

var searchUser = function() {
    username = _gi('flickruser').value;
    if( username=='') {
	searchPhotos('',1,1);
	return;
    }
    var url = 'http://www.flickr.com/photos/' + username + '/';
    showLoadingMessage('Search user...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: 'http://flickr.com/services/rest/?method=flickr.urls.lookupUser&api_key=' + api_key + '&url=' + url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    if(!flickr_referrer) flickrPhoto.innerHTML = '';
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var users = dom.getElementsByTagName('user');
	    if( users.length == 0 ) {
		alert('No such user');
		return;
	    }
	    nsid = users[0].getAttribute('id');
	    searchPhotos(nsid,1,1);
//	    _gi('mode1').text = username + '\'s photos';
	}
    });
}

var userInfo = function(userid,callback) {
    showLoadingMessage('Read user info...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: 'http://flickr.com/services/rest/?method=flickr.people.getInfo&api_key=' +api_key+ '&user_id=' + userid,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml'
	},
	onload: callback
    });
}

var searchPhotos = function(userid,page,mode) {
        if( page == undefined || mode == undefined ) {
            mode = 0;
            userid = nsid;
            page = 1;
        }
        if(mode<=3 && page==1) {
            var str = '' + _gi('searchtags').value;
            var tags = str.replace(/ +/, ',');
            if( _gi('flickrtag1').checked ) {
		_tags = tags;
		tags_sig = 'tags' + tags + 'tag_modeall';
		tags = '&tags=' + tags + '&tag_mode=all';
	    }
            if( _gi('flickrtag2').checked ) {
		_tags = '';
		tags = '';
		tags_sig = '';
	    }
	    if( userid != '' || tags != '' ) {
		if( authenticated && userid==auth_nsid ) {
		    var method = 'flickr.photos.search';
		    var str = 'f5ac5b5817ae4d5bapi_key' + api_key + 'auth_token' + auth_token + 'method' + method + 'user_id' + userid + tags_sig + 'per_page'+ _perpage + 'page'+page;
		    var api_sig = hex_md5(str);
		    url = 'http://flickr.com/services/rest/?method=flickr.photos.search&api_key=' + api_key + '&user_id=' + userid + tags + '&per_page=' +_perpage+ '&page=' + page + '&auth_token=' + auth_token + '&api_sig=' + api_sig;
		    params = { method: method,
			user_id: userid,
			tags: _tags,
			tag_mode: 'all',
			per_page: _perpage,
			page: page,
			extras: 'geo'
		    };
		    if(_gi('on_the_map').checked) params.bbox = '-180,-90,180,90';
		    url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
		} else {
		    url = 'http://flickr.com/services/rest/?method=flickr.photos.search&api_key=' + api_key + '&user_id=' + userid + tags + '&per_page=' + _perpage;
		    params = { method: 'flickr.photos.search',
			user_id: userid,
			tags: _tags,
			tag_mode: 'all',
			per_page: _perpage,
			page: page,
			extras: 'geo'
		    }
		    if(_gi('on_the_map').checked) params.bbox = '-180,-90,180,90';
		    url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
		}
		if( userid != '' ) {
		    if( users[userid] ) _gi('flickruser').value = users[userid].path;
		    else {
			userInfo(userid, function(responseDetails) {
			    var parser = new DOMParser();
			    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
			    var photosurl = dom.getElementsByTagName('photosurl').item(0).firstChild.data;
			    var flickr_url = /^http:\/\/([w\.]*)flickr.com\/photos\/([^\/]+)/;
			    if( photosurl.match(flickr_url) ) {
				var a = flickr_url.exec(photosurl);
				username = a[2];
				_gi('flickruser').value = username;
			    }
			    users[userid] = new Object();
			    users[userid].id = userid;
			    users[userid].photosurl = photosurl;
			    users[userid].path = username;
			});
		    }
		    _userid = userid;
		    userid = '&user_id=' + userid;
		} else var _userid = '';
   		url = 'http://flickr.com/services/rest/?method=flickr.photos.search&api_key=' + api_key + userid + tags + '&per_page=' +_perpage+ '&page=' + page;
		params = { method: 'flickr.photos.search',
		    tags: _tags,
		    tag_mode: 'all',
		    per_page: _perpage,
		    page: page,
		    extras: 'geo'
		}
		if(_gi('on_the_map').checked) params.bbox = '-180,-90,180,90';
		if( _userid!='' ) params.user_id = _userid;
		url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
	    } else {
		url = 'http://flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=' +api_key+ '&per_page=' +_perpage+ '&page='+page;
//		params = { method: 'flickr.photos.getRecent',
		params = { method: 'flickr.photos.search',
		    per_page: _perpage,
		    page: page,
		    extras: 'geo'
		}
		if(_gi('on_the_map').checked) params.bbox = '-180,-90,180,90';
		url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
	    }
        }
        if(mode>=4) {
            var url = 'http://flickr.com/services/rest/?method=flickr.groups.pools.getPhotos&api_key=' +api_key+ '&group_id=' + userid + '&per_page=' +_perpage+ '&page=' + page;
	    params = { method: 'flickr.groups.pools.getPhotos',
		group_id: userid,
		per_page: _perpage,
		page: page,
		extras: 'geo'
	    }
	    if(_gi('on_the_map').checked) params.bbox = '-180,-90,180,90';
	    url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
        }
        showLoadingMessage('Loading photos...');

	if( page==1 ) {
	    pager.search_url = url;
	    url += '&page=' + page;
	    pager.params = params;
	    pager.params.page = page;
	    url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
	} else {
	    url = pager.search_url + '&page=' + page;
	    pager.params.page = page;
	    url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(pager.params);
	}

//	_gi('msgBar').innerHTML = mode + ',' + url;
//	alert(url);
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
            },
            onload: function(responseDetails) {
                hideLoadingMessage();
                var i,id;
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
		var stat = dom.getElementsByTagName('rsp')[0].getAttribute('stat');
		if(stat!='ok') {
		    var msg = dom.getElementsByTagName('err')[0].getAttribute('msg');
		    alert('Error: ' +msg);
		    return;
		}
                pages = 1*dom.getElementsByTagName('photos')[0].getAttribute('pages');
                var _photos = dom.getElementsByTagName('photo');
                flickrPhotos.innerHTML = '';
		var first_photo = null;
                for(i=0;i<_photos.length;i++) {
                    id = _photos[i].getAttribute('id');
		    if( ! photos[id] ) {
                        photos[id] = new Object();
                        photos[id].id = id;
                        photos[id].lat = 999;
                        photos[id].lon = 999;
                        photos[id].owner = _photos[i].getAttribute('owner');
                        photos[id].secret = _photos[i].getAttribute('secret');
                        photos[id].server = _photos[i].getAttribute('server');
                        photos[id].title = _photos[i].getAttribute('title');
                        photos[id].lat = 1*_photos[i].getAttribute('latitude');
                        photos[id].lon = 1*_photos[i].getAttribute('longitude');
                        photos[id].img_s = 'http://static.flickr.com/' + photos[id].server + '/' + id + '_' + photos[id].secret + '_s.jpg';
                        photos[id].img_m = 'http://static.flickr.com/' + photos[id].server + '/' + id + '_' + photos[id].secret + '_m.jpg';
                        photos[id].img = 'http://static.flickr.com/' + photos[id].server + '/' + id + '_' + photos[id].secret + '.jpg';
                        photos[id].url = 'http://www.flickr.com/photos/' + photos[id].owner + '/' + id + '/';
			if( photos[id].lat != 0 && photos[id].lon != 0) {
			    if( !first_photo ) first_photo = photos[id];
			    photos[id].datum = 'WGS84';
			    photos[id].description = '';
			    if( !photos[id].marker ) photos[id].marker = new Array();
			    if( !photos[id].marker[map.mtype] ) {
				var linktothispage = 'http://maps.yuan.cc/flickr/' + photos[id].owner + '/' + id + '/';
				var draggable = (photos[id].owner==auth_nsid) ? true: false;
				var label = (draggable) ? 'Drag to change location' :photos[id].title;
				var desc = '<div style="width:230px;font-size:10px"><a href="javascript:;" onclick="lightBox(\''+photos[id].img+'\');"><img src="' + photos[id].img_s + '" border=0 width=50 height=50 align="left" /></a><b>' + photos[id].title + '</b><br />' + photos[id].lat + ', ' + photos[id].lon + '<br />';
				desc += (photos[id].taken) ? photos[id].taken.toGMTString() : '';
				desc += '<br clear="all"><p>' + photos[id].description + '</p>See <a href="javascript:;" onclick="mode=0;_gi(\'selectgroup\').selectedIndex=0;_gi(\'searchtags\').value=\'geotagged\';changeTab(1);searchPhotos(\'' +photos[id].owner+ '\',1,1)">' + ((photos[id].username)? photos[id].username : 'owner') + '\'s geotagged photos</a>. <br /><a href="javascript:;" onclick="ping('+id+')">Ping Yuan.CC Maps</a> | <a href="'+linktothispage+'">Link to this page</a> | <a href="javascript:;" onclick="map.centerAtLatLng(map.LatLng('+photos[id].lat+','+ photos[id].lon+'))">Recenter</a></div>';
				var marker = map.Marker(map.LatLng(photos[id].lat, photos[id].lon),null,label,desc,draggable);
				marker.html = desc;
				marker.photoid = id;
				marker.addListener('mouseover', function() {
				    var lat = this.getPoint().lat();
				    var lon = this.getPoint().lng();
//				    lat = Math.round(lat*1000000)/1000000;
//				    lon = Math.round(lon*1000000)/1000000;
				    if( lat!=photos[this.photoid].lat || lon!=photos[this.photoid].lon) var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
				    else str = '';
				    this.openInfoWindowHtml(this.html + str);
				});
				marker.addListener('dragend', function() {
				    var lat = this.getPoint().lat();
				    var lon = this.getPoint().lng();
				    lat = Math.round(lat*1000000)/1000000;
				    lon = Math.round(lon*1000000)/1000000;
				    var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
				    this.openInfoWindowHtml(this.html + str);
				});
				photos[id].marker[map.mtype] = marker;
				map.addOverlay(marker);
			    }
			}
		    } else {
			if( photos[id].lat != 0 && photos[id].lon != 0) if( !first_photo ) first_photo = photos[id];
		    }
//		    if( photos[id].lat != 0 && photos[id].lon != 0 )
//                    flickrPhotos.innerHTML += '<a href="javascript:photos['+id+'].open=true;locatePhoto('+id+');" id="flickr_'+id+'" flickr="'+id+'" title="'+ photos[id].title +'"><img src="' + photos[id].img_s + '" alt="' + photos[id].title + '" width=48 height=48 style="border:solid 1px #008099;margin:1px 1px 1px 1px;-moz-opacity:0.8;" onmouseover="this.style.MozOpacity=1" onmouseout="this.style.MozOpacity=0.8" /></a>';
//		    else
                    flickrPhotos.innerHTML += '<a href="javascript:photos['+id+'].open=true;locatePhoto('+id+');" id="flickr_'+id+'" flickr="'+id+'" title="'+ photos[id].title +'"><img src="' + photos[id].img_s + '" alt="' + photos[id].title + '" border=0 width=50 height=50 style="margin:1px 1px 1px 1px;-moz-opacity:0.8;" onmouseover="this.style.MozOpacity=1" onmouseout="this.style.MozOpacity=0.8" /></a>';
		    photos[id].open = false;
//		    requestQueue.push(id);
                }
		if( first_photo && first_photo.marker && first_photo.marker[map.mtype] && !flickr_referrer) {
		    first_photo.marker[map.mtype].openInfoWindowHtml(first_photo.marker[map.mtype].html);
		}
                var _page = _ce('div');
                _page.style.margin = '5px';
                _page.style.fontFamily = 'arial';
                _page.style.fontSize = '12px';
                _page.innerHTML = pager.html(page,pages);
                flickrPhotos.appendChild(_page);
            }
        });
}

function runQueue() {
    if( requestQueue.length == 0 ) return;
    locatePhoto(requestQueue.pop());
    setTimeout('runQueue()', 1500);
}

var ping = function(photoid) {
    var url = 'http://maps.yuan.cc/api.php?method=flickr.ping&photo_id='+photoid;
    showLoadingMessage('Ping Yuan.CC Maps ...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var stat = dom.getElementsByTagName('rsp')[0].getAttribute('stat');
	    var msg = dom.getElementsByTagName('rsp').item(0).firstChild.data;
	    if(stat=='ok') {
		showLoadingMessage('Successful. ' + msg);
	    } else {
		showLoadingMessage('Fail. ' + msg);
	    }
	    ping_localizeus(photoid);
	}
    });
}

var ping_localizeus = function(photoid) {
    var url = 'http://alize.us/flickr/ping?id='+photoid;
    showLoadingMessage('Ping loc.alize.us ...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    return;
/*
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var stat = dom.getElementsByTagName('rsp')[0].getAttribute('stat');
	    var msg = dom.getElementsByTagName('rsp').item(0).firstChild.data;
	    if(stat=='ok') {
		showLoadingMessage('Successful. ' + msg);
	    } else {
		showLoadingMessage('Fail. ' + msg);
	    }
*/
	}
    });
}

var syncAuto = function() {
    var login_id;

    if( !authenticated ) return;
    if( login_userid ) login_id = login_userid;
    else login_id = '';
    auth_sync = _gi('autosync').checked;
    var url = 'http://maps.yuan.cc/mapi.php?method=flickr.sync&userid=' +auth_nsid+ '&sync=' + auth_sync + '&login_id=' + login_id;
    showLoadingMessage('Saving auto-sync setting ...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var stat = dom.getElementsByTagName('autosync')[0].getAttribute('stat');
	    if(stat=='true') {
		_gi('autosync').checked = true;
		_gi('synclog').innerHTML = '<p style="color:red">Auto-sync enabled.</p><p>Yuan.CC Maps will fetch geo-info of your photos from Flickr to our database in the background periodically, so you can see all your geotagged photos in Yuan.CC Maps or <a href="http://maps.yuan.cc/kml.php?flickr_id=' +auth_nsid+ '">Google Earth</a>.</p>';
	    } else {
		_gi('autosync').checked = false;
		_gi('synclog').innerHTML = '<p style="color:red">Auto-sync disabled.</p><p>Yuan.CC Maps have stopped to fetch your geotagged photos. No more new photo info will be updated.</p>';
	    }
	}
    });
}

var syncPhotos = function() {

    if( !authenticated ) return;

    var syncing = function(page, total) {
	var _perpage = 5;

	if( _stop ) return;
	if( (page+1)*_perpage > total) {
	    _gi('synclog').innerHTML += '<p>Sync geotagged photos done.';
	    return;
	}
	var url = 'http://maps.yuan.cc/sync_flickr.php?perpage=' +_perpage+ '&page=' +page+ '&nsid='+auth_nsid+ '&login_id=' + login_userid;
	GM_xmlhttpRequest({
	    method: 'GET',
	    url: url,
	    headers: {
		'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
		'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	    },
	    onload: function(responseDetails) {
		_gi('synclog').innerHTML = 'Page ' + page + '<p>';
		_gi('synclog').innerHTML += responseDetails.responseText;
		_gi('synclog').innerHTML += '</p><a href="javascript:;" onclick="_stop=true;">Stop syncing</a> ...';
		syncing(page+1,total);
	    }
	});
    }

    url = 'http://flickr.com/services/rest/?method=flickr.photos.search&api_key=' + api_key + '&user_id=' + auth_nsid + '&tags=geotagged&per_page=1&page=1';
//    _gi('synclog').innerHTML = url + '<p>';
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var photo_count = 1*dom.getElementsByTagName('photos')[0].getAttribute('total');
	    _gi('synclog').innerHTML = 'Total geotagged photos: ' + photo_count;
	    _stop = false;
	    syncing(1,photo_count);
	}
    });

}

var browsePhotos = function(p) {

    if( _flickr_mode != 'browse' ) return;

    var minX = map.getBoundsLatLng().minX;
    var minY = map.getBoundsLatLng().minY;
    var maxX = map.getBoundsLatLng().maxX;
    var maxY = map.getBoundsLatLng().maxY;
/*
    var url = 'http://maps.yuan.cc/api.php?method=flickr.search&';
    url += 'BBOX=' + minX + ',' + minY + ',' + maxX + ',' + maxY;
    url += '&page=' +p+ '&perpage=' + _perpage;
    if( Flickr.browse_filter!='' ) url += '&flickr_id=' + Flickr.browse_filter;
    else if( authenticated && _gi('flickrBrowseMode').checked ) url += '&flickr_id=' + auth_nsid;
*/

    var userid='';
    if( Flickr.browse_filter!='' ) userid = Flickr.browse_filter;
    else if( authenticated && _gi('flickrBrowseMode').checked ) userid = auth_nsid;
    params = { method: 'flickr.photos.search',
	tags: 'geotagged',
	tag_mode: 'all',
	per_page: _perpage,
	page: p,
	extras: 'geo'
    }
    if( userid!='' ) params.user_id = userid;
    params.bbox = minX + ',' + minY + ',' + maxX + ',' + maxY;
    var url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
//  flickrPhotos.innerHTML = '<textarea>' +url+ '</textarea>';

    if( true || _flickr_mode == 'browse' ) {
        showLoadingMessage('Browsing photos...');
//	showLoadingMessage(minX + ',' + minY +','+ maxX +','+ maxY );
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
            },
            onload: function(responseDetails) {
                hideLoadingMessage();
                var i,id;
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
                var pages = 1*dom.getElementsByTagName('photos')[0].getAttribute('pages');
                var page = 1*dom.getElementsByTagName('photos')[0].getAttribute('page');
                var _photos = dom.getElementsByTagName('photo');
		if( _photos.length==0 ) flickrPhotos.innerHTML = '<span style="color:#aaa">No geotagged photos in this area.</span>';
		else flickrPhotos.innerHTML = '';
                for(i=0;i<_photos.length;i++) {
                    id = _photos[i].getAttribute('id');
		    if( ! photos[id] ) photos[id] = new Object();
		    photos[id].id = id;
//		    photos[id].lat = 1* _photos[i].getElementsByTagName('latitude').item(0).firstChild.data;
//		    photos[id].lon = 1* _photos[i].getElementsByTagName('longitude').item(0).firstChild.data;
		    photos[id].lat = 1* _photos[i].getAttribute('latitude');
		    photos[id].lon = 1* _photos[i].getAttribute('longitude');
		    photos[id].owner = _photos[i].getAttribute('owner');
		    photos[id].secret = _photos[i].getAttribute('secret');
		    photos[id].server = _photos[i].getAttribute('server');
//		    photos[id].title = _photos[i].getElementsByTagName('title').item(0).firstChild.data;
		    photos[id].title = _photos[i].getAttribute('title');
		    photos[id].img_s = 'http://static.flickr.com/' + photos[id].server + '/' + id + '_' + photos[id].secret + '_s.jpg';
		    photos[id].img_m = 'http://static.flickr.com/' + photos[id].server + '/' + id + '_' + photos[id].secret + '_m.jpg';
		    photos[id].img = 'http://static.flickr.com/' + photos[id].server + '/' + id + '_' + photos[id].secret + '.jpg';
		    photos[id].url = 'http://www.flickr.com/photos/' + photos[id].owner + '/' + id + '/';
		    photos[id].datum = 'WGS84';
		    photos[id].description = '';
		    if( !photos[id].marker ) photos[id].marker = new Array();
		    if( !photos[id].marker[map.mtype] ) {
			var draggable = (photos[id].owner==auth_nsid) ? true: false;
			var label = (draggable) ? 'Drag to change location' :photos[id].title;
			var linktothispage = 'http://maps.yuan.cc/flickr/' + photos[id].owner + '/' + id + '/';
			var desc = '<div style="width:230px;font-size:10px"><a href="javascript:;" onclick="lightBox(\''+photos[id].img+'\');"><img src="' + photos[id].img_s + '" border=0 width=50 height=50 align="left" /></a><b>' + photos[id].title + '</b><br />' + photos[id].lat + ', ' + photos[id].lon + '<br clear="all"><p>' + photos[id].description + '</p>See <a href="javascript:;" onclick="mode=0;_gi(\'selectgroup\').selectedIndex=0;_gi(\'searchtags\').value=\'geotagged\';changeTab(1);searchPhotos(\'' +photos[id].owner+ '\',1,1)">' + ( (photos[id].username) ? photos[id].username:'owner') + '\'s geotagged photos</a>. <br /><a href="javascript:;" onclick="ping('+id+')">Ping Yuan.CC Maps</a> | <a href="'+linktothispage+'">Link to this page</a> | <a href="javascript:;" onclick="map.centerAtLatLng(map.LatLng('+photos[id].lat+','+ photos[id].lon+'))">Recenter</a></div>';
			var marker = map.Marker(map.LatLng(photos[id].lat, photos[id].lon),null,label,desc,draggable);
			marker.html = desc;
			marker.photoid = id;
			marker.addListener('mouseover', function() {
			    var lat = this.getPoint().lat();
			    var lon = this.getPoint().lng();
//			    lat = Math.round(lat*1000000)/1000000;
//			    lon = Math.round(lon*1000000)/1000000;
			    if( lat!=photos[this.photoid].lat || lon!=photos[this.photoid].lon) var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
			    else str = '';
			    this.openInfoWindowHtml(this.html + str);
			});
			marker.addListener('dragend', function() {
			    var lat = this.getPoint().lat();
			    var lon = this.getPoint().lng();
			    lat = Math.round(lat*1000000)/1000000;
			    lon = Math.round(lon*1000000)/1000000;
			    var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
			    this.openInfoWindowHtml(this.html + str);
			});
			photos[id].marker[map.mtype] = marker;
			map.addOverlay(marker);
		    }
		    flickrPhotos.innerHTML += '<a href="javascript:photos['+id+'].open=true;locatePhoto('+id+');" id="flickr_'+id+'" flickr="'+id+'" title="'+ photos[id].title +'"><img src="' + photos[id].img_s + '" alt="' + photos[id].title + '" border=0 width=50 height=50 style="margin:1px 1px 1px 1px;-moz-opacity:0.8;" onmouseover="this.style.MozOpacity=1" onmouseout="this.style.MozOpacity=0.8" /></a>';
//		    locatePhoto(id,photos[id].lat,photos[id].lon);
                }

                var _page = _ce('div');
                _page.style.margin = '5px';
                _page.style.fontFamily = 'arial';
                _page.style.fontSize = '12px';
                _page.innerHTML = pager.html(page,pages);
                flickrPhotos.appendChild(_page);
            }
        });
    }
}

var browseUsers = function(p) {

    var minX = map.getBoundsLatLng().minX;
    var minY = map.getBoundsLatLng().minY;
    var maxX = map.getBoundsLatLng().maxX;
    var maxY = map.getBoundsLatLng().maxY;
    var url = 'http://maps.yuan.cc/api.php?method=flickr.browseusers&';
    url += 'BBOX=' + minX + ',' + minY + ',' + maxX + ',' + maxY;
    if( true || _flickr_mode == 'browse_users' ) {
        showLoadingMessage('Searching users...');
//	showLoadingMessage(minX + ',' + minY +','+ maxX +','+ maxY );
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
            },
            onload: function(responseDetails) {
                hideLoadingMessage();
                var i,id;
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
                var users = dom.getElementsByTagName('user');
		var buddy = 'http://maps.yuan.cc/buddy24.png';
		var html = '<div style="width:100%;text-align:right;"><a id="search_close" href="javascript:;" onclick="this.parentNode.parentNode.style.display=\'none\';clearOnMapUsers();">Close</a><hr></div><h4><a href="javascript:;" onclick="browseUsers()">Who\'ve been here?</a></h4>';
		if( users.length==0 ) html += '<span style="color:#aaa">No user visited this area.</span>';
                for(i=0;i<users.length;i++) {
                    var nsid = users[i].getAttribute('nsid');
                    var count = users[i].getAttribute('count');
		    var icon_img = users[i].getElementsByTagName('icon').item(0).firstChild.data;
		    var home = users[i].getElementsByTagName('home').item(0).firstChild.data;
		    var username = users[i].getElementsByTagName('username').item(0).firstChild.data;
		    var lat = 1* users[i].getElementsByTagName('lat').item(0).firstChild.data;
		    var lon = 1* users[i].getElementsByTagName('lon').item(0).firstChild.data;
		    var photosurl = users[i].getElementsByTagName('photosurl').item(0).firstChild.data;
		    var profileurl = users[i].getElementsByTagName('profileurl').item(0).firstChild.data;
		    if( !flickr_users[nsid] ) flickr_users[nsid] = new Object();
		    if( !flickr_users[nsid].marker ) flickr_users[nsid].marker = new Array();
		    if( !flickr_users[nsid].marker[map.mtype] ) {
			var label = username;
			var linktothispage = 'http://maps.yuan.cc/flickr/' + nsid + '/';
			var desc = '<div style="width:230px;font-size:10px"><img src="' + icon_img + '" border=0 width=45 height=45 align="left" /><b>' + username + '</b><br />From ' + home + '<br />' + lat + ', ' + lon + '<br />Hi, I\'ve been here.<br clear="all"><a href="javascript:;" onclick="_gi(\'menu\').value=\'flickr\';selectMenu(_gi(\'menu\'));mode=0;_gi(\'selectgroup\').selectedIndex=0;_gi(\'searchtags\').value=\'geotagged\';changeTab(1);searchPhotos(\'' +nsid+ '\',1,1)">All my geotagged photos</a> | <a href="javascript:;" onclick="_gi(\'menu\').value=\'flickr\';selectMenu(_gi(\'menu\'));mode=0;_gi(\'selectgroup\').selectedIndex=0;_gi(\'searchtags\').value=\'geotagged\';Flickr.browse_filter=\''+nsid+'\';changeTab(2);">My nearby photos</a><br /> <a href="'+profileurl+'" target="_blank">Profile</a> | <a href="'+photosurl+'" target="_blank">Photos</a> | <a href="http://www.flickr.com/relationship.gne?id='+nsid+'" target="_blank">Add Contact</a></div>';
			var icon = map.Icon();
//			icon.setup(buddy,24,24,24,12,12,12);
			icon.setup(buddy,24,24,10,21,12,12);
			var marker = map.Marker(map.LatLng(lat, lon),icon,username,desc,false);
			marker.html = desc;
			marker.photoid = id;
			marker.addListener('mouseover', function() {
			    var lat = this.getPoint().lat();
			    var lon = this.getPoint().lng();
			    lat = Math.round(lat*1000000)/1000000;
			    lon = Math.round(lon*1000000)/1000000;
			    this.openInfoWindowHtml(this.html);
			});
			flickr_users[nsid].marker[map.mtype] = marker;
			map.addOverlay(marker);
		    } else {
			var marker = flickr_users[nsid].marker[map.mtype];
			marker.setPoint(map.LatLng(lat, lon));
		    }
		    html += '<a href="javascript:;" title="'+ username +'" onclick="var t=flickr_users[\''+nsid+'\'].marker[map.mtype];t.openInfoWindowHtml(t.html);"><img src="' + icon_img + '" alt="' + username + '" border=0 width=48 height=48 style="margin:1px 1px 1px 1px;-moz-opacity:0.7;" onmouseover="this.style.MozOpacity=1" onmouseout="this.style.MozOpacity=0.7" /></a>';
                }
		_gi('searchwell').innerHTML = html;
		_gi('searchwell').style.display = 'block';
            }
        });
    }
}

var clearOnMapUsers = function() {
	for(var i in flickr_users) {
	    map.removeOverlay(flickr_users[i].marker[map.mtype]);
	    delete flickr_users[i].marker;
	    delete flickr_users[i];
	}
}

var showLoadingMessage = function(message) {
	_gi('msgBar').innerHTML = '<span style="background:red;color:white;font-family:arial;padding:2px;">' +message+ '</span>';
	return;
        var loadingMessage;
        if (message) loadingMessage = message;
        else loadingMessage = "Loading...";
        var disabledZone = _gi('disabledZone');
        if (!disabledZone) {
            disabledZone = document.createElement('div');
            disabledZone.setAttribute('id', 'disabledZone');
            disabledZone.style.position = "absolute";
            disabledZone.style.zIndex = 1000;
            disabledZone.style.left = "0px";
            disabledZone.style.top = "0px";
            disabledZone.style.width = "100%";
            disabledZone.style.height = "100%";
            document.body.appendChild(disabledZone);
            var messageZone = document.createElement('div');
            messageZone.setAttribute('id', 'messageZone');
            messageZone.style.position = "absolute";
            messageZone.style.top = "0px";
            messageZone.style.right = "0px";
            messageZone.style.background = "red";
            messageZone.style.color = "white";
            messageZone.style.fontFamily = "Arial,Helvetica,sans-serif";
            messageZone.style.padding = "4px";
            disabledZone.appendChild(messageZone);
            var text = document.createTextNode(loadingMessage);
            messageZone.appendChild(text);
        } else {
            _gi('messageZone').innerHTML = loadingMessage;
            disabledZone.style.visibility = 'visible';
        }
}

var hideLoadingMessage = function() {
    _gi('msgBar').innerHTML = ''; return;
    _gi('disabledZone').style.visibility = 'hidden';
}

var selectGroup = function(mode,groupOnly) {
    var html=m1=m2=m3=m4=m5='';

    if( !groupOnly ) {
	onchange = ' onChange="onChangeSelGroup(this)"';
	sel_id = 'selectgroup';
    } else {
	onchange = '';
	sel_id = 'selectgroup2';
    }
    for(var i in Flickr_Groups) {
	if(mode == Flickr_Groups[i].mode) Flickr_Groups[i].selected = 'selected';
	else Flickr_Groups[i].selected = '';
    }
    html += '<select id="' +sel_id+ '" style="font-family:arial;font-size:10px;margin-right:10px" ' + onchange + '>';
    if( !groupOnly ) {
	html += '<option value="">Select Photostream</option>';
	html += '<option value="geotagged" ' + m1 + ' >Tag: geotagged</option>';
	html += '<option value="geo:tool=yuan.cc" ' + m2 + ' >Tag: geo:tool=yuancc</option>';
	html += '<option value="geo:tool=gmif" ' + m3 + ' >Tag: geo:tool=GMiF</option>';
    } else html += '<option value="">Select Group</option>';
    for(var i in Flickr_Groups)
	html += '<option value="' +Flickr_Groups[i].id+ '" ' + Flickr_Groups[i].selected + ' >' +Flickr_Groups[i].name+ '</option>';

    html += '</select>';
    return html;
}

var onChangeSelGroup = function(s) {
        if( s.value == '' ) return;
        if( s.value == 'geotagged' ) {
            mode = 1;
            photostream = '';
	    _gi('searchtags').value = 'geotagged';
	    _gi('flickruser').value = '';
            searchPhotos(photostream,1,mode);
	    return;
        }
        if( s.value == 'geo:tool=yuan.cc' ) {
            mode = 2;
            photostream = '';
	    _gi('searchtags').value = 'geo:tool=yuan.cc';
	    _gi('flickruser').value = '';
            searchPhotos(photostream,1,mode);
	    return;
        }
        if( s.value == 'geo:tool=gmif' ) {
            mode = 3;
            photostream = '';
	    _gi('searchtags').value = 'geo:tool=gmif';
	    _gi('flickruser').value = '';
            searchPhotos(photostream,1,mode);
	    return;
        }
	mode = Flickr_Groups[s.value].mode;
	photostream = Flickr_Groups[s.value].id;
	searchPhotos(Flickr_Groups[s.value].id,1,Flickr_Groups[s.value].mode);
}

pager.changePage = function(p) {
//    alert('mode=' + mode + ', page=' + p);
    page = p;
    if( _flickr_mode == 'search' ) {
	if(mode==0) searchPhotos(nsid,p,mode);
	else searchPhotos(photostream,p,mode);
    }
    if( _flickr_mode == 'browse' ) {
	browsePhotos(p);
    }
}

pager.html = function(page,pages) {

    if( pages == 1 ) return '';

    var i, str='Page: ';

    if( pages > 1 && pages <= 10 ) {
        for(i=1; i<=pages; i++) {
            if( i==page ) str += '<a href="javascript:;"><font color=red><b>' + i + '</b></font></a> ';
            else str += '<a href="javascript:;" onClick="pager.changePage('+i+')"><b>' + i + '</b></a> ';
        }
    } else if( pages>10 && page < 10 ) {
        for(i=1; i<=10; i++) {
            if( i==page ) str += '<a href="javascript:;"><font color=red><b>' + i + '</b></font></a> ';
            else str += '<a href="javascript:;" onClick="pager.changePage(' + i + ')"><b>' + i + '</b></a> ';
        }
        i = Math.round((10+1*pages)/2);
        if( i != pages ) str += '...<a href="javascript:;" onClick="pager.changePage(' + i + ')"><b>' + i + '</b></a>...';
        str += '<a href="javascript:;" onClick="pager.changePage(' + pages + ')"><b>' + pages + '</b></a> ';
    } else if( pages>10 && page>=10 && page<(pages-5) ) {
        str += '<a href="javascript:;" onClick="pager.changePage(' +1+ ')"><b>' + 1 + '</b></a>...';
        i = Math.round((page-2)/2);
        str += '<a href="javascript:;" onClick="pager.changePage(' + i + ')"><b>' + i + '</b></a>...';
        for(i=(page-2); i<=(page+2); i++) {
            if( i==page ) str += '<a href="javascript:;"><font color=red><b>' + i + '</b></font></a> ';
            else str += '<a href="javascript:;" onClick="pager.changePage(' + i + ') "><b>' + i + '</b></a> ';
        }
        i = Math.round((1*i+1*pages)/2);
        str += '...<a href="javascript:;" onClick="pager.changePage(' + i + ')"><b>' + i + '</b></a> ';
        str += '...<a href="javascript:;" onClick="pager.changePage(' + pages + ')"><b>' + pages + '</b></a> ';
    } else if( pages>10 && page>=10 & page>=(pages-5) ) {
        i = Math.round((page-2)/2);
        str += '<a href="javascript:;" onClick="pager.changePage(' +1+ ')"><b>' + 1 + '</b></a>...';
        str += '<a href="javascript:;" onClick="pager.changePage(' +i+ ')"><b>' + i + '</b></a>...';
        for(i=page-3; i<=pages; i++) {
            if( i==page ) str += '<a href="javascript:;"><font color=red><b>' + i + '</b></font></a> ';
            else str += '<a href="javascript:;" onClick="pager.changePage(' + i + ')"><b>' + i + '</b></a> ';
        }
    }

    return str;
}

function locatePhoto(id,lat,lon) {
    CK.photoid = id;
    var linktothispage = 'http://maps.yuan.cc/flickr/' + photos[id].owner + '/' + id + '/';
    if( lat == null || lat == undefined || flickrPhoto.innerHTML=='' ) {
	var html='';
	if( photos[id].title == undefined ) photos[id].title = '';
	html += '<div style="float:right;width:16px;height:16px;margin:4px 8px 0px 0px;padding:0px"><a href="'+linktothispage+'" title="Link to this page"><img src="http://maps.google.com/intl/en_ALL/mapfiles/bar_icon_link.gif" border="0" /></a></div>';
	html += '<div style="padding:2px 4px 0px 4px;border:1px solid #444;background:#fff;margin:2px 5px 2px 5px;text-align:center;">';
	html += '<p style="margin:0px 0px 0px 0px;padding:4px 0px 0px 0px"><span style="font-size:15px;font-weight:bolder;"><strong>' + photos[id].title + '</strong></span><br /><span id="geotags" style="font-family:arial;font-size:11px"></span> ';
	html += '<input id="addtags" type=button flickr="'+id+'" style="font-family:arial;font-size:11px" value="Save Location" onclick="addGeoTags()">';
	if(GPS.points.length) html += ' <a title="Match GPS Track" style="font-family:arial;font-size:8px;" href="javascript:;" onclick="GPS.matchTrack(\'' +id+ '\')">GPS</a>';
	html += '<br />';
	html += selectGroup(0,true) + '<input id="addtopool" type="button" flickr="'+id+'" style="font-family:arial;font-size:11px" value="Add" onclick="addToPool()"></p>';
	html += '<p style="margin-bottom:4px"><a id="photolink"' +id+ ' href="' + photos[id].url + '" target="_blank"><img id="photo' +id+ '" src="' + photos[id].img_m + '" border="0" /></a></p>';
//	html += '<p style="margin-bottom:4px"><div style="width:240px;height:180px;border:0px;background-image:url(' +photos[id].img_m+ ');"></div></p>';
	html += '</div>';
	if( id == _init_photoid || flickr_referrer) photos[id].open = true;
	if(photos[id].open) flickrPhoto.innerHTML = html;

	if( auth_nsid != photos[id].owner && _gi('addtags') && _gi('addtopool') ) {
	    _gi('addtags').disabled = true;
	    _gi('addtopool').disabled = true;
	}
//	_gi('cursorphoto').innerHTML = '';
	if( photos[id].lat == 999 ) {
	    getLatLon(id);
	    return;
	}
	if( photos[id].taken == undefined ) getPhotoInfo(id);
    }
    if( photos[id].height>180 && _gi('photo'+id) ) _gi('photo'+id).height = 180;
    if( photos[id].datum == 'WGS84' ) {
	if( _latlon == 'DM.m' ) {
	    var photo_lon = Dd_to_DMm(photos[id].lon,'lon');
	    var photo_lat = Dd_to_DMm(photos[id].lat,'lat');
	} else {
	    var photo_lon = photos[id].lon;
	    var photo_lat = photos[id].lat;
	}
	if(photos[id].open) _gi('geotags').innerHTML = '' + photo_lat + ', ' + photo_lon;
//	_gi('cursorphoto').innerHTML = '<img src="' + photos[id].img_s + '" width=50 height=50 style="-moz-opacity:0.5;" onmouseover="this.style.MozOpacity=1" onmouseout="this.style.MozOpacity=0.5" />';
	if( !photos[id].marker[map.mtype] ) {
	    if( photos[id].description == undefined ) photos[id].description='';
	    var draggable = (photos[id].owner==auth_nsid) ? true: false;
	    var label = (draggable) ? 'Drag to change location' :photos[id].title;
	    var desc = '<div style="width:230px;font-size:10px"><a href="javascript:;" onclick="lightBox(\''+photos[id].img+'\');"><img src="' + photos[id].img_s + '" border=0 width=50 height=50 align="left" /></a><b>' + photos[id].title + '</b><br />' + photos[id].lat + ', ' + photos[id].lon + '<br />';
	    desc += (photos[id].taken) ? photos[id].taken.toGMTString() : '';
	    desc += '<br clear="all"><p>' + photos[id].description + '</p>See <a href="javascript:;" onclick="mode=0;_gi(\'selectgroup\').selectedIndex=0;_gi(\'searchtags\').value=\'geotagged\';changeTab(1);searchPhotos(\'' +photos[id].owner+ '\',1,1)">' + ((photos[id].username)? photos[id].username : 'owner') + '\'s geotagged photos</a>. <br /><a href="javascript:;" onclick="ping('+id+')">Ping Yuan.CC Maps</a> | <a href="'+linktothispage+'">Link to this page</a> | <a href="javascript:;" onclick="map.centerAtLatLng(map.LatLng('+photos[id].lat+','+ photos[id].lon+'))">Recenter</a></div>';
	    var marker = map.Marker(map.LatLng(photos[id].lat, photos[id].lon),null,label,desc,draggable);
	    marker.html = desc;
	    marker.photoid = id;
	    marker.addListener('mouseover', function() {
		var lat = this.getPoint().lat();
		var lon = this.getPoint().lng();
//		lat = Math.round(lat*1000000)/1000000;
//		lon = Math.round(lon*1000000)/1000000;
		if( lat!=photos[this.photoid].lat || lon!=photos[this.photoid].lon) var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
		else str = '';
		this.openInfoWindowHtml(this.html + str);
	    });
	    marker.addListener('dragend', function() {
		var lat = this.getPoint().lat();
		var lon = this.getPoint().lng();
		lat = Math.round(lat*1000000)/1000000;
		lon = Math.round(lon*1000000)/1000000;
		var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
		marker.openInfoWindowHtml(marker.html + str);
	    });
	    photos[id].marker[map.mtype] = marker;
	    map.addOverlay(marker);
	}
	var lat = photos[id].marker[map.mtype].getPoint().lat();
	var lon = photos[id].marker[map.mtype].getPoint().lng();
//	lat = Math.round(lat*1000000)/1000000;
//	lon = Math.round(lon*1000000)/1000000;
	if( lat!=photos[id].lat || lon!=photos[id].lon) var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
	else str ='';
	if(photos[id].open) photos[id].marker[map.mtype].openInfoWindowHtml(photos[id].marker[map.mtype].html +str);
	return;
    }
}

function showLatLon(x,ll) {

    if( _latlon == 'D.d' ) {
	x = Math.round(x*1000000)/1000000;
	return x;
    }
    if( _latlon == 'DM.m' ) {
	return Dd_to_DMm(x,ll);
    }
}

function getLatLon(id) {

    var callback = function(result) {
	hideLoadingMessage();
	var parser = new DOMParser();
	var dom = parser.parseFromString(result.responseText, "application/xml");
	var pid = dom.getElementsByTagName('photo').item(0).getAttribute('id');

	if(!photos[pid]) photos[pid] = new Object();
	photos[pid].id = id;
	photos[pid].lat = 999;
	photos[pid].lon = 999;
	photos[pid].owner = dom.getElementsByTagName('owner').item(0).getAttribute('nsid');
	photos[pid].username = dom.getElementsByTagName('owner').item(0).getAttribute('username');
	photos[pid].secret = dom.getElementsByTagName('photo').item(0).getAttribute('secret');
	photos[pid].server = dom.getElementsByTagName('photo').item(0).getAttribute('server');
	photos[pid].title = (dom.getElementsByTagName('title').item(0).firstChild) ? dom.getElementsByTagName('title').item(0).firstChild.data : '';
	photos[pid].description = (dom.getElementsByTagName('description').item(0).firstChild) ? dom.getElementsByTagName('description').item(0).firstChild.data : '';
	photos[pid].img_s = 'http://static.flickr.com/' + photos[pid].server + '/' + pid + '_' + photos[pid].secret + '_s.jpg';
	photos[pid].img_m = 'http://static.flickr.com/' + photos[pid].server + '/' + pid + '_' + photos[pid].secret + '_m.jpg';
	photos[pid].img = 'http://static.flickr.com/' + photos[pid].server + '/' + pid + '_' + photos[pid].secret + '.jpg';
	photos[pid].url = 'http://www.flickr.com/photos/' + photos[pid].owner + '/' + pid + '/';

        var rExp = /\\'/gi;
	var str = '' + photos[pid].description;
        str = str.replace(rExp, "'")
	photos[pid].description = str;

	var taken = dom.getElementsByTagName('dates').item(0).getAttribute('taken');
	var date_pattern = /(\d+)-(\d+)-(\d+) +(\d+):(\d+):(\d+)/;
	if( taken.match(date_pattern) ) {
	    var a = date_pattern.exec(taken);
	    var year = a[1];
	    var mon = 1*a[2]-1;
	    var day = a[3];
	    var hour = a[4];
	    var min = a[5];
	    var sec = a[6];
	    photos[pid].taken = new Date(year,mon,day,hour,min,sec,0);
	}

	var tags = dom.getElementsByTagName('tag');
	for(var i=0; i<tags.length; i++) {
	    var splits = tags[i].getAttribute('raw').split('=');
	    if( splits[0] == 'geo:lat' ) { var lat = convCoords(splits[1]); var tag_lat = tags[i].getAttribute('id'); }
	    if( splits[0] == 'geo:lon' || splits[0] == 'geo:long' ) { var lon = convCoords(splits[1]); var tag_lon = tags[i].getAttribute('id'); }
	}

// Test for Geo API 
/*
if( auth_nsid == '62869273@N00' ) {
	GeoAPI.getLocation(pid, function(id,lat,lon) {
		locatePhoto(id,lat,lon);
	    });
} else {
*/
	if( lat != undefined && lon != undefined ) {
	    photos[pid].tag_lat = tag_lat;
	    photos[pid].tag_lon = tag_lon;
	    photos[pid].lat = lat;
	    photos[pid].lon = lon;
	    photos[pid].datum = 'WGS84';
	    photos[pid].marker = new Array();
	    locatePhoto(pid,lat,lon);
	} else {
	    var getExif_callback = function(pid,lat,lon) {
		photos[pid].lat = lat;
		photos[pid].lon = lon;
		photos[pid].datum = 'WGS84';
		photos[pid].marker = new Array();
		locatePhoto(pid,lat,lon);
	    }
	    getExif(pid,photos[pid],getExif_callback);
	}
// }
// Test for Geo API 

	var setsize = function(result,id){
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(result.responseText, "application/xml");
	    var sizes = dom.getElementsByTagName('size');
	    for(i=0;i<sizes.length;i++) {
		if( sizes[i].getAttribute('label') == 'Small' ) {
		    var h = 1*sizes[i].getAttribute('height');
		    var w = 1*sizes[i].getAttribute('width');
		}
	    }
	    photos[id].width = w;
	    photos[id].height = h;
	    if( h>180 && _gi('photo'+id) ) _gi('photo'+id).height = 180;
	}
	showLoadingMessage('Get photo size...');
	GM_xmlhttpRequest({
	    method: 'GET',
	    url: 'http://flickr.com/services/rest/?method=flickr.photos.getSizes&api_key=' +api_key+ '&photo_id=' + id,
	    headers: {
		'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
		'Accept': 'application/atom+xml,application/xml,text/xml'
	    },
	    onload: function(result) { setsize(result,id); }
	});
    }

    if( photos[id] && photos[id].lat != 999 && photos[id].lon != 999 ) {
	locatePhoto(id,photos[id].lat,photos[id].lon);
	return;
    }
    showLoadingMessage('Read photoinfo...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: 'http://flickr.com/services/rest/?method=flickr.photos.getInfo&api_key=' +api_key+ '&photo_id=' + id,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml'
	},
	onload: callback
    });
}

function getPhotoInfo(id) {

    var callback = function(result) {
	hideLoadingMessage();
	var parser = new DOMParser();
	var dom = parser.parseFromString(result.responseText, "application/xml");
	var pid = dom.getElementsByTagName('photo').item(0).getAttribute('id');

	if(!photos[pid]) photos[pid] = new Object();
	photos[pid].id = id;
	photos[pid].owner = dom.getElementsByTagName('owner').item(0).getAttribute('nsid');
	photos[pid].username = dom.getElementsByTagName('owner').item(0).getAttribute('username');
	photos[pid].secret = dom.getElementsByTagName('photo').item(0).getAttribute('secret');
	photos[pid].server = dom.getElementsByTagName('photo').item(0).getAttribute('server');
	photos[pid].title = (dom.getElementsByTagName('title').item(0).firstChild) ? dom.getElementsByTagName('title').item(0).firstChild.data : '';
	photos[pid].description = (dom.getElementsByTagName('description').item(0).firstChild) ? dom.getElementsByTagName('description').item(0).firstChild.data : '';
	photos[pid].img_s = 'http://static.flickr.com/' + photos[pid].server + '/' + pid + '_' + photos[pid].secret + '_s.jpg';
	photos[pid].img_m = 'http://static.flickr.com/' + photos[pid].server + '/' + pid + '_' + photos[pid].secret + '_m.jpg';
	photos[pid].img = 'http://static.flickr.com/' + photos[pid].server + '/' + pid + '_' + photos[pid].secret + '.jpg';
	photos[pid].url = 'http://www.flickr.com/photos/' + photos[pid].owner + '/' + pid + '/';

        var rExp = /\\'/gi;
	var str = '' + photos[pid].description;
        str = str.replace(rExp, "'")
	photos[pid].description = str;

	var taken = dom.getElementsByTagName('dates').item(0).getAttribute('taken');
	var date_pattern = /(\d+)-(\d+)-(\d+) +(\d+):(\d+):(\d+)/;
	if( taken.match(date_pattern) ) {
	    var a = date_pattern.exec(taken);
	    var year = a[1];
	    var mon = 1*a[2]-1;
	    var day = a[3];
	    var hour = a[4];
	    var min = a[5];
	    var sec = a[6];
	    photos[pid].taken = new Date(year,mon,day,hour,min,sec,0);
	}

	var setsize = function(result,id){
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(result.responseText, "application/xml");
	    var sizes = dom.getElementsByTagName('size');
	    for(i=0;i<sizes.length;i++) {
		if( sizes[i].getAttribute('label') == 'Small' ) {
		    var h = 1*sizes[i].getAttribute('height');
		    var w = 1*sizes[i].getAttribute('width');
		}
	    }
	    photos[id].width = w;
	    photos[id].height = h;
	    if( h>180 && _gi('photo'+id) ) _gi('photo'+id).height = 180;
	}
	showLoadingMessage('Get photo size...');
	GM_xmlhttpRequest({
	    method: 'GET',
	    url: 'http://flickr.com/services/rest/?method=flickr.photos.getSizes&api_key=' +api_key+ '&photo_id=' + id,
	    headers: {
		'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
		'Accept': 'application/atom+xml,application/xml,text/xml'
	    },
	    onload: function(result) { setsize(result,id); }
	});
    }

    showLoadingMessage('Read photoinfo...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: 'http://flickr.com/services/rest/?method=flickr.photos.getInfo&api_key=' +api_key+ '&photo_id=' + id,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml'
	},
	onload: callback
    });
}

var getExif = function (photo_id,exif,callback) {

    showLoadingMessage('Read exif data...');
    GM_xmlhttpRequest({
        method: 'GET',
        url: 'http://flickr.com/services/rest/?method=flickr.photos.getExif&api_key=bc60075f4ce963fab3fac473d0741fe8&photo_id=' + photo_id,
        headers: {
            'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
            'Accept': 'application/atom+xml,application/xml,text/xml'
        },
        onload: function(result) {
	    hideLoadingMessage();
            var rExp = /[]/gi;
	    var xml = '' + result.responseText;
            xml = xml.replace(rExp, '')
            var i,lat='',lon='',lat0,lat1,lat2,lon0,lon1,lon2,lat_sign,lon_sign;
            var parser = new DOMParser();
            var dom = parser.parseFromString(xml, "application/xml");
            var tag_exif = dom.getElementsByTagName('exif');
	    if( dom.getElementsByTagName('photo').length <=0 ) return;
            var photoid = dom.getElementsByTagName('photo')[0].getAttribute('id');

            for(i=0; i<tag_exif.length; i++) {
                if( tag_exif[i].getAttribute('tagspace') != 'GPS' ) continue;
                if( tag_exif[i].getAttribute('label') == 'North or South Latitude' ) {
                    if( tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data=='N') lat_sign=1;
                    if( tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data=='S') lat_sign=-1;
                }
                if( tag_exif[i].getAttribute('label') == 'East or West Longitude' ) {
                    if( tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data=='E') lon_sign=1;
                    if( tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data=='W') lon_sign=-1;
                }
                if( tag_exif[i].getAttribute('label') == 'Latitude' ) {
                    lat_raw = tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data;
                    lat0 = lat_raw.split(',')[0].split('/')[0] / lat_raw.split(',')[0].split('/')[1];
                    lat1 = lat_raw.split(',')[1].split('/')[0] / lat_raw.split(',')[1].split('/')[1];
                    lat2 = lat_raw.split(',')[2].split('/')[0] / lat_raw.split(',')[2].split('/')[1];
                    lat = lat_sign * ((lat2/60+lat1)/60 + lat0);
                }
                if( tag_exif[i].getAttribute('label') == 'Longitude' ) {
                    lon_raw = tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data;
                    lon0 = lon_raw.split(',')[0].split('/')[0] / lon_raw.split(',')[0].split('/')[1];
                    lon1 = lon_raw.split(',')[1].split('/')[0] / lon_raw.split(',')[1].split('/')[1];
                    lon2 = lon_raw.split(',')[2].split('/')[0] / lon_raw.split(',')[2].split('/')[1];
                    lon = lon_sign * ((lon2/60+lon1)/60 + lon0);
                }
/*
                if( tag_exif[i].getAttribute('label') == 'Geodetic Survey Datum Used' ) {
                    geodetic_raw = tag_exif[i].getElementsByTagName('raw').item(0).firstChild.data;
                    if( geodetic_raw == 'TOKYO' || geodetic_raw == 'Tokyo' ) {
                        var lat0=lat, lon0=lon;
                        lat = GMiF.Tokyo2WGS84(lat0,lon0).lat;
                        lon = GMiF.Tokyo2WGS84(lat0,lon0).lon;
                    }
                }
*/
            }
            if( lat!='' && lon!='' ) {
		lon = Math.round(lon*1000000)/1000000;
		lat = Math.round(lat*1000000)/1000000;
                exif.lat = lat;
                exif.lon = lon;
		exif.datum = 'WGS84';
                if( callback ) callback(photoid,lat,lon);
            }
        }
    });
}


function checkFlickrAuth() {

    if( authenticated ) {
	flickrPanel.innerHTML = 'Logged in Flickr as <a href="javascript:;" onclick="changeTab(1);mode=0;_gi(\'selectgroup\').selectedIndex=0;_gi(\'flickruser\').value=auth_url;searchPhotos(auth_nsid,1,1);">' + auth_username + '</a> ';
	users[auth_nsid] = new Object();
	users[auth_nsid].id = auth_nsid;
	users[auth_nsid].photosurl = 'http://www.flickr.com/photos/' + auth_url + '/';
	users[auth_nsid].path = auth_url;
    } else {
	flickrPanel.innerHTML = 'To geotag photos, please <a href="?login=true">login Flickr</a> first.';
    }

    flickrPanel.innerHTML += '<div style="float:right; padding-right: 4px; font-size: 12px; margin:0px;"><a href="javascript:;" onclick="browseUsers()"><img src="http://maps.yuan.cc/buddy16.png" border="0" /></a> <a href="http://feeds.feedburner.com/yuanccmaps" title="Subscribe to my feed, Yuan.CC Maps GeoRSS feed" rel="alternate" type="application/rss+xml"><img src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="border:0"/></a> <a id="permlink" title="Link to this page" href="http://maps.yuan.cc/"><img src="http://maps.google.com/intl/en_ALL/mapfiles/bar_icon_link.gif" border="0" /></a></div>';
    flickrPanel.innerHTML += '<br /><span id="tab1" class="tab" style="background:#fff"><a href="javascript:;" onclick="changeTab(1)">Search</a></span>';
    flickrPanel.innerHTML += '<span id="tab2" class="tab"><a href="javascript:;" onclick=";Flickr.browse_filter=\'\';changeTab(2)">Browse</a></span>';
    if(authenticated) flickrPanel.innerHTML += '<span id="tab3" class="tab"><a href="javascript:;" onclick="changeTab(3)">Sync</a></span>';
    else flickrPanel.innerHTML += '<span id="tab3" class="tab" style="display:none"><a href="javascript:;" onclick="changeTab(3)">Sync</a></span>';
    flickrPanel.innerHTML += '<span id="tab4" class="tab"><a href="javascript:;" onclick="clearMap()">Clear</a></span>';

    if( authenticated ) {
	nsid = auth_nsid;
	if(_init_service=='flickr' && _init_photoid=='' && _init_nsid=='') changeTab(2);
	else if(!flickr_referrer) {
	    _gi('flickruser').value=auth_url;
	    if( _init_nsid == '') searchPhotos(auth_nsid,1,1);
	    else searchPhotos(_init_nsid,1,1);
	}
    } else {
	if(_init_service=='flickr' && _init_photoid=='' && _init_nsid=='') changeTab(2);
	else if(!flickr_referrer) {
	    _gi('flickruser').value=_init_nsid;
	    searchPhotos(_init_nsid,1,1);
	}
    }
    if(_init_service=='flickr' && (_init_photoid!='' || _init_nsid!='') ) changeTab(1);

}

function changeTab(tab) {

    // search
    if( tab == 1 ) {
	_gi('tab1').style.background = '#fff';
	_gi('tab2').style.background = '#e8f2fd';
	_gi('tab3').style.background = '#e8f2fd';
	_gi('flickrSync').style.display='none';
	_gi('flickrBrowse').style.display='none';
	_gi('flickrSearch').style.display='block';
	flickrPhotos.style.display='block';
	flickrPhoto.style.display='block';
	_flickr_mode = 'search';
    }
    // browse
    if( tab == 2 ) {
	_gi('tab1').style.background = '#e8f2fd';
	_gi('tab2').style.background = '#fff';
	_gi('tab3').style.background = '#e8f2fd';
	_gi('flickrSearch').style.display='none';
	_gi('flickrSync').style.display='none';
	_gi('flickrBrowse').style.display='block';
	flickrPhotos.style.display='block';
	flickrPhoto.style.display='block';
	_flickr_mode='browse';
	flickrPhotos.innerHTML = '<font color="red">Loading...</font>';
	browsePhotos(1);
    }
    // sync
    if( tab == 3 ) {
	_gi('tab1').style.background = '#e8f2fd';
	_gi('tab2').style.background = '#e8f2fd';
	_gi('tab3').style.background = '#fff';
	_gi('flickrSearch').style.display='none';
	flickrPhotos.style.display='none';
	flickrPhoto.style.display='none';
	_gi('flickrSync').style.display='block';
	_gi('flickrBrowse').style.display='none';
	_flickr_mode='sync';
    }
}

function addGeoTags(photo_id,lat,lon,callback) {

	if(photo_id==undefined) var photo_id = _gi('addtags').getAttribute('flickr');
	var newlocation = false;

	if( lat == undefined || lon == undefined) {
	    lon = 1000000*map.getCenterLatLng().lng();
	    lat = 1000000*map.getCenterLatLng().lat();
	    lon = Math.round(lon)/1000000;
	    lat = Math.round(lat)/1000000;
	}
	if( photos[photo_id].lon == lon && photos[photo_id].lat == lat ) return;
	if( photos[photo_id].lat == 999 ) var newlocation = true;

	photos[photo_id].datum = 'WGS84';
	photos[photo_id].lon = lon;
	photos[photo_id].lat = lat;
	if( photos[photo_id].marker && photos[photo_id].marker[map.mtype] ) {
	    marker = photos[photo_id].marker[map.mtype];
	    marker.setPoint(map.LatLng(lat,lon));
	} else {
	    if( photos[photo_id].description == undefined ) photos[photo_id].description='';
	    var draggable = (photos[photo_id].owner==auth_nsid) ? true: false;
	    var label = (draggable) ? 'Drag to change location' :photos[photo_id].title;
	    var linktothispage = 'http://maps.yuan.cc/flickr/' + photos[photo_id].owner + '/' + photo_id + '/';
	    var desc = '<div style="width:230px;font-size:10px"><a href="javascript:;" onclick="lightBox(\''+photos[photo_id].img+'\');"><img src="' + photos[photo_id].img_s + '" border=0 width=50 height=50 align="left" /></a><b>' + photos[photo_id].title + '</b><br />' + photos[photo_id].lat + ', ' + photos[photo_id].lon + '<br clear="all"><p>' + photos[photo_id].description + '</p>See <a href="javascript:;" onclick="_gi(\'searchtags\').value=\'geotagged\';changeTab(1);searchPhotos(\'' +photos[photo_id].owner+ '\',1,1)">' + ( (photos[photo_id].username) ? photos[photo_id].username : 'owner') + '\'s geotagged photos</a>. <br /><a href="javascript:;" onclick="ping('+photo_id+')">Ping Yuan.CC Maps</a> | <a href="'+linktothispage+'">Link to this page</a> | <a href="javascript:;" onclick="map.centerAtLatLng(map.LatLng('+photos[photo_id].lat+','+ photos[photo_id].lon+'))">Recenter</a></div>';
	    var marker = map.Marker(map.LatLng(photos[photo_id].lat, photos[photo_id].lon),null,label,desc);
	    marker.html = desc;
	    marker.photoid = photo_id;
	    marker.addListener('mouseover', function() {
		var lat = this.getPoint().lat();
		var lon = this.getPoint().lng();
//		lat = Math.round(lat*1000000)/1000000;
//		lon = Math.round(lon*1000000)/1000000;
		if( lat!=photos[this.photoid].lat || lon!=photos[this.photoid].lon) var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
		else str = '';
		this.openInfoWindowHtml(this.html+str);
	    });
	    marker.addListener('dragend', function() {
		var lat = this.getPoint().lat();
		var lon = this.getPoint().lng();
		lat = Math.round(lat*1000000)/1000000;
		lon = Math.round(lon*1000000)/1000000;
		var str = '<p style="font-size:10px">You\'ve dragged the photo, <a href="javascript:;" onclick="addGeoTags('+id+','+lat+','+lon+');">save new location</a>.</p>';
		this.openInfoWindowHtml(this.html + str);
	    });
	    photos[photo_id].marker = new Array();
	    photos[photo_id].marker[map.mtype] = marker;
	    map.addOverlay(marker);
	}

// Call Geo API to ping flickr
	var params = { 
	    method: 'flickr.photos.geo.setLocation',
	    photo_id: photo_id,
	    lat: lat,
	    lon: lon
	};
	var url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
	showLoadingMessage('Save Location of photo...');
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain,text/html'
            },
            onload: function(responseDetails) {
		hideLoadingMessage();
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
		if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') == 'ok' ) {
		    if(callback) callback(photo_id);
		} else {
		    alert('Set photo location failed. Please set your Geo privacy in your account profile');
		}
	    }
	});

	var method = 'flickr.photos.addTags';
	var tags = 'geotagged geo:tool=yuancc geo:lat=' +lat+ ' geo:lon=' +lon;
	var str = 'f5ac5b5817ae4d5bapi_key' + api_key + 'auth_token' + auth_token + 'method' + method + 'photo_id' + photo_id + 'tags' + tags;
	var api_sig = hex_md5(str);
	var url = 'http://www.flickr.com/services/rest/?method=flickr.photos.addTags&api_key=' +api_key+ '&photo_id=' + photo_id + '&tags=' + tags + '&auth_token=' + auth_token + '&api_sig=' + api_sig;
//	_gi('msgBar').innerHTML = url;
	showLoadingMessage('Add tags...');
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain,text/html'
            },
            onload: function(responseDetails) {
		hideLoadingMessage();
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
		if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') == 'ok' ) {
//		    alert('Geotags added!');
		    if( _latlon == 'DM.m' ) {
			var photo_lon = Dd_to_DMm(photos[photo_id].lon,'lon');
			var photo_lat = Dd_to_DMm(photos[photo_id].lat,'lat');
		    } else {
			var photo_lon = photos[photo_id].lon;
			var photo_lat = photos[photo_id].lat;
		    }
		    if( CK.activePage == _gi('flickrTab'))
			_gi('geotags').innerHTML = '<font color="red">' + photo_lat + ', ' + photo_lon + '</font>';
		    ping(photo_id);
		}
	    }
	});

	setMeta(photo_id);
	if( newlocation ) return;

	if( photos[photo_id].tag_lat != undefined && photos[photo_id].tag_lat != lat ) {
	var method = 'flickr.photos.removeTag';
	var tag_id = photos[photo_id].tag_lat;
	var str = 'f5ac5b5817ae4d5bapi_key' + api_key + 'auth_token' + auth_token + 'method' + method + 'tag_id' + tag_id;
	var api_sig = hex_md5(str);
	var url = 'http://www.flickr.com/services/rest/?method=flickr.photos.removeTag&api_key=' +api_key+ '&tag_id=' + tag_id + '&auth_token=' + auth_token + '&api_sig=' + api_sig;
//	showLoadingMessage('Remove tags...');
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
		'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain,text/html'
            },
            onload: function(responseDetails) {
//		hideLoadingMessage();
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
		if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') != 'ok' ) {
		    alert('Warning: tag modified fails!');
		}
	    }
	});
	}
	
	if( photos[photo_id].tag_lon != undefined && photos[photo_id].tag_lon != lon ) {
	var tag_id = photos[photo_id].tag_lon;
	var str = 'f5ac5b5817ae4d5bapi_key' + api_key + 'auth_token' + auth_token + 'method' + method + 'tag_id' + tag_id;
	var api_sig = hex_md5(str);
	var url = 'http://www.flickr.com/services/rest/?method=flickr.photos.removeTag&api_key=' +api_key+ '&tag_id=' + tag_id + '&auth_token=' + auth_token + '&api_sig=' + api_sig;
//	showLoadingMessage('Remove tags...');
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
		'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
                'Accept': 'application/atom+xml,application/xml,text/xml,text/plain,text/html'
            },
            onload: function(responseDetails) {
//		hideLoadingMessage();
                var parser = new DOMParser();
                var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
		if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') != 'ok' ) {
		    alert('Warning: tag modified fails!');
		}
	    }
	});
	}
}

var setMeta = function(photo_id) {

    var title = photos[photo_id].title;
    var lat = photos[photo_id].lat;
    var lon = photos[photo_id].lon;

    if( photos[photo_id].description == undefined ) photos[photo_id].description = '';
    var where = ' See where this photo was taken at ';

    switch(_maplink) {
	case 'yuancc': where += '<a href="http://maps.yuan.cc/" target="_blank" rel="nofollow">Yuan.CC Maps</a>.'; break;
	case 'gmap': where += '<a href="http://maps.google.com/?q='+lat+','+lon+'('+title+')&amp;t=h" target="_blank" rel="nofollow">Google Maps</a>.'; break;
	case 'geotagviewer': where += '<a href="http://geobloggers.tafoni.net/" target="_blank" rel="nofollow">GeoTag Viewer</a>.'; break;
	case 'flickrfly': where += '<a href="http://www.roblog.com/flickrfly.kml" rel="nofollow">Google Earth</a> (FlickrFly).'; break;
	case 'flickr2map': where += '<a href="http://www.robogeo.com/Flickr2Map/" rel="nofollow">Google Earth</a> (RoboGEO).'; break;
	case 'localizeus': where += '<a href="http://loc.alize.us#/geo:'+lat+','+lon+',17/" rel="nofollow">loc.alize.us</a>.'; break;
//	case 'none': where = ''; break;
	case 'none': return; break;
	default: where += '<a href="http://maps.yuan.cc/" target="_blank" rel="nofollow">Yuan.CC Maps</a>.';
    }

    var description = photos[photo_id].description + where;
//    description = escape_utf8(description);
//    description = encodeURIComponent(description);
//    alert(description);

    var method = 'flickr.photos.setMeta';
    var str = 'f5ac5b5817ae4d5bapi_key' + api_key + 'auth_token' + auth_token + 'description' + description + 'method' + method + 'photo_id' + photo_id + 'title' + title;
    var api_sig = hex_md5(str);
    var url = 'http://www.flickr.com/services/rest/?method=flickr.photos.setMeta&api_key=' +api_key+ '&photo_id=' + photo_id + '&description=' + description + '&title=' + title + '&auth_token=' + auth_token + '&api_sig=' + api_sig;
    var params = { 
	method: 'flickr.photos.setMeta',
	photo_id: photo_id,
	description: description,
	title: title
    };
    var url = 'http://flickr.com/services/rest/?' + FlickrAPI_sign(params);
    showLoadingMessage('Save photo description ...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain,text/html,application/x-www-form-urlencoded'
	},
	onload: function(responseDetails) {
//	    hideLoadingMessage();
//	    alert(responseDetails.responseText);
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') == 'ok' ) 
		showLoadingMessage('Photo description is saved.');
	    if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') == 'fail' ) {
		var err = dom.getElementsByTagName('err')[0].getAttribute('msg');
		alert(err);
//		showLoadingMessage('Photo description is saved.');
	    }
	}
    });

}

var addToPool = function() {
    var photo_id = _gi('addtags').getAttribute('flickr');
    var group_id = _gi('selectgroup2').value;

    var method = 'flickr.groups.pools.add';
    var str = 'f5ac5b5817ae4d5bapi_key' + api_key + 'auth_token' + auth_token + 'group_id' + group_id + 'method' + method + 'photo_id' + photo_id;
//  alert(auth_token + ', ' + str);
    var api_sig = hex_md5(str);
    var url = 'http://www.flickr.com/services/rest/?method=flickr.groups.pools.add&api_key=' +api_key+ '&photo_id=' + photo_id + '&group_id=' + group_id + '&auth_token=' + auth_token + '&api_sig=' + api_sig;
    showLoadingMessage('Add this photo to group pool ...');
//    _gi('msgBar').innerHTML = url;
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible) Yuan.CC Maps',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain,text/html'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
//	    alert(responseDetails.responseText);
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') == 'ok' ) 
		showLoadingMessage('Photo added to group pool successfully.');
	    if( dom.getElementsByTagName('rsp')[0].getAttribute('stat') == 'fail' ) {
		var err = dom.getElementsByTagName('err')[0].getAttribute('msg');
		alert(err);
//		showLoadingMessage('Photo added to group pool successfully.');
	    }
	}
    });

}

var convCoords = function(value) {

        var DMS = /^([\+\-]?)(\d{0,3})\.([0-5]?\d)\.([0-5]?\d)\.(\d+)$/;
        var DMm = /^([\+\-]?)(\d{0,3})\.([0-5]?\d)\.(\d+)$/;
        var Dd =  /^[\+\-]?\d{0,3}\.\d+$/;

        value = '' + value;
        if( DMS.test(value) ) {
            a = DMS.exec(value);
            value = ((1*('0.'+a[5]) + 1*a[4])/60 + 1*a[3] )/60 + 1*a[2];
            if( a[1] == '-' ) value = -1*value;
            return value;
        }
        if( DMm.test(value) ) {
            a = DMm.exec(value);
            value = a[3] + '.' + a[4];
            value = (1*value)/60 + 1*a[2];
            if( a[1] == '-' ) value = -1*value;
            return value;
        }
        if( Dd.test(value) ) {
            return 1*value;
        }
        return 1*value;
}

function clearMap() {
//    map.clearOverlays();
    for(var i in photos) {
	if(photos[i].marker && photos[i].marker[map.mtype]) {
	    map.removeOverlay(photos[i].marker[map.mtype]);
	    delete photos[i].marker[map.mtype];
	}
    }
}

function geocache() {

    geocache_key = _get_cookie('geocache_apikey');
    var div = _gi('geocachePanel');
    div.style.textAlign = 'right';
    div.style.fontSize = '11px';
    div.style.fontFamily = 'arial';
    div.style.lineHeight = '14px';
    div.parentNode.style.padding = '4px';
    div.innerHTML = '<a href="javascript:;" onClick="geocache_apikey()">Setup API Key</a> <a href="javascript:;" onClick="geocache_refresh()">Find Geocaches</a>';
}

function geocache_apikey() {

    if(_gi('geocache_api')) return;
    var apikey = _get_cookie('geocache_apikey');
    if(apikey == null) apikey='';
    var div = _gi('geocachePanel');
    var key = _ce('div');
    key.id = 'geocache_api';
    key.innerHTML = '<p align="left">API Key: <input id="geocache_apikey" style="font-family:arial;font-size:10px" type="text" size="30" value="' +apikey+ '"> <input type="button" style="font-family:arial;font-size:10px" value="Save" onClick="save_apikey()"></p><p align="left">How to find your own Geocaching API key? Click "<a href="http://www.geocaching.com/kml/buildnetworkkml.aspx" target="_blank">Geocache browser in Google Earth</a>" in Geocaching official site, then save as a file. Open the KML file from text editor and you will see the API key.</p>';
    div.appendChild(key);

}

function save_apikey() {
    _set_cookie('geocache_apikey', _gi('geocache_apikey').value);
    _gi('geocachePanel').removeChild(_gi('geocache_api'));
    geocache_key = _get_cookie('geocache_apikey');
}

function geocache_refresh() {
    var url = 'http://api.groundspeak.com/networkkml/geocache.aspx?key='+geocache_key;
    minX = map.getBoundsLatLng().minX;
    minY = map.getBoundsLatLng().minY;
    maxX = map.getBoundsLatLng().maxX;
    maxY = map.getBoundsLatLng().maxY;
    url += '&BBOX=' + minX + ',' + minY + ',' + maxX + ',' + maxY;
    showLoadingMessage('Loading geocaches ...');
    GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	headers: {
	    'User-agent': 'Mozilla/4.0 (compatible)',
	    'Accept': 'application/atom+xml,application/xml,text/xml,text/plain'
	},
	onload: function(responseDetails) {
	    hideLoadingMessage();
	    var parser = new DOMParser();
	    var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
	    var caches = dom.getElementsByTagName('Placemark');
//	    _gi('geocache').innerHTML += '<p>' + caches.length;
	    if( caches.length == 0 ) {
		return;
	    }
	    var str='<b>Results:</b><ul>';
	    for(var i=0;i<caches.length;i++) {
		if( caches[i].getElementsByTagName('latitude').length == 0 ) break;
		var lat = 1*caches[i].getElementsByTagName('latitude').item(0).firstChild.data;
		var lon = 1*caches[i].getElementsByTagName('longitude').item(0).firstChild.data;
		var name = caches[i].getElementsByTagName('name').item(0).firstChild.data;
		var description = caches[i].getElementsByTagName('description').item(0).firstChild.data;
		name = name.replace(/\\/g, '');
		var key = hex_md5(name);
		description = description.replace(/\\/g,'');
		description = description.replace(/\/\/seek/g,'/seek');

		var icon_img = caches[i].getElementsByTagName('href').item(0).firstChild.data;
		var icon = map.Icon();
		icon.setup(icon_img,32,32,16,16,16,16);
		str += '<li><a href="javascript:;" onclick="geocaches[\''+key+'\'].marker.openInfoWindowHtml(geocaches[\''+key+'\'].html)">' + name + '</a></li>';

		var marker = map.Marker(map.LatLng(lat,lon), icon, name, description);

		if( !geocaches[key] ) {
		    geocaches[key] = new Object();
		} else {
		    map.removeOverlay(geocaches[key].marker);
		    delete geocaches[key].marker;
		    delete geocaches[key].icon;
		}
	        geocaches[key].lat = lat;
	        geocaches[key].lon = lon;
	        geocaches[key].name = name;
	        geocaches[key].description = description;
	        geocaches[key].icon = icon;
	        geocaches[key].marker = marker;
		geocaches[key].html = '<div style="width:200px">' + name + '<br />' + lat + ', ' + lon + '<br />' + description + '</div>';
		marker.geocache = geocaches[key];
		marker.addListener('mouseover', function() {
		    this.openInfoWindowHtml(this.geocache.html);
//		    map.centerAtLatLng(map.LatLng(photos[id].lat, photos[id].lon));
		});
		map.addOverlay(marker);
	    }
	    str += '</ul>';
//	    _gi('geocacheBody').style.height = _gt('body')[0].clientHeight-125 + 'px';
	    _gi('geocacheBody').style.height = _gt('body')[0].clientHeight-125-30 + 'px';
	    _gi('geocacheBody').style.overflow = 'scroll';
	    _gi('geocacheBody').innerHTML = str;
	}
    });
}

function showTip(a,b) {

    var str ='<div style="border:solid 1px #008000;background:#e2ffe4;color:#000;padding:4px;margin:4px;"><span style="color:#008000"><b>'+a+'</b></span>&nbsp;&nbsp;' +b+ '</div>';
    return str;
}

function lightBox(img) {


    var disabledZone = _ce('div');
    disabledZone.id = 'disabledZone';
    disabledZone.setAttribute('style', 'background-color: #000000; -moz-opacity: 0.75');
    disabledZone.style.position = 'absolute';
    disabledZone.style.zIndex = 25000;
    disabledZone.style.left = '0px';
    disabledZone.style.top = '0px';
    disabledZone.style.width = '100%';
    disabledZone.style.height = '100%';
    disabledZone.addEventListener('click', function() { 
	document.body.removeChild(_gi('imgZone'));
	document.body.removeChild(this);
    }, true);
    document.body.appendChild(disabledZone);

    var imgZone = _ce('div');
    imgZone.id = 'imgZone';
    imgZone.style.MozOpacity=1;
    imgZone.style.position = 'absolute';
    imgZone.style.zIndex = 25001;
    imgZone.style.top = (document.body.clientHeight-375)/3 + 'px';
    imgZone.style.left = (document.body.clientWidth-500)/2 + 'px';
    imgZone.innerHTML = '<img src="'+img+'" />';
    imgZone.addEventListener('click', function() { 
	document.body.removeChild(_gi('disabledZone'));
	document.body.removeChild(this);
    }, true);
    document.body.appendChild(imgZone);
}

//
// a replacement for escape() which encodes the data using UTF8
//
// (C)2004 Cal Henderson <cal@iamcal.com>
//

var escape_utf8 = function(_42) {
        if(_42===""||_42===null||_42===undefined) return "";
        _42=_42.toString();
        var _43="";
        for(var i=0; i<_42.length; i++) {
                var c=_42.charCodeAt(i);
                var bs=new Array();
                if(c>65536) {
                        bs[0]=240|((c&1835008)>>>18);
                        bs[1]=128|((c&258048)>>>12);
                        bs[2]=128|((c&4032)>>>6);
                        bs[3]=128|(c&63);
                } else {
                        if(c>2048) {
                                bs[0]=224|((c&61440)>>>12);
                                bs[1]=128|((c&4032)>>>6);
                                bs[2]=128|(c&63);
                        } else {
                                if(c>128) {
                                        bs[0]=192|((c&1984)>>>6);
                                        bs[1]=128|(c&63);
                                } else {
                                        bs[0]=c;
                                }
                        }
                }
                if(bs.length>1) {
                        for(var j=0; j<bs.length; j++) {
                                var b=bs[j];
                                var hex=nibble_to_hex((b&240)>>>4)+nibble_to_hex(b&15);
                                _43+="%"+hex;
                        }
                } else {
                        _43+=encodeURIComponent(String.fromCharCode(bs[0]));
                }
        }
        return _43;
};


function nibble_to_hex(nibble){
	var chars = '0123456789ABCDEF';
	return chars.charAt(nibble);
}

