// required:
//  rococo.js, rococo_rccgm.js, rococo_imp.js

var MoveSun = new Object();

MoveSun.infoWindow = null;
// CONSTANTS
// -- Length, Weight, Opacity sunset/sunrise
// -- Unit of LENGTH maybe meter.
MoveSun.LINE_LENGTH = 500000;
MoveSun.LINE_WEIGHT = 3;
MoveSun.LINE_OPACITY = 0.75;

MoveSun.Kiban25000MapType = function() {
};
MoveSun.Kiban25000MapType.prototype.tileSize = new google.maps.Size(256,256);
MoveSun.Kiban25000MapType.prototype.maxZoom = 17;
MoveSun.Kiban25000MapType.prototype.name = "基盤地図";
MoveSun.Kiban25000MapType.prototype.alt = "基盤地図情報 (縮尺レベル25000)";
MoveSun.Kiban25000MapType.prototype.getTile = function(tile, zoom, ownerDocument) {
  var img = ownerDocument.createElement("img");
  img.style.width = this.tileSize.width + "px";
  img.style.height = this.tileSize.height + "px";
  img.src = "http://www.finds.jp/ws/kiban25000gwc.cgi?VERSION=1.1.1&REQUEST=GetMap&" +
      "STYLES=&SRS=EPSG:900913&" +
      "BBOX=" + MoveSun.getBBox(tile,zoom) + "&" +
      "WIDTH=256&HEIGHT=256&FORMAT=image/png&" +
      "LAYERS=kiban25000:AllT";
  return img;
};


//MoveSun.reqMoveSun = new Rococo.cl.xml.XmlRequest(
//	  '日出日の入り計算',
//	  new Rococo.cl.UrlSetting('http://www.finds.jp/ws/movesun.php'),
//	  new Rococo.cl.DecisionSetting(['movesun','status'], 200, ['movesun','error'] )
//	);

MoveSun.reqMoveSun = new Rococo.cl.jsonp.JsonpRequest(
	  '日出日の入り計算',
	  new Rococo.cl.UrlSetting('http://www.finds.jp/ws/movesun.php',null,'GET','jsonp'),
	  new Rococo.cl.DecisionSetting(['status'], 200, ['error'] )
	);


MoveSun.onMapClick = function( event ) {
  var latlng = event != null ? event.latLng : null;
  var options = MoveSun.rccgm.topmenuholder.getItem('options');
  var year = options.getItem('year').getChild('input').getValue();
  var date = options.getItem('date').getChild('input').getValue();
  var elv = options.getItem('elv').getChild('input').getValue();
  var tz = options.getItem('tz').getChild('input').getValue();

  if( latlng == null || year == null || date == null || elv == null || tz == null ) {
    return;
  }

  MoveSun.removeResult();
  MoveSun.removeSunLines();

  if( MoveSun.infoWindow != null ) {
    MoveSun.infoWindow.close();
  }
  date.year = year.year;
  MoveSun.callMoveSun( latlng, date, elv, tz );
};

MoveSun.writeResult = function( latlng, date, elv, tz, events ) {
  // 先に残った結果を削除
  MoveSun.removeResult();
//  var root = MoveSun.rccgm.consoleholder;
  var root = MoveSun.rccgm.freepanel;
  var e = document.createElement('p');
  e.className = 'result';
  var s;
  // 年月日 標高
  s = date.year + '/' + date.month + '/' + date.mday + ' ('+ (tz=='Z' ? 'UTC' : tz) + ') ' + elv + 'm';
  // 順次追加
  for( var n = 0; n < events.length; n++ ) {
    if( events[n].time == null ) {
      s = s + ' ' + events[n].name;
    }
    else if( events[n].azimuth == null ) {
      s = s + ' ' + events[n].name + '-' + events[n].time;
    }
    else {
      s = s + ' ' + events[n].name + '-' + events[n].time + ' (' + events[n].azimuth + ')';
    }
  }
  e.appendChild(document.createTextNode(s));
  root.appendChild(e);
};

MoveSun.openResult = function( latlng, date, elv, tz, events ) {
  var root = document.createElement('div');
  var e;
  // 年月日 + (tz)
  e = document.createElement('div');
  e.appendChild(document.createTextNode(date.year + '年' + date.month + '月' + date.mday + '日' + ' ('+ (tz=='Z' ? 'UTC' : tz) + ')'));
  root.appendChild(e);
  // (tz)
//  e = document.createElement('div');
//  e.appendChild(document.createTextNode());
//  root.appendChild(e);
  // 標高
  e = document.createElement('div');
  e.appendChild(document.createTextNode('標高 ' + elv + 'm'));
  root.appendChild(e);
  // 順次追加
  for( var n = 0; n < events.length; n++ ) {
    e = document.createElement('div');
    var s = '';
    if( events[n].time == null ) {
      s = events[n].name;
    }
    else if( events[n].azimuth == null ) {
      s = events[n].name + ' - ' + events[n].time;
    }
    else {
      s = events[n].name + ' - ' + events[n].time + ' (' + events[n].azimuth + ')';
    }
    e.appendChild(document.createTextNode(s));
    root.appendChild(e);
  }
  // 情報ウィンドウ
  if( MoveSun.infoWindow == null ) {
    MoveSun.infoWindow = new google.maps.InfoWindow();
  }
  else {
      MoveSun.infoWindow.close();
  }
  MoveSun.infoWindow.setContent(root);
  MoveSun.infoWindow.setPosition(latlng);
  MoveSun.infoWindow.open( MoveSun.gmap, null);
};

MoveSun.callMoveSun = function( latlng, date, elv, tz ) {
  var params = 'lat='+latlng.lat()+'&lon='+latlng.lng()+'&y='+date.year+'&m='+date.month+'&d='+date.mday+'&tz='+tz+'&e='+elv;
  MoveSun.reqMoveSun.request(params,MoveSun.callBack);
};


MoveSun.SunLines = { 'sunrise': null, 'sunset': null, 'sunrise_r': null, 'sunset_r': null };

MoveSun.getSunlineDestination = function(centerLatLng, azimuth, distance ) {
  var r = 6378137;
  var alpha = azimuth / 180.0 * Math.PI;
//  // --------
//  // centerLatLng -> centerXY
//  var cx = r * centerLatLng.lng()/180.0*Math.PI;
//  var cy = r * Math.log(Math.tan(0.25*Math.PI+0.5*centerLatLng.lat()/180.0*Math.PI));
//  // centerXY -> termXY
//  var tx = cx + distance * Math.sin(alpha);
//  var ty = cy + distance * Math.cos(alpha);
//  // termXY -> termLonLat
//  var lam1 = tx / r;
//  var phi1 = 2.0*Math.atan(Math.exp(ty/r))-0.5*Math.PI;
//  var lon1 = lam1 * 180.0 / Math.PI;
//  var lat1 = phi1 * 180.0 / Math.PI;
//  // -------- reduced #1
//  //  centerLatLng -> centerXY -> termXY
//  var tx = r * centerLatLng.lng()/180.0*Math.PI + distance * Math.sin(alpha);
//  var ty = r * Math.log(Math.tan(0.25*Math.PI+0.5*centerLatLng.lat()/180.0*Math.PI)) + distance * Math.cos(alpha);
//  // termLonLat
//  var lon1 = (tx / r) * 180.0 / Math.PI;
//  var lat1 = ( 2.0*Math.atan(Math.exp(ty/r))-0.5*Math.PI ) * 180.0 / Math.PI;
//  // -------- reduced #2
//  var lon1 = (centerLatLng.lng()/180.0*Math.PI + distance*Math.sin(alpha)/r) * 180.0 / Math.PI;
//  var lat1 = ( 2.0*Math.atan(Math.exp(Math.log(Math.tan(0.25*Math.PI+0.5*centerLatLng.lat()/180.0*Math.PI)) + distance*Math.cos(alpha)/r))-0.5*Math.PI ) * 180.0 / Math.PI;
//  // -------- reduced #3(lon)
//  var lon1 = centerLatLng.lng() + distance*Math.sin(alpha)*180.0/(r*Math.PI);
//  var lat1 = ( 2.0*Math.atan(Math.exp(Math.log(Math.tan(0.25*Math.PI+centerLatLng.lat()*Math.PI/360.0)) + distance*Math.cos(alpha)/r))-0.5*Math.PI ) * 180.0 / Math.PI;

  return new google.maps.LatLng(
	  ( 2.0*Math.atan(Math.exp(Math.log(Math.tan(0.25*Math.PI+centerLatLng.lat()*Math.PI/360.0)) + distance*Math.cos(alpha)/r))-0.5*Math.PI ) * 180.0 / Math.PI,
	  centerLatLng.lng() + distance*Math.sin(alpha)*180.0/(r*Math.PI)
	);
};

//MoveSun.getSunlineDestination = function(centerLatLng, azimuth, distance ) {
//  var alpha = azimuth / 180 * Math.PI;
//  var c = distance / 6378137;
//  var sin_c = Math.sin(c);
//  var sin_alpha = Math.sin(alpha);
//  var cos_alpha = Math.cos(alpha);
//  var sin_a = sin_c * sin_alpha;
//  var a = Math.asin(sin_a);
//  var cos_a = Math.cos(a);
//  var sin_b = sin_c * cos_alpha / cos_a;
//  var b = Math.asin(sin_b);
//  var dlon = a*180/Math.PI;
//  var dlat = b*180/Math.PI;
//  return new google.maps.LatLng(centerLatLng.lat()*1+dlat,centerLatLng.lng()*1+dlon);
//};



MoveSun.addSunLine = function(name,centerLatLng, azimuth, color, weight) {
  var dst = MoveSun.getSunlineDestination(centerLatLng,azimuth,MoveSun.LINE_LENGTH);
  MoveSun.SunLines[name] = new google.maps.Polyline({
	  clickable: false,
	  path: [centerLatLng,dst],
	  strokeColor: color,
	  strokeWeight: weight,
	  strokeOpacity:MoveSun.LINE_OPACITY
	});
  MoveSun.SunLines[name].setMap(MoveSun.gmap);
};

MoveSun.addSunriseLine = function(centerLatLng, azimuth) {
  MoveSun.addSunLine('sunrise',centerLatLng, azimuth,'#FF0000',MoveSun.LINE_WEIGHT);
  MoveSun.addSunLine('sunrise_r',centerLatLng, (azimuth+180)%360,'#993333',MoveSun.LINE_WEIGHT*0.5);
};

MoveSun.addSunsetLine = function(centerLatLng, azimuth) {
  MoveSun.addSunLine('sunset',centerLatLng, azimuth,'#0000FF',MoveSun.LINE_WEIGHT);
  MoveSun.addSunLine('sunset_r',centerLatLng, (azimuth+180)%360,'#333399',MoveSun.LINE_WEIGHT*0.5);
};

MoveSun.addSunCulmination = function(centerLatLng,sunrise,culmination,sunset) {
  // --
  // It does not use sunrise, sunset.
  // I do not know how to notify with point when users click the polygon,
  // so I am giving up to add GPolygon.
  // --
//  var dst_sunrise = MoveSun.getSunlineDestination(centerLatLng,sunrise,100000);
//  var dst_culmination = MoveSun.getSunlineDestination(centerLatLng,culmination,100000);
//  var dst_sunset = MoveSun.getSunlineDestination(centerLatLng,sunset,100000);
//  var points = [centerLatLng,dst_sunrise,dst_culmination,dst_sunset,centerLatLng];
//  MoveSun.SunLines['sun'] = new GPolygon(points, "#FFFFFF", 0, 0, "#FFFF00", 0.25);
//  MoveSun.gmap.addOverlay(MoveSun.SunLines['sun']);

  MoveSun.addSunLine('sun',centerLatLng, culmination,'#CC9900',MoveSun.LINE_WEIGHT);
};

MoveSun.removeResult = function() {
//  var root = MoveSun.rccgm.consoleholder;
  var root = MoveSun.rccgm.freepanel;
  if( root != null ) {
    root.clearAllChildren();
  }

};

MoveSun.removeSunLines = function() {
  for( var k in MoveSun.SunLines ) {
    if( MoveSun.SunLines[k] ) {
      MoveSun.SunLines[k].setMap(null);
      MoveSun.SunLines[k] = null;
    }
  }
};


MoveSun.callBack = function( status, res ) {
  if( status == false ) {
    alert(res);
    return;
  }

  MoveSun.removeSunLines();

//  var latlng = new google.maps.LatLng(res.movesun.argument.latitude,res.movesun.argument.longitude);
//  var elv = res.movesun.argument.elevation;
//  var dateorg = res.movesun.argument.date;
//  var event = res.movesun.result.event;
//  var first = res.movesun.result.first;

  var latlng = new google.maps.LatLng(res.argument.latitude,res.argument.longitude);
  var elv = res.argument.elevation;
  var dateorg = res.argument.date;
  var tz = res.argument.timezone;
  var event = res.result.event;
  var first = res.result.first;

  var date = {year: dateorg.substr(0,4), month:dateorg.substr(5,2), mday:dateorg.substr(8,2) };

  var events = new Array();
  var s = '';

  // creates event list
  if( event ) {
    var azimuth_sunrise = null;
    var azimuth_sunset = null;
    var azimuth_culmination = null;

    for( var n = 0; n < event.length; n++ ) {
      var ev = event[n];
      if( ev.type == 'daytime' ) {
        if( ev.boundary == 'start' ) {
          azimuth_sunrise = ev.azimuth;
          events.push({name: '日出', time: ev.time.substr(11,5), azimuth: ev.azimuth});
        }
        else if( ev.boundary == 'end' ) {
          azimuth_sunset = ev.azimuth;
          events.push({name: '日没', time: ev.time.substr(11,5), azimuth: ev.azimuth});
        }
      }
      else if( ev.type == 'culmination' ) {
        azimuth_culmination = ev.azimuth;
        var es = ev.azimuth < 90 || ev.azimuth > 270 ? "北中" : "南中";
        events.push({name: es, time: ev.time.substr(11,5)});
      }
    }
    if( azimuth_culmination != null ) {
      MoveSun.addSunCulmination(latlng,azimuth_sunrise,azimuth_culmination,azimuth_sunset);
    }
    if( azimuth_sunrise != null ) {
      MoveSun.addSunriseLine(latlng,azimuth_sunrise);
    }
    if( azimuth_sunset != null ) {
      MoveSun.addSunsetLine(latlng,azimuth_sunset);
    }
  }

  if( events.length <= 0 && first != null ) {
    if( first.type == 'daytime' ) {
      events.push({name: '白夜'});
	}
    else {
      events.push({name: '極夜'});
	}
  }

  MoveSun.writeResult( latlng, date, elv, tz, events );
  MoveSun.openResult( latlng, date, elv, tz, events );
};

MoveSun.setParams = function(year,month,mday,elv) {
  var options = MoveSun.rccgm.topmenuholder.getItem('options');
  if( year != null && Rococo.ut.isNumeric(year) ) {
    year = year * 1;
    options.getItem('year').getChild('input').setValue({getYear: function() {return year;},getMonth: function() {return null; }, getDate: function() { return null; } });
  }
  if( month != null && mday != null && Rococo.ut.isNumeric(month) && Rococo.ut.isNumeric(mday) ) {
    options.getItem('date').getChild('input').setValue(
        {getYear: function(){ return null; }, getMonth: function() {return month-1;}, getDate: function() { return mday*1;} }
      );
  }
  if( elv != null && Rococo.ut.isNumeric(elv) ) {
    options.getItem('elv').getChild('input').setValue(elv*1);
  }
}

MoveSun.setMapHeight = function() {
  if( MoveSun.rccgm.topmenuholder && MoveSun.rccgm.topmenuholder.getChild('view') && MoveSun.rccgm.topmenuholder.getChild('view').getItem('size') && MoveSun.rccgm.topmenuholder.getChild('view').getItem('size').getChild('input') ) {
    MoveSun.rccgm.setMapSize({height:MoveSun.rccgm.topmenuholder.getChild('view').getItem('size').getChild('input').getValue()});
  }
}

MoveSun.tzlist = [
{'text': '+14:00', 'value': 14},
{'text': '+13:00', 'value': 13},
{'text': '+12:45', 'value': 12.75},
{'text': '+12:00', 'value': 12},
{'text': '+11:30', 'value': 11.5},
{'text': '+11:00', 'value': 11},
{'text': '+10:30', 'value': 10.5},
{'text': '+10:00', 'value': 10},
{'text': '+9:30', 'value': 9.5},
{'text': '+9:00', 'value': 9},
{'text': '+8:45', 'value': 8.75},
{'text': '+8:00', 'value': 8},
{'text': '+7:00', 'value': 7},
{'text': '+6:30', 'value': 6.5},
{'text': '+6:00', 'value': 6},
{'text': '+5:45', 'value': 5.75},
{'text': '+5:30', 'value': 5.5},
{'text': '+5:00', 'value': 5},
{'text': '+4:30', 'value': 4.5},
{'text': '+4:00', 'value': 4},
{'text': '+3:30', 'value': 3.5},
{'text': '+3:00', 'value': 3},
{'text': '+2:00', 'value': 2},
{'text': '+1:00', 'value': 1},
{'text': '(UTC)', 'value': 0},
{'text': '-1:00', 'value': -1},
{'text': '-2:00', 'value': -2},
{'text': '-3:00', 'value': -3},
{'text': '-3:30', 'value': -3.5},
{'text': '-4:00', 'value': -4},
{'text': '-4:30', 'value': -4.5},
{'text': '-5:00', 'value': -5},
{'text': '-6:00', 'value': -6},
{'text': '-7:00', 'value': -7},
{'text': '-8:00', 'value': -8},
{'text': '-9:00', 'value': -9},
{'text': '-9:30', 'value': -9.5},
{'text': '-10:00', 'value': -10},
{'text': '-11:00', 'value': -11},
{'text': '-12:00', 'value': -12}
];

// -- init
MoveSun.init = function() {
  // constatns
  MoveSun.init_mapheight = '360';
  MoveSun.smk_r = 5;
  // variabloes
  MoveSun.rccgm = null;
  MoveSun.gmap = null;
  MoveSun.e = new Object();
  MoveSun.e.form = new Object();
  // ---------------- box
  var e = document.getElementById('box');
  var p = document.createElement('p');
  p.innerHTML = '今日以外の日の出日の入り時刻をご覧になるには「オプション」を開いて下さい。';
  e.appendChild(p);
  var today = new Date();
  // ---------------- gmap
//  MoveSun.rccgm = new Rococo.rccgm.Rccgm(document.getElementById('map'),{mapw: '100%', maph: MoveSun.init_mapheight+"px", cmark:{visible: false}},0);
  MoveSun.rccgm = new Rococo.rccgm.Rccgm(document.getElementById('map'),{mapw: '100%', cmark:{visible: false}},0);
  MoveSun.rccgm.mapholder.style.width ='100%';
  MoveSun.rccgm.mapholder.style.margin ='0px';
  MoveSun.rccgm.mapholder.style.float ='none';
  var settings = Rococo.rccgm.preset.createTopMenuSettings(MoveSun.rccgm,['view','gotodd','jpgeocode']);

// ---- height
  settings[0].items[0] = {
	  subid: 'view',
	  tagname:'select',
	  title: Rococo.rccgm.locale.Rccgm.size(),
	  subid:'size',
	  attributes: {
		list: [
		  {text:'-------', value:'' },
		  {text:'300', value:'300'}, {text:'360', value:'360'},
		  {text:'450', value:'450'}, {text:'600', value:'600'},
		  {text:'720', value:'720'}
	    ],
	    value: null
	  },
	  events: [{
		  type: 'change',
		  listener:MoveSun.setMapHeight
	  }]
	};

  MoveSun.rccgm.appendTopMenu(settings);
  MoveSun.rccgm.createMap();
  MoveSun.gmap = MoveSun.rccgm.map;
  // -- gmap/event
  google.maps.event.addListener(MoveSun.gmap,'click',MoveSun.onMapClick);
  // ---------------- 2008/1/1
  // <a href="./index.html?y=2008&m=1&d=1">2008年1月1日</a>

  // ---------------- options
  // -- year list (this year -3 - +3)
  var today = new Date();
  var yc = today.getFullYear();
  var yl = new Array();
  for( var y = yc - 3; y <= yc + 3; y++ ) {
    yl.push({value: y});
  }

  MoveSun.rccgm.appendTopMenu([
	  {
	    subid: 'options', title: 'オプション', items: [
	      { subid: 'year', tagname: 'date', title: '日付', attributes: {format: 'Y年', yearlist: yl } },
	      { subid: 'date', tagname: 'date', title: '', attributes: {format: 'm月d日' } },
	      { subid: 'tz', tagname: 'select', title: '時差', attributes: {list: MoveSun.tzlist, value: 9} },
	      { subid: 'elv', tagname: 'text', title: '標高', attributes: { value: 1.5, size: 6 } }
	    ]
	  }
	]);

  // stores map height element (select element)
  MoveSun.mapHeightElement =
    MoveSun.rccgm.topmenuholder && MoveSun.rccgm.topmenuholder.getChild('view') && MoveSun.rccgm.topmenuholder.getChild('view').getItem('size')
    ? MoveSun.rccgm.topmenuholder.getChild('view').getItem('size').getChild('input')
    : null;

  // url options
  var url_options = Rococo.ut.getParamArray(document.URL);
  if( url_options != null ) {
    MoveSun.setParams(url_options.y,url_options.m,url_options.d,url_options.e);
    if( url_options.maph != null ) {
      if( MoveSun.mapHeightElement ) {
        MoveSun.mapHeightElement.setValue(url_options.maph);
      }
    }
  }
  // kiban
//  var kiban25000MapType = new MoveSun.Kiban25000MapType();
//  MoveSun.rccgm.map.mapTypes.set("kiban25000", kiban25000MapType);
//  MoveSun.rccgm.map.setOptions({
//      mapTypeControlOptions: {
//        mapTypeIds: [
//          google.maps.MapTypeId.ROADMAP,google.maps.MapTypeId.SATELLITE,
//          google.maps.MapTypeId.HYBRID,
//          google.maps.MapTypeId.TERRAIN,
//          "kiban25000"
//        ]
//      }
//    });


  // new year
  if( today.getMonth() == 11 && today.getDate() > 24 ) {
    var ny = today.getFullYear() + 1;
    p = document.createElement('p');
	var nyurl = 'index.html?y='+ny+'&amp;m=1&amp;d=1';
    if( url_options != null && url_options.maph != null ) {
		nyurl = nyurl + '&maph=' +  url_options.maph;
	}
    p.innerHTML = ny+'年1月1日をご覧になる場合は<a href="' + nyurl + '">'+nyurl+'</a>を開いて下さい。';
    e.appendChild(p);
  }


  // set default height if needed.
  if( MoveSun.mapHeightElement && !MoveSun.mapHeightElement.getValue() ) {
    MoveSun.mapHeightElement.setValue(MoveSun.init_mapheight);
  }
  // really resize.
  MoveSun.setMapHeight();
};

MoveSun.getBBox = function(tile,zoom) {
  var pxs = 256 * (1 << zoom);
  var pxsh = pxs / 2;
  var mtr = 40075017;
  var mpp = mtr/pxs;
  var x1 = (tile.x*256-pxsh) * mpp;
  var x2 = ((tile.x*256+256)-pxsh) * mpp;
  var y2 = (pxsh-tile.y*256) * mpp;
  var y1 = (pxsh-(tile.y*256+256)) * mpp;
  return x1 + "," + y1 + "," + x2 + "," + y2;
}


//
// init
//
Rococo.init.push(MoveSun.init);

