
var GPS = new Object();
GPS.lockDiv = false;
GPS.browseMode = false;
GPS.points = new Array();
GPS.trackAreas = new Array();
GPS.offset = 0;
GPS.selectedIndex = 0;
GPS.timeoffset = 0;

x = new Date();
GPS.offset = x.getTimezoneOffset()*60*1000;

GPS.setup = function() {

    if( GPS.lockDiv ) return;
    var gps;
    var h = _gt('body')[0].clientHeight-200-15 + 'px';

    if( !_gi('gps') ) {
	var infoPanel = _gi('infoPanel');
	gps = _ce('div');
	gps.id = 'gps';
	gps.style.display = 'block';
	gps.style.fontFamily = 'Arial';
	gps.style.fontSize = '12px';
	gps.style.padding = '4px';
	infoPanel.appendChild(gps);
    } else gps = _gi('gps');

    var html = '<h3>GPS Tracks</h3>';
//    html += '<p>Current GPX file: <span id="gps_file">none</span></p>';
//    if( logged_in ) {
	html += '<p>';
	html += '<b>Tracks</b>: ';
	if(logged_in) html += '<a href="javascript:;" onclick="GPS.myTracks();">My</a> | ';
	html += '<a href="javascript:;" onclick="GPS.publicTracks(\'\',1);">Public</a> | ';
	html += '<a id="browse_onoff" href="javascript:;" onclick="GPS.browseOnOff();">Browse On</a> <br />';
	html += '<b>Action</b>: ';
	if(logged_in) html += '<a href="javascript:;" onclick="GPS.uploadGPX();">Upload</a> | ';
	if(logged_in) html += '<a href="javascript:;" onclick="GPS.readTrack();">Open</a> | ';
	html += '<a href="javascript:;" onclick="GPS.clear();">Clear</a> </p>';
	if(!logged_in) html += showTip('TIP','To upload and display your GPS tracks on the map, please <a href="javascript:;" onclick="login();">login Yuan.CC Maps</a>.');
	html += '<div id="gps_result" style="height:'+h+';"></div>';
//    } else {
//	html += '<p>To upload and see your GPS tracking data, please <a href="javascript:;" onclick="login();">login Yuan.CC Maps</a>.</p>';
//    }
    gps.innerHTML = html;
    if( logged_in && _init_track=='') GPS.myTracks();
    else GPS.publicTracks('',1,_init_track);
}

GPS.browseOnOff = function(state) {

    var link = _gi('browse_onoff');
    if(state == undefined) GPS.browseMode = !GPS.browseMode;
    else GPS.browseMode = state;
    if(GPS.browseMode) GPS.browseTracks();
    else {
	for(var s in GPS.trackAreas) {
	    map.removeOverlay(GPS.trackAreas[s]);
	    delete GPS.trackAreas[s];
	}
    }
    if(link) link.innerHTML = (GPS.browseMode) ? 'Browse Off' : 'Browse On';
}

GPS.readTrack = function() {

    var gps_result = _gi('gps_result');
    var url = 'http://maps.yuan.cc/gpx.php?username=' + login_username;

    gps_result.style.textAlign = 'left';
    GPS.lockDiv = true;
    showLoadingMessage('Reading GPS Tracks ...');
    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 tracks = dom.getElementsByTagName('trk');
	    var html = '<ul>';
	    for(var i=0; i<tracks.length; i++) {
		name = tracks[i].getElementsByTagName('name').item(0).firstChild.data;
		src = tracks[i].getElementsByTagName('name').item(0).firstChild.data;
		track_id = tracks[i].getAttribute('id');
		html += '<li>Track ' +i+ ': <a href="javascript:;" onclick="GPS.readSeg('+track_id+');">' + name + '</a></li>';
	    }
	    html += '</ul>';
	    gps_result.innerHTML = html;
        }
    });
}

GPS.readSeg = function(trk) {

    var gps_result = _gi('gps_result');
    var url = 'http://maps.yuan.cc/gpx.php?username=' +login_username + '&track=' + trk;

    gps_result.style.textAlign = 'left';
    showLoadingMessage('Reading GPS Tracks ...');
    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 segments = dom.getElementsByTagName('trkseg');
	    var html = '<p><b>Select</b>: <a href="javascript:;" onclick="GPS.selectSeg(1)">All</a>, <a href="javascript:;" onclick="GPS.selectSeg(2)">None</a>, <a href="javascript:;" onclick="GPS.selectSeg(3)">Reverse</a><br />';
	    html += '<b>Display</b>: <a href="javascript:;" onclick="GPS.loadSegs()">Selected Segments</a><br /><br />';
	    for(var i=0; i<segments.length; i++) {
		segments_id = segments[i].getAttribute('id');
		time = segments[i].getAttribute('time');
		points = segments[i].getAttribute('points');
		html += '<input type="checkbox" id="seg' +segments_id+ '" name="seg' +segments_id+ '" trk="'+trk+'" seg="'+segments_id+'"> ';
		html += '<a href="javascript:;" onclick="GPS.readPoint(' +trk+ ','+segments_id+');"> Seg #' +segments_id+ '</a>: ' +time+ ' (' +points+ ' points)<br />';
	    }
	    html += '</p>';
	    gps_result.innerHTML = html;
        }
    });
}


GPS.readPoint = function(trk,seg,src) {

    var MULTI_SEGS, gps_trk,gps_result, url, trk_id,p;

    gps_result = _gi('gps_result');
    gps_result.style.textAlign = 'left';
    if( typeof(seg) == 'object' ) MULTI_SEGS = true;
    else MULTI_SEGS = false;

    if(MULTI_SEGS) {
	_seg = seg;
	p = _seg.shift();
	url = 'http://maps.yuan.cc/gpx.php?username=' +login_username + '&track=' + trk + '&segment=' + p.seg;
	for(var i in _seg) url += ',' + _seg[i].seg;
	trk_id = login_username + '_' + p.trk_id;
	trk = p.trk;
	seg = p.seg;
	if( !_gi('working_segs') ) {
	    var tip = _ce('div'); tip.id = 'working_segs'; tip.style.padding = '0px'; tip.style.margin = '0px';
	    tip.innerHTML = showTip('TIP', 'The current list of track/segments is a temporary working file. If you want to keep it in your archive, remember to click "<b>Save this track</b>" in the opened bubble.');
	    gps_result.insertBefore(tip, gps_result.firstChild);
	}
    } else {
	if( src == undefined ) {
	    url = 'http://maps.yuan.cc/gpx.php?username=' +login_username + '&track=' + trk + '&segment=' + seg;
	    trk_id = +login_username + '_' + trk + '_' + seg;
//	    gps_result.innerHTML = showTip('TIP', 'The current list of track/segments is a temporary working file. If you want to keep it in your archive, remember to click "<b>Save this track</b>" in the opened bubble.') + gps_result.innerHTML;
	    if( !_gi('working_segs') ) {
		var tip = _ce('div'); tip.id = 'working_segs'; tip.style.padding = '0px'; tip.style.margin = '0px';
		tip.innerHTML = showTip('TIP', 'The current list of track/segments is a temporary working file. If you want to keep it in your archive, remember to click "<b>Save this track</b>" in the opened bubble.');
		gps_result.insertBefore(tip, gps_result.firstChild);
	    }
	} else {
	    url = src;
	    trk_id = src;
	}
    }
    if( !MULTI_SEGS && gps_tracks[trk_id] && gps_tracks[trk_id].onMap && gps_tracks[trk_id].mtype == map.mtype ) {
	gps_trk = gps_tracks[trk_id];
	if(!GPS.browseMode) {
	    var zoom = map.getBoundsZoomLevel(gps_trk.min_lat,gps_trk.min_lon,gps_trk.max_lat,gps_trk.max_lon);
	    map.centerAndZoom(map.LatLng((gps_trk.min_lat+gps_trk.max_lat)/2, (gps_trk.min_lon+gps_trk.max_lon)/2),zoom);
	}
	gps_trk.track[0].openInfoWindowHtml(gps_trk.track[0].html);
	if( GPS.trackAreas[trk_id] ) map.removeOverlay(GPS.trackAreas[trk_id]);
	return;
    }

    showLoadingMessage('Reading GPS Tracks');
    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 points = dom.getElementsByTagName('trkpt');
	    if( gps_tracks[trk_id] && gps_tracks[trk_id].points ) {
		var pa = gps_tracks[trk_id].points;
		var max_lat = gps_tracks[trk_id].max_lat;
		var min_lat = gps_tracks[trk_id].min_lat;
		var max_lon = gps_tracks[trk_id].max_lon;
		var min_lon = gps_tracks[trk_id].min_lon;
	    } else {
		var pa = new Array();
		var max_lat = max_lon = -999;
		var min_lat = min_lon = 999;
	    }
	    if( points.length > 3000 ) var step = Math.round(points.length/3000);
	    else step = 1;
	    for(var i=0; i<points.length; i++) {
		point_id = points[i].getAttribute('id');
		lat = 1*points[i].getAttribute('lat');
		lon = 1*points[i].getAttribute('lon');
		ele = (points[i].getElementsByTagName('ele').item(0).firstChild) ? 1*points[i].getElementsByTagName('ele').item(0).firstChild.data : 0;
		time = (points[i].getElementsByTagName('time').item(0).firstChild) ? points[i].getElementsByTagName('time').item(0).firstChild.data : '';
		if(i==0) start_time = time;
		if(i==(points.length-1)) end_time = time;

		var date_pattern = /(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;
		if( time.match(date_pattern) ) {
		    var a = date_pattern.exec(time);
		    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];
		    var index = GPS.points.length;
		    GPS.points[index] = new Object();
//		    GPS.points[index].date = new Date(year,mon,day,hour,min,sec,0);
		    GPS.points[index].date = new Date();
		    GPS.points[index].date.setUTCFullYear(year);
		    GPS.points[index].date.setUTCMonth(mon);
		    GPS.points[index].date.setUTCDate(day);
		    GPS.points[index].date.setUTCHours(hour);
		    GPS.points[index].date.setUTCMinutes(min);
		    GPS.points[index].date.setUTCSeconds(sec);
		    GPS.points[index].lat = lat;
		    GPS.points[index].lon = lon;
		    GPS.points[index].ele = ele;
		}

		if( i%step ==0 ) pa[pa.length] = map.LatLng(lat,lon);
		max_lat = ( lat>max_lat ) ? lat : max_lat;
		max_lon = ( lon>max_lon ) ? lon : max_lon;
		min_lat = ( lat<min_lat ) ? lat : min_lat;
		min_lon = ( lon<min_lon ) ? lon : min_lon;
	    }
	    GPS.points.sort(GPS.compareDate);

//	    if( !MULTI_SEGS || (MULTI_SEGS && _seg.length == 0) ) var gps_trk = map.Polyline(pa);
//	    else var gps_trk = null;
	    if( !gps_tracks[trk_id] ) {
		gps_tracks[trk_id] = new Object();
		gps_tracks[trk_id].onMap = false;
	    }
	    var gps_trk = map.Polyline(pa);
	    gps_tracks[trk_id].points = pa;
	    gps_tracks[trk_id].mtype = map.mtype;
	    gps_tracks[trk_id].track = gps_trk;
	    gps_tracks[trk_id].max_lat = max_lat;
	    gps_tracks[trk_id].max_lon = max_lon;
	    gps_tracks[trk_id].min_lat = min_lat;
	    gps_tracks[trk_id].min_lon = min_lon;
	    if( !gps_tracks[trk_id].start ) gps_tracks[trk_id].start = start_time;
	    if( !gps_tracks[trk_id].end ) gps_tracks[trk_id].end = end_time;
	    gps_tracks[trk_id].end = end_time;
	    if( gps_trk ) {
		if(!GPS.browseMode) {
		    var zoom = map.getBoundsZoomLevel(min_lat,min_lon,max_lat,max_lon);
		    map.centerAndZoom(map.LatLng((min_lat+max_lat)/2, (min_lon+max_lon)/2),zoom);
		    map.zoomOut();
		}
//		if( GPS.trackAreas[trk_id] ) map.removeOverlay(GPS.trackAreas[trk_id]);
		for(var i=0; i<gps_trk.length; i++) map.addOverlay(gps_trk[i]);

		gps_tracks[trk_id].onMap = true;
		gps_trk[0].html += '<br />' + gps_tracks[trk_id].start;
		gps_trk[0].html += '<div style="font-size:10px">';
		if(gps_tracks[trk_id].title) gps_trk[0].html += '<h3>' + gps_tracks[trk_id].title + '</h3>';
		if(gps_tracks[trk_id].desc) gps_trk[0].html += '<p>' + gps_tracks[trk_id].desc + '</p>';
		gps_trk[1].html += '<br />' + gps_tracks[trk_id].end;
		gps_trk[1].html += '<div style="font-size:10px">';
		if(gps_tracks[trk_id].title) gps_trk[1].html += '<h3>' + gps_tracks[trk_id].title + '</h3>';
		if(gps_tracks[trk_id].desc) gps_trk[1].html += '<p>' + gps_tracks[trk_id].desc + '</p>';

		if( logged_in && src==undefined) {
		    if(MULTI_SEGS) gps_trk[0].html += '<a href="javascript:;" onclick="GPS.saveTrackDiv(true,\''+trk_id+'\','+trk+',\''+GPS.trkseg_str+'\')">Save this track</a>';
		    else gps_trk[0].html += '<a href="javascript:;" onclick="GPS.saveTrackDiv(false,\''+trk_id+'\','+trk+','+seg+')">Save this track</a>';
		}
		var permalink = 'http://maps.yuan.cc/gps/' + gps_tracks[trk_id].id +'/';
		gps_trk[0].html += ' <a href="javascript:;" onclick="GPS.clearTrack(\'' +trk_id+ '\')">Clear it</a>';
		if(src != undefined) gps_trk[0].html += ' | <a href="'+src+'" target="_blank">Download</a>';
		if(src != undefined) gps_trk[0].html += ' | <a href="'+permalink+'">Link to this page</a>';
		gps_trk[0].html += '<br />';
		gps_trk[1].html += ' <a href="javascript:;" onclick="GPS.clearTrack(\'' +trk_id+ '\')">Clear it</a>';
		if(src != undefined) gps_trk[1].html += ' | <a href="'+src+'" target="_blank">Download</a>';
		if(src != undefined) gps_trk[1].html += ' | <a href="'+permalink+'">Link to this page</a>';
		gps_trk[1].html += '<br />';
		if( _init_service=='gps' && _init_nsid!='') {
		    GPS.searchFlickr(trk_id, 0);
		    _init_nsid = '';
		} else if(authenticated && login_userid==gps_tracks[trk_id].owner) {
		    gps_trk[0].html += '<a href="javascript:;" onclick="GPS.searchFlickr(\''+trk_id+'\')">Search my flickr photos along this track</a>';
		    GPS.searchFlickr(trk_id, 0);
		} else if( gps_tracks[trk_id].flickrid != '' ){
		    GPS.searchFlickr(trk_id, 0);
		}

		gps_trk[0].html += '</div>';
		gps_trk[1].html += '</div>';
		gps_trk[0].openInfoWindowHtml(gps_trk[0].html);
	    }

//	    if( MULTI_SEGS && _seg.length>0 ) GPS.readPoint(trk,_seg);
        }
    });
}

GPS.saveTrackDiv = function(multi,trk_id,trk,seg) {

//    if(multi) { alert(trk_id +': '+ trk); return;}
    var gps_trk = gps_tracks[trk_id].track;
    var html = '<div style="width:250px;height:180px;font-size:10px">';
    html += '<h3>Save this track</h3>';
    html += '<p><b>Lat</b>: ' + gps_tracks[trk_id].points[0].lat() + '<br />';
    html += '<b>Lon</b>: ' + gps_tracks[trk_id].points[0].lng() + '<br />';
    html += '<b>Title</b>: <input id="track_title" type="text" size="20"> ';
    html += '<input id="track_privacy" type="checkbox"> <b>Private</b> <br />';
    html += '<b>Description</b>:<br /><textarea id="track_desc" style="font-size:12px" cols="30" rows="3"></textarea><br />';
    html += '<input type="button" value="SAVE" onclick="GPS.saveTrack('+true+',\''+trk_id+'\','+trk+',\''+seg+'\')">';
    html += '</div>';
    gps_trk[0].openInfoWindowHtml(html);
}

GPS.clearTrack = function(trk_id) {

    if(!gps_tracks[trk_id].track) return;
    var gps_trk = gps_tracks[trk_id].track;
    gps_tracks[trk_id].onMap = false;
    for(var i=0; i<gps_trk.length; i++) map.removeOverlay(gps_trk[i]);
    map.closeInfoWindow();

    for(i in gps_tracks[trk_id].photos) {
	if(!gps_tracks[trk_id].photos[i].marker) continue;
	var marker = gps_tracks[trk_id].photos[i].marker[map.mtype];
	map.removeOverlay(marker);
	delete gps_tracks[trk_id].photos[i].marker;
	delete photos[gps_tracks[trk_id].photos[i].photoid];
    }
    delete gps_tracks[trk_id].photos;
    delete gps_tracks[trk_id].points;
    delete gps_tracks[trk_id].track;
//    delete gps_tracks[trk_id];
}

GPS.saveLocations = function(trk_id) {

    if(!gps_tracks[trk_id].track) return;
    if(!gps_tracks[trk_id].photos) return;
    if(gps_tracks[trk_id].photos.length==0) return;
    var photos = gps_tracks[trk_id].photos;

    callback = function(photoid) {
	_gi('trkphoto_'+photoid).style.border = 'solid 1px #0000ff';
    }

    for(i in photos) {
	showLoadingMessage('Saving photo coords ' + i);
	if( !_gi('trkphoto_'+i) ) continue;
	_gi('trkphoto_'+i).style.border = 'solid 1px #ff0000';
//	addGeoTags(i, photos[i].lat, photos[i].lon, callback);
	GPS.geotag(trk_id, i, callback);
    }
}

GPS.saveTrack = function(multi,trk_id,trk,seg) {

//    alert( login_username +','+ trk +','+ seg +','+ gps_tracks[trk_id].max_lat +','+ gps_tracks[trk_id].max_lon +','+ gps_tracks[trk_id].start);
//    if(multi) { alert(trk_id +': '+ seg); return;}
    var title = _gi('track_title').value;
    var desc = _gi('track_desc').value;
    var private = (_gi('track_privacy').checked) ? 1 : 0;
    var url = 'http://maps.yuan.cc/gpx.php?';
    url += 'title=' + title + '&desc=' + desc;
    url += '&userid=' +login_userid+ '&username=' +login_username + '&track=' + trk + '&segment=' + seg + '&save=1&private=' + private;
    url += '&max_lat=' +gps_tracks[trk_id].max_lat+ '&max_lon=' +gps_tracks[trk_id].max_lon+ '&min_lat=' + gps_tracks[trk_id].min_lat + '&min_lon=' +gps_tracks[trk_id].min_lon+ '&time1=' + gps_tracks[trk_id].start + '&time2=' + gps_tracks[trk_id].end;
    url = encodeURI(url);
    showLoadingMessage('Saving GPS Tracks ...');
    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' ) alert(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	    else alert(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	}
    });
}

GPS.uploadGPX = function() {

    var cwf = _gi('gps_file');
    var gps_result = _gi('gps_result');
    var html = '<div id="upload_gpx"><iframe width=250 height=300 border=0 src="/upload.php?username=' +login_username+ '"></iframe></div>';

    GPS.lockDiv = true;
    gps_result.style.overflow = 'auto';
    gps_result.style.textAlign = 'left';
    gps_result.innerHTML = html;
}

GPS.clear = function() {
//    map.clearOverlays();
//    gps_tracks = new Array();
    for(var i in gps_tracks) GPS.clearTrack(i);

    delete GPS.points;
    GPS.points = new Array();
}

GPS.myTracks = function() {

    GPS.browseOnOff(false);
    var url = 'http://maps.yuan.cc/gpx.php?userid=' +login_userid+ '&method=gpx.mytracks';
    showLoadingMessage('Loading my GPS tracks ...');
    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,title,time;
            var parser = new DOMParser();
            var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
            var tracks = dom.getElementsByTagName('trk');
	    var list = '<div style="font-size:14px;"><b>My Tracks</b></div>';
	    list += showTip('TIP', 'The checkbox indicates whether the track is private or not. Uncheck it to share your track to the public.');
	    for(var i=0; i<tracks.length; i++) {
		id = tracks[i].getAttribute('id');
		private = tracks[i].getAttribute('private');
		flickrid = tracks[i].getAttribute('flickrid');
		diff = tracks[i].getAttribute('timeoffset');
		owner = tracks[i].getAttribute('owner');
		title = tracks[i].getElementsByTagName('name').item(0).firstChild.data;
		desc = tracks[i].getElementsByTagName('desc').item(0).firstChild.data;
		src = tracks[i].getElementsByTagName('src').item(0).firstChild.data;
		time = tracks[i].getElementsByTagName('time').item(0).firstChild.data;
		if(private=='1') private='checked'; else private='';

		if( !gps_tracks[src] ) gps_tracks[src] = new Object();
		gps_tracks[src].id = id;
		gps_tracks[src].owner = owner;
		gps_tracks[src].private = private;
		gps_tracks[src].flickrid = flickrid;
		gps_tracks[src].diff = 1*diff;
		gps_tracks[src].title = title;
		gps_tracks[src].desc = desc;
		gps_tracks[src].src = src;
		gps_tracks[src].time = time;

		list += '<input type="checkbox" id="mytrack_' +i+ '" '+private+' trkid="'+id+'" trksrc="'+src+'" onclick="GPS.setPrivate(this);"> ';
		list += '<a href="javascript:;" onclick="GPS.readPoint(1,1,\'' +src+ '\')">' +title+ '</a> ';
		list += '[<a href="javascript:;" title="delete this track?" onclick="GPS.delTrack('+id+')">X</a>] ';
		list += '<a href="javascript:;" style="text-decoration:none" onclick="if(_gi(\'mytrack_desc_' +i+ '\').style.display==\'none\') _gi(\'mytrack_desc_' +i+ '\').style.display=\'block\'; else _gi(\'mytrack_desc_' +i+ '\').style.display=\'none\';this.innerHTML=(this.innerHTML==\'+\')?\'-\':\'+\'">+</a><br />';
		list += '<div id="mytrack_desc_' +i+ '" style="color:#444;display:none;padding-left:24px;">'+desc+'</div>';
	    }
	    _gi('gps_result').style.textAlign = 'left';
	    _gi('gps_result').innerHTML = list;
        }
    });
}

GPS.publicTracks = function(userid,x,init_trk) {

    GPS.browseOnOff(false);
    var url = 'http://maps.yuan.cc/gpx.php?method=gpx.publictracks&sort='+x + ((userid=='') ?'' :'&userid='+userid);
    showLoadingMessage('Loading public GPS tracks ...');
    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,title,time;
            var parser = new DOMParser();
            var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
            var tracks = dom.getElementsByTagName('trk');
//	    var list = '<h3>Users Shared Tracks</h3><ul>';
	    for(var i=0; i<tracks.length; i++) {
		id = tracks[i].getAttribute('id');
		owner = tracks[i].getAttribute('owner');
		private = tracks[i].getAttribute('private');
		username = tracks[i].getAttribute('username');
		flickrid = tracks[i].getAttribute('flickrid');
		diff = tracks[i].getAttribute('timeoffset');
		title = (tracks[i].getElementsByTagName('name').item(0).firstChild) ? tracks[i].getElementsByTagName('name').item(0).firstChild.data : '';
		desc = tracks[i].getElementsByTagName('desc').item(0).firstChild.data;
		src = tracks[i].getElementsByTagName('src').item(0).firstChild.data;
		time = (tracks[i].getElementsByTagName('time').item(0).firstChild) ? tracks[i].getElementsByTagName('time').item(0).firstChild.data : '';
		if(private=='1') private='checked'; else private='';

		if(i==0 && userid=='') var list = '<h3>Tracks shared by all users</h3><ul>';
		if(i==0 && userid!='') var list = '<h3>Tracks shared by '+username+'</h3><ul>';
		if( !gps_tracks[src] ) gps_tracks[src] = new Object();
		gps_tracks[src].id = id;
		gps_tracks[src].private = private;
		gps_tracks[src].owner = owner;
		gps_tracks[src].flickrid = flickrid;
		gps_tracks[src].diff = 1*diff;
		gps_tracks[src].title = title;
		gps_tracks[src].desc = desc;
		gps_tracks[src].src = src;
		gps_tracks[src].time = time;
		if(init_trk!=undefined && init_trk==id) GPS.readPoint(1,1,src);

		list += '<li>';
		list += '<a href="javascript:;" onclick="GPS.readPoint(1,1,\'' +src+ '\')">' +title+ '</a>';
		if(userid=='') list += ' (<a href="javascript:;" onclick="GPS.publicTracks('+owner+',1)">'+username+'</a>) ';
		if(desc!='') {
		    list += ' <a href="javascript:;" style="text-decoration:none" onclick="if(_gi(\'mytrack_desc_' +i+ '\').style.display==\'none\') _gi(\'mytrack_desc_' +i+ '\').style.display=\'block\'; else _gi(\'mytrack_desc_' +i+ '\').style.display=\'none\';this.innerHTML=(this.innerHTML==\'+\')?\'-\':\'+\'">+</a><br /> ';
		    list += '<div id="mytrack_desc_' +i+ '" style="border:solid 1px #eeeec3;background:#fffff0;color:#444;display:none;padding:2px 0px 2px 0px;margin-bottom:2px;">'+desc+'</div></li>';
		}
	    }
	    list += '</ul>';
	    _gi('gps_result').style.textAlign = 'left';
	    _gi('gps_result').innerHTML = list;
//	    if(init_trk!=undefined) GPS.readPoint(1,1,);
        }
    });
}

GPS.browseTracks = function() {

    if(!_gi('gps') || CK.activePage != _gi('gps')) return;
    if(!GPS.browseMode) return;

    var minX = map.getBoundsLatLng().minX;
    var minY = map.getBoundsLatLng().minY;
    var maxX = map.getBoundsLatLng().maxX;
    var maxY = map.getBoundsLatLng().maxY;
    var bbox = 'BBOX=' + minX + ',' + minY + ',' + maxX + ',' + maxY;

    var url = 'http://maps.yuan.cc/gpx.php?method=gpx.browsetracks&'+bbox+'&userid='+login_userid;
    showLoadingMessage('Browsing public GPS tracks ...');
    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();
	    for(var s in GPS.trackAreas) {
		map.removeOverlay(GPS.trackAreas[s]);
		delete GPS.trackAreas[s];
	    }
	    var i,id,title,time;
            var parser = new DOMParser();
            var dom = parser.parseFromString(responseDetails.responseText, "application/xml");
            var tracks = dom.getElementsByTagName('trk');
	    var list = '<h3>Tracks within viewable area</h3>';
//	    list += '<div style="text-align:right"><span style="padding:2px;background:#ddd;"><a href="javascript:;" style="text-decoration:none;" onclick="GPS.browseMode=false; this.parentNode.innerHTML=\'\';">Disable Browse Mode</a></span></div><ul>';
	    for(var i=0; i<tracks.length; i++) {
		id = tracks[i].getAttribute('id');
		private = tracks[i].getAttribute('private');
		owner = tracks[i].getAttribute('owner');
		username = tracks[i].getAttribute('username');
		flickrid = tracks[i].getAttribute('flickrid');
		diff = tracks[i].getAttribute('diff');
		title = tracks[i].getElementsByTagName('name').item(0).firstChild.data;
		desc = tracks[i].getElementsByTagName('desc').item(0).firstChild.data;
		src = tracks[i].getElementsByTagName('src').item(0).firstChild.data;
		max_lat = 1*tracks[i].getElementsByTagName('maxlat').item(0).firstChild.data;
		max_lon = 1*tracks[i].getElementsByTagName('maxlon').item(0).firstChild.data;
		min_lat = 1*tracks[i].getElementsByTagName('minlat').item(0).firstChild.data;
		min_lon = 1*tracks[i].getElementsByTagName('minlon').item(0).firstChild.data;
		time = (tracks[i].getElementsByTagName('time').item(0).firstChild) ? tracks[i].getElementsByTagName('time').item(0).firstChild.data : '';
		if(private=='1') private='checked'; else private='';

		if( !gps_tracks[src] ) gps_tracks[src] = new Object();
		gps_tracks[src].id = id;
		gps_tracks[src].owner = owner;
		gps_tracks[src].private = private;
		gps_tracks[src].flickrid = flickrid;
		gps_tracks[src].diff = 1*diff;
		gps_tracks[src].title = title;
		gps_tracks[src].desc = desc;
		gps_tracks[src].src = src;
		gps_tracks[src].time = time;
		gps_tracks[src].max_lat = max_lat;
		gps_tracks[src].max_lon = max_lon;
		gps_tracks[src].min_lat = min_lat;
		gps_tracks[src].min_lon = min_lon;

		list += '<li>';
		list += '<a href="javascript:;" onclick="GPS.readPoint(1,1,\'' +src+ '\')" onMouseOver="GPS.showArea(\''+src+'\',1)" onMouseOut="GPS.showArea(\''+src+'\',0)">' +title+ '</a> ';
		list += ' (<a href="javascript:;" onclick="GPS.publicTracks('+owner+',1)">'+username+'</a>) ';
		if(desc!='') {
		    list += '<a href="javascript:;" style="text-decoration:none" onclick="if(_gi(\'mytrack_desc_' +i+ '\').style.display==\'none\') _gi(\'mytrack_desc_' +i+ '\').style.display=\'block\'; else _gi(\'mytrack_desc_' +i+ '\').style.display=\'none\';this.innerHTML=(this.innerHTML==\'+\')?\'-\':\'+\'">+</a><br /> ';
		    list += '<div id="mytrack_desc_' +i+ '" style="border:solid 1px #eeeec3;background:#fffff0;color:#444;display:none;padding:2px 0px 2px 0px;margin-bottom:2px;">'+desc+'</div></li>';
		}

		var corners = new Array();
//		if(!GPS.trackAreas[src] && !gps_tracks[src].onMap ) {
		if(!GPS.trackAreas[src]) {
		    corners[corners.length] = map.LatLng(min_lat,min_lon);
		    corners[corners.length] = map.LatLng(max_lat,min_lon);
		    corners[corners.length] = map.LatLng(max_lat,max_lon);
		    corners[corners.length] = map.LatLng(min_lat,max_lon);
		    corners[corners.length] = map.LatLng(min_lat,min_lon);
		    box1 = map.Polyline(corners,'#ff0000',1,0.9);
		    box2 = map.Polyline(corners,'#ffff00',1,0.9);
		    GPS.trackAreas[src] = new Object();
		    GPS.trackAreas[src].box1 = box1[2];
		    GPS.trackAreas[src].box2 = box2[2];
//		    map.addOverlay(box1[2]);
		}
	    }
	    list += '</ul>';
	    _gi('gps_result').style.textAlign = 'left';
	    _gi('gps_result').innerHTML = list;
        }
    });
}

GPS.showArea = function(id,mode) {

    if(mode==1) {
	var lat = (gps_tracks[id].max_lat + gps_tracks[id].min_lat)/2;
	var lon = (gps_tracks[id].max_lon + gps_tracks[id].min_lon)/2;
//	map.openInfoWindowHtml(map.LatLng(lat,lon), gps_tracks[id].title);
//	map.removeOverlay(GPS.trackAreas[id].box1);
	map.addOverlay(GPS.trackAreas[id].box2);
    } else {
	map.removeOverlay(GPS.trackAreas[id].box2);
//	map.addOverlay(GPS.trackAreas[id].box1);
//	map.closeInfoWindow();
    }
}

GPS.matchTrack = function(photo_id) {

//    alert(GPS.points[0].date.toGMTString() + '\n' + GPS.points[GPS.points.length-1].date.toGMTString());
//    alert(photos[photo_id].taken.toGMTString() );
    var diff = Math.abs(Date.UTC());

    for(var i=0;i<GPS.points.length;i++) {
	if( diff < Math.abs(GPS.points[i].date - photos[photo_id].taken - GPS.offset) ) {
	    i--;
	    break;
	}
	diff = Math.abs(GPS.points[i].date - photos[photo_id].taken - GPS.offset);
    }
    
    if( i== GPS.points.length ) alert('Out of range');
    else {
	map.centerAtLatLng(map.LatLng(GPS.points[i].lat,GPS.points[i].lon));
	var offset = GPS.points[i].date - photos[photo_id].taken;
	var html = '<p>' + GPS.points[i].date.toGMTString() + '<br />';
	html += 'Time offset: ' + (offset/1000) + ' sec (' + (offset-GPS.offset) + ')</p>';
	html += '<a href="javascript:;" onclick="GPS.move(' + (i-1) + ',' +photo_id+ ')">Prev Point</a> ';
	html += '<a href="javascript:;" onclick="GPS.move(' + (i+1) + ',' +photo_id+ ')">Next Point</a> | ';
	html += '<a href="javascript:;" onclick="GPS.offset=' +offset+ ';GPS.move('+i+','+photo_id+')">Adjust offset</a>';
	map.openInfoWindowHtml(map.LatLng(GPS.points[i].lat,GPS.points[i].lon), html);
    }
}

GPS.move = function(i,photo_id) {

    if( i<=0 ) i = 0;
    if( i>=GPS.points.length ) i = GPS.points.length-1;

    map.centerAtLatLng(map.LatLng(GPS.points[i].lat,GPS.points[i].lon));
    var offset = GPS.points[i].date - photos[photo_id].taken;
    var html = '<p>' + GPS.points[i].date.toGMTString() + '<br />';
    html += 'Time offset: ' + (offset/1000) + ' sec (' + (offset-GPS.offset) + ')</p>';
    html += '<a href="javascript:;" onclick="GPS.move(' + (i-1) + ',' +photo_id+ ')">Prev Point</a> ';
    html += '<a href="javascript:;" onclick="GPS.move(' + (i+1) + ',' +photo_id+ ')">Next Point</a> | ';
    html += '<a href="javascript:;" onclick="GPS.offset=' +offset+ ';GPS.move('+i+','+photo_id+')">Adjust offset</a>';
    map.openInfoWindowHtml(map.LatLng(GPS.points[i].lat,GPS.points[i].lon), html);

}

GPS.compareDate = function(a,b) {

//    return a.date.getTime() - b.date.getTime();
    return a.date - b.date;
}

GPS.selectSeg = function(x) {
    var checkboxes = _gi('gps_result').getElementsByTagName('input');
    for(var i=0;i<checkboxes.length;i++) {
	switch(x) {
	    case 1: checkboxes[i].checked = true; break;
	    case 2: checkboxes[i].checked = false; break;
	    case 3: checkboxes[i].checked = !checkboxes[i].checked; break;
	}
    }
}

GPS.loadSegs = function() {

    var i,checkboxes,trk,seg,str;

    GPS.selectedSegs = new Array();
    checkboxes = _gi('gps_result').getElementsByTagName('input');
    str = 'multi';
    for(i=0;i<checkboxes.length;i++) {
	if(checkboxes[i].checked) str += checkboxes[i].getAttribute('trk')+checkboxes[i].getAttribute('seg');
    }
    str = hex_md5(str);
    GPS.trkseg_str = '';
    for(i=0;i<checkboxes.length;i++) {
	if(checkboxes[i].checked) {
	    trk = checkboxes[i].getAttribute('trk');
	    seg = checkboxes[i].getAttribute('seg');
	    GPS.selectedSegs.push( {trk_id:str, trk:trk, seg:seg} );
	    if( GPS.trkseg_str=='' ) GPS.trkseg_str = seg;
	    else GPS.trkseg_str += ','+seg;
	}
    }
    GPS.readPoint(trk,GPS.selectedSegs);
}

GPS.setPrivate = function(x) {

    var trkid = x.getAttribute('trkid');
    var url = 'http://maps.yuan.cc/gpx.php?method=gpx.setprivacy&userid=' +login_userid+ '&track='+trkid+'&private='+((x.checked)?1:0);
    showLoadingMessage('Setting GPS Track privacy ...');
    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' ) showLoadingMessage(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	    else alert(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	}
    });
}

GPS.delTrack = function(id) {

    var url = 'http://maps.yuan.cc/gpx.php?method=gpx.deltrack&userid=' +login_userid+ '&track='+id;
    if( !confirm('Are you sure to delete this track?') ) return;
    showLoadingMessage('Delete GPS Track ...');
    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' ) {
		showLoadingMessage(dom.getElementsByTagName('rsp').item(0).firstChild.data);
		GPS.myTracks();
	    } else alert(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	}
    });
}

GPS.searchFlickr = function(trk_id, diff) {

    var date_pattern = /(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;

//    if(diff == undefined) GPS.offset = 1000*prompt('Input the time difference between your GPS device and the Camera (in second)', GPS.offset/1000);
//    else GPS.offset = diff;
    map.closeInfoWindow();
    for(i in gps_tracks[trk_id].photos) {
	if(!gps_tracks[trk_id].photos[i].marker) continue;
	var marker = gps_tracks[trk_id].photos[i].marker[map.mtype];
	map.removeOverlay(marker);
	delete gps_tracks[trk_id].photos[i].marker;
	delete photos[gps_tracks[trk_id].photos[i].photoid];
    }

    var timeoffset = 0;
    if( _gi('timezone') && _gi('timeoffset') ) {
	diff = -60*60 * _gi('timezone').value + (1*_gi('timeoffset').value);
	GPS.selectedIndex = _gi('timezone').selectedIndex;
	GPS.timeoffset = _gi('timeoffset').value;
    } else {
	if(gps_tracks[trk_id].diff) diff = gps_tracks[trk_id].diff/1000;
	else diff = 0;
    }
    GPS.offset = 1000*diff;

    var start = gps_tracks[trk_id].start;
    if( start.match(date_pattern) ) {
	var a = date_pattern.exec(start);
	var year=a[1], mon=1*a[2]-1, day=a[3], hour=a[4], min=a[5], sec=a[6];
	x = new Date();
	x.setUTCFullYear(year);
	x.setUTCMonth(mon);
	x.setUTCDate(day);
	x.setUTCHours(hour);
	x.setUTCMinutes(min);
	x.setUTCSeconds(sec);
	x.setUTCMinutes(1*min-30);
	x.setUTCSeconds(1*sec-diff);
	y = x.getUTCFullYear();
	m = x.getUTCMonth()+1;
	d = x.getUTCDate();
	h = x.getUTCHours();
	n = x.getUTCMinutes();
	s = x.getUTCSeconds();
	start_time = y +'-'+ m +'-'+ d +' '+ h +':'+ n +':'+ s;
    }

    var end = gps_tracks[trk_id].end;
    if( end.match(date_pattern) ) {
	var a = date_pattern.exec(end);
	var year=a[1], mon=1*a[2]-1, day=a[3], hour=a[4], min=a[5], sec=a[6];
	x = new Date();
	x.setUTCFullYear(year);
	x.setUTCMonth(mon);
	x.setUTCDate(day);
	x.setUTCHours(hour);
	x.setUTCMinutes(min);
	x.setUTCSeconds(sec);
	x.setUTCMinutes(1*min+30);
	x.setUTCSeconds(1*sec-diff);
	y = x.getUTCFullYear();
	m = x.getUTCMonth()+1;
	d = x.getUTCDate();
	h = x.getUTCHours();
	n = x.getUTCMinutes();
	s = x.getUTCSeconds();
	end_time = y +'-'+ m +'-'+ d +' '+ h +':'+ n +':'+ s;
    }
//  alert(start +','+ start_time +','+ end_time);

    if( _init_service=='gps' && _init_nsid!='' ) {
	var gps_nsid = _init_nsid;
	_init_nsid = _init_service = _init_track = '';
    } else var gps_nsid = auth_nsid;
    var gps_nsid = gps_tracks[trk_id].flickrid;

    var url = 'http://flickr.com/services/rest/?method=flickr.photos.search&api_key='+api_key+'&user_id='+gps_nsid+'&min_taken_date=' +start_time+ '&max_taken_date=' +end_time+ '&extras=date_taken&per_page=500';
//  alert(url);

    showLoadingMessage('Search photos along this track...');
    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 p = dom.getElementsByTagName('photo');
	    gps_tracks[trk_id].photos = new Array();
	    trk_photos = gps_tracks[trk_id].photos;
	    var permalink = 'http://maps.yuan.cc/gps/' + gps_tracks[trk_id].id +'/'+auth_nsid+'/';
	    var html = showTip('Photos Taken Along This Track', '<br />Start time: ' + gps_tracks[trk_id].start + '<br />End time: ' + gps_tracks[trk_id].end + '<br />Points: '+gps_tracks[trk_id].points.length+'&nbsp;&nbsp;Photos: '+p.length+'&nbsp;&nbsp;Time Diff: '+(GPS.offset/1000)+'<br /><a href="'+permalink+'">Link to this page</a>&nbsp;&nbsp;<a href="javascript:;" onclick="var i=gps_tracks[\''+trk_id+'\'].track[0];i.openInfoWindowHtml(i.html);">Open it</a>&nbsp;&nbsp;<a href="javascript:;" onclick="GPS.clearTrack(\'' +trk_id+ '\')">Clear it</a>' + ((login_userid == gps_tracks[trk_id].owner)? '<br /><a href="javascript:;" onclick="GPS.saveLocations(\'' +trk_id+ '\')">Save all photos\' locations</a><br /><a href="javascript:;" onclick="GPS.saveTimeDiff(\'' +trk_id+ '\')">Save Time difference for this track</a>': '') );
//	    if(p.length==0) return;

	    if( login_userid == gps_tracks[trk_id].owner ) {
		x = new Date();
		currentTimeZoneOffsetInHours = x.getTimezoneOffset()/60;
		timezone =  'Camera Timezone:	<select name="timezone" id="timezone">';
		timezone += '		<option value="0">Please select timezone</option>';
		timezone += '		<option value="-12">-12:00 International Date Line West</option>';
		timezone += '		<option value="-11">-11:00 Midway Island, Samoa</option>';
		timezone += '		<option value="-10">-10:00 Hawaii</option>';
		timezone += '		<option value="-9">-09:00 Alaska</option>';
		timezone += '		<option value="-8">-08:00 Pacific Time (US &amp; Canada)</option>';
//		timezone += '		<option value="-8">-08:00 Pacific Time (US &amp; Canada); Tijuana</option>';
		timezone += '		<option value="-7">-07:00 Arizona</option>';
		timezone += '		<option value="-7">-07:00 Chihuahua, La Paz, Mazatlan</option>';
		timezone += '		<option value="-7">-07:00 Mountain Time (US &amp; Canada)</option>';
		timezone += '		<option value="-6">-06:00 Central America</option>';
		timezone += '		<option value="-6">-06:00 Central Time (US &amp; Canada)</option>';
		timezone += '		<option value="-6">-06:00 Monterrey</option>';
//		timezone += '		<option value="-6">-06:00 Guadalajara, Mexico City, Monterrey</option>';
		timezone += '		<option value="-6">-06:00 Saskatchewan</option>';
		timezone += '		<option value="-5">-05:00 Bogota, Lima, Quito</option>';
		timezone += '		<option value="-5">-05:00 Eastern Time (US &amp; Canada)</option>';
		timezone += '		<option value="-5">-05:00 Indiana (East)</option>';
		timezone += '		<option value="-4">-04:00 Atlantic Time (Canada)</option>';
		timezone += '		<option value="-4">-04:00 Caracas, La Paz</option>';
		timezone += '		<option value="-4">-04:00 Santiago</option>';
		timezone += '		<option value="-3">-03:30 Newfoundland</option>';
		timezone += '		<option value="-3">-03:00 Brasilia</option>';
		timezone += '		<option value="-3">-03:00 Buenos Aires, Georgetown</option>';
		timezone += '		<option value="-3">-03:00 Greenland</option>';
		timezone += '		<option value="-2">-02:00 Mid-Atlantic</option>';
		timezone += '		<option value="-1">-01:00 Azores</option>';
		timezone += '		<option value="-1">-01:00 Cape Verde Is.</option>';
		timezone += '		<option value="0">+00:00 Casablanca, Monrovia</option>';
		timezone += '		<option value="0" selected>+00:00 GMT: London</option>';
//		timezone += '		<option value="0">+00:00 Dublin, Edinburgh, Lisbon, London</option>';
		timezone += '		<option value="1">+01:00 Amsterdam</option>';
//		timezone += '		<option value="1">+01:00 Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</option>';
//		timezone += '		<option value="1">+01:00 Belgrade, Bratislava, Budapest, Ljubljana, Prague</option>';
//		timezone += '		<option value="1">+01:00 Brussels, Copenhagen, Madrid, Paris</option>';
//		timezone += '		<option value="1">+01:00 Sarajevo, Skopje, Warsaw, Zagreb</option>';
		timezone += '		<option value="1">+01:00 West Central Africa</option>';
		timezone += '		<option value="2">+02:00 Athens</option>';
//		timezone += '		<option value="2">+02:00 Athens, Beirut, Istanbul, Minsk</option>';
		timezone += '		<option value="2">+02:00 Bucharest</option>';
		timezone += '		<option value="2">+02:00 Cairo</option>';
		timezone += '		<option value="2">+02:00 Harare, Pretoria</option>';
		timezone += '		<option value="2">+02:00 Helsinki</option>';
//		timezone += '		<option value="2">+02:00 Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius</option>';
		timezone += '		<option value="2">+02:00 Jerusalem</option>';
		timezone += '		<option value="3">+03:00 Baghdad</option>';
		timezone += '		<option value="3">+03:00 Kuwait, Riyadh</option>';
		timezone += '		<option value="3">+03:00 Moscow</option>';
//		timezone += '		<option value="3">+03:00 Moscow, St. Petersburg, Volograd</option>';
		timezone += '		<option value="3">+03:00 Nairobi</option>';
		timezone += '		<option value="3">+03:30 Tehran</option>';
		timezone += '		<option value="4">+04:00 Abu Dhabi, Muscat</option>';
		timezone += '		<option value="4">+04:00 Baku, Tbilisi, Yerevan</option>';
		timezone += '		<option value="4">+04:30 Kabul</option>';
		timezone += '		<option value="5">+05:00 Ekaterinburg</option>';
		timezone += '		<option value="5">+05:00 Islamabad, Karachi, Tashkent</option>';
		timezone += '		<option value="5.5">+05:30 New Delhi</option>';
//		timezone += '		<option value="5.5">+05:30 Chennai, Kolkata, Mumbai, New Delhi</option>';
		timezone += '		<option value="5.75">+05:45 Kathmandu</option>';
		timezone += '		<option value="6">+06:00 Almaty, Novosibirsk</option>';
		timezone += '		<option value="6">+06:00 Astana, Dhaka</option>';
		timezone += '		<option value="6">+06:00 Sri Jayawardenepura</option>';
		timezone += '		<option value="6.5">+06:30 Rangoon</option>';
		timezone += '		<option value="7">+07:00 Bangkok</option>';
//		timezone += '		<option value="7">+07:00 Bangkok, Hanoi, Jakarta</option>';
		timezone += '		<option value="7">+07:00 Krasnoyarsk</option>';
		timezone += '		<option value="8">+08:00 Beijing</option>';
//		timezone += '		<option value="8">+08:00 Beijing, Chongqing, Hong Kong, Urumqi</option>';
		timezone += '		<option value="8">+08:00 Irkstsk, Ulaan Bataar</option>';
		timezone += '		<option value="8">+08:00 Singapore</option>';
//		timezone += '		<option value="8">+08:00 Kuala Lumpur, Singapore</option>';
		timezone += '		<option value="8">+08:00 Perth</option>';
		timezone += '		<option value="8">+08:00 Taipei</option>';
		timezone += '		<option value="9">+09:00 Tokyo</option>';
//		timezone += '		<option value="9">+09:00 Osaka, Sapporo, Tokyo</option>';
		timezone += '		<option value="9">+09:00 Seoul</option>';
		timezone += '		<option value="9">+09:00 Yakutsk</option>';
		timezone += '		<option value="9.5">+09:30 Adelaide</option>';
		timezone += '		<option value="9.5">+09:30 Darwin</option>';
		timezone += '		<option value="10">+10:00 Brisbane</option>';
		timezone += '		<option value="10">+10:00 Melbourne, Sydney</option>';
//		timezone += '		<option value="10">+10:00 Canberra, Melbourne, Sydney</option>';
		timezone += '		<option value="10">+10:00 Guam, Port Moresby</option>';
		timezone += '		<option value="10">+10:00 Hobart</option>';
		timezone += '		<option value="10">+10:00 Vladivostok</option>';
		timezone += '		<option value="11">+11:00 Magadan</option>';
//		timezone += '		<option value="11">+11:00 Magadan, Soloman Is., New Caledonia</option>';
		timezone += '		<option value="12">+12:00 Auckland, Wellington</option>';
		timezone += '		<option value="12">+12:00 Fiji, Marshall Is.</option>';
//		timezone += '		<option value="12">+12:00 Fiji, Kamchatka, Marshall Is.</option>';
		timezone += '		<option value="13">+13:00 Nuku\'alofa</option>';
		timezone += '	</select>';

		timeoffset = 'Time offset: <input type="text" id="timeoffset" size="4" value="' +GPS.timeoffset+ '"> Seconds';
		timeoffset += ' <input type=button value="Search" onClick="GPS.searchFlickr(\''+trk_id+'\',0)">';
		timeoffset += '<br /><small>(GPS time - Camera time)</small>';
		html += '<div style="padding:10px;text-align:left">' + timezone + '<br />' +  timeoffset + '</div>';
	    }
	    for(var i=0; i<p.length; i++) {
		var photo_id = p[i].getAttribute('id');
		trk_photos[photo_id] = new Object();
		trk_photos[photo_id].photo_id = p[i].getAttribute('id');
		trk_photos[photo_id].owner = p[i].getAttribute('owner');
		trk_photos[photo_id].secret = p[i].getAttribute('secret');
		trk_photos[photo_id].server = p[i].getAttribute('server');
		trk_photos[photo_id].title = p[i].getAttribute('title');
		trk_photos[photo_id].taken = ''+p[i].getAttribute('datetaken');
		trk_photos[photo_id].img_s = 'http://static.flickr.com/' + trk_photos[photo_id].server + '/' + trk_photos[photo_id].photo_id + '_' + trk_photos[photo_id].secret + '_s.jpg';
		trk_photos[photo_id].img_m = 'http://static.flickr.com/' + trk_photos[photo_id].server + '/' + trk_photos[photo_id].photo_id + '_' + trk_photos[photo_id].secret + '_m.jpg';
		trk_photos[photo_id].img = 'http://static.flickr.com/' + trk_photos[photo_id].server + '/' + trk_photos[photo_id].photo_id + '_' + trk_photos[photo_id].secret + '.jpg';
		trk_photos[photo_id].url = 'http://www.flickr.com/photos/' + trk_photos[photo_id].owner + '/' + photo_id + '/';

		var location = GPS.matchLatLon(trk_photos[photo_id].taken);
		if(!location) continue;
//		trk_photos[photo_id].lat = location.lat();
//		trk_photos[photo_id].lon = location.lng();

		if( !trk_photos[photo_id].marker ) trk_photos[photo_id].marker = new Array();
		if( !trk_photos[photo_id].marker[map.mtype] ) {
		    var label = trk_photos[photo_id].title;
		    var desc = '<div style="width:200px;font-size:10px"><a href="javascript:;" onclick="lightBox(\''+trk_photos[photo_id].img+'\');"><img src="' + trk_photos[photo_id].img_s + '" border=0 width=50 height=50 align="left" /></a><b>' + trk_photos[photo_id].title + '</b><br />' + location.lat() + ', ' + location.lng() + '<br />' +trk_photos[photo_id].taken+ '<br clear="all"><p /><a href="javascript:;" onclick="GPS.geotag(\''+trk_id+'\',\''+photo_id+'\')">Add Geotags</a>&nbsp;&nbsp;<a href="javascript:;" onclick="lightBox(\''+trk_photos[photo_id].img+'\');"><br />See Large Photo</a>&nbsp;&nbsp;<a href="'+trk_photos[photo_id].url+'" target="_blank">Flickr Photo Page</a></div>';
		    var marker = map.Marker(location, null,trk_photos[photo_id].title,'',true);
		    marker.photo_id = photo_id;
		    marker.html = desc;
		    marker.addListener('mouseover', function() {
			this.openInfoWindowHtml(this.html);
		    });
		    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;
			this.html = '<div style="width:200px;font-size:10px"><a href="javascript:;" onclick="lightBox(\''+trk_photos[this.photo_id].img+'\');"><img src="' + trk_photos[this.photo_id].img_s + '" border=0 width=50 height=50 align="left" /></a><b>' + trk_photos[this.photo_id].title + '</b><br />' + lat + ', ' + lon + '<br />' +trk_photos[this.photo_id].taken+ '<br clear="all"><p /><a href="javascript:;" onclick="GPS.geotag(\''+trk_id+'\',\''+this.photo_id+'\')">Add Geotags</a>&nbsp;&nbsp;<a href="javascript:;" onclick="lightBox(\''+trk_photos[photo_id].img+'\');"><br />See Large Photo</a>&nbsp;&nbsp;<a href="'+trk_photos[this.photo_id].url+'">Flickr Photo Page</a></div>';
		    });

		    trk_photos[photo_id].marker[map.mtype] = marker;
		    map.addOverlay(marker);
		}

		html += '<a href="javascript:;" id="flickr_'+photo_id+'" flickr="'+photo_id+'" title="'+ trk_photos[photo_id].title +'"><img id="trkphoto_'+photo_id+'" src="' + trk_photos[photo_id].img_s + '" alt="' + trk_photos[photo_id].title + '" width=50 height=50 style="border:solid 1px #fff;margin:1px 1px 1px 1px;-moz-opacity:0.8;" onmouseover="this.style.MozOpacity=1" onmouseout="this.style.MozOpacity=0.8" onclick="t=gps_tracks[\''+trk_id+'\'].photos[\''+photo_id+'\'].marker[map.mtype];t.openInfoWindowHtml(t.html)" /></a>';
	    }
	    _gi('gps_result').style.textAlign = 'center';
	    _gi('gps_result').innerHTML = html;
	    if( _gi('timezone') ) _gi('timezone').selectedIndex = GPS.selectedIndex;
	}
    });
}

GPS.geotag = function(trk_id, photoid, callback) {

//    alert(photoid + ': '+ lat +','+ lon);
    photos[photoid] = gps_tracks[trk_id].photos[photoid];
    photos[photoid].desc = '';
    lat = photos[photoid].marker[map.mtype].getPoint().lat();
    lon = photos[photoid].marker[map.mtype].getPoint().lng();
    lat = Math.round(lat*1000000)/1000000;
    lon = Math.round(lon*1000000)/1000000;

    addGeoTags(photoid,lat,lon,callback)
}

GPS.matchLatLon = function(time) {

    var date_pattern = /(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/;

    if( time.match(date_pattern) ) {
	var a = date_pattern.exec(time);
	var year=a[1], mon=1*a[2]-1, day=a[3], hour=a[4], min=a[5], sec=a[6];
	x = new Date();
	x.setUTCFullYear(year);
	x.setUTCMonth(mon);
	x.setUTCDate(day);
	x.setUTCHours(hour);
	x.setUTCMinutes(min);
	x.setUTCSeconds(sec);
    }

    var diff = Math.abs(Date.UTC());
    for(var i=0;i<GPS.points.length;i++) {
	if( diff < Math.abs(GPS.points[i].date - x - GPS.offset) ) {
	    i--;
	    break;
	}
	diff = Math.abs(GPS.points[i].date - x - GPS.offset);
    }
    
//    if( i== GPS.points.length ) alert('Out of range');
    if( i== GPS.points.length ) return null;
    else return map.LatLng(GPS.points[i].lat,GPS.points[i].lon);
}

GPS.saveTimeDiff = function(trk_id) {

    var id = gps_tracks[trk_id].id;

    var url = 'http://maps.yuan.cc/gpx.php?method=gpx.settimediff&track='+id+'&diff=' + GPS.offset;
    showLoadingMessage('Saving Time diff between GPS and camera ...');
    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' ) alert(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	    else alert(dom.getElementsByTagName('rsp').item(0).firstChild.data);
	}
    });
}

