// PlaceEngine JavaScript API
// $Id: pengine.js,v 1.35 2008/11/18 12:56:13 rekimoto Exp rekimoto $
// Copyright(c)2005-2007 Jun Rekimoto
// Copyright(c)2008,2009 Koozyt, Inc.

// check version
var versions = [
     //name      api_ver
     ["w081105", 1]
    ,["w090309", 2]
    ,["w091014", 2]
    ,["w091127", 2]
    ,["w091202", 2]
    ,["m080303", 1]
    ,["o080701", 1]
    ,["o081105", 1]
    ,["o091028", 1]
    ,["y080101", 1]
    ,["i080201", 1]
    ,["s080714", 1]
    ,["v080903", 2]
    ,["v090203", 2]
];
var __pe = null;
function PEngine(cb) {
    this.version = "1.01";
    this.host = "http://www.placeengine.com/api";
    this.rtagd = "http://127.0.0.1:5448";
    this.debug = false;
    this.clientexists = false;
    this.appkey = null;
    this.rtag = null;
    this.time = null;
    this.sameserver = false;
    this.x = 0;
    this.y = 0;
    this.numap = 0;
    this.onGetWifi = null;
    this.onFindClient = null;
    this.onGetLocation = null;
    this.onMessage = null;
    this.idstatus = null;
    this.lang_en = false;
    this.api_ver = 1;

    if (cb != null) {
	if (cb.host != null) { this.host = cb.host; }
	if (cb.rtagd != null) { this.rtagd = cb.rtagd; }
	if (cb.debug != null) { this.debug = cb.debug; }
	if (cb.lang_en != null) { this.lang_en = cb.lang_en; }
	if (cb.sameserver != null) { this.sameserver = cb.sameserver;}
	if (cb.idstatus != null) { this.idstatus = cb.idstatus; }
	if (cb.onGetLocation != null) { this.onGetLocation = cb.onGetLocation;}
	if (cb.onMessage != null) { this.onMessage = cb.onMessage;}
	if (cb.onGetWifi != null) { this.onGetWifi = cb.onGetWifi;}
	if (cb.onFindClient != null) { this.onFindClient = cb.onFindClient;}
	if (cb.appkey != null) {this.appkey = cb.appkey;}
    }
    this.callback = cb;


    function sendScript(url){
	if (this.debug) alert("peSendScript: " + url);
	var s = document.createElement("script");
	s.src= url;
	s.charset="UTF-8";
	document.body.appendChild(s);
    }
    PEngine.prototype.sendScript = sendScript;

    function message(str) {
	if (this.debug) alert("msg:"+ str);
	if (this.idstatus != null && document.getElementById(this.idstatus) != null) document.getElementById(this.idstatus).innerHTML = str;
	if (__pe.onMessage != null) __pe.onMessage(str);
    }
    PEngine.prototype.message = message;

    function errmsg(code) {
	if (this.debug) alert("errmsg:"+ code);
	if (this.idstatus != null) {
	    if (code<=-100) {
		__pe.message(this.lang_en ?
			     "Not registered in PlaceEngine DB"		     
			     :
			     "まだ位置情報が登録されていません。");
	    } else if (code<=0) {
		__pe.message((this.lang_en ?
			      "Cannot get Wi-Fi information. No access points nearby of Wi-Fi device is OFF.":
			      "Wi-Fi情報が取得できません。周辺にアクセスポイントが無いか, 無線LANがOFFになっています。") + code);
	    }
	}
    }
    PEngine.prototype.errmsg = errmsg;

    function getLocation() {
	this.numap = 0;
	this.message(this.lang_en?"Retrieving Wi-Fi information...":"Wi-Fi情報取得中...");
	if (this.appkey != null) {
            //
            // call the getloc API if the api ver == 2
            //
            if (__pe.api_ver == 2) {
	      this.sendScript(this.rtagd + "/getlocjs?t=" + (new Date().getTime()) + "&appk=" + this.appkey + "&usecache=0&m=p,l,g&restrict=1");
            } else {
	      this.sendScript(this.rtagd + "/rtagjs?t=" + (new Date().getTime()) + "&appk=" + this.appkey);
            }
	} else {
	    this.sendScript(this.rtagd + "/rtagjs?t=" + (new Date().getTime()));
	}
    }
    PEngine.prototype.getLocation = getLocation;

    // obtain RTAG from the client
    function getRtag() {
	this.numap = 0;
	this.message(this.lang_en?"Retrieving Wi-Fi information...":"Wi-Fi情報取得中...");
	if (this.appkey != null) {
	      this.sendScript(this.rtagd + "/rtagjs?t=" + (new Date().getTime()) + "&appk=" + this.appkey);
	} else {
	    this.sendScript(this.rtagd + "/rtagjs?t=" + (new Date().getTime()));
	}
    }
    PEngine.prototype.getRtag = getRtag;

    // note: this is googleMap dependent
    function registerLocation(map) {
	var url = "http://www.placeengine.com/map?regiloc=1";
	if (map != null) {
	    var c = map.getCenter();
	    url = "http://www.placeengine.com/map?regiloc=1&x=" + c.lng() + "&y=" + c.lat() + "&z=" + map.getZoom();
	} else if (__pe.x != 0 && __pe.y != 0) {
	    url = "http://www.placeengine.com/map?regiloc=1&x=" + __pe.x + "&y=" + __pe.y;
	}
	window.open(url, "_blank");
    }
    PEngine.prototype.registerLocation = registerLocation;

    function pingClient(msg) {
	if (msg != null) this.message(msg);
	this.sendScript(this.rtagd + "/ackjs?t=" + (new Date().getTime()));
    }
    PEngine.prototype.pingClient = pingClient;

    function submitRtag(rtag,time) {
	this.message("[" + this.numap + "] <b>" + (this.lang_en?"Connecting to PlaceEngine server...":"PlaceEngine</b>サーバー問い合わせ中..."));
	var param = 'rtag=' + rtag + "&t=" + time;
	if (this.appkey != null) {
	    param += "&appk=" + this.appkey;
	}
	param += "&ref=" + encodeURIComponent(location.href);
	if (this.sameserver) {
	    param += '&fmt=json';
	    if (this.lang_en) param += "&lang=en";
	    new Ajax.Request('/api/loc', {method:'get',parameters:param,onComplete:recvLoc2});
	} else {
	    this.sendScript(this.host + "/loc?" + param);
	}
    }
    PEngine.prototype.submitRtag = submitRtag;
    __pe = this;

  this.message(this.lang_en ? "'Get Location' becomes available once PlaceEngine client is <a href=http://www.placeengine.com/showe/install>installed</a>" : "PlaceEngineを <a href=http://www.placeengine.com/show/install>インストール</a> すると現在地取得機能が使えるようになります")
		 
    this.sendScript(this.rtagd + "/ackjs?t=" + (new Date().getTime()));
    return this;
}
// from PlaceEngine server
function recvLoc(x, y, range, info) {
    if (__pe == null) return;
    if (__pe.debug) alert("recvLoc: " + x + "," + y + ",range=" + range + "," + info);
    __pe.x = x;
    __pe.y = y;
    if (x !=0 && y != 0 && range >= 0) {
	var cx = Math.floor(x * 10000) / 10000;
	var cy = Math.floor(y * 10000) / 10000;
	__pe.message((__pe.numap>0? "(" + __pe.numap + ") " : "") + "<b>" + (cy>0?"N":"S")+Math.abs(cy)+" "+(cx>0?"E":"W")+Math.abs(cx) + "</b> " + (info.addr?info.addr:"") + (info.floor?" " + info.floor:"") + " " + range + "m");
    } else if (info.msg != null && info.msg.length > 0) {
	__pe.message(info.msg);
    } else {
	__pe.errmsg(range);
    }
    if (__pe.onGetLocation != null) __pe.onGetLocation(x, y, range, info);
}
// from PlaceEngine server
// callback from locserver (when sameserver==true)
function recvLoc2(json) {
    // sanity checks
    if (__pe == null) return;
    if (__pe.api_ver == 2) {
        if (json instanceof Array) {
          data = json[0];
        } else {
          data = json;
        }

    	if (data.x == null || data.y == null || data.r == null || data.info == null) {
    	  __pe.message("recvLoc2: invalid return values from PlaceEngine client.");
    	  return;
    	}
    	recvLoc(data.x, data.y, data.r, data.info);
    } else {
	var val = eval(json.responseText);
	if (val.length >= 4) 
	    recvLoc(val[0], val[1], val[2], val[3]);
    }
}
// from rtagd
function recvRTAG(rtag,numap,time){
    if (__pe == null) return;
    if (__pe.debug) alert("recvRTAG: " + numap);
    if (numap >= 0) __pe.numap = numap;
    if (rtag != null && rtag != undefined) __pe.rtag = rtag;
    if (time!=null) __pe.time = time;
    if (numap > 0) {
	__pe.message("[" + numap + (__pe.lang_en?"] Wi-Fi information retrieved":"] Wi-Fi情報を取得しました"));
    } else if (numap == -4 || numap == -5 || numap == -6) {
	__pe.message((__pe.lang_en?"Refused retrieving Wi-Fi information":"Wi-Fi情報取得が拒絶されました(")+numap+")");
    } else if (numap == -2) {
	__pe.message(__pe.lang_en?"No access points nearby of Wi-Fi device":"アクセスポイントが見つかりませんでした");
    } else if (numap == -1) {
	__pe.message(__pe.lang_en?"Wi-Fi device is OFF":"無線LANがOFFです");
    } else {
	__pe.message((__pe.lang_en?"Cannot get Wi-Fi information. No access ponts nearby of Wi-Fi device is OFF. (":"Wi-Fi情報が取得できません。周辺にアクセスポイントがないか無線LANがOFFになっています(")+numap+")");
    }
    var askserver = true;
    if (__pe.onGetWifi != null) askserver = __pe.onGetWifi(rtag,numap);
    if (numap > 0 && askserver) __pe.submitRtag(rtag,time);
}
function checkVersion(ver){ 
    for(var i=0; i<versions.length; i++){
        if( ver == versions[i][0] )
            return true;
    }
    return false;
}
function getApiVersion(ver){
    for(var i=0; i<versions.length; i++){
        if( ver == versions[i][0] )
            return versions[i][1];
    }
    return 1; // default
}
// callback from rtagd
function ackRTAG(ver){
    if (__pe == null) return;
    if (__pe.debug) alert("ackRTAG");
    if (checkVersion(ver)) {
	__pe.message(__pe.lang_en?"<b>PlaceEngine</b> client found":"<b>PlaceEngine</b>クライアントが見つかりました。");
	__pe.api_ver = getApiVersion(ver);
    } else {
	__pe.message(__pe.lang_en?("A" + ' [ <a href="http://www.placeengine.com/show/install" target="_blank">new version</a> ]' + " of the PlaceEngine client is available"):
		     ("PlaceEngineクライアントの " + '[ <a href="http://www.placeengine.com/show/install" target="_blank">新バージョン</a> ]' + " がダウンロード可能です."));
    }
    __pe.clientexists = true;
    if (__pe.onFindClient != null) {__pe.onFindClient(ver);}
}

