var formName;
var listName;
var onCloseUrl;
var onShareUrl;
var appletWidth = 0;
var appletHeight = 0;
var appletMode = "MODE_STANDARD";
var preferredLanguage = "NONE";
var appletProcessorURL = null;
/*
  * This method will be used to embed Applet in web page
  * @param RootFolderURL URL that applet will use to interact with ADSS Server
  * @param CryptoMode Key Access Mode e.g. MSCAPI, PKCS#11, ROAMING_KEY etc
  *	@param WorkflowId Workflow identifier that will show the sequence of operations to be performed
  * Usage This method will be called in all cases
*/
function GoSign_EmbedApplet(RootFolderURL, WorkflowId){	
	var codeBase = RootFolderURL+"/lib";
	var jars = Applet_LoadJars();	
	if(jars == null){
		alert('Invalid applet mode');
		return false;
	}
	document.write(
        '<p>' +
	'<!--[if !IE]> Firefox and others will use outer object -->' +
	'      <object classid=\"java:com.ascertia.adss.applet.gosign.ASC_GoSignApplet.class\" ' +
	'           name=\"GoSign_FF\" '+
        '           id=\"GoSign_FF\" '+
        '           type=\"application/x-java-applet\"' +
	'           archive=\"adss_gosign.jar\" ' +
	'           height=\"' + appletHeight + '\" width=\"' + appletWidth+ '\" >' +
	'           <!-- Konqueror browser needs the following param --> ' +
	'	    	<param name=\"codebase\" value=\"' + codeBase + '\" />' +
	'           <param name=\"archive\" value= \"' + jars[0]  + ' \"/>' +
	'           <param name=\"cache_archive\" value= \"' + jars [0]+ '\" />' +
	'           <param name=\"cache_version\" value= \"' + jars [1]+ '\" />' +
	'           <param name=\"GoSignRootFolderURL\" value=\"' + RootFolderURL + '\">' +
	'           <param name=\"WorkflowId\" value=\"' + WorkflowId + '\">' +
	'           <param name=\"AppletProcessorURL\" value=\"' + appletProcessorURL + '\">' +
	'           <param name=\"PreferredLanguage\" value=\"' + preferredLanguage + '\">' +
	'       	<param name=\"java_arguments\" value=\"-Xms128m -Xmx1024m\"/> ' +
	'	    	<param name=\"name\" value=\"Ascertia GoSign\" />' +
	'	    	<param name=\"mayscript\" value=\"true\">' +
	'	    	<param name=\"progressbar\" value=\"true\">' +
	'<!--<![endif]-->' +
	'      <!-- MSIE (Microsoft Internet Explorer) will use inner object --> ' +
	'      <object classid=\"clsid:CAFEEFAC-0016-0000-FFFF-ABCDEFFEDCBA\" '+
        '           name=\"GoSign_IE\" '+
        '           id=\"GoSign_IE\" '+
        '           title=\"Ascertia GoSign\" ' +
	'           width=\"' + appletWidth + '\" height=\"' + appletHeight + '\" hspace=\"0\" vspace=\"0\" align=\"baseline\"' +
	'           codebase=\"http://java.sun.com/update/1.6.0/jinstall-6u10-windows-i586.cab#Version=1,6,0_10,33\"'+
        '       >' +
	'	    	<param name=\"codebase\" value=\"' + codeBase + '\" />' +
	'           <param name=\"code\" value=\"com.ascertia.adss.applet.gosign.ASC_GoSignApplet.class\">' +
	'           <param name=\"name\" value=\"Ascertia GoSign\">' +
	'           <param name=\"archive\" value= \"' + jars[0]  + '\" />' +
	'           <param name=\"cache_archive\" value= \"' + jars [0]+ '\" />' +
	'           <param name=\"cache_version\" value= \"' + jars [1]+ '\" />' +
	'           <param name=\"GoSignRootFolderURL\" value=\"' + RootFolderURL + '\">' +
	'           <param name=\"WorkflowId\" value=\"' + WorkflowId + '\">' +
	'           <param name=\"AppletProcessorURL\" value=\"' + appletProcessorURL + '\">' +
	'           <param name=\"PreferredLanguage\" value=\"' + preferredLanguage + '\">' +	
	'       	<param name=\"java_arguments\" value=\"-Xms128m -Xmx1024m\"/> ' +
	'           <param name=\"mayscript\" value=\"true\">' +
	'	    	<param name=\"progressbar\" value=\"true\">' +
	'     <font color=\"#FF0000\">' +
	'      No Java Runtime Environment (JRE) found, get the correct Java plug-in from ' +
	' <a href=\"http://www.java.com/en/download/\"><font color=\"#0000FF\">here.</font></a>' +
	'  </object>  ' +
	'<!--[if !IE]> close outer object -->' +
	'      </object>' +
	'<!--<![endif]-->  ' +
	'</p>' +
	'<p>' +
	' <div id=\"JreVerificationMessage\">   <p>' +
	'     <strong>NOTE:</strong> Java Runtime Environment (JRE) version 6.0 (or latest) is needed to run the Ascertia GoSign applet. If the applet does not load properly please get the correct Java plug-in from' +
	'      <a href=\"http://www.java.com/en/download/\">' +
	'        <font color=\"#0000FF\">here.</font>' +
	'      </a>' +
	'</p>');
}
/*
* This method is used to hide the JRE message displayed
*/

function GoSign_HideJreMessage() {
    var elem = document.getElementById('JreVerificationMessage');
    elem.style.visibility = 'hidden';
}
/*
  * This method will be used to set the PKCS#11 device configurations
  * @param DeviceName  PKCS#11 device name
  * @param Library PKCS#11 library name
  * @param Pin PKCS#11 device pin  
  *	@param SlotId PKCS#11 slot Id 	
  * Usage This method will only be used when CryptoMode is PKCS#11
*/
function GoSign_SetPkcs11Params(DeviceName,Library,SlotId,Pin){
	var gosign = GoSign_AppletGetObject();
	gosign.setPkcs11Params(DeviceName,Library,SlotId,Pin);
}
/*
  * This method is used to apply certifcate filtering criteria.
  * @param CriteriaIdentifier Identifier to uniquely identify each criteria e.g. SHOW_EXPIRED_CERTIFICATES
  * @param CriteriaValue Criteria value that will be used for filtering certificates matching the criteria value
  * Usage This method will only be used when CryptoMode is either PKCS#11 or MSCAPI
*/
function GoSign_SetFilterCriteria(CriteriaIdentifier, CriteriaValue) {
	var gosign = GoSign_AppletGetObject();
 	gosign.setFilterCriteria(CriteriaIdentifier, CriteriaValue);
}

function GoSign_SetFileChooserName(FileChooserName){
	var gosign = GoSign_AppletGetObject();
	gosign.setFileChooserName(FileChooserName);
}

function GoSign_SetDocumentId(DocumentId){
	var gosign = GoSign_AppletGetObject();
	gosign.setDocumentId(DocumentId);
}

function GoSign_SetDocumentType(DocumentType){
	var gosign = GoSign_AppletGetObject();
	gosign.setDocumentType(DocumentType);
}

function GoSign_SetHashAlgorithm(HashAlgorithm){
	var gosign = GoSign_AppletGetObject();
	gosign.setHashingAlgorithm(HashAlgorithm);
}

/*
  * This method is used to show filter certificates in specified format e.g. Subject DN, Organization
  * @param AliasTemplate Template that will be used for displaying certificate in specified format
  * Usage This method will only be used when CryptoMode is either PKCS#11 or MSCAPI
*/
function GoSign_SetAliasDisplayTemplate(aliasTemplate){
	var gosign = GoSign_AppletGetObject();
	gosign.setAliasDisplayTemplate(aliasTemplate);
}

function GoSign_SetAliasDisplayValueMissing(aliasDisplayMissingValue){
	var gosign = GoSign_AppletGetObject();
	gosign.setAliasDisplayValueMissing(aliasDisplayMissingValue);
}

/*
  * This method is used to set the form having drop down list control to display certificates
  * @param FormName Name of the form
  * Usage This method will only be used when CryptoMode is either PKCS#11 or MSCAPI
*/
function GoSign_SetFormName(a_formName){
	formName = a_formName;
	var gosign = GoSign_AppletGetObject();
	gosign.setFormName(a_formName);	
}
/*
  * This method is used to set list control name having filtered certificates
  * @param ListName Name of the drop down list control
  * Usage This method will only be used when CryptoMode is either PKCS#11 or MSCAPI
*/
function GoSign_SetCertificateListName(a_listName){
	listName = a_listName;
	var gosign = GoSign_AppletGetObject();
	gosign.setCertificateListName(a_listName);	
}

function GoSign_SetEmptySignatureFieldName(FieldName){
	var gosign = GoSign_AppletGetObject();
	gosign.setFieldName(FieldName);
}

function GoSign_SetAppletSize(a_width,a_height){
	appletWidth = a_width;
	appletHeight = a_height;
}

function GoSign_SetOnCloseURL(url){
	onCloseUrl = url;
}

function GoSign_SetOnShareURL(url){
	onShareUrl = url;
}

/*
  * This method is used to set signing reason used during signing operation
  * @param SigningReason Reason of signing
  * Usage This method will be used in all cases either Crypto Mode is set to MSCAPI,PKCS#11 or ROAMING_KEY and document is PDF.
*/
function GoSign_SetSigningReason(a_strSigningReason){
	var gosign = GoSign_AppletGetObject();
	gosign.setSigningReason(a_strSigningReason);
}
/*
  * This method is used to set signing location used during signing operation
  * @param SigningLocation Location of signing
  * Usage This method will be used in all cases either Crypto Mode is set to MSCAPI,PKCS#11 or ROAMING_KEY and document is PDF.
*/
function GoSign_SetSigningLocation(a_strSigningLocation){
	var gosign = GoSign_AppletGetObject();
	gosign.setSigningLocation(a_strSigningLocation);
}

/*
  * This method is used to set contact info used during signing operation
  * @param ContactInfo Contact Info of signer
  * Usage This method will be used in all cases either Crypto Mode is set to MSCAPI,PKCS#11 or ROAMING_KEY and document is PDF.
*/
function GoSign_SetContactInfo(a_strContactInfo){
	var gosign = GoSign_AppletGetObject();
	gosign.setContactInfo(a_strContactInfo);
}

/*
  * This method is used to set the XML document with meta data information
  * Usage This method will only be used in XML Encryption
*/
function GoSign_SetWrappingXmlFieldName( wrappingXmlFieldName ){
	var gosign = GoSign_AppletGetObject();
	gosign.setWrappingXml(GoSign_AppletGetFormFieldValue(wrappingXmlFieldName));
}

/*
  * This method is used to set XML document element name that need to be encrypted
  * @param ElementToBeEncrypted XML document element name
  * Usage This method will be used in all cases either Crypto Mode is set to MSCAPI,PKCS#11 or ROAMING_KEY, document is XML and encryption certificate is set.
*/
function GoSign_SetContentElement(contentElement){
	var gosign = GoSign_AppletGetObject();
	gosign.setContentElement(contentElement);
}

/*
  * This method is used to set encryption certificate that will be used for encryption process
  * @param EncryptionCertificate Encryption certificate
  * Usage This method will be used in all cases either Crypto Mode is set to MSCAPI,PKCS#11 or ROAMING_KEY and document is XML.
*/
function GoSign_SetCertificateFieldName( encCertFeildame ){	
	var gosign = GoSign_AppletGetObject();
	gosign.setCertificate(GoSign_AppletGetFormFieldValue(encCertFeildame));
}

/*
  * This method is used to set signature appearance XML
  * @param AppearanceXML signature appearance xml how signature should look like 
  * Usage This method will be used when PDF document is viewed in ViewSign when blank field is signed
*/
function GoSign_SetSignatureAppearanceFieldName(AppearanceXMLName){
	var gosign = GoSign_AppletGetObject();
	gosign.setSignatureAppearance(GoSign_AppletGetFormFieldValue(AppearanceXMLName));
}

/*
  * This method is used to set Subject DN for the certificate that will be generated during roaming key registration
  * @param SubjectDN SubjectDN of the certificate e.g. CN = Ascertia Pvt Ltd. EMAILADDRESS=support@ascertia.com
  * Usage This method will be used in roaming key registration
*/
function GoSign_SetSubjectDN(SubjectDN){
	var gosign = GoSign_AppletGetObject();
	gosign.setSubjectDN(SubjectDN);
}

function GoSign_SetRoamingKeyGenParams(KeySize, KeyAlgorithm){
	var gosign = GoSign_AppletGetObject();
	gosign.setRoamingKeyGenParams(KeySize, KeyAlgorithm);
}

function GoSign_SetRoamingKeyFieldName(RoamingKeyFieldName){
	var gosign = GoSign_AppletGetObject();
	gosign.setRoamingKey(GoSign_AppletGetFormFieldValue(RoamingKeyFieldName));
}

/*
  * This method is used to set roaming key credentials taken from ADSS Server containing encrypted private key, public key, key name and certificate chain
  * @param RoamingKeyCredentials
  * Usage This method will be used to perform signing operation using roaming key
*/
function GoSign_SetRoamingCertificateFieldName(RoamingCertFieldName){
	var gosign = GoSign_AppletGetObject();	
	gosign.setRoamingCertificate(GoSign_AppletGetFormFieldValue(RoamingCertFieldName));
}

/*
  * This method is used to set list of contacts
  * @param Contacts Contacts list in the form of Base64 XML containing contact name and his/her email address
  * Usage This method will be used when PDF document is viewed in ViewSign when blank field is drawn
*/
function GoSign_SetContactsXmlFieldName(ContactFieldName){
	var gosign = GoSign_AppletGetObject();
	gosign.setContacts(GoSign_AppletGetFormFieldValue(ContactFieldName));
}
/*
  * This method is used to set currently logged in user ID
  * @param LoggedInUser
  * Usage This method will be used when PDF document is viewed in ViewSign when blank field is drawn
*/
function GoSign_SetLoggedInUserId(LoggedInUser){
	var gosign = GoSign_AppletGetObject();
	gosign.setLoggedInUser(LoggedInUser);
}

/*
  * This method is used to set currently logged in user Name
  * @param LoggedInUser
  * Usage This method will be used when PDF document is viewed in ViewSign when blank field is drawn
*/
function GoSign_SetLoggedInUserName(LoggedInUserName){	
	var gosign = GoSign_AppletGetObject();
	gosign.setLoggedInUserName(LoggedInUserName);
}

/*
  * This method is used to set account password hash
  * @param PasswordHash Password Hash
  * Usage This method will be used when PDF document is viewed in ViewSign when blank field is signed
*/
function GoSign_SetPasswordHash(PasswordHash){
	var gosign = GoSign_AppletGetObject();
	gosign.setPasswordHash(PasswordHash);
}
/*
  * This method is used to set Certificate Alias that will be used for Server Side Signing
  * @param CertAlias Certificate alias used for signing 
  * Usage This method will be used when server side signing is performed
*/
function GoSign_SetCertificateAlias(CertAlias){
	var gosign = GoSign_AppletGetObject();	
	gosign.setCertificateAlias(CertAlias);
}

function GoSign_SetResultFilePostfix(postfix){
	var gosign = GoSign_AppletGetObject();
	gosign.setResultFilePostfix(postfix);
}

/*
  * This method is used to set the applet processor URL
  * @param processorURL
*/
function GoSign_SetAppletProcessor(strAppletProcessor){
	appletProcessorURL = strAppletProcessor;
}

function GoSign_ShowViewer(){ 
	var gosign = GoSign_AppletGetObject();
	var success = gosign.showViewer();
	return success;
}

function GoSign_GetErrorCode(){
	var gosign = GoSign_AppletGetObject();
	var errorCode = gosign.getErrorCode();
	return errorCode;
}

function GoSign_GetErrorReason(){
	var gosign = GoSign_AppletGetObject();
	var errorReason = gosign.getErrorReason();
	return errorReason;
}
/*
  * This method is used to show the filtered certificates matching the criteria in list control
  * Usage This method will only be used when CryptoMode is either PKCS#11 or MSCAPI
*/
function GoSign_IsAvailable(){
	GoSign_AppletIsReady();
	var gosign = GoSign_AppletGetObject();
	var error_code = gosign.getErrorCode();
	while( error_code == "undefined" || error_code == -1 ){
		error_code = gosign.getErrorCode();
	}
	if( error_code == null ){
		return true;
	}
	else{
		return false;
	}
}

function GoSign_ShowCertificates(){
	var gosign = GoSign_AppletGetObject();
	var success = gosign.showCertificates();
	return success;
}

function GoSign_Process(){
	var gosign = GoSign_AppletGetObject();
	var success = gosign.process();
	return success;
}

function GoSign_LoadCertificates(){
	var gosign = GoSign_AppletGetObject();
	var success = gosign.loadCertificates();
	return success;
}

/*
  * This method is used to download roaming key credentials taken from ADSS Server containing encrypted private key, public key, key name and certificate chain
  * @param RoamingKeyCredentials
  * Usage This method will be used to perform signing operation using roaming key
*/
function GoSign_RequestRoamingCredentials(b_download){
	 var gosign = GoSign_AppletGetObject(); 
	 gosign.requestRoamingCredentials(b_download);
}

/*
  * This method is used to set the browser name whose keystore will be used e.g. Firefox
  * @param Name of browser
  * Usage This method will be used to load the keystore of specified browser
*/
function GoSign_SetNssKeyStoreProvider(name){
	var gosign = GoSign_AppletGetObject();	
	gosign.setNssKeyStoreProvider(name);
}

/*
  * This method is used to set Applet mode
  * @param mode
*/
function GoSign_SetMode(mode){
	appletMode = mode;
}

/*
  * This method is used to set the preferred language of the browser
  * @param language
*/
function GoSign_SetPreferredLanguage(language){
	preferredLanguage = language;	
}

/*
  * This method is  used to set the HTML form field name containing the base64 encoded contents of the input document to be signed by GoSign Applet
  * @param String formFieldForInputDoc in the form of Base64 data  
*/
function GoSign_SetInputDocumentFieldName(formFieldForInputDoc){
	var gosign = GoSign_AppletGetObject();
	gosign.setInputDocument(GoSign_AppletGetFormFieldValue(formFieldForInputDoc));
}

/*
  * This method is used to set signed/encrypted document in form field name
  * @param OutputFieldValue Field that will contain the value of signed/encrypted document
  * Usage This method will be used in all cases either Crypto Mode is set to MSCAPI,PKCS#11 or ROAMING_KEY, document is XML and encryption certificate is set.
*/
function GoSign_SetOutputDocumentFieldName(formFieldForSignedDoc){
	var gosign = GoSign_AppletGetObject();
	gosign.setOutputDocumentFieldName(formFieldForSignedDoc);
}

/*
  * This method is used to directly pass the base64 encoded contents of the input document to GoSign Applet for signing. 
  * @param String inputDocToBeSigned in the form of Base64 data  
*/
function GoSign_SetInputDocument(inputDocToBeSigned){	
	var gosign = GoSign_AppletGetObject();	
	gosign.setInputDocument(inputDocToBeSigned);
}

/*
  * This method is used to get the base64 encoded contents of the signed documents.   
*/
function GoSign_GetOutputDocument(){
	var gosign = GoSign_AppletGetObject();	
	return gosign.getOutputDocument();
}

/*
 * This utility function can be used to decode the base64 encoded textual or XML formatted contents.   
*/
function GoSign_Base64Decode(contentToBeDecoded){
	return Base64.decode(contentToBeDecoded)	
}

/*
 * This utility function can be used to base64 encode the textual or XML formatted contents.
*/
function GoSign_Base64Encode(contentToBeEncoded){
	return Base64.encode(contentToBeEncoded)
}


function GoSign_AppletGetCertificateList(a_listName){
	var list_exists = true;
	var list_certs = document.getElementById(a_listName);
	if(list_certs == null){
		list_exists = false;
	}else{
		list_exists = true;
	}
	return list_exists;
}

function GoSign_AppletGetLocalFilePath(a_strFileControlName){
	var fileChooser = document.getElementById( a_strFileControlName )
	var filePath = "";
	if ((navigator.userAgent.indexOf("Firefox")!=-1 || navigator.userAgent.indexOf("Mozilla")!=-1) && navigator.userAgent.indexOf("MSIE")==-1){
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			alert('Unable to access local files due to browser security settings. To overcome this, follow these steps: (1) Enter "about:config" in the URL field; (2) Right click and select New->Boolean; (3) Enter "signed.applets.codebase_principal_support" (without the quotes) as a new preference name; (4) Click OK and try loading the file again.');
			return;
		}	
		filePath=fileChooser.value;
	}
	else {
		filePath=fileChooser.value;
	}
	return filePath;	
}

function GoSign_AppletGetFormFieldValue(a_strFieldName){
	return document.forms[formName].elements[a_strFieldName].value
}

function GoSign_AppletSetFormFieldValue(a_strFieldName,a_strFieldValue){
	document.forms[formName].elements[a_strFieldName].value = a_strFieldValue
}

function GoSign_AppletPopulateCertificates(certs){
	var select_certs = document.getElementById(listName);	
	var array_certs = certs.split('~!~');
	for(var i=0; i<array_certs.length-1; i++){
		var array_alias = array_certs[i].split('~&~');
		select_certs.options[select_certs.options.length] = new Option(array_alias[0], array_alias[1]);
	}
}

function GoSign_AppletGetSelectedCertificate(formName,ListName){
	document.formName.ListName.value;
}

function GoSign_AppletGetObject(){
	if(navigator.appName == "Netscape"){
		return document.getElementById('GoSign_FF');
	}else{
		return document.getElementById('GoSign_IE');
	}
}

function GoSign_AppletIsReady(){
	var status = false;
	var gosign = GoSign_AppletGetObject();
	status = gosign.isActive();
	while( status != true ){
		GoSign_AppletSleep(1000);
		status = gosign.isActive();
	}	
}

function GoSign_AppletSleep(interval) {
	var gosign = GoSign_AppletGetObject();
	gosign.sleep(interval);
}

function GoSign_AppletOnClose() {
	window.location = onCloseUrl;
}

function GoSign_AppletOnShare() {
	window.location = onShareUrl;
}

function Applet_LoadJars(){  
  var requiredJars = "adss_gosign.jar,adss_gosign_common.jar,adss_gosign_protocol.jar,asc_xmlsec.jar,asc_bc142_obf.jar,asc_multipart.jar";
  var requiredVersions = "0.4.1.0,0.4.1.0,0.4.1.0,0.3.8.0,0.4.1.0,0.4.0.0";
  var viewerJars = "adss_gosign_viewer.jar,jPDFImages.jar,adss_gosign_viewer_images.jar";
  var viewerVersions = "0.4.1.0,0.3.8.0,0.4.1.0";
  var pdfHashJars = "asc_pdf.jar,iText.jar";
  var pdfHashVersions = "0.4.1.0,0.3.8.0";
  
  var requiredSet = new Array();
  requiredSet[0] = requiredJars;
  requiredSet[1] = requiredVersions; 
  
  var pdfHashSet  = new Array();
  pdfHashSet[0] = requiredJars +","+ pdfHashJars;
  pdfHashSet[1] = requiredVersions +","+ pdfHashVersions; 
      
  var viewerSet = new Array();
  viewerSet[0] = requiredJars +","+ viewerJars +","+ pdfHashJars;
  viewerSet[1] = requiredVersions +"," + viewerVersions +","+ pdfHashVersions;
  
  if(appletMode==GoSign_Constants.MODE_BASIC){
  	return requiredSet;  
  } else if(appletMode==GoSign_Constants.MODE_STANDARD){
	return pdfHashSet; 
  } else if(appletMode==GoSign_Constants.MODE_PROFESSIONAL){
	return viewerSet; 
  } else {
	return null;  
  }  
}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
 
var Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	} 
}

/*
  * Constants
*/
function GoSign_Constants() {}
  GoSign_Constants.SHA1 = "SHA1";
  GoSign_Constants.SHA256 = "SHA256";
  GoSign_Constants.SHA384 = "SHA384";
  GoSign_Constants.SHA512 = "SHA512";
  GoSign_Constants.TRUE = "TRUE";
  GoSign_Constants.FALSE = "FALSE";
  GoSign_Constants.SUBJECT_DN_CONTAINS = "SUBJECT_DN";
  GoSign_Constants.ISSUER_DN_CONTAINS = "ISSUER_DN";
  GoSign_Constants.SHOW_EXPIRED_CERTIFICATES = "SHOW_EXPIRED_CERTIFICATES";
  GoSign_Constants.KEY_USAGE_CONTAINS = "KEY_USAGE";
  GoSign_Constants.POLICY_OID_CONTAINS = "POLICY_OID";
  GoSign_Constants.ALGORITHM_OID_CONTAINS = "ALGORITHM_OID";
  GoSign_Constants.DIGITAL_SIGNATURE = "DIGITAL_SIGNATURE";
  GoSign_Constants.NON_REPUDIATION = "NON_REPUDIATION";
  GoSign_Constants.KEY_ENCIPHERMENT = "KEY_ENCIPHERMENT";
  GoSign_Constants.DATA_ENCIPHERMENT = "DATA_ENCIPHERMENT";
  GoSign_Constants.KEY_AGREEMENT = "KEY_AGREEMENT";
  GoSign_Constants.KEY_CERT_SIGN = "KEY_CERT_SIGN";
  GoSign_Constants.CRL_SIGN = "CRL_SIGN";
  GoSign_Constants.ENCIPHER_ONLY = "ENCIPHER_ONLY";
  GoSign_Constants.DECIPHER_ONLY = "DECIPHER_ONLY";
  GoSign_Constants.SUBJECT_CN = "SUBJECT_CN";
  GoSign_Constants.SUBJECT_C = "SUBJECT_C";
  GoSign_Constants.SUBJECT_OU = "SUBJECT_OU";
  GoSign_Constants.SUBJECT_O = "SUBJECT_O";
  GoSign_Constants.SUBJECT_S = "SUBJECT_S";
  GoSign_Constants.SUBJECT_L = "SUBJECT_L";
  GoSign_Constants.SUBJECT_E = "SUBJECT_E";
  GoSign_Constants.ISSUER_CN = "ISSUER_CN";
  GoSign_Constants.ISSUER_C = "ISSUER_C";
  GoSign_Constants.ISSUER_OU = "ISSUER_OU";
  GoSign_Constants.ISSUER_O = "ISSUER_O";
  GoSign_Constants.ISSUER_S = "ISSUER_S";
  GoSign_Constants.ISSUER_L = "ISSUER_L";
  GoSign_Constants.ISSUER_E = "ISSUER_E";
  GoSign_Constants.MSCAPI = "MSCAPI";
  GoSign_Constants.PKCS11 = "PKCS11";
  GoSign_Constants.ROAMING_KEY_GENERATION = "ROAMING_KEY_GENERATION";
  GoSign_Constants.ROAMING_KEY = "ROAMING_KEY";
  GoSign_Constants.MOZILLA_FIREFOX = "MOZILLA_FIREFOX";
  GoSign_Constants.MODE_BASIC = "MODE_BASIC";
  GoSign_Constants.MODE_STANDARD = "MODE_STANDARD";
  GoSign_Constants.MODE_PROFESSIONAL = "MODE_PROFESSIONAL";