// ==UserScript==
// @name           Nice Link for Hatena Diary
// @namespace      http://nazo.yi.org/
// @author         nazoking <nazoking@gmail.com>
// @description    Make link tag from google result.
// @include        http://d.hatena.ne.jp/*
// @include        http://*.g.hatena.ne.jp/*
// ==/UserScript==

(function () {
  var Textarea = document.getElementById('textarea-edit');
  if(!Textarea) return;

  var ResultView =null;
  var setLink=function(r){
    setSelectedText( Textarea, '<a href="'+r.link+'" target="_blank">'+htmlEscape(r.word)+'</a>');
  }
  var init=function(){
    var toolbar = document.evaluate(
      'preceding-sibling::table[1]/tbody/tr/td[1]',
      Textarea, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE,
      null ).iterateNext();
    var n;
    toolbar.appendChild( n=createButton( 'Nice', getGoogleResults, setResultView ,unescape('%u9078%u629E%u3055%u308C%u305F%u6587%u5B57%u5217%u3092WEB%u3067%u691C%u7D22%u3057%u3001%u30EA%u30F3%u30AF%u3057%u307E%u3059') ) );//選択された文字列をWEBで検索し、リンクします
    n.style.marginRight='0';
    toolbar.appendChild( createButton( '1!', getGoogleResults, setResult1,unescape("WEB%u691C%u7D22%u3057%u4E00%u756A%u76EE%u306E%u30B5%u30A4%u30C8%u306B%u30EA%u30F3%u30AF%u3057%u307E%u3059") ) );// WEB検索し一番目のサイトにリンクします
    toolbar.appendChild( createButton( '?D',getHatenaResults, setResultView ,unescape('%u81EA%u5206%u306E%u30C0%u30A4%u30A2%u30EA%u30FC%u5185%u3092%u691C%u7D22%u3057%u3001%u30EA%u30F3%u30AF%u3057%u307E%u3059') ) );// 自分のダイアリー内を検索し、リンクします
    toolbar.appendChild( createButton( '?B',getHatenaBMResults, setResultView, unescape('%u81EA%u5206%u306E%u306F%u3066%u306A%u30D6%u30C3%u30AF%u30DE%u30FC%u30AF%u5185%u3092%u691C%u7D22%u3057%u3001%u30EA%u30F3%u30AF%u3057%u307E%u3059') ) ); //自分のはてなブックマーク内を検索し、リンクします
  };

  var initResultView=function(word){
    if( !ResultView ) ResultView = createResultView();
    ResultView.innerHTML = 'Searching ' + htmlEscape(word)+'...';
    ResultView.word = word;
    ResultView.show();
  }
  var createResultView=function(){
    ResultView = document.createElement( 'div' );
    ResultView.setAttribute('style','position:absolute; background:white; border:2px solid black;padding:2px 2px 2px 1em');
    ResultView.addEventListener( 'click', function(){ ResultView.unshow(); return false; }, false );
    ResultView.show=function(){ this.style.display='' };
    ResultView.unshow=function(){ this.style.display='none' };
    ResultView.setNotFound=function(word){
      this.innerHTML = '<b>Not Found</b><br />'+htmlEscape(word);
    }
    ResultView.maxlist = 10;
    ResultView.setListItem=function(r){
      var atitle = document.createElement( 'a' );
      atitle.innerHTML=r.title;
      atitle.title = r.summary
        atitle.setAttribute('style','color:green;text-decoration:underline;cursor:pointer;margin-right:5px;');
      atitle.addEventListener( 'click', function(){ r.word = r.title; setLink(r); } , false );
      this.appendChild( atitle );

      var alink = document.createElement( 'a' );
      alink.innerHTML = r.link;
      alink.title = r.summary;
      alink.addEventListener( 'click', function(){ setLink(r); }, false );
      alink.setAttribute('style','text-decoration:underline;cursor:pointer;margin-right:5px;');
      this.appendChild( alink );

      var ajump = document.createElement( 'a' );
      ajump.href= r.link;
      ajump.innerHTML = '&#10138;';
      ajump.target = '_blank';
        ajump.setAttribute('style','font-size:80%;background:#FFC;cursor:pointer;border:1px outset #CCC;');
      this.appendChild( ajump );

      this.appendChild( document.createElement( 'br' ) );
    }
    ResultView.setList=function(ret){
      this.ret = ret;
      if( !ret.length ) return this.setNotFound(ret.word);
      this.innerHTML = '<b>Select Link Site ('+htmlEscape(ret.word)+')</b><br>';
      for( var i=0; i<ret.length; i++ ){
        ret[i].word = ret.word;
        this.setListItem( ret[i] );
        if( i+1 >= this.maxlist )break;
      }
    }
    Textarea.parentNode.insertBefore( ResultView, Textarea );
    Textarea.addEventListener( 'focus', function(){ ResultView.unshow(); },false );
    return ResultView;
  }
  var createButton=function(label, searchfunc, viewfunc ,title){
    var btn = document.createElement( 'button' );
    btn.setAttribute('style','background:#D0DCFF; border:1px outset; height:19px; font-size:10pt; padding:0px; cursor:pointer; vertical-align:top;margin-right:5px;');
    btn.innerHTML = label;
    btn.addEventListener( 'click',function(e){
      e.preventDefault(); e.stopPropagation();
      var word = getWord();
      if(!word)return;
      if( ResultView && ResultView.lastsearch == searchfunc && ResultView.word == word ) return viewfunc( ResultView.ret );
      initResultView( word );
      ResultView.lastsearch = searchfunc;
      searchfunc( word, viewfunc );
    } , false );
    if( title ) btn.title = title;
    return btn;
  }
  var setResult1=function(ret){
    if( !ret || !ret.length ) return ResultView.setNotFound(ret.word);
    ResultView.unshow();
    ret[0].word = ret.word;
    setLink( ret[0] );
  }
  var setResultView=function(ret){
    ResultView.show();
    ResultView.setList(ret);
  }
  var getWord=function(){
    return removeTags(getSerectedText( Textarea )) || prompt('Site Title');
  }



  var getGoogleResults=function(word,onloaded){
    var url = 'http://www.google.com/search?start=0&ie=utf-8&oe=utf-8&q='+encodeURI(word);
    GM_xmlhttpRequest({
      method:"GET",
      headers:{"Cookie":"-"},
      url:url,
      onload:function(details) {
        var b = details.responseText;
        b = b.substr(b.indexOf('<!--a'));
        var as = b.split( '<!--m');
        var ret = new Array;
        ret.word = word;
        if( !as ) return onloaded(ret);
        for( var i=0; i<as.length; i++ ){
          as[i].match(/\<a([^<]+)href="(.*?)".*?>(.*?)\<\/a\>/);
          var title = RegExp.$3;
          var link = RegExp.$2;
          var summary = RegExp.rightContext;
          summary = removeTags(summary);
          title = removeTags(title);
          if( title=='')continue;
          ret.push( {link:link, title:title, summary:summary } );
        }
        return onloaded(ret);
      }
    } );
  }
  var getHatenaResults=function(word,onloaded){
    var u = location.href.split('/');
    var baseurl = u.slice(0,4).join('/');
    var host = u.slice(0,3).join('/');
    var url = baseurl +'/searchdiary?word='+encodeURI(word);
    GM_xmlhttpRequest({
      method:"GET",
      url:url,
      onload:function(details) {
        var b = details.responseText;
        b = b.substr(b.indexOf('<div class="day">'));
        var as = b.match( /\t\t\<div class="section"\>(.|\n)*?\n\t\t\<\/div\>/g );
        var ret = new Array;
        ret.word = word;
        if( !as ) return onloaded(ret);
        for( var i=0; i<as.length; i++ ){
          if( as[i].indexOf('<span class="highlight">')!=-1 || removeTags(as[i]).indexOf( word )!=-1 ){
            as[i].match( /\<h3\><a href="(.*?)" name="(.*?)">.*?\<\/a\>(.*?)\<\/h3\>/ );
            var title = RegExp.$3;
            var link =  host + RegExp.$1;
            var summary = removeCtrls(removeTags(RegExp.rightContext)).substr(0,100);
            ret.push( { title:removeTags( title ), link:link, summary:summary } );
          }
        }
        return onloaded(ret);
      }
    } );
  }

  var getHatenaBMResults=function(word,onloaded){
    var u = location.href.split('/');
    u[2]='b.hatena.ne.jp';
    var baseurl = u.slice(0,4).join('/');
    var url = baseurl +'/rss?word='+encodeURI(word);
    GM_xmlhttpRequest({
      method:"GET",
      url:url,
      onload:function(details) {
        var b = details.responseText;
        var as = b.split( '<item rdf:about=');
        as.shift();
        alert(as[0]);
        var ret = new Array;
        ret.word = word;
        if( !as || !as.length ) return onloaded(ret);
        for( var i=0; i<as.length; i++ ){
          ret.push( {
          link:as[i].match( /\<link\>(.*?)\</ )?htmlUnEscape( RegExp.$1 ):'',
          title:as[i].match( /\<title\>(.*?)\</ )?htmlUnEscape( RegExp.$1 ):'',
          summary: ( as[i].match( /\<description\>(.*?)\</ ) )?
            htmlUnEscape( removeTags( RegExp.$1 ) ):''
            } );
        }
        return onloaded(ret);
      }
    } );
  }


  var htmlEscape=function(word){
    return word.replace(/&/g,'&amp;').replace(/\</g,'&lt;').replace(/\>/g,'&gt;');
  }
  var htmlUnEscape=function(word){
    return word.replace(/\&gt\;/g,'<').replace(/\&gt\;/g,'>').replace(/\&amp\;/g,'&');
  }
  var removeTags=function(word){
    return word.replace(/\<.*?\>/g,'' );
  }
  var removeCtrls=function(word){
    return word.replace(/[\x00-\x20]/g,' ' ).replace(/ {2,}/,' ');
  }
  var getSerectedText=function(e){
    if (document.selection) return document.selection.createRange().text;
    var length = e.textLength;
    var start = e.selectionStart;
    var end = e.selectionEnd;
    if (end == 1 || end == 2) end = length;
    return e.value.substring(start, end).replace(/(.*)\n+$/,"$1");
  }
  var setSelectedText=function(e,v){
    if (document.selection) document.selection.createRange().text = v;
    var scrollTop=e.scrollTop;
    var length = e.textLength;
    var start = e.selectionStart;
    var end = e.selectionEnd;
    if (end == 1 || end == 2) end = length;
    e.value = e.value.substring(0, start) + v + e.value.substr(end, length);
    e.setSelectionRange(start, start + v.length);
    e.focus();
    e.scrollTop=scrollTop;
  }
  init();
})();