function Realtime(map){this.engine=new RealtimeEngine();this.georss_client=new GeoRSSClient(map,this.engine);this.renderer=new RealtimeRenderer(map,this.engine);this.start=function(){this.engine.start();this.georss_client.start();this.renderer.start();}
this.startShowcase=function(){this.renderer.showcase=true;this.renderer.startShowcase();}
this.toggleDisplayFilter=function(type){this.renderer.toggleDisplayFilter(type);}}
function GeoRSSClient(map,realtimeEngine){this.map=map;this.realtimeEngine=realtimeEngine;this.INTERVAL=60000;this.server_url='/rtserver/web/GeoRSS';this.base_params={};this.move_event_timeout=null;this.MOVE_EVENT_UPDATE_DELAY=5000;this.start=function(){this.updateFromServer()();window.setInterval(this.updateFromServer(true),this.INTERVAL);};this.updateFromServer=function(on_interval){var grclient=this;f=function(){$.ajax({url:grclient.server_url,type:'GET',success:function(xml){var output=GeoRSSParser.parse(xml);var newEntities=output.entities;grclient.realtimeEngine.entities=grclient._mergeEntities(grclient.realtimeEngine.entities,newEntities);grclient.realtimeEngine.aux_data=output.aux_data;},data:grclient._getURLParams(on_interval),dataType:"xml"});}
return f;};this._mergeEntities=function(oldEntities,newEntites){var entities={};var bounds=this.map.maxExtent;for(var id in newEntites){if(!bounds.contains(newEntites[id].x,newEntites[id].y)){continue;}
var clone=this._clone(newEntites[id]);entities[id]=clone;var old=oldEntities[id];if(!old||old.type!="user"||old.path.length==0)
continue;clone.x=old.x;clone.y=old.y;clone.time=old.time;clone.delta_x=old.delta_x;clone.delta_y=old.delta_y;clone.phantom=old.phantom;if(clone.phantom)
clone.wait=old.wait;var cut_point=0;var lastTime=old.path[old.path.length-1].time;for(vertex in clone.path){var next=clone.path[vertex];if(next.time<=lastTime)
cut_point++;}
clone.path.splice(0,cut_point);clone.path=old.path.concat(clone.path);}
return entities;};this._getExtent=function(){var extent=null;if(this.map.baseLayer&&this.map.baseLayer.getTilesBounds)
extent=this.map.baseLayer.getTilesBounds();else
extent=this.map.getExtent();return extent;}
this._getURLParams=function(on_interval){var markerRadius=20*OpenLayers.INCHES_PER_UNIT["m"]*this.map.getResolution();var extent=this._getExtent();var rand=Math.random();var params={os:60,left:extent.left,right:extent.right,bottom:extent.bottom,top:extent.top,mr:markerRadius,sc:parseInt(this.map.getScale()),rand:rand,types:"alerts,users"}
for(var i in this.base_params)
params[i]=this.base_params[i];if(this.realtimeEngine.aux_data)
if(on_interval&&this.realtimeEngine.aux_data.next)
params.st=this.realtimeEngine.aux_data.next_str;else if(!on_interval&&this.realtimeEngine.aux_data.now)
params.st=this.realtimeEngine.aux_data.now_str;return params;}
this.map.events.register("moveend",this,function(evt){window.clearTimeout(this.move_event_timeout);var gc=this;this.move_event_timeout=window.setTimeout(function(){gc.updateFromServer(false)();},this.MOVE_EVENT_UPDATE_DELAY);});this._clone=function(obj){if(obj==null||typeof(obj)!='object')
return obj;var temp=new obj.constructor();if(obj.constructor.toString().split(/\s+/)[1]=="Date()")
temp.setTime(obj.getTime());for(var key in obj)
temp[key]=this._clone(obj[key]);return temp;}}
var GeoRSSParser={parse:function(rssFeed){var entities={};var aux_data={}
var dateArr=$(":ns(http://www.linqmap.com,time)",rssFeed).text().split(',');aux_data.now=this._parseDate(dateArr[0]);aux_data.now_str=dateArr[0];aux_data.next_str=dateArr[1];var thisParser=this;$("item",rssFeed).each(function(){var entity={};entity.id=$(":ns(http://www.linqmap.com,entityid)",this).text();entity.reported_by=$(":ns(http://www.linqmap.com,reportBy)",this).eq(0).text();entity.creation_date=thisParser._parseDate($("pubDate",this).text());var raw_point=($(":ns(http://www.georss.org/georss,point)",this).text()).split(" ");var y=parseFloat(raw_point[0]);var x=parseFloat(raw_point[1]);entity.y=y;entity.x=x;var desc=$(":ns(http://www.linqmap.com,reportDescription)",this);entity.description=desc.length>0?desc.text():"";entity.type=$(":ns(http://www.linqmap.com,type)",this).text();entity.inscale=($(":ns(http://www.linqmap.com,inscale)",this).text())=="true"?true:false;switch(entity.type){case'user':GeoRSSParser.parseUser(entity,this);break;default:break;}
entity.comments=[];$(":ns(http://www.linqmap.com,comment)",this).each(function(){var comment={};comment.text=$(":ns(http://www.linqmap.com,text)",this).text();comment.reported_by=$(":ns(http://www.linqmap.com,reportBy)",this).text();comment.creation_date=thisParser._parseDate($(":ns(http://www.linqmap.com,reportDate)",this).text());entity.comments.push(comment);});entities[entity.id]=entity;});return{entities:entities,aux_data:aux_data};},parseUser:function(entity,userFeed){entity.delta_x=0;entity.delta_y=0;entity.time=0;entity.phantom=false;entity.server_error=false;var fields=[[parseFloat,'y'],[parseFloat,'x'],[function(time){return parseInt(time)*1000},'time'],[parseFloat,'speed'],[parseFloat,'angle']];entity.path=[];var gps_path=$.trim($(":ns(http://www.linqmap.com,gpspath)",userFeed).text());if(!gps_path||gps_path.length==0)
return;var raw_steps=gps_path.split(" ");var lastTime=0;for(var i in raw_steps){var raw_step=raw_steps[i].split(",");var next={};for(var j in fields)
next[fields[j][1]]=fields[j][0](raw_step[j]);if(next.time>=lastTime){entity.path.push(next);lastTime=next.time;}
else
entity.server_error=true;}
var mod=entity.path[0].time%60000;if(mod>0){entity.phantom=true;entity.wait=mod;}
entity.x=entity.path[0].x;entity.y=entity.path[0].y;entity.time=entity.path[0].time;},_parseDate:function(dateString){var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');function LZ(x){return(x<0||x>9?"":"0")+x}
function isDate(val,format){var date=getDateFromFormat(val,format);if(date==0){return false;}
return true;}
function compareDates(date1,dateformat1,date2,dateformat2){var d1=getDateFromFormat(date1,dateformat1);var d2=getDateFromFormat(date2,dateformat2);if(d1==0||d2==0){return-1;}
else if(d1>d2){return 1;}
return 0;}
function formatDate(date,format){format=format+"";var result="";var i_format=0;var c="";var token="";var y=date.getYear()+"";var M=date.getMonth()+1;var d=date.getDate();var E=date.getDay();var H=date.getHours();var m=date.getMinutes();var s=date.getSeconds();var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;var value=new Object();if(y.length<4){y=""+(y-0+1900);}
value["y"]=""+y;value["yyyy"]=y;value["yy"]=y.substring(2,4);value["M"]=M;value["MM"]=LZ(M);value["MMM"]=MONTH_NAMES[M-1];value["NNN"]=MONTH_NAMES[M+11];value["d"]=d;value["dd"]=LZ(d);value["E"]=DAY_NAMES[E+7];value["EE"]=DAY_NAMES[E];value["H"]=H;value["HH"]=LZ(H);if(H==0){value["h"]=12;}
else if(H>12){value["h"]=H-12;}
else{value["h"]=H;}
value["hh"]=LZ(value["h"]);if(H>11){value["K"]=H-12;}else{value["K"]=H;}
value["k"]=H+1;value["KK"]=LZ(value["K"]);value["kk"]=LZ(value["k"]);if(H>11){value["a"]="PM";}
else{value["a"]="AM";}
value["m"]=m;value["mm"]=LZ(m);value["s"]=s;value["ss"]=LZ(s);while(i_format<format.length){c=format.charAt(i_format);token="";while((format.charAt(i_format)==c)&&(i_format<format.length)){token+=format.charAt(i_format++);}
if(value[token]!=null){result=result+value[token];}
else{result=result+token;}}
return result;}
function _isInteger(val){var digits="1234567890";for(var i=0;i<val.length;i++){if(digits.indexOf(val.charAt(i))==-1){return false;}}
return true;}
function _getInt(str,i,minlength,maxlength){for(var x=maxlength;x>=minlength;x--){var token=str.substring(i,i+x);if(token.length<minlength){return null;}
if(_isInteger(token)){return token;}}
return null;}
function getDateFromFormat(val,format){val=val+"";format=format+"";var i_val=0;var i_format=0;var c="";var token="";var token2="";var x,y;var now=new Date();var year=now.getYear();var month=now.getMonth()+1;var date=1;var hh=now.getHours();var mm=now.getMinutes();var ss=now.getSeconds();var ampm="";while(i_format<format.length){c=format.charAt(i_format);token="";while((format.charAt(i_format)==c)&&(i_format<format.length)){token+=format.charAt(i_format++);}
if(token=="yyyy"||token=="yy"||token=="y"){if(token=="yyyy"){x=4;y=4;}
if(token=="yy"){x=2;y=2;}
if(token=="y"){x=2;y=4;}
year=_getInt(val,i_val,x,y);if(year==null){return 0;}
i_val+=year.length;if(year.length==2){if(year>70){year=1900+(year-0);}
else{year=2000+(year-0);}}}
else if(token=="MMM"||token=="NNN"){month=0;for(var i=0;i<MONTH_NAMES.length;i++){var month_name=MONTH_NAMES[i];if(val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()){if(token=="MMM"||(token=="NNN"&&i>11)){month=i+1;if(month>12){month-=12;}
i_val+=month_name.length;break;}}}
if((month<1)||(month>12)){return 0;}}
else if(token=="EE"||token=="E"){for(var i=0;i<DAY_NAMES.length;i++){var day_name=DAY_NAMES[i];if(val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()){i_val+=day_name.length;break;}}}
else if(token=="MM"||token=="M"){month=_getInt(val,i_val,token.length,2);if(month==null||(month<1)||(month>12)){return 0;}
i_val+=month.length;}
else if(token=="dd"||token=="d"){date=_getInt(val,i_val,token.length,2);if(date==null||(date<1)||(date>31)){return 0;}
i_val+=date.length;}
else if(token=="hh"||token=="h"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<1)||(hh>12)){return 0;}
i_val+=hh.length;}
else if(token=="HH"||token=="H"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<0)||(hh>23)){return 0;}
i_val+=hh.length;}
else if(token=="KK"||token=="K"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<0)||(hh>11)){return 0;}
i_val+=hh.length;}
else if(token=="kk"||token=="k"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<1)||(hh>24)){return 0;}
i_val+=hh.length;hh--;}
else if(token=="mm"||token=="m"){mm=_getInt(val,i_val,token.length,2);if(mm==null||(mm<0)||(mm>59)){return 0;}
i_val+=mm.length;}
else if(token=="ss"||token=="s"){ss=_getInt(val,i_val,token.length,2);if(ss==null||(ss<0)||(ss>59)){return 0;}
i_val+=ss.length;}
else if(token=="a"){if(val.substring(i_val,i_val+2).toLowerCase()=="am"){ampm="AM";}
else if(val.substring(i_val,i_val+2).toLowerCase()=="pm"){ampm="PM";}
else{return 0;}
i_val+=2;}
else{if(val.substring(i_val,i_val+token.length)!=token){return 0;}
else{i_val+=token.length;}}}
if(i_val!=val.length){return 0;}
if(month==2){if(((year%4==0)&&(year%100!=0))||(year%400==0)){if(date>29){return 0;}}
else{if(date>28){return 0;}}}
if((month==4)||(month==6)||(month==9)||(month==11)){if(date>30){return 0;}}
if(hh<12&&ampm=="PM"){hh=hh-0+12;}
else if(hh>11&&ampm=="AM"){hh-=12;}
var newdate=new Date(year,month-1,date,hh,mm,ss);return newdate.getTime();}
function parseDate(val){var preferEuro=(arguments.length==2)?arguments[1]:false;generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');dateFirst=new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');var d=null;for(var i=0;i<checkList.length;i++){var l=window[checkList[i]];for(var j=0;j<l.length;j++){d=getDateFromFormat(val,l[j]);if(d!=0){return new Date(d);}}}
return null;}
var d=new Date();d.setTime(getDateFromFormat(dateString,'E NNN d HH:mm:ss +0000 yyyy'));return d;}}
function RealtimeEngine(){this.entities={};this.INTERVAL=100.0;this.start=function(){window.setInterval(this._realtimeStep(),this.INTERVAL);};this._realtimeStep=function(){var rt=this;f=function(){for(var id in rt.entities){rt._updateEntity(rt.entities[id]);}}
return f;};this._updateEntity=function(entity){if(entity.type!="user")
return;if(entity.phantom){if(entity.wait>0)
entity.wait-=this.INTERVAL;if(entity.wait<=0)
entity.phantom=false;return;}
var path=entity.path;if(path.length<2)
return;if(entity.time==path[0].time||entity.time==path[1].time){while(path.length>1&&entity.time==path[1].time)
path.shift();if(path.length<2)
return;entity.delta_x=((path[1].x-path[0].x)/(path[1].time-path[0].time))*this.INTERVAL;entity.delta_y=((path[1].y-path[0].y)/(path[1].time-path[0].time))*this.INTERVAL;}
entity.x+=entity.delta_x;entity.y+=entity.delta_y;entity.time+=this.INTERVAL;};}
function extend(father,son){var from_proto=father.prototype;var to_proto=son.prototype;for(m in from_proto){if(typeof from_proto[m]!='function')
continue;to_proto[m]=from_proto[m];}
son.prototype.superClass=father;}
function CssCache(){this.map={};}
CssCache.prototype.get=function(element,property){var map=this.map;var key=element.id+'-'+property;if(map[key])
return map[key];var str=this.getNotCached(element,property);map[key]=str;return map[key];}
CssCache.prototype.getNotCached=function(element,property){var str='';if(element['style']&&element.style[property])
str=element.style[property];else
str=$(element).css(property);return str;}
CssCache.prototype.getNotCachedInt=function(element,property){return parseInt(this.getNotCached(element,property).replace('px',''));}
CssCache.prototype.getAsInt=function(element,property){return parseInt(this.get(element,property).replace('px',''));}
CssCache.prototype.getWidth=function(element){var map=this.map;var key=element.id+'-jquery-width';if(map[key])
return map[key];var str=$(element).width();map[key]=str;return map[key];}
function Avatar(container,entity_id,cssClass){this.cache=new CssCache();this.entity_id=entity_id;this.entity={};this.container=container;this.cssClass=cssClass;this.tooltipElement=null;this.comments=null;this.element=this._createElement();}
Avatar.prototype.update=function(now,entity){this.entity.x=entity.x;this.entity.y=entity.y;this.entity.inscale=false;this.entity.creation_date=new Date(entity.creation_date);this.entity.reported_by=entity.reported_by;this.entity.description=entity.description;this.entity.comments=entity.comments;this.now=new Date(now);}
Avatar.prototype.destroy=function(){if(this.comments)
this.container.removeChild(this.comments);if(this.tooltipElement)
this.container.removeChild(this.tooltipElement);this.container.removeChild(this.element);}
Avatar.prototype._createTooltipElement=function(){var avatar=this;var tt=document.createElement('div');tt.id=this.entity_id+"_tooltip";$(tt).addClass('tooltip');this._setOpacity(tt,0.9);$(tt).html($("#tooltip_mold").html());var ent=this;$("a.commentsLink",tt).click(function(e){avatar._updateCommentsWindow();var winQ=$("#"+ent.entity_id+"_comments");if($(".comment",winQ).length==0)
return false;var left=parseInt($(tt).css("left").replace("px",""))+$(tt).outerWidth()-40+"px";winQ.css("left",left);var top=parseInt($(tt).css("top").replace("px",""))+$(tt).outerHeight()-15+"px";winQ.css("top",top);winQ.show();return false;});$(tt).css("zIndex","751");this.container.appendChild(tt);return tt;}
Avatar.prototype._createCommentsWindow=function(){var avatar=this;var win=document.createElement('div');this.container.appendChild(win);win.id=this.entity_id+"_comments";$(win).addClass('comments');$(win).html($('#panel_mold').html());$(win).addClass('panel');$(".frame",win).append("תגובות");$(".contents",win).append("<div class='commentsContainer'>");$("a.closeBtn",win).click(function(e){if(avatar.comments)
avatar.container.removeChild(avatar.comments);avatar.comments=null;return false;});this._setOpacity(win,0.95);$(win).hide();$(win).mousedown(function(){return false;});$(win).click(function(){return false;});$(win).css("zIndex","752");return win;}
Avatar.prototype._createElement=function(){var avatar=this;var container=this.container;var e=document.createElement('div');e.id=this.entity_id;var tt_id=this.entity_id+'_tooltip';$(e).addClass(this.cssClass);$(e).hover(over=function(){if(avatar.entity.inscale)
return;$(".tooltip:not(.user-tooltip)").hide();if(!avatar.tooltipElement)
avatar.tooltipElement=avatar._createTooltipElement();avatar._renderTooltip();avatar.updateTooltipContents();},out=function(){if(avatar.entity.inscale)
return;if(!avatar.tooltipElement)
return;window.setTimeout(function(){if(!avatar.tooltipElement)
return;if(avatar.tooltipElement){avatar.container.removeChild(avatar.tooltipElement);avatar.tooltipElement=null;}},1500);return true;});$(e).css("zIndex","750");this.container.appendChild(e);return e;}
Avatar.prototype._setPosition=function(x,y){var old_left=this.element.style.left;var old_top=this.element.style.top;this.element.style.left=(x-this.element.clientWidth/2)+"px";this.element.style.top=(y-this.element.clientHeight/2)+"px";}
Avatar.prototype.render=function(map){var lonlat=new OpenLayers.LonLat(lon=this.entity.x,lat=this.entity.y);var pixel=map.getLayerPxFromLonLat(lonlat);this._setPosition(pixel.x,pixel.y);if(this.entity.inscale)
this._renderTooltip();}
Avatar.prototype._renderTooltip=function(){if(this.tooltipElement==null){this.tooltipElement=this._createTooltipElement();this.updateTooltipContents();}
var e=this.element;var tt=this.tooltipElement;var e_left=this.cache.getNotCachedInt(e,'left');var e_top=this.cache.getNotCachedInt(e,'top');var left=e_left-$(tt).outerWidth()+$(e).outerWidth();var top=e_top-$(tt).outerHeight();tt.style.left=left+'px';tt.style.top=top+'px';}
Avatar.prototype.updateTooltipContents=function(){var tt=this.tooltipElement;if(!tt)
return;var millisecs_ago=this.now.getTime()-this.entity.creation_date.getTime();var minutes_ago=Math.ceil(millisecs_ago/(1000*60))+2;if(this.entity.reported_by.length>0){if($('a.user_name',tt).text()!=this.entity.reported_by)
$('a.user_name',tt).text(this.entity.reported_by);$('a.user_name:hidden',tt).show();}
else
$('a.user_name:visible',tt).hide();if($('span',tt).text()!=this.entity.description)
$('span',tt).text(this.entity.description);if(parseInt($('.time',tt).text().replace(/[^0-9]/g,""))!=minutes_ago)
$('.time',tt).text('עודכן לפני '+minutes_ago+' דקות');if(this.entity.comments.length!=$(".comment",this.comments).length){if(this.entity.comments.length>0){$('a.commentsLink',tt).text(this.entity.comments.length+" תגובות");$('a.commentsLink:hidden',tt).show();}
else
$('a.commentsLink:visible',tt).hide();}
if(this.comments)
this._updateCommentsWindow();}
Avatar.prototype._updateCommentsWindow=function(){if(this.comments==null)
this.comments=this._createCommentsWindow();var win=this.comments;$(".comment",win).remove();for(var i in this.entity.comments){var next=this.entity.comments[i];var e=document.createElement('div');$(".commentsContainer",win).append(e);$(e).addClass("comment");if(next.reported_by)
$(e).append("<a href='#'>"+next.reported_by+"</a>")
var millisecs_ago=this.now.getTime()-next.creation_date.getTime();var minutes_ago=Math.ceil(millisecs_ago/(1000*60))+2;$(e).append(next.text);$(e).append("<div class='time'>"+'עודכן לפני '+minutes_ago+' דקות'+"</div>");}
$(".comment:even",win).css("background-color","#fff");}
Avatar.prototype._setOpacity=function(obj,value){obj.style.opacity=value;obj.style.filter='alpha(opacity='+value*100+')';}
function Policeman(container,entity){this.superClass(container,entity,'policeman');}
extend(Avatar,Policeman);function Accident(container,entity){this.superClass(container,entity,'accident');}
extend(Avatar,Accident);function TrafficJam(container,entity){this.superClass(container,entity,'trafficjam');}
extend(Avatar,TrafficJam);function Other(container,entity){this.superClass(container,entity,'other');this._setPosition=function(x,y){this.element.style.left=(x-15)+"px";this.element.style.top=(y-46)+"px";}
$(this.tooltipElement).addClass('other-tooltip');}
extend(Avatar,Other);function User(container,entity_id){this.superClass(container,entity_id,'user');var avatars=['red','blue'];$(this.element).addClass(avatars[Math.floor(Math.random()*avatars.length)]);}
extend(Avatar,User);User.prototype._createTooltipElement=function(){var tt=this.superClass.prototype._createTooltipElement.apply(this);$(tt).html("<a href='#'></a><span></span><div class='twit'></div>");$(tt).addClass('user-tooltip');return tt;}
User.prototype.update=function(now,entity){this.superClass.prototype.update.apply(this,[now,entity]);this.entity.inscale=entity.inscale;this.entity.path=entity.path;this.entity.time=entity.time;this.entity.id=entity.id;this.entity.description=entity.description;this.entity.server_error=entity.server_error;}
User.prototype.render=function(map){var user=this.entity;var e=this.element;if(user.time==0||user.phantom){$(e).hide();return;}
$(e).show();var id=user.id;var lonlat=new OpenLayers.LonLat(lon=user.x,lat=user.y);var pixel=map.getLayerPxFromLonLat(lonlat);this._setPosition(pixel.x,pixel.y);if(user.inscale)
this._renderTooltip();var imageClass=user.inscale?'left':'leftSmall';if(user.path&&user.path.length>0){var drivingLeft=true;var angle=user.path[0].angle;if(angle>=0&&angle<=180)
drivingLeft=false;imageClass=drivingLeft?(user.inscale?'left':'leftSmall'):(user.inscale?'right':'rightSmall');}
if(!$(e).hasClass(imageClass)){$(e).removeClass('left');$(e).removeClass('leftSmall');$(e).removeClass('right');$(e).removeClass('rightSmall');$(e).addClass(imageClass);}}
User.prototype.updateTooltipContents=function(){var tt=this.tooltipElement;if(!tt)
return;var user=this.entity;var speed_in_meters_per_sec=0;if(user.path&&user.path.length>1)
speed_in_meters_per_sec=user.path[0].speed;var speedStr=Math.round(speed_in_meters_per_sec*3.6)+'kmh';var userTime=new Date(user.time);var timeStr=this._formatTime(userTime);var statPart=speedStr+", "+timeStr;if(user.server_error)
statPart+=", ACHTUNG ACHTUNG Server Error!";$('a',tt).text(user.id);$('span',tt).text(statPart);if(user.description.length>0){$('.twit',tt).text(user.description);$('.twit:hidden',tt).show();}
else $('.twit:visible',tt).hide();}
User.prototype._formatTime=function(date){function _zeroComplement(integer,len){str=integer.toString();while(str.length<len)
str='0'+str;return str;}
return _zeroComplement(date.getHours(),2)+":"+_zeroComplement(date.getMinutes(),2);}
function RealtimeRenderer(map,realtimeEngine){this.map=map;this.type_filter_map={'user':true};this.realtimeEngine=realtimeEngine;this.RENDER_INTERVAL=1000;this.UPDATE_TOOLTIP_CONTENTS_INTERVAL=60000;this.SHOWCASE_USER_INTERVAL=20000;this.SHOWCASE_ALERT_INTERVAL=15000;this.SHOWCASE_ZOOM=8;this.avatars={};this.start=function(){window.setInterval(this._render(),this.RENDER_INTERVAL);window.setInterval(this._updateTooltipsContents(),this.UPDATE_TOOLTIP_CONTENTS_INTERVAL);};this.startShowcase=function(){this._showcaseNext()();};this._showcaseNext=function(){var renderer=this;var f=function(){var entities_arr=[];for(var id in renderer.realtimeEngine.entities)
entities_arr.push(renderer.realtimeEngine.entities[id]);if(entities_arr.length>0){var index=Math.floor(Math.random()*entities_arr.length);var selected=entities_arr[index];renderer.map.setCenter(new OpenLayers.LonLat(lon=selected.x,lat=selected.y),renderer.SHOWCASE_ZOOM);var interval=(selected.type=='user'?renderer.SHOWCASE_USER_INTERVAL:renderer.SHOWCASE_ALERT_INTERVAL);$(".comments").hide();var comQ=$("#"+selected.id+"_comments");var ttQ=$("#"+selected.id+"_tooltip");if(ttQ.length==1&&$(".comment",comQ).length>0){var left=parseInt(ttQ.css("left").replace("px",""))+ttQ.outerWidth()-40+"px";comQ.css("left",left);var bottom=parseInt(ttQ.css("bottom").replace("px",""))+15-comQ.outerHeight()+"px";comQ.css("bottom",bottom);comQ.show();}}
window.setTimeout(renderer._showcaseNext(),interval);}
return f;};this._makeAvatar=function(entity){switch(entity.type){case"user":return new User(this.map.layerContainerDiv,entity.id);break;case"POLICEMAN":return new Policeman(this.map.layerContainerDiv,entity.id);break;case"ACCIDENT":return new Accident(this.map.layerContainerDiv,entity.id);break;case"JAM":return new TrafficJam(this.map.layerContainerDiv,entity.id);break;case"OTHER":return new Other(this.map.layerContainerDiv,entity.id);break;default:return null;}}
this.toggleDisplayFilter=function(type){if(!this.type_filter_map[type])
this.type_filter_map[type]=true;else
this.type_filter_map[type]=false;}
this.setFilter=function(type_filter_map){this.type_filter_map=type_filter_map;}
this.filterEntities=function(entities){var filteredEntities={};for(var id in entities)
if(!this.type_filter_map[entities[id].type])
filteredEntities[id]=entities[id];return filteredEntities;}
this._recalibrate=function(){var filtered=this.filterEntities(this.realtimeEngine.entities);for(var id in filtered)
if(!this.avatars[id]){var avatar=this._makeAvatar(filtered[id]);if(avatar)
this.avatars[id]=avatar;}
var removeList=[];for(var id in this.avatars)
if(!this.realtimeEngine.entities[id]||!filtered[id])
removeList.push(id);for(var i=0;i<removeList.length;i++){var nextId=removeList[i];this.avatars[nextId].destroy();delete this.avatars[nextId];}}
this._render=function(){var renderer=this;f=function(){renderer._recalibrate();if(renderer.realtimeEngine.aux_data)
renderer.now=renderer.realtimeEngine.aux_data.now;var filtered=renderer.filterEntities(renderer.realtimeEngine.entities);for(var id in filtered){var next=renderer.avatars[id]
if(next){next.update(renderer.now,filtered[id]);if(renderer.showcase)
next.entity.inscale=filtered[id].inscale;next.render(renderer.map);}}}
return f;};this._updateTooltipsContents=function(){var renderer=this;f=function(){var filtered=renderer.filterEntities(renderer.realtimeEngine.entities);for(var id in filtered){var next=renderer.avatars[id]
if(next)
next.updateTooltipContents();}}
return f;};}