var LDMapTwitter=function(mm,lng,lat,z){this.mm=mm;this.lng=lng;this.lat=lat;this.z=z;this.events=[];this.reqStatus=0;this.loadElements();this.init();};LDMapTwitter.prototype=$.extend({},{config:{path:"/"},domEl:{map:$("#map"),bread:$("#breadCrumbs"),header:$("#header"),footer:$("#footer"),mapHeader:$("#map-header"),mapFooter:$("#map-footer"),aside:$("#aside"),timeline:$("#timeline"),login:$(".twitter-login"),wheel:$("#wheel"),hiddenAdr:$("#hiddenAdr")},loadElements:function(){this.loginEl=this.domEl.login;this.wheelEl=this.domEl.wheel;this.windowEl=$(window);},init:function(){var mm=this.mm;this.mp=new MPoint(this.lng,this.lat);mm.autoScroll=false;mm.centerAndZoom(this.mp,this.z);var slider=new MSliderMapionControl();mm.addControl(slider);slider.update(mm.getCenterLatLng());MEvent.clearListeners(mm,"wheel");mm.addControl(new MScaleControl(),new MControlPosition(M_ANCHOR_BOTTOM_RIGHT,"5","5"));this.updateMapUrl();this.updateLocAddress();this.fitToWindow();var self=this;this.events.push(MEvent.addListener(mm,"click",function(anon,mp,anon){if(mp)mm.recenterOrPanToLatLng(mp);}));this.events.push(MEvent.addListener(mm,"moveend",function(){self.mp=mm.getCenterLatLng();slider.update(self.mp);self.updateMapUrl();self.updateLocAddress();self.notify();}));this.events.push(MEvent.addListener(mm,"zoom",function(){self.updateMapUrl();}));if(this.loginEl){this.loginEl.each(function(i){var el=$(this);el.bind("click",function(){self.redirectLogin(el);return false;});});}if(this.wheelEl){this.wheelEl.bind("click",function(){var el=$(this).parent();if(el.hasClass("on")){MEvent.clearListeners(mm,"wheel");el.removeClass("on");}else{MEvent.addListener(mm,"wheel",function(direction){if(direction>0)slider.zoomIn();else slider.zoomOut();});el.addClass("on");}});}this.windowEl.bind("resize",function(){self.fitToWindow();});},updateMapUrl:function(){var mp=this.mp;var zoom=this.mm.getZoomLevel();$("#mapUrl").val([["http://",window.location.host,this.config.path].join(""),["lng="+mp.x,"lat="+mp.y,"zoom="+zoom].join("&")].join("?"));},updateLocAddress:function(){if(this.reqStatus)return;this.reqStatus=1;var mp=this.mp;var url=["/api/geo/g2a",["lng="+mp.x,"lat="+mp.y].join("&")].join("?");var self=this;$.getJSON(url,function(data){self.reqStatus=0;var el=self.domEl.bread;el.empty();var hidden=self.domEl.hiddenAdr;hidden.val("");var loc=[];var entry=data.entry;if(entry==null||entry.pref_id==null){loc.push("不明な場所");}else{if(entry.pref!=null)loc.push(entry.pref);if(entry.city!=null)loc.push(entry.city);if(entry.town!=null)loc.push(entry.town);if(entry.block!=null)loc.push(entry.block);}el.html(loc.join(" &gt; "));hidden.val(loc.join(""));});},fitToWindow:function(){var self=this;if(this.resizeTimeoutId)window.clearTimeout(this.resizeTimeoutId);this.resizeTimeoutId=window.setTimeout(function(){self.doMapResize();},50);},doMapResize:function(){var windowEl=this.windowEl;var headerEl=this.domEl.header;var footerEl=this.domEl.footer;var mapEl=this.domEl.map;var mapHeaderEl=this.domEl.mapHeader;var mapFooterEl=this.domEl.mapFooter;var asideEl=this.domEl.aside;var timelineEl=this.domEl.timeline;var mapHeight=windowEl.height()-(headerEl.height()+10+3+mapHeaderEl.height()+mapFooterEl.height()+8*2+10+footerEl.height()+2);var mapWidth=windowEl.width()-(asideEl.width()+6+40+2);mapEl.css({width:mapWidth,height:mapHeight});timelineEl.height(mapEl.height()+mapFooterEl.height());this.mm.refreshMapDivSize();},redirectLogin:function(el){var mp=this.mp;var next=[this.config.path,["lng="+mp.x,"lat="+mp.y,"zoom="+this.mm.getZoomLevel()].join("&")].join("?");var redirectTo=[el.attr("href"),["next="+encodeURIComponent(next)].join("&")].join("?");el=null;mp=null;next=null;window.location.href=redirectTo;},createTweet:function(){this.oTweet=new LDMapTwitter.Tweet(this.oLoader);this.oTweet.currentCoord(this.mp,this.mm.getZoomLevel());this.oLoader.oTweet=this.oTweet;},notify:function(){if(this.oTweet)this.oTweet.currentCoord(this.mp,this.mm.getZoomLevel());},createLoader:function(){this.oLoader=new LDMapTwitter.Loader(this.mm);},destroy:function(){if(this.oLoader){this.oLoader.destroy();this.oLoader=null;}if(this.oTweet){this.oTweet.destroy();this.oTweet=null;}var len=this.events.length;for(var i=0;i<len;i++){MEvent.removeListener(this.events.pop());}MEvent.clearListeners(this.mm,"wheel");this.mm=null;this.mp=null;if(this.loginEl){this.loginEl.each(function(i){$(this).unbind();});this.loginEl=null;}if(this.wheelEl){this.wheelEl.unbind();this.wheelEl=null;}this.windowEl.unbind();this.windowEl=null;}});LDMapTwitter.Tweet=function(oLoader){this.oLoader=oLoader;this.replyProps={};this.init();};LDMapTwitter.Tweet.prototype=$.extend({},{config:{maxLength:119,updateUrl:["http://",window.location.host,"/twiz_api/status/update"].join("")},domEl:{text:$("#tweetText"),submit:$("#tweetSubmit"),form:$("#tweetForm"),count:$("#textCount"),adrFill:$("#addressFillin"),hiddenAdr:$("#hiddenAdr")},init:function(){this.textEl=this.domEl.text;this.submitEl=this.domEl.submit;this.submitEl.attr("disabled",true);this.formEl=this.domEl.form;this.countEl=this.domEl.count;this.adrFillEl=this.domEl.adrFill.children(":first-child");this.updateCount();var self=this;this.textEl.keyup(function(e){if(self.hasValidTextLength())self.submitEl.attr("disabled",false);else self.submitEl.attr("disabled",true);self.updateCount();});this.textEl.bind("click",function(){if(self.hasValidTextLength())self.submitEl.attr("disabled",false);else self.submitEl.attr("disabled",true);self.updateCount();});this.formEl.bind("submit",function(){if(self.hasValidTextLength())self.submit();return false;});this.adrFillEl.bind("click",function(){var adr=self.domEl.hiddenAdr.val();self.textEl.val([self.getText(),"L:",adr].join(""));self.updateCount();self.enableForm();});},hasValidTextLength:function(){var len=parseInt(this.getText().length);return len&&(len<=this.config.maxLength)?true:false;},updateCount:function(){var remaining=this.config.maxLength-this.getText().length;this.countEl.html(remaining<0?"長すぎます!":["",remaining,""].join(" "));},currentCoord:function(coord,zoom){this.coord=coord;this.zoom=zoom;},getText:function(){return this.textEl.val();},disableForm:function(){this.textEl.attr("disabled",true);this.submitEl.attr("disabled",true);},enableForm:function(){this.textEl.attr("disabled",false);this.textEl.focus();if(this.hasValidTextLength())this.submitEl.attr("disabled",false);else this.submitEl.attr("disabled",true);},refreshForm:function(){this.textEl.val("");this.updateCount();this.replyProps={};},submit:function(){if(!this.hasValidTextLength()||!this.coord)return;this.disableForm();var text=this.getText();var url=this.config.updateUrl;var self=this;$.post(url,{text:text,in_reply_to_status_id:this.replyProps.status_id||"",in_reply_to:this.replyProps.screen_name||"",lng:this.coord.x,lat:this.coord.y,z:this.zoom},function(data){self.oLoader.getRecents();if(data.isSuccess){self.refreshForm();}self.enableForm();},"json");},initReply:function(props){this.replyProps=props;this.textEl.val(['@',props.screen_name,' ',this.getText()].join(""));this.updateCount();this.enableForm();},destroy:function(){this.textEl.unbind();this.formEl.unbind();this.adrFillEl.unbind();}});LDMapTwitter.Loader=function(mm){this.mm=mm;this.events=[];this.init();};LDMapTwitter.Loader.prototype=$.extend({},{config:{apiUrl:["http://",window.location.host,"/api/bounds/"].join(""),interval:5*60*1000},domEl:{timeline:$("#timeline")},init:function(){this.reqStatus=0;this.items=[];this.timelineEl=this.domEl.timeline;var self=this;this.events.push(MEvent.addListener(this.mm,"moveend",function(){self.getRecents();}));this.events.push(MEvent.addListener(this.mm,"zoom",function(){self.getRecents();}));function getRecents(){self.getRecents();self.sto=window.setTimeout(getRecents,self.config.interval);}getRecents();},getRecents:function(){if(this.reqStatus)return;var params=this.getParams();params.push("type=statuses");var url=[this.config.apiUrl,params.join("&")].join("?");this.reqStatus=1;var self=this;$.getJSON(url,function(data){var mm=self.mm;self.removeMarkers();var items=[];var len=data.entries.length;for(var i=0;i<len;i++){var entry=data.entries.pop();var item=new LDMapTwitter.Item(self.mm,entry,self.oTweet);item.addMarker();items.push(item);}self.items=items;self.updateRecents();self.reqStatus=0;});},getParams:function(){var mm=this.mm;var params=[];var center=mm.getCenterLatLng();params.push("lng="+center.x);params.push("lat="+center.y);var bounds=mm.getBoundsLatLng();params.push("min_lng="+bounds.minX);params.push("min_lat="+bounds.minY);params.push("max_lng="+bounds.maxX);params.push("max_lat="+bounds.maxY);return params;},removeMarkers:function(){var len=this.items.length;for(var i=0;i<len;i++){var item=this.items.pop();item.removeMarker();item=null;}this.mm.clearOverlays();},updateRecents:function(){this.timelineEl.empty();var len=this.items.length;if(len){for(var i=len-1;i>=0;i--){var listItem=this.items[i].genListItem();this.timelineEl.append(listItem);}}else{this.timelineEl.append($(document.createElement("li")).html("この付近につぶやきはありませんでした"));}},destroy:function(){if(this.sto)window.clearTimeout(this.sto);this.removeMarkers();var len=this.events.length;for(var i=0;i<len;i++){MEvent.removeListener(this.events.pop());}}});LDMapTwitter.Item=function(mm,item,oTweet){this.mm=mm;this.item=item;this.oTweet=oTweet;this.events=[];this.init();};LDMapTwitter.Item.prototype=$.extend({},{config:{iconProps:{width:36,height:36,aLng:18,aLat:59},shadowProps:{image:"/img/icon_shadow.png",width:62,height:62,aLng:22,aLat:63}},init:function(){this.point=new MPoint(this.item.lng,this.item.lat);var shadowProps=this.config.shadowProps;var shadow={};shadow.image=shadowProps.image;shadow.width=shadowProps.width;shadow.height=shadowProps.height;shadow.iconAnchor=new MPoint(shadowProps.aLng,shadowProps.aLat);this.mShadow=new MMarker(this.point,shadow,false);shadow=null;var iconProps=this.config.iconProps;var icon=new MIcon();icon.image=this.item.profile_icon;icon.width=iconProps.width;icon.height=iconProps.height;icon.iconAnchor=new MPoint(iconProps.aLng,iconProps.aLat);this.mMarker=new MMarker(this.point,icon);var self=this;this.events.push(MEvent.addListener(this.mMarker,"click",function(mk){self.markerClick(mk);}));},recursiveEmpty:function(el){if(el.hasChildNodes()){var len=el.childNodes.length;while(len){if(el.firstChild.hasChildNodes())this.recursiveEmpty(el.firstChild);el.removeChild(el.firstChild);len--;}}},getMarker:function(){return this.mMarker;},getShadow:function(){return this.mShadow;},getPoint:function(){return this.point;},addMarker:function(){this.mm.addOverlay(this.getShadow());this.mm.addOverlay(this.getMarker());},removeMarker:function(){var shadow=this.getShadow();var marker=this.getMarker();this.mm.removeOverlay(shadow);this.mm.removeOverlay(marker);function recursiveRemove(el){if(el.hasChildNodes()){var len=el.childNodes.length;while(len){if(el.firstChild.hasChildNodes())recursiveRemove(el.firstChild);el.removeChild(el.firstChild);len--;}}el=null;}this.destroy();},markerClick:function(){var self=this;var item=this.item;var html=['<div class="balloon">','<p class="entry-text">',this.autoLinkHtml(item.text),'</p>','<p class="entry-name"><a href="',this.genUserLink(item.screen_name),'" target="_blank" title="',item.screen_name,'\'s tweets">',item.screen_name,'</a></p>','<p class="entry-datetime"><a href="',this.genPermalinkLink(item.screen_name,item.status_id),'" target="_blank" title="permalink in twitter">',item.datetime,'</a></p>',this.oTweet?'<p class="entry-reply"><a href="javascript:void(0);" title="reply to this tweet">reply</a></p>':"",'</div>'].join("");function onOpenFn(){if(self.oTweet){$(self.mm.infowindow.divArea).find(".entry-reply > a:first").bind("click",function(){self.oTweet.initReply({screen_name:self.item.screen_name,status_id:self.item.status_id});});}}function onCloseFn(){$(self.mm.infowindow.divArea).empty();}this.mm.openInfoWindowHtml(this.point,html,new MSize(10,50),onOpenFn,onCloseFn);},genListItem:function(){var item=this.item;var locationText=item.location?item.location+"付近":"";this.listItemEl=$(document.createElement("li")).html(['<div class="thumb"><a href="',this.genUserLink(item.screen_name),'" target="_blank" title="',item.screen_name,'\'s tweets"><img src="',item.profile_icon,'" width="48" height="48" /></a></div>','<div class="status-body">','<span class="entry-content">',item.text,'</span>',this.oTweet?'<span class="entry-reply"><a href="javascript:void(0);" title="reply to this tweet">reply</a></span>':'','<span class="entry-location">',locationText?locationText:"不明な場所",'</span>','<span class="screen-name"><a href="',this.genUserLink(item.screen_name),'" target="_blank" title="',item.screen_name,'\'s tweets">',item.screen_name,'</a></span>','<span class="entry-date"><a href="',this.genPermalinkLink(item.screen_name,item.status_id),'" target="_blank" title="permalink in twitter">',item.datetime,'</a></span>','</div>'].join(""));var self=this;this.listItemEl.bind("click",function(){self.mm.recenterOrPanToLatLng(self.getPoint());setTimeout(function(){self.markerClick();},700);});if(this.oTweet){this.listItemEl.find(".entry-reply > a:first").bind("click",function(){self.oTweet.initReply({screen_name:self.item.screen_name,status_id:self.item.status_id});});}return this.listItemEl;},genUserLink:function(screen_name){return["/tweets/",screen_name,"/"].join("");},genPermalinkLink:function(screen_name,status_id){return["http://twitter.com/",screen_name,"/status/",status_id].join("");},autoLinkHtml:function(html){return html.replace(/(https?:\/\/[^\s]+)/g,"<a href=\"$1\" target=\"_blank\">$1</a>");},destroy:function(){var len=this.events.length;this.listItemEl.remove();for(var i=0;i<len;i++){MEvent.removeListener(this.events.pop());}this.mShadow=null;this.mMarker=null;}});