// localize description on startup :o)
window.addEventListener("load",init,false);


// Global prefs var
var lcPref = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);


function init () {
    var linkcheckerLocalizationPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("extensions.{49f3fc85-dcfe-4e42-9301-226ebe658509}.");
    var str = Components.classes[ "@mozilla.org/supports-string;1" ].createInstance( Components.interfaces.nsISupportsString );
    str.data = document.getElementById("linkchecker-strings").getString("LinkcheckerDescription");
    linkcheckerLocalizationPrefs.setComplexValue( "description", Components.interfaces.nsISupportsString, str );
   
    document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", lcSetContextVis, false);
    document.getElementById("contentAreaContextMenu").addEventListener("popuphidden", lcSetContextVis, false);
}


var linkCheckerStatus = 0;
var count = 0;
var pageLinks = new Array();
var pageLinkCount = null;
var linkList = new Array();
var timeOutInterval = null;
var timeOutSet = 0;


function lcSetContextVis() {
    var sel = window._content.getSelection();
    if(sel.rangeCount > 0 && sel.toString().length > 0) {
        var checkSome = document.getElementById("menu_lcchecksome");
        var checkSomeStatus = checkSome.getAttribute("disabled");
        if(checkSomeStatus == "false")
            setTo = "true";
        else
            setTo = "false";

        checkSome.setAttribute("disabled", setTo);
    }
}

function toggleLinkChecker(whichLinks) {
	linkCheckerToolbarButton = document.getElementById("LinkCheckerButton");
	
	if(linkCheckerStatus == 0) { // run linkchecker
		getLinks(whichLinks);
		if(pageLinks.length > 0) { // if the page has links
			getLinkList();
			
			linkCheckerToolbarButton.setAttribute("checked", "true");
			linkCheckerToggleTo = 1;
		} else {
			linkCheckerToggleTo = 0;
		}
	}
	else if(linkCheckerStatus == 1) { // stop linkchecker
		stopLinkChecker();
		
		linkCheckerToolbarButton.setAttribute("checked", "false");
		linkCheckerToggleTo = 0;
	}
	
	linkCheckerStatus = linkCheckerToggleTo;
}

function getLinks(whichLinks) {
    var x = window._content;

    switch(whichLinks) {
        case "all":
            var theseLinks = x.document.getElementsByTagName("a");
            break;

        case "selected":
			var allLinks = x.document.getElementsByTagName("a");

            var sel = window._content.getSelection();
            var selObj = sel.getRangeAt(0);
			var selLinks = new Array();

			for(i=0; i<allLinks.length; i++) {
				var intersectChk = selObj.intersectsNode(allLinks[i]);
				if(intersectChk)
					selLinks[selLinks.length] = allLinks[i];
			}

			// reset selection state
			sel.removeRange(selObj);
			document.getElementById("menu_lcchecksome").setAttribute("disabled", "true");
            
            var theseLinks = selLinks;
            break;
    }
    
    pageLinks = theseLinks;
}

function getLinkList() {
  count = 0;

  var linkTypeList = new Array(0,0,0,0); // 0 - relative, 1 - absolute, 2 - email, 3 - secure
  var localLinkList = new Array();
  var x = window._content;
  // var x = window.frames['mybrowser'];
  // pageLinks = x.document.getElementsByTagName("a");

  for(i=0; i<pageLinks.length; i++) {
    var pageLink = pageLinks[i];
    var linkHref = pageLink.getAttribute("href");

    // check for no HREF (e.g. anchor link)
    if(linkHref != null) {
      if(linkHref.substr(0,5) != "http:" && linkHref.substr(0,6) != "https:" && linkHref.substr(0,4) != "ftp:") {

        // check for email links
        if(linkHref.substr(0,7) == "mailto:") { linkHref = null; linkTypeList[2]++; }
        else if(linkHref.substr(0,11) == "javascript:" || linkHref.substr(0,7) == "telnet:" || linkHref.substr(0,5) == "news:" || linkHref.substr(0,5) == "file:" || linkHref.substr(0,4) == "irc:") { linkHref = null; }

        // check for relative site links
        else { linkHref = pageLink.href; linkTypeList[0]++; }
      }
      else { linkTypeList[1]++; }
    }

    // add links to array of page links
    localLinkList[localLinkList.length] = linkHref;
  }

  linkList = localLinkList;

  // alert("pageLinks: " + pageLinks.length + "\nlinkList: " + linkList.length);
  var linkCount = pageLinks.length;
  pageLinkCount = linkCount;
  // alert("Relative Links: " + linkTypeList[0] + "\n" + "Absolute Links: " + linkTypeList[1] + "\n" + "Email Links: " + linkTypeList[2]);
  
  // show progress meter
  updateProgress();
  
  linkStatus();
}

function linkStatus() {
  // if link isn't blank and no banned link keywords were found, check the link
  if(linkList[count] != null && bannedKeywordCount() == 0) {
    xmlHttp = new XMLHttpRequest();

    // the following is used for local testing purposes only
    // netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserAccess UniversalBrowserRead UniversalBrowserWrite');

    xmlHttp.onreadystatechange = getLinkStatus;
    xmlHttp.open("HEAD", linkList[count], true);
    xmlHttp.send(null);
  }
  else { // links with null value are skipped
    labelLink(4);
  }
}

function getLinkStatus() {
  // insert timeout for URLs that just won't return a header in reasonable time
  
  if (xmlHttp.readyState < 4) {
    if(timeOutSet == 0) {
        timeOutInterval = setTimeout("labelLink(4)", lcPref.getIntPref("extensions.linkchecker.linkTimeout"));
        
        timeOutSet = 1;
    }

  } else if(xmlHttp.readyState == 4) {
    clearTimeout(timeOutInterval);
    timeOutSet = 0;
    
    try {
      var httpStatus = xmlHttp.status;

      // color code links
      if(httpStatus == 200) { labelLink(1); }
      else if(httpStatus == 404) { labelLink(2); }
      else { labelLink(3); }
    }
    catch(e) { // non-existant domain name
        labelLink(2);
    }

    // pageLinks[count].style.borderBottom = "2px dashed " + linkBgColor;

    // var linkInfoText = document.createTextNode(httpStatus);
    // var linkInfo = document.createElement("SUP");
    // linkInfo.setAttribute("style", "position: absolute; background: #ddd; color: #000; font: bold 8pt arial, sans-serif; margin: -1em 0 0 -.5em; padding: 0 3px 0 3px; border: 1px outset #ccc;")

    // linkInfo.appendChild(linkInfoText);
    // pageLink.appendChild(linkInfo);
  }
}

function labelLink(linkCode) {
    if(timeOutSet == 1) {
      clearTimeout(timeOutInterval);
      timeOutSet = 0;
    }

    switch(linkCode) {
      case 1: // valid link address, 200
        var linkBgColor = lcPref.getCharPref("extensions.linkchecker.validLinkBg");
        var linkTxtColor = "#363";
        var linkImgName = "grn";
        var linkstatusmessage = document.getElementById('linkchecker-strings').getString("ValidLink");
        break;
      case 2: // invalid link address, 404
        var linkBgColor = lcPref.getCharPref("extensions.linkchecker.invalidLinkBg");
        var linkTxtColor = "#633";
        var linkImgName = "red";
        var linkstatusmessage = document.getElementById('linkchecker-strings').getString("InvalidLink");
        break;
      case 3: // dubious link, 403 etc
        var linkBgColor = lcPref.getCharPref("extensions.linkchecker.dubiousLinkBg");
        var linkTxtColor = "#663";
        var linkImgName = "ylo";
        var linkstatusmessage = document.getElementById('linkchecker-strings').getString("DubiousLink");
        break;
      case 4: // skipped link, telnet:, news:, file:, etc
        var linkBgColor = lcPref.getCharPref("extensions.linkchecker.skipLinkBg");
        var linkTxtColor = "#666";
        var linkImgName = "gry";
        var linkstatusmessage = document.getElementById('linkchecker-strings').getString("SkippedLink");
        break;
    }

    // adjust link colors
    var pageLink = pageLinks[count];
    pageLink.style.backgroundColor = linkBgColor + " !important";
    pageLink.style.color = linkTxtColor + " !important";

    // add link hover title
    pageLink.setAttribute("title", linkstatusmessage);
    
    // swap image src with its background
    var linkImgs = pageLink.getElementsByTagName("img");
    for(j=0; j<linkImgs.length; j++) {
      var linkImg = linkImgs[j];
      var linkImgSrc = linkImg.src;
      var computedImgInfo = document.defaultView.getComputedStyle(linkImg, "");
    
      var imgWidth = computedImgInfo.getPropertyValue("width");
      var imgHeight = computedImgInfo.getPropertyValue("height");
      if(imgWidth == "auto" && imgHeight == "auto") {
        var imgWidth = linkImg.width;
        var imgHeight = linkImg.height;
      }
      
      // get padding values
      var imgPadTop = computedImgInfo.getPropertyValue("padding-top");
      var imgPadLt = computedImgInfo.getPropertyValue("padding-left");

      var linkImgTitle = linkImg.getAttribute("title");
      if(linkImgTitle == null) { linkImgTitle = ""; }

      // check if background already exists; if so, just replace src
      var imgBknd = computedImgInfo.getPropertyValue("background-image");
      if(imgBknd == "none") {
        linkImg.style.background = linkBgColor + " url(" + linkImgSrc + ") " + imgPadLt + " " + imgPadTop + " no-repeat";
      }

      linkImg.setAttribute("width", parseInt(imgWidth));
      linkImg.setAttribute("height", parseInt(imgHeight));
      linkImg.setAttribute("src", "chrome://linkchecker/skin/linkchecker-status-" + linkImgName + ".png");
      linkImg.setAttribute("title", linkImgTitle + " (" + linkstatusmessage + ") ");
    }

    // move on to the next link on the list
    count++;
    
    updateProgress();
    
    if(count<pageLinkCount) { linkStatus(); }
}

function updateProgress() {
    var ofmessage = document.getElementById('linkchecker-strings').getString("OfProgress");
    var progressMeterPanel = document.getElementById("linkchecker-statusbar-progresspanel");
    var progressMeterIcon = document.getElementById("linkchecker-statusbar-icon");
    var progressMeterText = document.getElementById("linkchecker-statusbar-text");
    // var statusText = document.getElementById("linkchecker-status-text");
    // var statusMeter = document.getElementById("linkchecker-statusbar-icon");
    
    var statusTextLabel = "";

    if(count == 0 && pageLinkCount > 0) {  
      progressMeterPanel.collapsed = false;
      
      progressMeterIcon.style.backgroundPosition = "0 0";
      statusTextLabel = "0 " + ofmessage + " " + pageLinkCount + " (0%)";
      // statusMeter.value = 0;
    }
    
    if(count < pageLinkCount) {
      var percentage = Math.round((count * 100) / pageLinkCount);
      
      statusTextLabel = count + " " + ofmessage + " " + pageLinkCount + " (" + percentage + "%)";
      
      if(percentage >= 25) { progressMeterIcon.style.backgroundPosition = "-16px 0"; }
      if(percentage >= 50) { progressMeterIcon.style.backgroundPosition = "-32px 0"; }
      if(percentage >= 75) { progressMeterIcon.style.backgroundPosition = "-48px 0"; }
      
      // statusMeter.value = percentage;
    }
    else {
      statusTextLabel = count + " " + ofmessage + " " + pageLinkCount + " (100%)";
      
      progressMeterIcon.style.backgroundPosition = "-64px 0";
      setTimeout("document.getElementById('linkchecker-statusbar-progresspanel').collapsed = true; if(linkCheckerStatus == 1) { toggleLinkChecker(); }", 2000);

      // statusMeter.value = 100;
    }
    
    progressMeterText.value = statusTextLabel;
}

function stopLinkChecker() {
    if(pageLinkCount != null) {
      document.getElementById("linkchecker-statusbar-progresspanel").collapsed = true;
      pageLinkCount = 0;
    }
    else {
        setInterval(stopLinkChecker(), 500);
    }
}

// added 2006-02-04 by KF
function bannedKeywordCount() {
	bannedList = lcPref.getCharPref("extensions.linkchecker.bannedList");
	bannedArr = bannedList.split(",");

	var patterns = new Array();
	for(k=0; k<bannedArr.length; k++)
		patterns[k] = new RegExp(bannedArr[k], "i");

	// grab current link and other info
	var thisLink = pageLinks[count];
	var thisLinkInnards = thisLink.innerHTML;
	var thisLinkHref = thisLink.getAttribute("href");

	// loop through keywords to avoid (e.g. logout, exit, delete, etc.)
	var foundBanned = 0;
	for(j=0; j<patterns.length; j++) {
		// check link href
		// check link innerhtml

		if(thisLinkInnards.search(patterns[j]) > -1 || thisLinkHref.search(patterns[j]) > -1) {
			foundBanned++;
		}
	}

	return foundBanned;
}

