//**************************************
// * FSIMS Doc Utils -- JavaScript
// * Date: 06/15/06
// * Author: C.Hall
// * Updated: 06/05/08 by D. Mottolo
// * Updated: 10/16/08 by F. Harrison
// * Updated: 10/23/08 by D. Mottolo
// * Version: 3.1
// * Description:
// *    Contains common js utilities used by all fsims doc (in WDocs)
// *    Must be stored on server/mobile client in a relative path to 
// *    WDocs root directory. Import into all WDocs file containing links.
// * DO NOT DELETE THIS FILE!!!
// *************************************

var linkErrors = 0;
var linksProcessed;
var currLoc = location.href.toLowerCase().replace("\\", "/");
var currSrv = location.host;
var currSrvName = location.hostname;
var isLocal = false;
var isRGL = false; // links to rgl .nsf source
var isFSIMS = false; // links to fsmis.nsf
var isViewLink = false; // links to notes views
var disableReason = "";
var status = 0;
var isPublicServer = false;

var checkedLinksArray = new Array(); // holds each checked link
var checkedLinksResultsArray = new Array(); // holds 1-to-1 index with true/false if url is found

var notFoundMsg = "Sorry, this document link is currently unavailable to FSIMS. \n\nIt may not be included in your library selection or is not supported when offline."
var xmlhttp;

var minMsgLev = 3; // alert if this lev or higher

function msg(strMsg, intLev) {
	if(intLev == null) {
		intLev = 0;
	}
	if(intLev >= minMsgLev) {
		alert(strMsg);
	}
}

//*** Document Opening Code --- Section Jump To */

var tempwin;
var rng;

function winPopup(url,pixelsWide,pixelsHigh){
	if(pixelsWide==null){pixelsWide='760'};
	if(pixelsHigh==null){pixelsHigh='600'};
	var windowParams = ',menubar=yes,screenX=150,screenY=50,left=150,top=50,scrollbars=yes,resizable=no';
	if(url.toLowerCase().indexOf("/wdocs/") == -1) {
	  windowParams = ',menubar=yes,screenX=150,screenY=50,left=150,top=50,scrollbars=yes,resizable=yes';
	}
	tempwin = window.open(url,'newwin','alwaysRaised=yes,height='+pixelsHigh+',width='+pixelsWide+windowParams);
} 


function openPage(url,sec,sub1,sub2){
	// Updated 9/28/07
  try {	
	url = url.toLowerCase();
	winPopup(url);
	for(var count=0;count<1000000;count++){
		if(tempwin.document.body){break;}
	}
	rng = tempwin.document.body.createTextRange();
	var foundMatch=false;
	var index=-1;
	var alphabet='abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
	index=alphabet.indexOf(sec);
	for(i=0;i<=index;i++){
		if(rng.findText('('+alphabet.substring(i,i+1)+') ')==false){
			break;
		}else if(alphabet.substring(i,i+1)==sec){
			if(rng!=null && rng.offsetLeft<20){
				foundMatch=true;
				break;
			}else{
				j=0;
				while(j<5 && rng!=null){  
					j++;
					rng.collapse(false);
					rng.findText('('+alphabet.substring(i,i+1)+')');			
					if(rng!=null && rng.boundingWidth<20){
						//alert( "Rng boundingLeft ="+ rng.boundingLeft + " j=" + j ); // This code formerly use boundingLeft
						foundMatch=true;
						break;
					}
				}
			}
		}
	}
	if(foundMatch==false && sec!=null && sec!=''){
		if(rng.findText(sec)==true){
			foundMatch=true;
		}
	}
	if(foundMatch){
		if(sub1!=null && sub1!=''){
			index=parseInt(sub1);
			if(isNaN(index)){
				rng.findText('('+sub1+ ') ');
			}else{
				for(i=0;i<=index;i++){
					rng.findText('('+i.toString()+') ');
				}
				i=0;
				while(i<5 && rng.boundingWidth>25){
					i=i+1;
					rng.collapse(false);
					rng.findText('('+index.toString()+') ');
				}
			}
			
			if(sub2!=null && sub2!=''){
				rng.findText('('+sub2+') ');
				i=0;
				while(i<5 && rng.boundingWidth>25){
					i=i+1;
					rng.collapse(false);
					rng.findText('('+sub2+') ');
				}
			}
		}

		tempwin.focus();
		if(rng){
			setTimeout('jumpTo(tempwin,rng)',20);
		}	
	}
  } catch (e) {
	 msg("Error in openPage()-main: " + e.message,2);
  }	
}

function jumpTo(win,rng){
  try {
	win.scrollTo(rng.offsetLeft,rng.offsetTop);
	rng.select();
  } catch (e) {
	msg("Error in openPage()-jumpTo: " + e.message,2);
  }	
}
//* End Doc Opening code ***/

//*** Link Checker/Disabler code */

var anchors;

function checkDocLinks(htmlDoc, aArray) {
	// create XMLHttpRequest to each link
	// check if it can be opened
	// disable if not
	msg("Status: running checkDocLinks()", 1);
	
	// first see if local, if not, don't run this on the server
	if(currSrvName.toLowerCase() == "localhost" || currSrv.indexOf("127.0.0.1") == 0) {
		msg("Running checkDocLinks() on remote library, continue...",2);
		isLocal = true;
		//isPublicServer = true;
	} else {
		msg("Running checkDocLinks() on server, exit routine (well, exit when in production)...",2);
		isLocal = false;
		// check for public site - 3.0 mod to disable unavailable public links		 
		if(currSrvName.toLowerCase() == "fsims.faa.gov" || currSrv.indexOf("162.58.34.7") == 0) {
		    msg("Running checkDocLinks() on public server, continue...",2);
		    isPublicServer = true;
		} else {
		    // return only if on server and not public server
		    return;
		}
	}	

	if(htmlDoc == null) {
		htmlDoc = document;
	}
	if(aArray == null) {
		aArray = htmlDoc.getElementsByTagName("A");
	}
	
	var a;
	var curAnchor;	
	var url;
	for (a = 0; a <= aArray.length-1 && linkErrors < 1000; a++) {
	//for (a = 0; a <= aArray.length-1 && a < 10; a++) {
	
		// clear global doc variables
		isFSIMS = false;
		isRGL = false;
		isViewLink = false;
		disableReason = "";
		
		curAnchor = aArray[a];
		//msg(a + ") " + curAnchor.href, 1);
		url = (curAnchor.href).toLowerCase();
		//url = url.toLowerCase();
		//msg(url);
		url = trim(decodeURI(url) + "");
		if(url.indexOf("openpage(") > 0) {
			url = getURLFromJS(url);
		}
		url += "";
		
		if(url != "" && url != "null") {
			if (testLink(url) == false) {
				disableAnchor(curAnchor);
			}
		} else {
			msg("Empty anchor found: " + a + ") " + curAnchor.href,1);
			disableReason = "Invalid URL";
			disableAnchor(curAnchor);
		}
	}
	msg("Number of unique, checked links: " + checkedLinksArray.length,1);
	return;
}

function getCheckedLinkIndex(url) {
	// returns the index of the link in the checked link arrays
	// -1 means it hasn't been found yet
	var a;
	for(a = 0; a <= checkedLinksArray.length-1; a++) {
		if(url.toLowerCase() == checkedLinksArray[a].toLowerCase()) {
			//found
			//msg("url found at index: " + a);
			return a;
		}
	}
	return -1;
}

function setLinkAsChecked(url, ok) {
	try {
		checkedLinksArray.push(url);
		checkedLinksResultsArray.push(ok);
		return 1;
	} catch(e) {
		msg("could not set link to array: " + e.message,1);
		return 0;
	}
	
}

function isURLRequestable(url) {
	//var checkIt = true;
	url = url.replace("\\", "/");
	// is this a jump to achor #?
	if(url.indexOf("#") == 0) {
		return false;
	}
	
	// is there a path or is it a link to itself?
	if(url.indexOf("/") == -1) {
		return false;
	}
	
	// adding check to let http (external links) in public site go through unchecked
	if(url.toLowerCase().indexOf("://") > 0) {
		return false;
	}
	// may need to add more checks, for now let it go..
	return true;
}

function testLink(url) {
	var ok = false;
	var crossSrv;
	var urlSrv;
	var checkedLinkIndex = -1;  // -1 = not found or unchecked link
		
	// rules for this release - 1.0:
	// a. applies to disconnected, mobile lib only (isLocal)
	//    - if not, this code should not be called
	// b. if isRGL or isFSIMS (.nsf) links, all docs should be down, so enable/skip
	// c. if external link (http or not relative or not same server) then disable
	// d. other wise, should be to wdocs or relative from wdocs, so test it
	
	//var url = aObj.getAttribute("href");
	if(url && url != "" && url != null){
		// got one, continue...
		//msg("test: " + url);
	} else {
		//msg("no url");      
		return false;
	}

	// test if this is cross-server (httpRequest will get permission denied)
	url = url.toLowerCase().replace("\\", "/");
	url = trim(url);
	
	var lstLine = 0;
	try{	
	// test if url already checked
	checkedLinkIndex = getCheckedLinkIndex(url);
	if(checkedLinkIndex != -1) {
		// already tested
		msg("already tested: " + url + " at " + checkedLinkIndex,1);
		return checkedLinksResultsArray[checkedLinkIndex];
	}
	// not tested so test it now...
	
	if(url.indexOf("/wdocs/") == 0 || url.indexOf("/") == 0) {
		// not cross-server
		crossSrv = false;
	} else if(url.indexOf("://") > 0) {
		urlSrv = "" + url.substr(url.indexOf("://")+ 3);
		urlSrv = urlSrv.substring(0, urlSrv.indexOf("/"));
		//msg(urlSrv);
		if(url.indexOf(currSrv) >= 0) {
			crossSrv = false;
		} else {
			crossSrv = true;
		}
	}
	
	
	if(crossSrv == true && !isPublicServer) {
		// just disable it for now 
		// may load in iframe, if needed, but permission is denied on cross-server scripting..
		// for public site http links will be left on/unchecked
		setLinkAsChecked(url, false);
		disableReason = "Link not accessable";
		return false;
	}	
	
	// file is on this server so let's get an httpRequest handle to it and see if it is found

	// hold on, new logic, is it to FSIMS or RGL? (if so, skip/return true)
	if(url.indexOf("fsims.nsf") > 0) {
		isFSIMS = true;
	}		
	if(url.indexOf("/regulatory_and_guidance_library/") > -1 && url.indexOf(".nsf") > 0) {
		isRGL = true;
	}
	
	// view links cause problems in fsims
	// is it to an fsims view
	if(url.indexOf("?openview") > 0) {
		// currently view links are risky (may contain unselected docs);
		isViewLink = true;
	}
		
	if(isFSIMS || isRGL) {
		if(isFSIMS && isViewLink && !isPublicServer) {
			// disable for now
			ok = false;
			setLinkAsChecked(url, false);
			disableReason = "View links may not contain all content";
			return ok;
		}
		if(isFSIMS && isPublicServer) {
			// also disable until fsims domino is available relatively to public site disable for now
			ok = false;
			setLinkAsChecked(url, false);
			disableReason = "Domino link is not available from this server";
			return ok;
		}
		// skip this doc, it should be available - on mobile only
		ok = true;
		setLinkAsChecked(url, true);
		return ok;		    
	}
	
	// found other instances where file should not be processed, check here..
	if(!isURLRequestable(url)) {
		// not requestable means, don't check it, skip it
		ok = true;
		setLinkAsChecked(url, true);
		return ok;
	}
	}catch(e) {
		// failed to set up the url for making a req
		ok = false;
		setLinkAsChecked(url, false);
		disableReason = "Error validating url";
		return ok;
	}
	
	lstLine++; // 1

	xmlhttp = false;
	// branch for native XMLHttpRequest object
	
	// JScript gives us Conditional compilation, we can cope with old IE versions.
	// and security blocked creation of the objects.
	try {
		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e2) {
			xmlhttp = false;
			//linkErrors++;
		}
	}
	if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
			xmlhttp = new XMLHttpRequest();
		} catch (e) {
			xmlhttp = false;
			//linkErrors++;
		}
	}
	if (!xmlhttp && window.createRequest) {
		try {
			xmlhttp = window.createRequest();
		} catch (e) {
			xmlhttp = false;
			//linkErrors++;
		}
	}
	if(!xmlhttp) {
		// still can't get a req, return failure
		ok = false;
		disableReason = "ActiveX security or failure occurred";
		linkErrors++;
	} else {
		try {
			xmlhttp.open("HEAD", url, false);
			xmlhttp.onreadystatechange = function() {
				if (xmlhttp.readyState==4) {
					if (xmlhttp.status==200) {
						//found and good
						msg('url ok [' + xmlhttp.status + ']: ' + url, 1);
						ok = true;
					} else {
						//bad
						msg('url failed [' + xmlhttp.status + ']: ' + url, 1);
						disableReason = "Request failure - (" + xmlhttp.status + ") " + xmlhttp.statusText;
						ok = false;
					}	
					//else if (xmlhttp.status==404) alert("URL doesn't exist!")
					//else alert("Status is "+xmlhttp.status)
				}
			}
			xmlhttp.send(null);
			xmlhttp.abort();
		} catch(e) {
			msg("Error opening request: " + e.message, 3);
			linkErrors++;
			disableReason = "Error opening request - " + e.message;
			ok = false;
			if(xmlhttp) {
				try {
					xmlhttp.abort();
				} catch(e2) {
					//error closing faulty request
					msg("Error closing request: " + e2.message, 3);
				}
			}	
		}
	}
	status = setLinkAsChecked(url, ok);
	return ok;
}

function getURLFromJS(url) {
	var outURL = url;
	url = url.toLowerCase();
	var startStr = "openpage(";
	var endStr = "'";
	var pos = url.indexOf(startStr);
	if(pos >= 0) {
		pos += startStr.length + 1;
	}
	//msg(pos);
	outURL = url.substr(pos);
	pos = outURL.indexOf(endStr);
	//msg(pos);
	outURL = outURL.substr(0, pos);
	//msg(outURL);
	if(outURL != "") {
		return outURL;
	} else {
		return url;
	}
}

function disableAnchor(obj) {

	// if is public site
	// disable and take of click/link (make it appear as if not a link)
	if(isPublicServer) {
		obj.removeAttribute("href");
		obj.onclick = null;
		return;
	}

	var href = obj.getAttribute("href");
	if(href && href != "" && href != null){
		obj.setAttribute('href_bak', href);
	}
	var hrefDsp = "Document link is unavailable";
	if(disableReason != "") {
		hrefDsp += " [" + disableReason + "] ";
	}
	hrefDsp += ": " + href;
	//window.status = hrefDsp;
	
	//* attempt to set a mouseover event to display url in status
	//obj.onmouseover = "showStatMsg(hrefDsp); return true;";
	//obj.onmouseout = "clrStatMsg(); return true;";
	//obj.setAttribute('onmouseover',"showStatMsg(obj.getAttribute('href_bak');");
	//obj.onclick = "msg('Document is unavailable.\n\nIt may not be included in your library selection.'); return true;";
	
	
	//* disable link */
	//obj.disabled = true;  // doesn't stop link, though it looks disabled

	// since disable doesn't work, remove/change href value with brute force
	// uncomment following 1 of the 2 following lines (message or no message)
	//obj.setAttribute("href","javascript:alert('"+notFoundMsg+" \n\n"+href+"');");
	obj.setAttribute('href',"javascript:void(0);");
	// incase there's an onclick, override it
	obj.onclick = null;
	// use styles to handle disabled affect
	obj.style.color="gray";
	obj.setAttribute("title",""+hrefDsp);
	//obj.style.textDecoration="underline";
}

function showStatMsg(txt) {
    window.status = txt;
}

function clrStatMsg() {
    window.status = "";
}

//* End Link Check/Disable code ***/

function trim(str){
		
	// trim off leading spaces
	while (str.charAt(0) == ' '){
		str = str.substring(1);
	}
	
	//trim off trailing spaces
	while (str.charAt(str.length-1) == ' '){
		str = str.substring(0,str.length-1);
	}
	return str;
}

//*** Auto-run code for Link Check/Disable */


var numAttempts = 0;

function waitForLoad() {
	if (document.readyState == 'complete'&& isLibrarian != true ) {
	      checkDocLinks(document);
	} else {
		if(numAttempts++ < 25) {
			setTimeout('waitForLoad()', 1000);
		}
	}
}

//  The isLibrarian variable will be undefined if the HTML page does not load librarian.js before loading this file.
//  Since only librarians should have the librarian.js file on their local computer, it will only be 'true' for them.
//  And the checkDocLinks() function, that disables external links, will only run for non-librarians. 
if ( isLibrarian == undefined ) {
  var isLibrarian = false;
}

waitForLoad();


//* End Auto-run code for Link Check/Disable */
