/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
(function (global) {
// Used for managing the DOM for infobar part of the page
'use strict';

var g = global;
global.initMap = function initMap(mapcanvas, mapDocument) {
  var onDragMap = false;
  var mapDragStart = {};

  var oriMapViewBox = mapcanvas.getAttribute('viewBox');

  // update info when clicking on a node in the graph visualization
  document.querySelector('#content').addEventListener('click', function (event) {
    // click could happen on .node or an element inside of .node
    if (event.target.mozMatchesSelector('.node, .node *')) {
      var node = event.target;
      var name;
      if (node.mozMatchesSelector('[type=checkbox], td [type=checkbox]')) return;
      while (node.mozMatchesSelector('.node *')) {
        node = node.parentElement;
      }
      if (node.dataset && node.dataset.isBlocked) {
        return;
      }
      name = node.getAttribute("data-name");
      selectedNodeEffect(name);
      updateInfo(name);
    }
  }, false);

  document.querySelector(".connections-list ul").addEventListener("click", function (event) {
    var name = event.target.textContent;
    var previouslySelected = document.querySelector(".connections-list ul li[data-selected]");
    if (previouslySelected) {
      document.querySelector(".connections-list ul li[data-selected]").removeAttribute("data-selected");
    }
    event.target.setAttribute("data-selected", true);
    resetAllGlow("connected");
    connectedNodeEffect(name);
  });
  var currentRequest;
  // get server info from http://freegeoip.net
  function getServerInfo(nodeName, callback) {
    var info = parseUri(nodeName); // uses Steven Levithan's parseUri 1.2.2
    var jsonURL = "http://freegeoip.net/json/" + info.host;
    var request = new XMLHttpRequest();
    currentRequest = info.host;
    request.open("GET", jsonURL, true);
    request.onload = function () {
      if (currentRequest === info.host) {
        callback((request.status === 200) ? JSON.parse(request.responseText) : false);
      }
    };
    request.send(null);
  }

  // reset map
  function resetMap() {
    var preHighlight = mapDocument.querySelectorAll(".highlight-country");
    if (preHighlight) {
      toArray(preHighlight).forEach(function (element) {
        element.classList.remove("highlight-country");
      });
    }
    mapcanvas.setAttribute("viewBox", oriMapViewBox);
  }

  // update map
  function updateMap(countryCode) {
    var countryOnMap = mapcanvas.getElementById(countryCode);
    if (!countryOnMap) {
      console.log('no country found for country code "%s"', countryCode);
      return;
    }
    countryOnMap.classList.add('highlight-country');

    // position the highlighted country in center
    var svgViewBox = mapcanvas.getAttribute("viewBox").split(" ");
    var worldDimen = mapcanvas.getBoundingClientRect();
    var countryDimen = countryOnMap.getBoundingClientRect();

    var ratio = svgViewBox[2] / worldDimen.width;
    var worldCenter = {
      x: 0.5 * worldDimen.width + worldDimen.left,
      y: 0.5 * worldDimen.height + worldDimen.top
    };
    var countryCenter = {
      x: 0.5 * countryDimen.width + countryDimen.left,
      y: 0.5 * countryDimen.height + countryDimen.top
    };

    var newViewBox = {
      x: (countryCenter.x - worldCenter.x) * ratio,
      y: (countryCenter.y - worldCenter.y) * ratio,
      w: svgViewBox[2],
      h: svgViewBox[3]
    };
    setZoom(newViewBox, mapcanvas);
  }

  document.querySelector(".pref-action .block").addEventListener('click', function (evt) {
    var site = this.dataset.siteName;
    confirmBlockSitesDialog(function (confirmed) {
      if (confirmed) {
        userSettings[site] = 'block';
        global.self.port.emit('updateBlocklist', site, true);
        showSitePref(site);
      }
    });
    evt.preventDefault();
  });

  document.querySelector(".pref-action .unblock").addEventListener('click', function (evt) {
    var site = this.dataset.siteName;
    userSettings[site] = '';
    global.self.port.emit('updateBlocklist', site, false);
    showSitePref(site);
    evt.preventDefault();
  });

  // updates info on the info panel
  function updateInfo(nodeName) {

    // get server info and then update content on the info panel
    getServerInfo(nodeName, function (data) {
      var nodeList = aggregate.nodeForKey(nodeName);
      showFavIcon(nodeName);
      showFirstAndLastAccess(nodeList[nodeName]);
      showSitePref(nodeName);
      showConnectionsList(nodeName, nodeList);
      // display site profile in Info Panel 
      showSiteProfile();
      // update map after we have loaded the SVG
      showServerLocation(data);
    });

  }

  function showFavIcon(nodeName) {
    var title = document.querySelector('.holder .title');
    while (title.childNodes.length) {
      title.removeChild(title.firstChild);
    }
    title.appendChild(elem(nodeName, {
      src: 'http://' + nodeName + '/favicon.ico',
      'class': 'favicon'
    }));
    title.appendChild(document.createTextNode(nodeName));
  }

  function showFirstAndLastAccess(site) {
    var firstAccess = formattedDate(site.firstAccess, "long");
    var lastAccess = formattedDate(site.lastAccess, "long");
    document.querySelector('.info-first-access').textContent = firstAccess;
    document.querySelector('.info-last-access').textContent = lastAccess;
  }

  function showSitePref(nodeName) {
    var prefTag = document.querySelector(".pref-tag");
    var blockButton = document.querySelector(".pref-action .block");
    var unblockButton = document.querySelector(".pref-action .unblock");
    var sitePref = userSettings[nodeName];
    if (sitePref) {
      prefTag.querySelector("img").src = "icons/lightbeam_icon_" + sitePref + ".png";
      prefTag.querySelector("span").className = "";
      prefTag.querySelector("span").classList.add(sitePref + "-text");
      prefTag.querySelector("span").textContent = (sitePref == "hide") ? "hidden" : sitePref + "ed";
      prefTag.classList.remove("hidden");
      if (sitePref == "block") {
        unblockButton.classList.remove("hidden");
        blockButton.classList.add("hidden");
      } else {
        unblockButton.classList.add("hidden");
        blockButton.classList.remove("hidden");
      }
    } else {
      prefTag.classList.add("hidden");
      unblockButton.classList.add("hidden");
      blockButton.classList.remove("hidden");
    }
    unblockButton.dataset.siteName = nodeName;
    blockButton.dataset.siteName = nodeName;
  }

  function showConnectionsList(nodeName, nodeList) {
    var htmlList = elem('ul');
    var numConnectedSites = 0;
    for (var key in nodeList) {
      if (key != nodeName) { // connected site
        htmlList.appendChild(elem('li', {}, key));
        numConnectedSites++;
      }
    }
    document.querySelector(".num-connected-sites").textContent = numConnectedSites + " " + singularOrPluralNoun(numConnectedSites, "site");

    var list = document.querySelector(".connections-list");
    list.removeChild(list.querySelector('ul'));
    list.appendChild(htmlList);
  }

  function showServerLocation(serverData) {
    if (!serverData || serverData.country_name === "Reserved") {
      document.querySelector("#country").textContent = "(Unable to find server location)";
      resetMap();
    } else {
      // update country info only when it is different from the current one
      if (serverData.country_name !== document.querySelector("#country").textContent) {
        resetMap();
        document.querySelector("#country").textContent = serverData.country_name;
        updateMap(serverData.country_code.toLowerCase());
      }
    }
  }

  function showSiteProfile() {
    var siteProfileTab = document.querySelector(".toggle-site-profile");
    var contentToBeShown = document.querySelector(".site-profile-content");
    var infoPanelOpen = document.querySelector("#content").classList.contains("showinfo");
    var siteProfileTabActive = document.querySelector(".toggle-site-profile").classList.contains("active");
    if (!infoPanelOpen) {
      document.querySelector("#content").classList.add("showinfo");
      showInfoPanelTab(siteProfileTab, contentToBeShown);
    }

    if (infoPanelOpen) {
      if (!siteProfileTabActive) {
        // make the previously active tab inactive
        deactivatePreviouslyActiveTab();
        showInfoPanelTab(siteProfileTab, contentToBeShown);
      }
    }

    document.querySelector(".toggle-site-profile").classList.remove("disabled");
  }


  /* mapcanvas events */
  mapcanvas.addEventListener("mousedown", function (event) {
    onDragMap = true;
    mapDragStart.x = event.clientX;
    mapDragStart.y = event.clientY;
  }, false);

  mapcanvas.addEventListener("mousemove", function (event) {
    if (onDragMap) {
      mapcanvas.style.cursor = "-moz-grab";
      var offsetX = (Math.ceil(event.clientX) - mapDragStart.x);
      var offsetY = (Math.ceil(event.clientY) - mapDragStart.y);
      var box = getZoom(mapcanvas);
      box.x -= (offsetX * 10);
      box.y -= (offsetY * 10);
      mapDragStart.x += offsetX;
      mapDragStart.y += offsetY;
      setZoom(box, mapcanvas);
    }

  }, false);

  mapcanvas.addEventListener("mouseup", function (event) {
    onDragMap = false;
    mapcanvas.style.cursor = "default";
  }, false);

  mapcanvas.addEventListener("mouseleave", function (event) {
    onDragMap = false;
    mapcanvas.style.cursor = "default";
  }, false);

  mapDocument.addEventListener("wheel", function (event) {
    if (event.target.mozMatchesSelector(".mapcanvas, .mapcanvas *")) {
      zoomWithinLimit(event, mapcanvas, mapZoomInLimit, mapZoomOutLimit);
    }
  }, false);


};


/* Info Panel Tabs ======================================== */


/* Toggle Site Profile */
document.querySelector(".toggle-site-profile").addEventListener("click", function () {
  var tabClicked = document.querySelector(".toggle-site-profile");
  if (!tabClicked.classList.contains("disabled")) {
    var contentToBeShown = document.querySelector(".site-profile-content");
    toggleInfoPanelTab(tabClicked, contentToBeShown);
  }
});

/* Toggle About */
document.querySelector(".toggle-about").addEventListener("click", function () {
  var tabClicked = document.querySelector(".toggle-about");
  var contentToBeShown = document.querySelector(".about-content");
  toggleInfoPanelTab(tabClicked, contentToBeShown);
});

/* Toggle Help Sections */
global.helpOnClick = function helpOnClick() {
  var tabClicked = document.querySelector(".toggle-help");
  var contentToBeShown = document.querySelector(".help-content ." + global.currentVisualization.name + "-view-help");
  toggleInfoPanelTab(tabClicked, contentToBeShown);
};

document.querySelector(".toggle-help").addEventListener("click", helpOnClick);


function toggleInfoPanelTab(tabClicked, contentToBeShown) {
  var infoPanelOpen = document.querySelector("#content").classList.contains("showinfo");
  var isActiveTab = tabClicked.classList.contains("active");
  if (infoPanelOpen) {
    if (isActiveTab) { // collapse info panel
      document.querySelector("#content").classList.remove("showinfo");
      tabClicked.classList.remove("active");
      tabClicked.querySelector("img").classList.remove("hidden");
      tabClicked.querySelector("i").classList.add("hidden");
    } else {
      // make the previously active tab inactive
      deactivatePreviouslyActiveTab();
      // make the selected tab active
      showInfoPanelTab(tabClicked, contentToBeShown);
    }
  } else {
    // open the info panel and make the selected tab active
    document.querySelector("#content").classList.add("showinfo");
    showInfoPanelTab(tabClicked, contentToBeShown);
  }
}


function deactivatePreviouslyActiveTab() {
  var previouslyActiveTab = document.querySelector(".info-panel-controls ul li.active");
  if (previouslyActiveTab) {
    previouslyActiveTab.classList.remove("active");
    previouslyActiveTab.querySelector("img").classList.remove("hidden");
    previouslyActiveTab.querySelector("i").classList.add("hidden");
  }
}


// make the selected tab active
function showInfoPanelTab(tabClicked, contentToBeShown) {
  tabClicked.classList.add("active");
  tabClicked.querySelector("img").classList.add("hidden");
  tabClicked.querySelector("i").classList.remove("hidden");
  hideAllInfoPanelContentExcept(contentToBeShown);
}


function hideAllInfoPanelContentExcept(elmToShow) {
  document.querySelector(".site-profile-content").classList.add("hidden");
  document.querySelector(".help-content .graph-view-help").classList.add("hidden");
  document.querySelector(".help-content .list-view-help").classList.add("hidden");
  document.querySelector(".about-content").classList.add("hidden");
  if (elmToShow) {
    elmToShow.classList.remove("hidden");
  }
}

})(this);
