var req;

/** TODO
* Select all password if browser is firefox (instead of copy to clipboard).
* Remember to escape < or > or & in punctuation.
*/
function loadXMLDoc(url) {
	req = false;
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest) {
    	try {
			req = new XMLHttpRequest();
        } catch(e) {
			req = false;
        }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
       	try {
        	req = new ActiveXObject("Msxml2.XMLHTTP");
      	} catch(e) {
        	try {
          		req = new ActiveXObject("Microsoft.XMLHTTP");
        	} catch(e) {
          		req = false;
        	}
		}
    }
	if(req) {
		req.onreadystatechange = processReqChange;
		req.open("GET", url, true);
		req.send(null);
	}
}

function processReqChange() {
    // only if req shows "loaded"
    if (req.readyState == 4) 
    {
        // only if "OK"
        if (req.status == 200) {
        returnCode = req.responseXML.getElementsByTagName("returnCode")[0].firstChild.nodeValue;
        Fat.fade_element('editctrlPassword', null, null, '#FFFF33', '#FFFFFF');
        //	enum {GRPRet_Success = 0, GRPRet_ErrNothingAllowed, GRPRet_InvalidLength, GRPRet_EmptyPunctuationString, GRPRet_OtherError, GRPRet_ErrLettersNotAllowed, GRPRet_DictionaryNotFound};
		if (returnCode == 1)
		{
			alert('No characters are allowed.  Please check some of the "Allowed Characters" checkboxes.');
			return;
		}
        else if (returnCode == 2)
        {
			if (passwordType == PT_dictionary || passwordType == PT_warpedDictionary)
			{
				var length = +document.getElementById("editctrlLength").value;
				if (length < 5)
					alert("The length is too small for a dictionary password.");
				else 
					alert("The length is too large for a dictionary password.");
			}
			else
				alert("Invalid length.")
			return;
		}
		else if (returnCode == 3)
		{
			alert('Please enter some punctuation characters in the punctuation box, or uncheck the "Punctuation" option.');
			return;
		}
		else if (returnCode == 5)
		{
			alert('Please select "Lowercase Letters" and/or "Uppercase Letters" to generate this type of password.');
			return;
		}
		else if (returnCode != 0)
		{
			alert('Unexpected return code:'+ returnCode);
			return;
		}
		
        thePassword = unescape(req.responseXML.getElementsByTagName("password")[0].firstChild.nodeValue);
		document.getElementById("editctrlPassword").value = thePassword;
        passwordType = GetPasswordType();
		document.getElementById("editctrlMnemonicSentence").value = "";
		document.getElementById("editctrlPronounceableSyllables").value = "";
		document.getElementById("editctrlOriginalWord").value = "";
        if (passwordType != PT_random)
        {
	        otherInfo = unescape(req.responseXML.getElementsByTagName("otherInfo")[0].firstChild.nodeValue);
			if (passwordType == PT_mnemonicSentence)
				document.getElementById("editctrlMnemonicSentence").value = otherInfo;
			else if (passwordType == PT_pronounceable)
				document.getElementById("editctrlPronounceableSyllables").value = otherInfo;
			else if (passwordType == PT_dictionary || passwordType == PT_warpedDictionary)
				document.getElementById("editctrlOriginalWord").value = otherInfo;
		}
		EnableDisableMnemonicCopyButtons();
		/** On browsers that don't let us put text in the clipboard, set the focus to the password field and select it.  That way the user can copy to the clipboard by just hitting control-C.
		*/
		if (CanBrowserCopyToClipboard())
			document.getElementById("editctrlPassword").scrollLeft = 0; // This works on IE only.
		else
		{
			if (navigator.userAgent.toLowerCase().indexOf("opera") >= 0)
			{
				document.getElementById("editctrlPassword").style.visibility = "hidden";
				document.getElementById("editctrlPassword").style.visibility = "visible";
				// Opera does not scroll the text box to the beginning if you change the value.  Unfortunately, we have to jump through some hoops to make it do it.
				setTimeout('document.getElementById("editctrlPassword").focus();document.getElementById("editctrlPassword").select();', 1);
			}
			else
			{
				document.getElementById("editctrlPassword").focus();
				document.getElementById("editctrlPassword").select();
			}
		}
       } 
       else 
       {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText);
       }
    }
}
function fixLength()
{
	var length = +document.getElementById("editctrlLength").value;
	if (length > 99)
		document.getElementById("editctrlLength").value = "99";
	else if (length <= 0 || isNaN(length))
		document.getElementById("editctrlLength").value = "8";
}

function fetchPassword()
{
	// This is really only necessary on Opera.  Opera doesn't always fire an onunload() event, apparently if it jumps to a page out of the cache it doesn't.  For example, the next/previous buttons typically don't make Opera fire an unload event.
	SaveOptions();
	fixLength();	
	options = "passwordType="+GetPasswordType();
	if (document.getElementById("editctrlPunctuation").value != "")
	{
		options += "&punctuation="+escape(document.getElementById("editctrlPunctuation").value);
	}
	options +=
		"&length="+escape(document.getElementById("editctrlLength").value) +
		"&AllowLowercase="+document.getElementById("checkctrlAllowLowercase").checked +
		"&AllowNumbers="+document.getElementById("checkctrlAllowNumbers").checked+
		"&AllowPunctuation="+document.getElementById("checkctrlAllowPunctuation").checked+
		"&AllowUppercase="+document.getElementById("checkctrlAllowUppercase").checked+
		"&timestamp=" + new Date().valueOf() // append a timestamp to prevent the request from being buffered.
		;
	loadXMLDoc("cgi-bin/PasswordGenerator.cgi?"+options);
}

/////////////////////////////////////////////////////////////////////////////////////
/// This code is a port of PasswordGeneratorUIDLL's PasswordGeneratorDlg.cpp.
/////////////////////////////////////////////////////////////////////////////////////
var PT_random = 0;
var PT_mnemonicSentence = 1;
var PT_pronounceable = 2;
var PT_dictionary = 3;
var PT_warpedDictionary = 4;

function GetPasswordType()
{
	if (document.getElementById("radioctrlMemoryAidPronounceable").checked)
		return PT_pronounceable;
	else if (document.getElementById("radioctrlMemoryAidSentence").checked)
		return PT_mnemonicSentence;
	else if (document.getElementById("radioctrlMemoryAidDictionary").checked)
	{
		if (document.getElementById("checkctrlWarped").checked)
			return PT_warpedDictionary;
		else
			return PT_dictionary
	}
	else
		return PT_random;
}

function SaveOptions()
{
	fixLength();
	SetCookie("AllowLowercase", document.getElementById("checkctrlAllowLowercase").checked);
	SetCookie("AllowNumbers", document.getElementById("checkctrlAllowNumbers").checked);
	SetCookie("AllowPunctuation", document.getElementById("checkctrlAllowPunctuation").checked);
	SetCookie("AllowUppercase", document.getElementById("checkctrlAllowUppercase").checked);
	SetCookie("Length", document.getElementById("editctrlLength").value);
	SetCookie("Punctuation", document.getElementById("editctrlPunctuation").value);
	SetCookie("PasswordType", GetPasswordType());
	SetCookie("WarpedCheck", document.getElementById("checkctrlWarped").checked);
}

// Retrieve the value of the cookie with the specified name.
function GetCookie(sName, defaultValue)
{
  // cookies are separated by semicolons
  var aCookie = document.cookie.split("; ");
  for (var i=0; i < aCookie.length; i++)
  {
    // a name/value pair (a crumb) is separated by an equal sign
    var aCrumb = aCookie[i].split("=");
    if (sName == aCrumb[0]) 
      return unescape(aCrumb[1]);
  }
  // a cookie with the requested name does not exist
  return defaultValue;
}

/*
@param deleteIfUndefined You only want to set this to true for edit boxes; checkboxes value is undefined if they aren't checked.
*/
function SetCookie(sName, sValue)
{
  if (sValue == "" && typeof(sValue) == "string")
  {
	document.cookie = sName + "=foo;expires=Thu, 01-Jan-1970 00:00:01 GMT;";
  }
  else
  {
	document.cookie = sName + "=" + escape(sValue) + ";"; // expires=" + date.toGMTString();
  }

}

function InitializePasswordTypeControls()
{
	// We want to save/restore whether the password is checked or not even if "dictionary" is not selected.  That way we remember whether the user prefers warped or unwarped dictionary passwords.
	document.getElementById("checkctrlWarped").checked = GetCookie("WarpedCheck", "false") == "true" ? true : false;

	passwordType = parseInt(GetCookie("PasswordType", "0"));
	switch (passwordType)
	{
	case PT_mnemonicSentence:
		document.getElementById("radioctrlMemoryAidSentence").checked = true;
		break;
	case PT_pronounceable:
		document.getElementById("radioctrlMemoryAidPronounceable").checked = true;
		break;
	case PT_dictionary:
		document.getElementById("radioctrlMemoryAidDictionary").checked = true;
		break;
	case PT_warpedDictionary:
		document.getElementById("radioctrlMemoryAidDictionary").checked = true;
		document.getElementById("checkctrlWarped").checked = true; // make sure this is checked
		break;
	default: //case PT_random:
		document.getElementById("radioctrlMemoryAidNone").checked = true;;
		break;
	}
}

function InitDialog()
{
	document.getElementById("checkctrlAllowLowercase").checked = GetCookie("AllowLowercase", "true") == "true" ? true : false;			
	document.getElementById("checkctrlAllowNumbers").checked = GetCookie("AllowNumbers", "true") == "true" ? true : false;
	document.getElementById("checkctrlAllowPunctuation").checked = GetCookie("AllowPunctuation", "true") == "true" ? true : false;
	document.getElementById("checkctrlAllowUppercase").checked = GetCookie("AllowUppercase", "true") == "true" ? true : false;
	InitializePasswordTypeControls();
	document.getElementById("editctrlLength").value = GetCookie("Length", "8");
	document.getElementById("editctrlPunctuation").value =  GetCookie("Punctuation", "!@#$^&*()-=");
	EnableDisableControls();
	if (CanBrowserCopyToClipboard())
	{
		document.getElementById("btnctrlCopyPasswordToClipboard").style.display = "inline";
		document.getElementById("btnctrlCopyMnemonicToClipboard").style.display = "inline";
		document.getElementById("brCorrespondingToCopyToClipboardButton").style.display = "inline";
	}
	// To prevent flashing in IE, we don't show the rest of the page until we show brCorrespondingToCopyToClipboardButton, because that pushes all the other controls down.
	document.getElementById("divShowAfterControlShowHide").style.display="inline";
}

function EnableDisableMnemonicCopyButtons()
{
	if (!CanBrowserCopyToClipboard())
		return;
	document.getElementById("btnctrlCopyPasswordToClipboard").disabled = (document.getElementById("editctrlPassword").value == "");		
	buf = document.getElementById("editctrlMnemonicSentence").value;
	hasMnemonicSentence = buf != ""; //&& buf != passwordTooLongMessage;
	document.getElementById("btnctrlCopyMnemonicToClipboard").disabled = !hasMnemonicSentence;
	document.getElementById("btnctrlCopyMnemonicToClipboard").style.visibility = (GetPasswordType() == PT_mnemonicSentence ? "visible" : "hidden");
}

function EnableDisableControls()
{
	EnableDisableMnemonicCopyButtons();
	passwordType = GetPasswordType();
	document.getElementById("checkctrlAllowPunctuation").disabled = (passwordType == PT_warpedDictionary);
	document.getElementById("checkctrlAllowNumbers").disabled  = (passwordType == PT_warpedDictionary);
	document.getElementById("editctrlPunctuation").disabled = (!(document.getElementById("checkctrlAllowPunctuation").checked && passwordType != PT_warpedDictionary));
	document.getElementById("checkctrlWarped").disabled = (passwordType != PT_warpedDictionary && passwordType != PT_dictionary);
	document.getElementById("editctrlMnemonicSentence").style.visibility = (passwordType == PT_mnemonicSentence ? "visible" : "hidden");
	document.getElementById("editctrlPronounceableSyllables").style.visibility = (passwordType == PT_pronounceable ? "visible" : "hidden");
	document.getElementById("staticMnemonicSentenceLabel").style.visibility = (passwordType == PT_mnemonicSentence ? "visible" : "hidden");
	document.getElementById("staticPronounceableSyllablesLabel").style.visibility = (passwordType == PT_pronounceable ? "visible" : "hidden");
	document.getElementById("staticOriginalWordLabel").style.visibility = (passwordType == PT_dictionary || passwordType == PT_warpedDictionary ? "visible" : "hidden");
	document.getElementById("editctrlOriginalWord").style.visibility = (passwordType == PT_dictionary || passwordType == PT_warpedDictionary ? "visible" : "hidden");
	
	// Fix the ZIndex, or the user won't be able to select the text in the edit controls in Firefox.
	if (passwordType == PT_dictionary || passwordType == PT_warpedDictionary)
	{
		document.getElementById("spanMnemonicSentence").style.zIndex = 0;
		document.getElementById("spanOriginalWord").style.zIndex = 1;
		document.getElementById("spanPronounceable").style.zIndex = 0;
	}
	else if (passwordType == PT_pronounceable)
	{
		document.getElementById("spanMnemonicSentence").style.zIndex = 0;
		document.getElementById("spanOriginalWord").style.zIndex = 0;
		document.getElementById("spanPronounceable").style.zIndex = 1;
	}
	else if (passwordType == PT_mnemonicSentence)
	{
		document.getElementById("spanMnemonicSentence").style.zIndex = 1;
		document.getElementById("spanOriginalWord").style.zIndex = 0;
		document.getElementById("spanPronounceable").style.zIndex = 0;
	}
}

/* Firefox doesn't let you copy text to the clipboard because it is considered a security risk.  
You can adjust this by tweaking the user.js: http://www.mozilla.org/editor/midasdemo/securityprefs.html
However, no user is going to do that, so we only enable the CopyToClipboard buttons on IE.
*/
function CanBrowserCopyToClipboard()
{
	return (document.getElementById("editctrlPassword").createTextRange && 
		document.getElementById("editctrlPassword").createTextRange().execCommand);
}

/** This only works in IE.  
See CanBrowserCopyToClipboard().
*/
function CopyPasswordToClipboard()
{
	// The password text may be blank if the user deleted it by hand.  If so, disable the copy to password button.
	if (document.getElementById("editctrlPassword").value == "")
		EnableDisableMnemonicCopyButtons();
	else
		document.getElementById("editctrlPassword").createTextRange().execCommand("copy");
}

/** See CopyPasswordToClipboard()
*/
function CopyMnemonicSentenceToClipboard()
{
	document.getElementById("editctrlMnemonicSentence").createTextRange().execCommand("copy");
}
