/*
 * Wiki Summary Box 0.1.2
 * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
 * MIT License [http://www.opensource.org/licenses/mit-license.php]
 */


var __WikiCallbacks = {};
var __wikiInit;

(function(){

  var showDelay = 200;
  var hideDelay = 300;

  var footerGFDLText = "(available under the <a href=\"http://en.wikipedia.org/wiki/Wikipedia:Text_of_the_GNU_Free_Documentation_License\" target=\"_blank\">GNU Free Documentation License</a>)."

  // List of wiki sites below, properties are:
  // basehost : base host of the wiki (ie.
  // lang : if true, the "http://[langcode].[basehost]/" format is used, if false we simply use basehost
  // apipath : the relative path of api.php on the wiki host
  // name : The name that will be displayed in the footer
  // GFDL : if true, a GNU Free Documentation License notice will be shown in the footer
  // fullarticle : use full article, ie. don't just pick out the first paragraphs

  var wikiSites = [
    {basehost : "wikipedia.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikipedia", licensetext : footerGFDLText},
    {basehost : "wikiquote.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikiquote", licensetext : footerGFDLText, fullarticle : false},
    {basehost : "species.wikimedia.org", lang : false, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikispecies", licensetext : footerGFDLText, fullarticle : true, css : "wikispecies"},
    {basehost : "wikinews.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikinews", licensetext : footerGFDLText, fullarticle : false},
    {basehost : "wikisource.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikisource", licensetext : footerGFDLText, fullarticle : false},
    {basehost : "wikibooks.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikibooks", licensetext : footerGFDLText, fullarticle : false},
    {basehost : "wiktionary.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wiktionary", licensetext : footerGFDLText, fullarticle : true, css : "wiktionary"},
    {basehost : "wikiversity.org", lang : true, apipath : "/w/api.php", articlepath : "/wiki/", name : "Wikiversity", licensetext : footerGFDLText, fullarticle : false}
  ]

  var loaderText = "Loading...";

  var footerText = "Summary via <a href=\"[wiki_url]\" target=\"_blank\">[wiki_name]</a> "
  //var footerArticleLink = "Read full article <a href=\"[article_url]\" target=\"_blank\">here</a>";
  var footerArticleLink = "<a href=\"[article_url]\" target=\"_blank\">Läs&nbsp;mer&nbsp;&nbsp;<img src='/site/falbygdens/images/static/readmore.gif' alt='' border='0' /></a>";

  var callCount = 0;

  var wikiResults = [];

  var visiWiki = null;

  var bodyHeight = 0;
  var bodyWidth = 0;

  var showTimer = 0;
  var hideTimer = 0;

  var dc = function(tag, className) {
    var el = document.createElement(tag);
    if (className)
      el.className = className;
    return el;
  };

  function sendRequest(site, keyword, lang, callback) {
    if (wikiResults[site.basehost+"_"+lang+"_"+keyword]) {
      if (callback)
        callback(wikiResults[site.basehost+"_"+lang+"_"+keyword]);
      return;
    }

    callCount++;

    lang = lang || "en";

    var url = "http://" + (site.lang ? (lang+"."+site.basehost) : site.basehost) + site.apipath + "?action=parse&prop=text&format=json&callback=__WikiCallbacks.fn_" + callCount + "&page=" + keyword;

    var script = document.createElement("script");

    __WikiCallbacks["fn_" + callCount] = function(res) {
      document.body.removeChild(script);

      if (!res.failed) {
        wikiResults[site.basehost+"_"+lang+"_"+keyword] = res;
      }
      if (callback)
        callback(res);
    };

    script.setAttribute("type", "text/javascript");
    document.body.appendChild(script);

    script.src = url
  }

  function addEvent(el, event, handler) {
    if (el.addEventListener)
      el.addEventListener(event, handler, false);
    else if (el.attachEvent)
      el.attachEvent("on" + event, handler);
  }

  function makeWikiLink(marker, site, keyword, lang) {
    if (site && keyword) {
      addEvent(marker, "mouseover",
        function(e) {
          e = e || window.event;
          if (!marker.wiki || marker.wiki != visiWiki) {
            if (visiWiki) {
              hideWiki(visiWiki);
            }

            if (showTimer) {
              clearTimeout(showTimer);
            }
            showTimer = setTimeout(
              function() {
                marker.wiki = showWiki(marker, site, keyword, lang, e||window.event);
              },showDelay
            );
          }
        }
      );
      addEvent(marker, "mouseout",
        function() {
          if (showTimer) {
            clearTimeout(showTimer);
            showTimer = 0;
          }
        }
      );
    }
  }

  function getElementPos(el) {
    var x = 0;
    var y = 0;

    while (el && el.nodeName != "BODY") {
      x += el.offsetLeft;
      y += el.offsetTop;
      el = el.offsetParent;
    }

    return {
      x : x,
      y : y
    }
  }

  function cleanLinks(node, baseurl) {
    if (!node.hasChildNodes) return;
    for (var i=0;i<node.childNodes.length;i++) {
      var child = node.childNodes[i];
      if (child.tagName == "A") {
        if (child.getAttribute("tmphref") && child.getAttribute("tmphref").substring(0,1) == "/") {
          child.setAttribute("href", baseurl + child.getAttribute("tmphref"));
          child.setAttribute("target", "_blank");
        }
      } else {
        if (child.hasChildNodes) {
          cleanLinks(child, baseurl);
        }
      }
    }
    return node;
  }

  function showWiki(marker, site, keyword, lang, event) {
    if (visiWiki) {
      hideWiki(visiWiki);
    }

    if (showTimer) {
      clearTimeout(showTimer);
      showTimer = 0;
    }
    bodyHeight = document.body.clientHeight;
    bodyWidth = document.body.scrollWidth;

    var ctr = dc("div", "wiki-summary-container");
    if (site.css)
      ctr.className += " wiki-summary-" + site.css;
    var header = dc("div", "wiki-summary-header");
    var content_outer = dc("div", "wiki-summary-content");
    var content = dc("div", "wiki-summary-content-inner");
    content_outer.appendChild(content);
    var footer = dc("div", "wiki-summary-footer");

    ctr.appendChild(header);
    ctr.appendChild(content_outer);
    ctr.appendChild(footer);

    var pos = getElementPos(marker);

    ctr.style.position = "absolute";
    ctr.style.left = pos.x+"px";
    ctr.style.top = pos.y+"px";

    ctr.style.display = "none";

    document.body.appendChild(ctr);
    ctr.marker = marker;

    var loader = dc("div", "wiki-summary-loader");
    loader.innerHTML = loaderText;
    content.appendChild(loader);

    sendRequest(site, keyword, lang,
      function(res) {
        var baseurl = "http://"+ (site.lang ? (lang+"."+site.basehost) : site.basehost);

        //header.innerHTML = decodeURIComponent(keyword).replace(/_/g, " ");
        header.innerHTML = "Från Wikipedia:";

        var rawContent = document.createElement("div");

        var rawHTML = res.parse.text["*"];

        // remove images, we don't want to leech off of the Wiki servers
        rawHTML = rawHTML.replace(/\<img\ .*?\>/g, "").replace("REDIRECT", "Omdirigera till&nbsp;");


        // Argh, this is no fun. IE won't let us get the relative paths to other Wiki pages so we can't distinguish them from other links.
        // This is all I could think of so far: replace the href attribute with another temporary attribute and then switch it back later when
        // we're walking the DOM tree of the Wiki content.
        rawContent.innerHTML = rawHTML.replace(/<a\ href\=\"/g, "<a tmphref=\"");

        var sumFragment = document.createDocumentFragment();

        if (site.fullarticle) {
          sumFragment.appendChild(cleanLinks(rawContent, baseurl));
        } else {
          var parNodes = [];
          for (var i=0;i<rawContent.childNodes.length;i++) {
            var node = rawContent.childNodes[i];
            if (node.tagName == "P") {
              var text = node.textContent || node.innerHTML || "";
              if (text.replace(/^\s*([\S\s]*?)\s*$/, '$1') == "") {
                                  continue;
                              }
              parNodes.push([node, rawContent]);
            }
            if (node.tagName == "UL" || node.tagName == "OL") {
              for (var j=0;j<node.childNodes.length;j++) {
                if (node.childNodes[j].tagName == "LI")
                  cleanLinks(node.childNodes[j], baseurl)
              }
              parNodes.push([node, rawContent]);
            }
            if (node.tagName == "H1" || node.tagName == "H2") {
              break;
            }
          }
          for (var i=0;i<parNodes.length;i++) {
            if (parNodes[i][0] && parNodes[i][1]) {
              parNodes[i][1].removeChild(parNodes[i][0]);
              sumFragment.appendChild(cleanLinks(parNodes[i][0], baseurl));
            }
          }
        }

        content.innerHTML = "";
        content.appendChild(sumFragment);

        //var fullFooterText = footerText + site.licensetext + "<br>" + footerArticleLink;
        var fullFooterText = footerArticleLink;

        footer.innerHTML =
          fullFooterText.replace(
            /\[article_url\]/g,
            "http://" + (site.lang ? (lang+"."+site.basehost) : site.basehost) + site.articlepath + keyword
          ).replace(
            /\[wiki_name\]/g, site.name
          ).replace(
            /\[wiki_url\]/g,
            "http://" + (site.lang ? (lang+"."+site.basehost) : site.basehost) + "/"
          );
      }
    );

    addEvent(ctr, "mouseout",
      function(e) {
        var relTarget = (e.relatedTarget) ? e.relatedTarget : e.toElement;
        while (relTarget && relTarget != ctr && relTarget.nodeName != "BODY")
          relTarget = relTarget.parentNode
        if (relTarget == ctr) return;

        if (marker.wiki) {
          if (hideTimer) {
            clearTimeout(hideTimer);
          }
          hideTimer = setTimeout(
            function() {
              hideWiki(marker.wiki);
            }, hideDelay
          );
        }
      }
    );
    addEvent(ctr, "mouseover",
      function() {
        if (hideTimer) {
          clearTimeout(hideTimer);
          hideTimer = 0;
        }
      }
    );

    visiWiki = ctr;

    setTimeout(function() {
      ctr.style.display = "block";

      var x = Math.max(0, Math.min(bodyWidth - ctr.offsetWidth, pos.x));
      ctr.style.left = x+"px";

      var y = Math.max(0, Math.min(bodyHeight - ctr.offsetHeight, pos.y));
      ctr.style.top = y+"px";


    },1);

    return ctr;
  }

  function hideWiki(ctr) {
    try {
      document.body.removeChild(ctr);
      ctr.marker.wiki = null;
    } catch(e) {}
    visiWiki = null;
  }

  var initDone = false;

  function init(as) {
//    if (initDone) return;

    initDone = true;
//    var as = document.getElementsByTagName("a");
    var patterns = [];
    for (var j=0;j<wikiSites.length;j++) {
      patterns[j] = new RegExp("http:\\/\\/" + (wikiSites[j].lang ? "([^/]+)?\\." : "") + wikiSites[j].basehost.replace(/\./g, "\\.") + "\\" + wikiSites[j].articlepath + "([^/]+)");
    }
    for (var i=0;i<as.length;i++) {
      if (as[i].getAttribute("href")) {
        for (var j=0;j<wikiSites.length;j++) {
          var pattern = patterns[j];
          var href = as[i].getAttribute("href").match(pattern);

          if (wikiSites[j].lang) {
            if (href && href.length == 3) {
              makeWikiLink(as[i], wikiSites[j], href[2], href[1]);
              break;
            }
          } else {
            if (href && href.length == 2) {
              makeWikiLink(as[i], wikiSites[j], href[1], href[0]);
              break;
            }
          }
        }
      }
    }
  }


  function onready(handler, param) {
    var handlerDone = false;
    var execHandler = function() {
      if (!handlerDone) {
        handlerDone = true;
        handler(param);
      }
    }
    document.write("<"+"script defer src=\"//:\" id=\"__onload_ie_sumbox__\"></"+"script>");
    var script = document.getElementById("__onload_ie_sumbox__");
    script.onreadystatechange = function() {
      if (script.readyState == "complete") {
        script.parentNode.removeChild(script);
        execHandler();
      }
    }
    if (document.addEventListener)
      document.addEventListener("DOMContentLoaded", execHandler, false);
    addEvent(window, "load", execHandler);
  }

  __wikiInit = init;

  onready(init, document.getElementsByTagName("a"));

})();
