var map;
var boolNowSearching;
var dd = new Date();
var tz = ( dd.getHours() - dd.getUTCHours() + 24 ) % 24;
var searchTimer = null;
var autoTimer = null;
var currentRequestId;
var infoDisplaying = false;
var currentObjs;
var baseUrl = "http://orecoco.hshstudio.com/";
var servicePath = "service";
var proxyPath = "op2";

function md5pass(_field,_origField) {
	if (_origField && _field.value == _origField.value) {
		return _origField.value;
	}
 	var data = utf16to8(_field.value);
    _field.value = MD5_hexhash(data);
}

function utf16to8(str) {
    var out, i, len, c;

    out = "";
    len = str.length;
    for(i = 0; i < len; i++) {
	c = str.charCodeAt(i);
	if ((c >= 0x0001) && (c <= 0x007F)) {
	    out += str.charAt(i);
	} else if (c > 0x07FF) {
	    out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
	    out += String.fromCharCode(0x80 | ((c >>  6) & 0x3F));
	    out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
	} else {
	    out += String.fromCharCode(0xC0 | ((c >>  6) & 0x1F));
	    out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
	}
    }
    return out;
}

function utf8to16(str) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = str.length;
    i = 0;
    while(i < len) {
	c = str.charCodeAt(i++);
	switch(c >> 4)
	{ 
	  case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
	    // 0xxxxxxx
	    out += str.charAt(i-1);
	    break;
	  case 12: case 13:
	    // 110x xxxx   10xx xxxx
	    char2 = str.charCodeAt(i++);
	    out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
	    break;
	  case 14:
	    // 1110 xxxx  10xx xxxx  10xx xxxx
	    char2 = str.charCodeAt(i++);
	    char3 = str.charCodeAt(i++);
	    out += String.fromCharCode(((c & 0x0F) << 12) |
					   ((char2 & 0x3F) << 6) |
					   ((char3 & 0x3F) << 0));
	    break;
	}
    }

    return out;
}

//    md5_T[i] = parseInt(Math.abs(Math.sin(i)) * 4294967296.0);
var MD5_T = new Array(0x00000000, 0xd76aa478, 0xe8c7b756, 0x242070db,
		      0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613,
		      0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1,
		      0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e,
		      0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51,
		      0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681,
		      0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87,
		      0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9,
		      0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122,
		      0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60,
		      0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085,
		      0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8,
		      0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7,
		      0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d,
		      0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314,
		      0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb,
		      0xeb86d391);

var MD5_round1 = new Array(new Array( 0, 7, 1), new Array( 1,12, 2),
			   new Array( 2,17, 3), new Array( 3,22, 4),
			   new Array( 4, 7, 5), new Array( 5,12, 6),
			   new Array( 6,17, 7), new Array( 7,22, 8),
			   new Array( 8, 7, 9), new Array( 9,12,10),
			   new Array(10,17,11), new Array(11,22,12),
			   new Array(12, 7,13), new Array(13,12,14),
			   new Array(14,17,15), new Array(15,22,16));

var MD5_round2 = new Array(new Array( 1, 5,17), new Array( 6, 9,18),
			   new Array(11,14,19), new Array( 0,20,20),
			   new Array( 5, 5,21), new Array(10, 9,22),
			   new Array(15,14,23), new Array( 4,20,24),
			   new Array( 9, 5,25), new Array(14, 9,26),
			   new Array( 3,14,27), new Array( 8,20,28),
			   new Array(13, 5,29), new Array( 2, 9,30),
			   new Array( 7,14,31), new Array(12,20,32));

var MD5_round3 = new Array(new Array( 5, 4,33), new Array( 8,11,34),
			   new Array(11,16,35), new Array(14,23,36),
			   new Array( 1, 4,37), new Array( 4,11,38),
			   new Array( 7,16,39), new Array(10,23,40),
			   new Array(13, 4,41), new Array( 0,11,42),
			   new Array( 3,16,43), new Array( 6,23,44),
			   new Array( 9, 4,45), new Array(12,11,46),
			   new Array(15,16,47), new Array( 2,23,48));

var MD5_round4 = new Array(new Array( 0, 6,49), new Array( 7,10,50),
			   new Array(14,15,51), new Array( 5,21,52),
			   new Array(12, 6,53), new Array( 3,10,54),
			   new Array(10,15,55), new Array( 1,21,56),
			   new Array( 8, 6,57), new Array(15,10,58),
			   new Array( 6,15,59), new Array(13,21,60),
			   new Array( 4, 6,61), new Array(11,10,62),
			   new Array( 2,15,63), new Array( 9,21,64));

function MD5_F(x, y, z) { return (x & y) | (~x & z); }
function MD5_G(x, y, z) { return (x & z) | (y & ~z); }
function MD5_H(x, y, z) { return x ^ y ^ z;          }
function MD5_I(x, y, z) { return y ^ (x | ~z);       }

var MD5_round = new Array(new Array(MD5_F, MD5_round1),
			  new Array(MD5_G, MD5_round2),
			  new Array(MD5_H, MD5_round3),
			  new Array(MD5_I, MD5_round4));

function MD5_pack(n32) {
  return String.fromCharCode(n32 & 0xff) +
	 String.fromCharCode((n32 >>> 8) & 0xff) +
	 String.fromCharCode((n32 >>> 16) & 0xff) +
	 String.fromCharCode((n32 >>> 24) & 0xff);
}

function MD5_unpack(s4) {
  return  s4.charCodeAt(0)        |
	 (s4.charCodeAt(1) <<  8) |
	 (s4.charCodeAt(2) << 16) |
	 (s4.charCodeAt(3) << 24);
}

function MD5_number(n) {
  while (n < 0)
    n += 4294967296;
  while (n > 4294967295)
    n -= 4294967296;
  return n;
}

function MD5_apply_round(x, s, f, abcd, r) {
  var a, b, c, d;
  var kk, ss, ii;
  var t, u;

  a = abcd[0];
  b = abcd[1];
  c = abcd[2];
  d = abcd[3];
  kk = r[0];
  ss = r[1];
  ii = r[2];

  u = f(s[b], s[c], s[d]);
  t = s[a] + u + x[kk] + MD5_T[ii];
  t = MD5_number(t);
  t = ((t<<ss) | (t>>>(32-ss)));
  t += s[b];
  s[a] = MD5_number(t);
}

function MD5_hash(data) {
  var abcd, x, state, s;
  var len, index, padLen, f, r;
  var i, j, k;
  var tmp;

  state = new Array(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
  len = data.length;
  index = len & 0x3f;
  padLen = (index < 56) ? (56 - index) : (120 - index);
  if(padLen > 0) {
    data += "\x80";
    for(i = 0; i < padLen - 1; i++)
      data += "\x00";
  }
  data += MD5_pack(len * 8);
  data += MD5_pack(0);
  len  += padLen + 8;
  abcd = new Array(0, 1, 2, 3);
  x    = new Array(16);
  s    = new Array(4);

  for(k = 0; k < len; k += 64) {
    for(i = 0, j = k; i < 16; i++, j += 4) {
      x[i] = data.charCodeAt(j) |
	    (data.charCodeAt(j + 1) <<  8) |
	    (data.charCodeAt(j + 2) << 16) |
	    (data.charCodeAt(j + 3) << 24);
    }
    for(i = 0; i < 4; i++)
      s[i] = state[i];
    for(i = 0; i < 4; i++) {
      f = MD5_round[i][0];
      r = MD5_round[i][1];
      for(j = 0; j < 16; j++) {
	MD5_apply_round(x, s, f, abcd, r[j]);
	tmp = abcd[0];
	abcd[0] = abcd[3];
	abcd[3] = abcd[2];
	abcd[2] = abcd[1];
	abcd[1] = tmp;
      }
    }

    for(i = 0; i < 4; i++) {
      state[i] += s[i];
      state[i] = MD5_number(state[i]);
    }
  }

  return MD5_pack(state[0]) +
	 MD5_pack(state[1]) +
	 MD5_pack(state[2]) +
	 MD5_pack(state[3]);
}

function MD5_hexhash(data) {
    var i, out, c;
    var bit128;

    bit128 = MD5_hash(data);
    out = "";
    for(i = 0; i < 16; i++) {
	c = bit128.charCodeAt(i);
	out += "0123456789abcdef".charAt((c>>4) & 0xf);
	out += "0123456789abcdef".charAt(c & 0xf);
    }
    return out;
}
function createDateParameter(_date) {
	var yy = _date.getUTCFullYear();
	var mm = _date.getUTCMonth() + 1;
	var dd = _date.getUTCDate();
	var hh = _date.getUTCHours();
	var mi = _date.getUTCMinutes();
	var ss = _date.getUTCSeconds();
	if (yy < 2000) { yy += 1900; }
	if (mm < 10) { mm = "0" + mm; }
	if (dd < 10) { dd = "0" + dd; }
	if (hh < 10) { hh = "0" + hh; }
	if (mi < 10) { mi = "0" + mi; }
	if (ss < 10) { ss = "0" + ss; }
	return yy + "-" + mm + "-" + dd+"%20"+hh+":"+mi+":"+ss+"%20-0000";
}

function formatDate(_date) {
	var yy = _date.getFullYear();
	var mm = _date.getMonth() + 1;
	var dd = _date.getDate();
	var hh = _date.getHours();
	var mi = _date.getMinutes();
	var ss = _date.getSeconds();
	if (yy < 2000) { yy += 1900; }
	if (mm < 10) { mm = "0" + mm; }
	if (dd < 10) { dd = "0" + dd; }
	if (hh < 10) { hh = "0" + hh; }
	if (mi < 10) { mi = "0" + mi; }
	if (ss < 10) { ss = "0" + ss; }
	//return yy + "-" + mm + "-" + dd+" "+hh+":"+mi+":"+ss;
	return mm + "/" + dd + " " + hh + ":" + mi;
}

function parseToCurrentDate(_strDate) {
	var year = parseInt(_strDate.substr(0,4),10);
	var month = parseInt(_strDate.substr(5,2),10)-1;
	var day = parseInt(_strDate.substr(8,2),10);
	var hour = parseInt(_strDate.substr(11,2),10);
	var min = parseInt(_strDate.substr(14,2),10);
	var sec = parseInt(_strDate.substr(17,2),10);
	var utcDate = new Date(year,month,day,hour,min,sec);
	var date = new Date();
	var tz = ( dd.getHours() - dd.getUTCHours() + 24 ) % 24;
	date.setTime(utcDate.getTime()+(tz*60*60*1000));
	return date;
}

function saveCurrentPosition() {
	document.cookie = "lp=lat%3D" + map.getCenter().lat()+"%26lng%3D" + map.getCenter().lng()+"%26z%3D"+map.getZoom()+";expires=" + new Date(2030, 1).toUTCString();;
}

function loadCurrentPosition() {
	var lat = null;
	var lng = null;
	var z = null;
	var values = document.cookie.split(";");
	for (var j = 0; j < values.length; j++) {
		var line = values[j].replace(/^\s+|\s+$/g, "");
		
		if (line.indexOf("lp=")==0) {
			var tokens = unescape(line.substr(line.indexOf("=")+1)).split("&");
			for (var i = 0; i < tokens.length; i++) {
				var index = tokens[i].indexOf("=");
				var key = tokens[i].substring(0,index);
				var value = tokens[i].substring(index+1,tokens[i].length);
				if (key == "lat") {
					lat = parseFloat(value);
				} else if (key == "lng") {
					lng = parseFloat(value);
				} else if (key == "z") {
					z = parseInt(value,10);
				}
			}
			if (lat != null && lng != null && z != null) {
				map.setCenter(new GLatLng(lat,lng),z);
				return true;
			}
		}
	}
	return false;
}

function searchPublicData() {
	var bounds = map.getBounds();
	var minPt = bounds.getSouthWest();
	var maxPt = bounds.getNorthEast();
	var parameters = "reqType=browse";
	var date = new Date();
	date.setTime(date.getTime() + (60*60*1000));
	var toDate = createDateParameter(date);
	date.setTime(date.getTime() - (24*60*60*1000*100));
	var fromDate = createDateParameter(date);
	parameters +="&fromDate="+fromDate;
	parameters +="&toDate="+toDate;
	parameters +="&minlat="+minPt.y;
	parameters +="&minlng="+minPt.x;
	parameters +="&maxlat="+maxPt.y;
	parameters +="&maxlng="+maxPt.x;
	parameters +="&pageIndex=0";
	if (Prototype.Browser.IE) {
		parameters +="&numOfPage=100";
	} else {
		parameters +="&numOfPage=100";
	}
	parameters +="&resformat=json";
	if (currentRequestId) {
		JSONUtil.ignoreRequest(currentRequestId);
	}
	currentRequestId = JSONUtil.r(baseUrl+proxyPath+"/service/log",parameters,receiveResult);
}

function showIcon(_id) {
	if (!currentObjs) {
		return;
	}
	for (var i = 0; i < currentObjs.length; i++) {
		var marker = currentObjs[i];
		if (marker.obj.id == _id) {
			infoDisplaying = true;
			var contents = formatDate(marker.obj.dateRegister)+"&nbsp;&nbsp;&nbsp;";
			contents += "<a href=\""+baseUrl+servicePath+"/blog/"+marker.obj.userId+"\">"+marker.obj.nickname.escapeHTML()+"</a><br/>";
			if (marker.obj.title &&marker.obj.title.length>0) {
				contents +=replaceToBR(marker.obj.title.escapeHTML())+"<hr/>";
			}
			contents +=replaceToBR(marker.obj.note.escapeHTML())+"<br/>";
			if (marker.obj.hasPhoto) {
				var imgUrl = baseUrl+proxyPath+"/service/getPhoto?oid="+marker.obj.userId+"&id="+marker.obj.id;
				contents += "<div style='height:120px;'><a href='"+imgUrl+"' class='highslide' onclick='return hs.expand(this)'><img src='"+imgUrl+"&tn=TRUE'></a></div>";
			}
			marker.openInfoWindowHtml(
				contents,{maxWidth:200}
				);
			map.panTo(marker.getPoint());
			return;	
		}
	}
}

function replaceToBR(_note) {
	return  _note.replace(RegExp("\x0A", "g"), "<br />");
}
function receiveResult(_object) {
	// アイコンをすべて消し描画
	map.clearOverlays();
	currentRequestId = null;
	// 描画
	var num = _object.result.length;
	var contents = "<div id=\"list_memo\"><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><th colspan=\"3\">位置メモ（公開＋新着）</th></tr><tr><td colspan=\"3\"><img src=\"http://orecoco.hshstudio.com/images/line.gif\" alt=\"line\" width=\"300\" /></td></tr>";
	var icon = new GIcon(G_DEFAULT_ICON);
	icon.iconSize = new GSize(32,32);
	icon.image = baseUrl+servicePath+"/icon.gif";
	currentObjs = new Array();
	for (var i = 0; i < num; i++) {
		var obj = _object.result[i];
		// ローカル時刻に変換
		obj.dateRegister = parseToCurrentDate(obj.dateRegister);
		var markerOptions = {
			title:obj.nickname.escapeHTML(),
			clickable:true,
			draggable:false, 
			icon:icon
		};
		var marker = new GMarker(new GLatLng(parseFloat(obj.lat),parseFloat(obj.lng)),markerOptions);
		marker.obj = obj;
		GEvent.addListener(marker, "click", function() {
			infoDisplaying = true;
			var contents = "<div>"+formatDate(this.obj.dateRegister)+"&nbsp;&nbsp;&nbsp;";
			contents += "<a href=\""+baseUrl+servicePath+"/blog/"+this.obj.userId+"\">"+this.obj.nickname.escapeHTML()+"</a><br/>";
			if (this.obj.title &&this.obj.title.length>0) {
				contents +=replaceToBR(this.obj.title.escapeHTML())+"<hr/>";
			}
			contents +=replaceToBR(this.obj.note.escapeHTML())+"<br/>";
			if (this.obj.hasPhoto) {
				var imgUrl = baseUrl+proxyPath+"/service/getPhoto?oid="+this.obj.userId+"&id="+this.obj.id;
				contents += "<div style='height:120px;'><a href='"+imgUrl+"' class='highslide' onclick='return hs.expand(this)'><img src='"+imgUrl+"&tn=TRUE'></a></div>";
			}
			contents +="</div>";
			this.openInfoWindowHtml(contents,{maxWidth:200});
			GEvent.addListener(map.getInfoWindow(),"closeclick",function() {
				infoDisplaying = false;
			});
		  }.bind(marker));
		map.addOverlay(marker);
		contents +="<tr>";
		contents +="<td align=\"left\" class=\"memo_col1\" style=\"width:110px;\">";
		contents +="<img src=\""+icon.image+"\" onclick=\"showIcon('"+obj.id+"');\"/>";
		contents +="<a href=\""+baseUrl+servicePath+"/blog/"+obj.userId+"\">"+obj.nickname.escapeHTML()+"</a>";
		contents +="</td>";
		contents +="<td class=\"memo_col2\">";
		contents +=formatDate(obj.dateRegister);
		contents +="</td>";
		contents +="<td align=\"left\" class=\"memo_col3\">";
		if (obj.title && obj.title.length > 0) {
			contents +=replaceToBR(obj.title.escapeHTML());
		} else {
			contents +=replaceToBR(obj.note.escapeHTML());
		}
		contents +="</td>";
		contents +="</tr>";
		contents +="<tr><td colspan=\"3\"><img src=\"http://orecoco.hshstudio.com/images/line.gif\" alt=\"line\" width=\"300\" /></td></tr>";
		currentObjs[currentObjs.length] = marker;
	}
	contents +="</table>";
	// コンソールにも表示
	var latest = document.getElementById("latest");
	latest.innerHTML = contents;
}

var TimerRunner = Class.create();
TimerRunner.prototype = {
  initialize: function(_callback, _frequency,_oneShot) {
	this.callback_ = _callback;
	this.frequency_ = _frequency;
	this.currentlyExecuting_ = false;
    this._registerCallback();
    this._oneShot = _oneShot;
  },
  _registerCallback: function() {
    this.timer = setInterval(this._onTimerEvent.bind(this), this.frequency_);
  },
  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },
  _onTimerEvent: function() {
    if (!this.currentlyExecuting_) {
      if (this._oneShot) {
      	this.stop();
      }
      try {
        this.currentlyExecuting_ = true;
        this.callback_(this);
      } finally {
        this.currentlyExecuting_ = false;
      }
    }
  }
};

var JSONUtil={};
JSONUtil._seq = 0; 
JSONUtil._cbs = $H(); 
JSONUtil.r = function( _base, _p, _cb,_sd ){
	var id_ = _sd != undefined?_sd:"spt"+this._seq++;
	var script_ = document.createElement('script');
	script_.charset = 'UTF-8';
	script_.src = _base+'?'+_p+'&cb=JSONUtil.d&sd='+id_ ;
	script_.id = id_ ;
	JSONUtil._cbs[id_] = _cb;
	$$('head')[0].appendChild(script_);
	return id_;
};
JSONUtil.ignoreRequest = function(_sd) {
	JSONUtil._cbs.unset(_sd);
	var script_ = $(_sd);
	if (script_){ 
		new TimerRunner(function(){$$('head')[0].removeChild(script_);},1000,true);
	}
};
JSONUtil.d = function( _response ){
	var scriptId_ = _response.scriptId;
	if (scriptId_){
		var callback_ = JSONUtil._cbs[scriptId_];
		if (callback_){
			if (typeof callback_=='string'){
				callback_ = eval(callback_);
			}
			callback_(_response);
			JSONUtil._cbs.unset(scriptId_);
		}
		var script_ = $(scriptId_);
		if (script_){ 
			new TimerRunner(function(){$$('head')[0].removeChild(script_);},1000,true);
		}
	}
};

JSONUtil.destroy = function(){
	JSONUtil._cbs.keys().each(function (_key){
		JSONUtil._cbs.unset(_key);
	});
	delete JSONUtil._cbs;
};


function load() {
  if (GBrowserIsCompatible()) {
    var myMapType=new GMapType(
    G_NORMAL_MAP.getTileLayers()
    , G_NORMAL_MAP.getProjection()
    , G_NORMAL_MAP.getName()
    , {"minResolution":5,"maxResolution":13}
    );
    map = new GMap2(document.getElementById("map"),{mapTypes:[myMapType]});
	map.addControl(new GLargeMapControl());
	GEvent.addListener(map, "dragstart", function() {
		map.closeInfoWindow();
	infoDisplaying = false;
	});
	GEvent.addListener(map, "zoomend", function() {
		map.closeInfoWindow();
		infoDisplaying = false;
	});
	GEvent.addListener(map, "moveend", function() {
	  saveCurrentPosition();
	  if (searchTimer != null) {
	  	searchTimer.stop();
	  }
	  if (!infoDisplaying) {
	  	searchTimer = new TimerRunner(searchPublicData,1000,true);
	  }
	});
	if (!loadCurrentPosition()) {
    	map.setCenter(new GLatLng(35.68351380631503,139.75811004638672), 12);
    }
//
	autoTimer = new TimerRunner(searchPublicData,180000,false);
  }
}

function destroy() {
	if (autoTimer) {
		autoTimer.stop();
	}
	if (searchTimer) {
		searchTimer.stop();
	}
}

function checkpass(_form) {
	if (_form.pass.value.length<4 || (_form.uname && _form.uname.value.length==0)) {
		return false;
	}
	md5pass(_form.pass);
	return true;
}

