// ==UserScript==
// @name           Yell 'Save to Placemarx' Script
// @namespace      hakon.gjm.info
// @description    adds a 'Save to Placemarx' link to Yell results
// @include        http://www.yell.com/*
// ==/UserScript==

(
  function() {

  var whitespace = '\t\n\r ';

  function removeWhitespace(s) {
    var r = '';
    var whiteCount = 0;
    for (var i=0;i<s.length;i++) {
       var c = s.charAt(i);
       var iswhite = whitespace.indexOf(c) != -1;
       if (!iswhite) {
         r += c;
         whiteCount = 0;
       }
       else {
         if (whiteCount == 0) {
            r += ' ';
         }
         whiteCount++;
       }
    }
    return r;
  }

  function addGlobalJS() {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    var js = 'function saveToPlacemarx(name,addr,tel) {\n';
    js += "  var url = 'http://spacemark.com/pweb/control?op=rsa&popup=true&lbl='+name+'&adr='+addr+'&tl='+tel;\n";
    js += "  var win = window.open(url,'placemarxWindow','height=600px,width=500px,toolbar=no,status=no,scrollbars=yes,resizable=yes');\n";
    js += '  win.focus();\n}';
    script.innerHTML = js;
    head.appendChild(script);
  }

  function trim(stringToTrim) {
	return stringToTrim.replace(/^\s+|\s+$/g,"");
  }

  function newLink(name,addr,tel) {
	var li = document.createElement('li');
  	var js = "javascript:saveToPlacemarx('"
                    +encodeURIComponent(name)+"','"
                    +encodeURIComponent(addr)+"','"
                    +encodeURIComponent(tel)+"');";
      var html = '&nbsp;&nbsp;<a href="'+js+'">Save to Spacemark</a>';
	li.innerHTML = html;
	return li;
  }

  function extractCompanyName(div) {
     var h2 = div.getElementsByTagName('h2')[0];
     var a = h2.getElementsByTagName('a')[0];
     if (a) {
        var s = a.innerHTML;
        var i = s.indexOf('<span');
	  if (i == -1) {
		return s;
	  }
	  else {
		return s.substring(0,i);
        }
     }
     else {
        return trim(h2.innerHTML);
     }
  }

  function removeComments(s) {
     while (true) {
		var i = s.indexOf('<!--');
     		if (i == -1) return s;
     		var j = s.indexOf('-->',i);
     		s = s.substring(0,i)+s.substring(j+3);
     	}
  }

  function removeNbsp(s) {
     while (true) {
		var i = s.indexOf('&nbsp;');
     		if (i == -1) return s;
     		s = s.substring(0,i)+' '+s.substring(i+6);
     	}
  }

  function containsTel(s) {
	 return (s.indexOf('Tel:')!=-1) || (s.indexOf('Freephone:')!=-1);
  }

  function extractAddressFromListingRow(div) {
     var s = trim(div.innerHTML);
     if (containsTel(s)) {
		return;
     }
     s = removeComments(s);
     s = removeWhitespace(s);
     return trim(s);
  }

  function extractTelFromListingRow(div) {
     var s = trim(div.innerHTML);
     if (!containsTel(s)) {
		return;
     }
     var strong = div.getElementsByTagName('strong')[0];
     var s = strong.innerHTML;
     s = removeNbsp(s);
     s = removeWhitespace(s);
     return trim(s);
  }

  function extractTel(div) {
     var tel = div.getElementsByTagName('div')[0];
     var strong = tel.getElementsByTagName('strong')[0];
     var s = strong.innerHTML;
     s = removeNbsp(s);
     s = removeWhitespace(s);
     return trim(s);
  }

  function processListing(listing) {
	var divs = listing.getElementsByTagName('div');
	var name = '';
	var addr = '';
      var tel = '';
     	for (var i = 0; i < divs.length; i++) {
            var cls = divs[i].getAttribute('class');
		if (cls == 'companyname') {
			name = extractCompanyName(divs[i]);
		}
		if (cls == 'fle-companyname') {
			name = extractCompanyName(divs[i]);
		}
		if (cls == 'listingRow') {
			var tmp = extractAddressFromListingRow(divs[i]);
			if (tmp) addr = tmp;
                  tmp = extractTelFromListingRow(divs[i]);
			if (tmp) tel = tmp;
		}
		if (cls == 'address') {
			addr = trim(removeWhitespace(divs[i].innerHTML));
		}
            if (cls == 'telephone') {
			tel = extractTel(divs[i]);
		}
        	if (cls == 'links') {
			var ul = divs[i].getElementsByTagName('ul')[0];
			var lis = ul.getElementsByTagName('li');
			var li = lis[lis.length-1];
    			li.parentNode.insertBefore(newLink(name,addr,tel), li.nextSibling);
		}
	}
  }

  function doMore() {
  	GM_log('document.location.href=' + document.location.href);
      addGlobalJS();
	var listings = document.evaluate(
    		"//div[@class='listing']",
    		document,
    		null,
    		XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    		null);
	for (var i = 0; i < listings.snapshotLength; i++) {
        	processListing( listings.snapshotItem(i) );
	}
	listings = document.evaluate(
    		"//div[@class='freelisting']",
    		document,
    		null,
    		XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    		null);
	for (var i = 0; i < listings.snapshotLength; i++) {
        	processListing( listings.snapshotItem(i) );
	}
}

doMore();
})();


