
/*
 * $Id: marukan.js 67 2008-02-20 12:47:14Z yuya $
 */

var map;
var manager;
var markers = $H({});
var target_trains = $A([]);
var visible_trains = $H({});
var train_index = 0;
var focused_train = undefined;
var calc_count = 0;
var calc_total_time = 0;

var TimeConverter = Class.create();
TimeConverter.count = 0;
TimeConverter.h_m_s_to_hms = function(hour, min, sec)
{
	return (hour * 60 * 60) + (min * 60) + sec;
}
TimeConverter.date_to_hms = function(date)
{
	return this.h_m_s_to_hms(date.getHours(), date.getMinutes(), date.getSeconds());
}
TimeConverter.get_current_hms = function()
{
	return this.date_to_hms(new Date());
//	return this.h_m_s_to_hms(12, 0, 0);
//	return this.h_m_s_to_hms(12, 0, 0) + this.count;
}

function show_status()
{
	if ( focused_train == undefined ) return;

	var time = TimeConverter.get_current_hms();
	var status = '';

	status  = focused_train.shinkansen.line_name;
	status += ' ';
	status += focused_train.train.full_name;
	status += ' ( ';
	status += focused_train.train.departure.station_name + '発';
	status += ' ';
	status += focused_train.train.arrival.station_name   + '行';
	status += ' )<br />';

	if ( focused_train.train.available(time) )
	{
		var prev_station = focused_train.train.get_prev_station(time);
		var next_station = focused_train.train.get_next_station(time);
		if ( prev_station.station == next_station.station )
		{
			status += '<em>';
			status += focused_train.shinkansen.stations[prev_station.station];
			status += '</em> に停車中';
		}
		else
		{
			status += '<em>';
			status += focused_train.shinkansen.stations[prev_station.station];
			status += '</em> を出発し <em>';
			status += focused_train.shinkansen.stations[next_station.station];
			status += '</em> へ向けて走行中';
		}
	}
	else
	{
		status += '<em>指定された列車は、現在運行されていません</em>';
	}
	$('info1').innerHTML = status;
	$('info2').innerHTML = status;

	if ( focused_train.train.available(time) )
	{
		var train = focused_train.train;
		handler = function(evt) {
			Event.stop(evt);
			var now = TimeConverter.get_current_hms();
			if ( train.available(now) )
			{
				var position = train.get_position(time);
				map.setCenter(new GLatLng(position.lat, position.lng));
			}
		};

		var anchor = document.createElement('a');
		anchor.href      = '#';
		anchor.innerHTML = '追跡';
		anchor.title     = '選択された列車を地図の中央に表示します';
		Event.observe(anchor, 'click', handler.bindAsEventListener(this), false);
		$('info1').appendChild(anchor);
		var dummy = document.createElement('span');
		dummy.innerHTML = '追跡';
		$('info2').appendChild(dummy);
	}
}

function update()
{
//	TimeConverter.count += 10;
	var time = TimeConverter.get_current_hms();

	var start_time = (new Date()).getTime();

	var i = 0, length = target_trains.length;
	for ( i = 0; i < 150; i++, train_index++ )
	{
		if ( train_index >= length )
		{
			train_index = 0;
			show_status();
		}

		var shinkansen = target_trains[train_index][0];
		var train      = target_trains[train_index][1];
		var key = train.key;

		if ( visible_trains[train.name] && train.available(time) )
		{
			var position = train.get_position(time);

			if ( markers[key] != undefined )
			{
				var cur = markers[key].getPoint();
				if ( Math.floor(cur.lat() * 500) != Math.floor(position.lat * 500) ||
				     Math.floor(cur.lng() * 500) != Math.floor(position.lng * 500) )
				{
					markers[key].setPoint(new GLatLng(position.lat, position.lng));
				}
			}
			else
			{
				var marker = new GMarker(new GLatLng(position.lat, position.lng), train.get_icon());
				marker.shinkansen = shinkansen;
				marker.train      = train;

				GEvent.addListener(marker, "click", function() {
					focused_train = {
						shinkansen: this.shinkansen,
						train: this.train
					};
					show_status();
				}.bind(marker));

				markers[key] = marker;
				manager.addMarker(marker, 5);
			}
		}
		else
		{
			if ( markers[key] != undefined )
			{
				manager.removeMarker(markers[key]);
				markers[key] = undefined;
			}
		}
	}

	var end_time  = (new Date()).getTime();
	var calc_time = end_time - start_time;
	calc_count++;
	calc_total_time += calc_time;
	$('time').innerHTML = Math.floor(calc_total_time / calc_count);

	manager.refresh();

	window.setTimeout(update, 1000);
}

function load()
{
	resize();

	map = new GMap2($("map"));
	map.addControl(new GLargeMapControl());
	map.addControl(new GScaleControl());
	map.addControl(new GMapTypeControl());
	map.enableDoubleClickZoom();
	map.enableScrollWheelZoom();
	map.disableContinuousZoom();
	map.checkResize();
	map.setCenter(new GLatLng(34.6694, 135.5273), 5, G_SATELLITE_MAP);
	manager = new MarkerManager(map, {trackMarkers: true});

	shinkansens.each(function(shinkansen) {
		var element = shinkansen.create_checkboxes(visible_trains);
		var checked = element.checkboxes.map(function(checkbox) { return checkbox.checked; });
		$('checkboxes').appendChild(element);

		// MEMO: Internet Explorer 6では、appendChildでチェックボックスの状態が失われてしまうので、復元する
		checked.each(function(value, index) {
			element.checkboxes[index].checked = value;
		});
	}.bind(this));

	shinkansens.each(function(shinkansen) {
		var pt = shinkansen.points.map(function(item) {
			//if ( item.station != undefined ) map.addOverlay(new GMarker(new GLatLng(item.lat, item.lng)));
			//if ( item.station != undefined ) manager.addMarker(new GMarker(new GLatLng(item.lat, item.lng)), 5);
			return new GLatLng(item.lat, item.lng);
		});
		map.addOverlay(new GPolyline(pt, "#ff0000"));
	});

	// MEMO: 曜日は 0:日曜日～6:土曜日
	// MEMO: 祝日は扱わず、日曜日のみ休日とする
	var wday = (new Date).getDay();
	shinkansens.each(function(shinkansen) {
		shinkansen.trains.each(function(train) {
			var running = (wday == 0 ? train.holiday  :
			               wday == 6 ? train.saturday : train.weekday);
			if ( running )
			{
				target_trains.push([shinkansen, train]);
			}
		});
	});

	var i = 0, length = target_trains.length;
	for ( i = 0; i < length; i++ )
	{
		var j = Math.floor(Math.random() * length);
		if ( j != i )
		{
			var tmp = target_trains[j];
			target_trains[j] = target_trains[i];
			target_trains[i] = tmp;
		}
	}

	window.setTimeout(update, 1500);
}

function resize(p)
{
	var header = $("header").offsetHeight;
	var footer = $("footer").offsetHeight;
	var height = document.body.clientHeight;
	if ( height == undefined || height == 0 )
	{
		height = window.innerHeight;
	}

	if ( height != undefined )
	{
		$("content").style.height = (height - header - footer) + "px";
	}
}

if ( GBrowserIsCompatible() )
{
	Event.observe(window, 'load', load, false);
	Event.observe(window, 'onunload', GUnload, false);
	Event.observe(window, 'resize', resize, false);
}
