// ==UserScript==
// @name           HN Comment Embed
// @namespace      HNE
// @description    Embed HN metadata & comments in any webpage that has been submitted to Hacker News.
// @include	   *
// @exclude        http://news.ycombinator.com*
// @exclude	   http://www.google.com*
// @exclude	   http://maps.google.com*
// @exclude	   http://images.google.com*
// @exclude	   http://video.google.com*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// @require        http://courses.ischool.berkeley.edu/i290-4/f09/resources/gm_jq_xhr.js
// ==/UserScript==

if (window.top != window.self)  //don't run on frames or iframes. From http://stackoverflow.com/questions/1535404/how-to-exclude-iframe-in-greasemonkey
    return;

version = 4;

$(document).ready(function() {
  
  domainName = getDomainName();
  if (domainName) {
    searchYC(domainName, 1);
  }
  
});

function getDomainName() {

  specialDomains = ["blogspot", "wordpress", "livejournal", "blogs", "typepad",
                   "weebly", "posterous", "blog-city", "supersized", "dreamhosters",
                   "eurekster", "blogsome", "edogo", "blog", "com"];

  specialSuffixes = ["uk", "jp", "au", "in", "ph", "tr", "za", "my", "nz", "br",
                          "mx", "th", "sg", "id", "pk", "eg", "il", "at", "pl"];

  try {
    hostparts = window.location.hostname.split(".")
  }
  catch(e) { 
    return false; 
  }
  
  if (hostparts.length < 1) {
    return false;
  }
  
  if (hostparts.length == 1) {
    return hostparts[0];
  }
  
  suffix = hostparts[hostparts.length-1];
  domainName = hostparts[hostparts.length-2];
  fullDomain = domainName + "." + suffix;
  
  if ((hostparts.length > 2) && 
      ((jQuery.inArray(suffix, specialSuffixes) > -1) || (jQuery.inArray(domainName, specialDomains) > -1))) {
    fullDomain = hostparts[hostparts.length-3] + "." + fullDomain;
  }
  
  return fullDomain;
}

function searchYC(fullDomain, pageNum) {
  GM_log("Querying " + fullDomain + ", page " + pageNum);
  $.getJSON("http://json.searchyc.com/submissions/" + fullDomain + "?page=" + pageNum, 
    function(data) {

      if (data.length < 1) {
	GM_log("Entry not found.");
	return false;
      }
      
      var foundItem;
      
      data.forEach(function(item, i) {
	if (window.location.toString().indexOf(item.url) == 0) { // allows extra query params at end of location
	  foundItem = item;
	}
      });  
      
      if (foundItem) {
	createPanel("<b>" + foundItem.title + "</b> posted on " + foundItem.post_date, "http://news.ycombinator.com/item?id=" + foundItem.id);
	return;
      }
      
      searchYC(fullDomain, pageNum+1);
    });
}

function toggleElement(elemName) {
  element = $(elemName);
  if (element.style.display == 'none') {
    element.style.display = 'block';http://stackoverflow.com/questions/1535404/how-to-exclude-iframe-in-greasemonkey
    GM_log('return');
    return;
  }
  GM_log('no return');
  element.style.display = 'none';
}

function createPanel(panelTitle, HNurl) {
  
  GM_log("Displaying HN Item: " + panelTitle + " || URL: " + HNurl);
  
  if ($(".HNembed").length > 0) return; // avoid situations where multiple results might be triggered.
  
  GM_addStyle(<><![CDATA[
    #HNembed 	{ position: fixed;
                  clear: both; 
                  width: 100%; 
                  height: 0px; 
                  bottom: 0; 
                  border: none; 
                  padding:0px; 
                  margin:0px; 
                  text-align: center; 
                  color: #335500; 
                  background-color: #F6F6EF; 
                  z-index:999999; 
                  left:0; 
                  right:0; }
    #HNsite 	{ width: 100%;
		  height: 178px; }
    #HNheader 	{ background-color: #FF6600;
		  color: #222222;
		  font-family: Verdana;
		  font-size: 10pt;
		  margin-top: 2px;
		  cursor: pointer;
		  height: 20px; }
    #HNtab	{ background-color: #FF6600;
		  color: #222222;
		  font-family: Verdana;
		  font-size: 10pt;
		  margin-top: 5px;
		  cursor: pointer;
		  clear:both;
		  right:20px;;
		  bottom: 0;
		  position: fixed;
		  width: 9em; 
		  z-index:999; 
		  font-weight: bold;
		  height: 20px; 
		  border-width: 2px 2px 0;
		  border-style: solid;
		  border-color: #F6F6EF; }
    #HNupdate	{ color: yellow;
		  margin-left: 10px;
		  font-weight: bold; }
    #HNtitle	{ width: 100%; }
  ]]></>.toString());

  HNembed = $("<div />").attr({'id' : 'HNembed'});
  
  HNsite = $("<iframe />").attr({'id' : 'HNsite', 'src' : HNurl});
  
  HNheader = $("<div />").attr({'id' : 'HNheader'}).click(togglePanel);
  
  HNtitle = $("<span>" + panelTitle + "</span>").attr({'id' : 'HNtitle'});
  
  HNtab = $("<div>HackerNews</div>").attr({'id' : 'HNtab'}).click(togglePanel);
  
  HNupdate = $("<span>Update Script</span>").attr({'id' : 'HNupdate'}).hide().click(function() {
    window.location.href="http://share.shmichael.com/hn_comment_embed.user.js?" + (new Date()).getTime() + ".user.js";
  });
  
  HNheader.append(HNtitle);
  HNheader.append(HNupdate);
  
  HNembed.append(HNheader);
  HNembed.append(HNsite);
  HNembed.hide();
  
  $('body').append(HNtab);
  $('body').append(HNembed);
  
  checkUpdate(HNupdate);
}

function togglePanel() {
  HNembed.toggle();
  
  openPanel = HNembed.is(":visible");
  GM_log("Panel Toggle. Is it an openning? " + openPanel);
  
  if (openPanel) {
    HNtab.animate({height: 0}, 150, "linear", function() {
      HNembed.toggle();
      HNtab.toggle();
      HNembed.animate({height: "200px"},300,"linear");
    });
  }
  else {
    HNembed.animate({height: 0}, 300, "linear", function() {
      HNtab.toggle();
      HNembed.toggle();
      HNtab.animate({height: "17px"},150,"linear");
    });
  }
}

function checkUpdate(HNupdate) {
  GM_log('testing updates');
  GM_xmlhttpRequest({
    method: 'GET',
    url: 'http://share.shmichael.com/hn_comment_embed.version?'+(new Date()).getTime(),
    headers: {
    'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
    'Accept': 'application/atom+xml,application/xml,text/xml',
    'Cache-Control': 'no-cache',
    },
    onload: function(responseDetails) {
      GM_log('updated version ' + responseDetails.responseText);
      if (parseInt(responseDetails.responseText) > version) {
	HNupdate.show();
      }
    }
  });
}
