
// XML

/* UTF-8 */

// ==========================================================================
// JavaScript Tool for URL Encoding/Decoding
// Copyright (C) 2006 Netzreport (netzreport.googlepages.com)
//
// Website: http://netzreport.googlepages.com/online_tool_for_url_en_decoding.html
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
//
// The GNU General Public License is also available from:
// http://www.gnu.org/copyleft/gpl.html
//
// A local copy of the GNU General Public License is available here:
// http://netzreport.googlepages.com/gpl.txt
// ==========================================================================
//
// --------------------------------------------------------------------------
// 2006-12-18: Changed character encoding. Now, one can choose between URL
//             encoding/decoding strings that are character encoded as ASCII
//             or UTF-8.
// 2006-11-19: First release
// --------------------------------------------------------------------------

// According to RFC 3986, only characters from a set of reserved and a set
// of unreserved characters are allowed in a URL:
var unreserved = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.~";
var reserved = "!*'();:@&=+$,/?%#[]";
var allowed = unreserved + reserved;
var hexchars = "0123456789ABCDEFabcdef";

// --------------------------------- Encoding -------------------------------

// This function returns a percent sign followed by two hexadecimal digits.
// Input is a decimal value not greater than 255.
function gethex(decimal) {
  return "%" + hexchars.charAt(decimal >> 4) + hexchars.charAt(decimal & 0xF);
}

function encode(sToDecode, encoding) { // encoding: one of [ascii, utf8]

  // Some variables:
  var decoded = sToDecode;
  var encoded = "";

  // ---------------- If ASCII character encoding was chosen: ----------------

  if (encoding == "ascii") {

    // Remember non-ASCII characters, which will not be encoded:
    var notascii = "";

    for (var i = 0; i < decoded.length; i++ ) {
      var ch = decoded.charAt(i);
      // Check if character is an unreserved character:
      if (unreserved.indexOf(ch) != -1) {
        encoded = encoded + ch;
      } else {
        // If position in the Unicode table is smaller than 128, then we have
        // an ASCII character:
        var charcode = decoded.charCodeAt(i);
        if (charcode < 128) {
          encoded = encoded + gethex(charcode);
        } else {
          encoded = encoded + ch;
          notascii = notascii + ch + " ";
        }
      }
    }

    // Display warning message if necessary:
    if (notascii != "") alert("Warning: Non-ASCII characters in decoded text!\n\nThus, these characters have not been encoded:\n" + notascii);

    // return result:
    return encoded;
  }

  // ---------------- If UTF-8 character encoding was chosen: ----------------

  if (encoding == "utf8") {
    for (var i = 0; i < decoded.length; i++ ) {
      var ch = decoded.charAt(i);
      // Check if character is an unreserved character:
      if (unreserved.indexOf(ch) != -1) {
        encoded = encoded + ch;
      } else {

        // The position in the Unicode table tells us how many bytes are needed.
        // Note that if we talk about first, second, etc. in the following, we are
        // counting from left to right:
        //
        //   Position in   |  Bytes needed   | Binary representation
        //  Unicode table  |   for UTF-8     |       of UTF-8
        // ----------------------------------------------------------
        //     0 -     127 |    1 byte       | 0XXX.XXXX
        //   128 -    2047 |    2 bytes      | 110X.XXXX 10XX.XXXX
        //  2048 -   65535 |    3 bytes      | 1110.XXXX 10XX.XXXX 10XX.XXXX
        // 65536 - 2097151 |    4 bytes      | 1111.0XXX 10XX.XXXX 10XX.XXXX 10XX.XXXX

        var charcode = decoded.charCodeAt(i);

        // Position 0 - 127 is equal to percent-encoding with an ASCII character encoding:
        if (charcode < 128) {
          encoded = encoded + gethex(charcode);
        }

        // Position 128 - 2047: two bytes for UTF-8 character encoding.
        if (charcode > 127 && charcode < 2048) {
          // First UTF byte: Mask the first five bits of charcode with binary 110X.XXXX:
          encoded = encoded + gethex((charcode >> 6) | 0xC0);
          // Second UTF byte: Get last six bits of charcode and mask them with binary 10XX.XXXX:
          encoded = encoded + gethex((charcode & 0x3F) | 0x80);
        }

        // Position 2048 - 65535: three bytes for UTF-8 character encoding.
        if (charcode > 2047 && charcode < 65536) {
          // First UTF byte: Mask the first four bits of charcode with binary 1110.XXXX:
          encoded = encoded + gethex((charcode >> 12) | 0xE0);
          // Second UTF byte: Get the next six bits of charcode and mask them binary 10XX.XXXX:
          encoded = encoded + gethex(((charcode >> 6) & 0x3F) | 0x80);
          // Third UTF byte: Get the last six bits of charcode and mask them binary 10XX.XXXX:
          encoded = encoded + gethex((charcode & 0x3F) | 0x80);
        }

        // Position 65536 - : four bytes for UTF-8 character encoding.
        if (charcode > 65535) {
          // First UTF byte: Mask the first three bits of charcode with binary 1111.0XXX:
          encoded = encoded + gethex((charcode >> 18) | 0xF0);
          // Second UTF byte: Get the next six bits of charcode and mask them binary 10XX.XXXX:
          encoded = encoded + gethex(((charcode >> 12) & 0x3F) | 0x80);
          // Third UTF byte: Get the last six bits of charcode and mask them binary 10XX.XXXX:
          encoded = encoded + gethex(((charcode >> 6) & 0x3F) | 0x80);
          // Fourth UTF byte: Get the last six bits of charcode and mask them binary 10XX.XXXX:
          encoded = encoded + gethex((charcode & 0x3F) | 0x80);
        }

      }

    }  // end of for ...

    // return result:
    return encoded;
  }
}

// --------------------------------- Decoding -------------------------------

// This function returns the decimal value of two hexadecimal digits.
// Input is a percent sign followed by two hexadecimal digits. If the input
// string is shorter than three characters, the percent sign is missing or if
// not a hexadecimal numeral is used, then the decimal value 256 is returned:
function getdec(hexencoded) {
  if (hexencoded.length == 3) {
    if (hexencoded.charAt(0) == "%") {
      if (hexchars.indexOf(hexencoded.charAt(1)) != -1 && hexchars.indexOf(hexencoded.charAt(2)) != -1) {
        return parseInt(hexencoded.substr(1,2),16);
      }
    }
  }
  return 256;
}

function decode(sToDecode, encoding) { // encoding: one of [ascii, utf8]

  // Some variables:
  var encoded = sToDecode;
  var decoded = "";
  // Remember characters that are not allowed in a URL:
  var notallowed = "";
  // Remember illegal percent encoding:
  var illegalencoding = "";

  // ---------------- If ASCII character encoding was chosen: ----------------
  if (encoding == "ascii") {
    var i = 0;
    while (i < encoded.length) {
      var ch = encoded.charAt(i);
      // Check for percent-encoded string:
      if (ch == "%") {
        // Check if percent-encoded string represents an ASCII character:
        if (getdec(encoded.substr(i,3)) < 128) {
          decoded = decoded + unescape(encoded.substr(i,3));
        } else {
          decoded = decoded + encoded.substr(i,3);
          illegalencoding = illegalencoding + encoded.substr(i,3) + " ";
        }
        i = i + 3;
      } else {
        // Check if character is an allowed character:
        if (allowed.indexOf(ch) == -1) notallowed = notallowed + ch + " ";
        decoded = decoded + ch;
        i++;
      }
    }

    // Display warning message if necessary:
    var warning = "";
    if (notallowed != "") warning = warning + "Characters not allowed in a URL:\n" + notallowed + "\n\n";
    if (illegalencoding != "") warning = warning + "Illegal percent-encoding (for ASCII):\n" + illegalencoding  + "\n\n";
    if (warning != "") alert("Warning: Illegal characters/strings in encoded text!\n\n" + warning);

    // return result:
    return decoded;
  }

  // ---------------- If UTF-8 character encoding was chosen: ----------------
  if (encoding == "utf8") {
    // UTF-8 bytes from left to right:
    var byte1, byte2, byte3, byte4 = 0;

    var i = 0;
    while (i < encoded.length) {
      var ch = encoded.charAt(i);
      // Check for percent-encoded string:
      if (ch == "%") {

        // Check for legal percent-encoding of first byte:
        if (getdec(encoded.substr(i,3)) < 255) {

          // Get the decimal values of all (potential) UTF-bytes:
          byte1 = getdec(encoded.substr(i,3));
          byte2 = getdec(encoded.substr(i+3,3));
          byte3 = getdec(encoded.substr(i+6,3));
          byte4 = getdec(encoded.substr(i+9,3));

          // Check for one byte UTF-8 character encoding:
          if (byte1 < 128) {
            decoded = decoded + String.fromCharCode(byte1);
            i = i + 3;
          }

          // Check for illegal one byte UTF-8 character encoding:
          if (byte1 > 127 && byte1 < 192) {
            decoded = decoded + encoded.substr(i,3);
            illegalencoding = illegalencoding + encoded.substr(i,3) + " ";
            i = i + 3;
          }

          // Check for two byte UTF-8 character encoding:
          if (byte1 > 191 && byte1 < 224) {
            if (byte2 > 127 && byte2 < 192) {
              decoded = decoded + String.fromCharCode(((byte1 & 0x1F) << 6) | (byte2 & 0x3F));
            } else {
              decoded = decoded + encoded.substr(i,6);
              illegalencoding = illegalencoding + encoded.substr(i,6) + " ";
            }
            i = i + 6;
          }

          // Check for three byte UTF-8 character encoding:
          if (byte1 > 223 && byte1 < 240) {
            if (byte2 > 127 && byte2 < 192) {
              if (byte3 > 127 && byte3 < 192) {
                decoded = decoded + String.fromCharCode(((byte1 & 0xF) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F));
              } else {
                decoded = decoded + encoded.substr(i,9);
                illegalencoding = illegalencoding + encoded.substr(i,9) + " ";
              }
            } else {
              decoded = decoded + encoded.substr(i,9);
              illegalencoding = illegalencoding + encoded.substr(i,9) + " ";
            }
            i = i + 9;
          }

          // Check for four byte UTF-8 character encoding:
          if (byte1 > 239) {
            if (byte2 > 127 && byte2 < 192) {
              if (byte3 > 127 && byte3 < 192) {
                if (byte4 > 127 && byte4 < 192) {
                  decoded = decoded + String.fromCharCode(((byte1 & 0x7) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F));
                } else {
                  decoded = decoded + encoded.substr(i,12);
                  illegalencoding = illegalencoding + encoded.substr(i,12) + " ";
                }
              } else {
                decoded = decoded + encoded.substr(i,12);
                illegalencoding = illegalencoding + encoded.substr(i,12) + " ";
              }
            } else {
              decoded = decoded + encoded.substr(i,12);
              illegalencoding = illegalencoding + encoded.substr(i,12) + " ";
            }
            i = i + 12;
          }

        } else {  // the first byte is not legally percent-encoded
          decoded = decoded + encoded.substr(i,3);
          illegalencoding = illegalencoding + encoded.substr(i,3) + " ";
          i = i + 3;
        }

      } else {  // the string is not percent encoded
        // Check if character is an allowed character:
        if (allowed.indexOf(ch) == -1) notallowed = notallowed + ch + " ";
        decoded = decoded + ch;
        i++;
      }
    }  // end of while ...

    // Display warning message if necessary:
    var warning = "";
    if (notallowed != "") warning = warning + "Characters not allowed in a URL:\n" + notallowed + "\n\n";
    if (illegalencoding != "") warning = warning + "Illegal percent-encoding (for UTF-8):\n" + illegalencoding  + "\n\n";
    if (warning != "") alert("Warning: Illegal characters/strings in encoded text!\n\n" + warning);

    // return result:
    return decoded;
  }
}

function getDomDocumentPrefix() {
	if (getDomDocumentPrefix.prefix) return getDomDocumentPrefix.prefix;
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			o = new ActiveXObject(prefixes[i] + ".DomDocument");
			return getDomDocumentPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	throw new Error("Could not find an installed XML parser");
}

function getXmlHttpPrefix() {
	if (getXmlHttpPrefix.prefix) return getXmlHttpPrefix.prefix;
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			return getXmlHttpPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	throw new Error("Could not find an installed XML parser");
}

function XmlHttp() {}

XmlHttp.create = function () {
	try {
		if (window.XMLHttpRequest) {
			var req = new XMLHttpRequest();
			if (req.readyState == null) {
				req.readyState = 1;
				req.addEventListener("load", function () {
					req.readyState = 4;
					if (typeof req.onreadystatechange == "function") req.onreadystatechange();
				}, false);
			}
			return req;
		}
		if (window.ActiveXObject) {
			return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
		}
	}
	catch (ex) {}
	throw new Error("Your browser does not support XmlHttp objects");
};

function XmlDocument() {}

XmlDocument.create = function () {
	try {
		if (document.implementation && document.implementation.createDocument) {
			var doc = document.implementation.createDocument("", "", null);
			if (doc.readyState == null) {
				doc.readyState = 1;
				doc.addEventListener("load", function () {
					doc.readyState = 4;
					if (typeof doc.onreadystatechange == "function") doc.onreadystatechange();
				}, false);
			}
			return doc;
		}
		if (window.ActiveXObject) return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
	}
	catch (ex) {}
	throw new Error("Your browser does not support XmlDocument objects");
};

if (window.DOMParser && window.XMLSerializer && window.Node && Node.prototype && Node.prototype.__defineGetter__) {
	XMLDocument.prototype.loadXML = Document.prototype.loadXML = function(s) {
		var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
		while (this.hasChildNodes()) this.removeChild(this.lastChild);
		for (var i = 0; i < doc2.childNodes.length; i++) this.appendChild(this.importNode(doc2.childNodes[i], true));
	};
	XMLDocument.prototype.__defineGetter__("xml", function () {return (new XMLSerializer()).serializeToString(this);});
	Document.prototype.__defineGetter__("xml", function () {return (new XMLSerializer()).serializeToString(this);});
}


function doXmlRequest(url, onSuccessHandler, onStartHandler, onErrorHandler) {
	var xmlHttp = XmlHttp.create();
	xmlHttp.open("POST", url, true); // async

	xmlHttp.onreadystatechange = function () {
		if (xmlHttp.readyState == 4) {
			var oXmlDoc = xmlHttp.responseXML;
			if(!oXmlDoc || (oXmlDoc.parserError && oXmlDoc.parseError.errorCode != 0) || !oXmlDoc.documentElement) {
				var error;
				if (!oXmlDoc || oXmlDoc.parseError.errorCode == 0) {
					error = "An error has occurred while loading data.\n\nResource URL: " + url + "\nStatus: " + xmlHttp.status + ", " + xmlHttp.statusText + "\n\nData:\n" + xmlHttp.responseText;
				} else {
					error = "An error has occurred while parsing data.\n\nResource URL: " + url + "\nReason: " + oXmlDoc.parseError.reason + "\nSource: " + oXmlDoc.parseError.srcText + "\nError code: " + oXmlDoc.parseError.errorCode + "\n\nData:\n" + oXmlDoc.responseText;
				}
				if (onErrorHandler) {
					onErrorHandler(url, error);
				}
				return;
			}
			onSuccessHandler(oXmlDoc);
		}
	};
	if (onStartHandler) {
		onStartHandler(url);
	}

// Set Length to zero since we don't send anything
	xmlHttp.setRequestHeader("Content-Length", 0);
	// call in new thread to allow ui to update
	window.setTimeout(function() {xmlHttp.send("");}, 10);
}
// EOF XML

// Cookie handling
//
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires=" + date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"=" + value + expires + "; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}
//
// EOF Cookie handling

var cookieName = "krafttagName"; 
eraseCookie(cookieName);

function checkCookie(){
	var existingNameCookie = readCookie(cookieName);
	if (existingNameCookie != null) {
		document.getElementById("nameFormDiv").style.display = "none";
	}
}


function trim(string){
	return string.replace(/(^\s+)|(\s+$)/g, "");
}


//Add new name
function addName() {
	
	var requestBody = false;
	requestBody = "";
	
	var name = document.getElementById("name");
	var captcha = document.getElementById("captcha");
	var namesList = document.getElementById("namesList");
	
    var onSuccess = function(oXmlDoc)  {
   	
	 try  {
	  if (!oXmlDoc || !oXmlDoc.childNodes) return;
	  var rootNode = false;
	  for (var i = 0; i < oXmlDoc.childNodes.length; i++) {
	   if (oXmlDoc.childNodes.item(i).nodeType == 1 && oXmlDoc.childNodes.item(i).nodeName == "persons") {
	   		rootNode = oXmlDoc.childNodes.item(i);
	   	}
	  }
	  if (!rootNode || !rootNode.childNodes) {
	   return;
	  }
	  
	  // If captcha is OK set cookie
	  createCookie(cookieName,name, 360);
	  
	  var namesListContent = "";
	  var resources = rootNode.childNodes;
	  if (resources.length > 0){
		  for (var j = 0; j < resources.length; j++) {
			  if (resources.item(j).nodeType == 1 && resources.item(j).nodeName == "person") {
				  var resource = resources.item(j);
				  namesListContent = namesListContent + "<br>"+  resource.getAttribute('name');
			  }
			  else if (resources.item(j).nodeType == 1 && resources.item(j).nodeName == "error"){
				  var resource = resources.item(j);
				  alert(resource.getAttribute('text'));
				  captcha.focus();
			  }
		  }	  
		  if (namesListContent != "") {
			  document.getElementById("nameFormDiv").style.display = "none";
			  namesList.innerHTML = namesListContent;
		  }  
	  }
	  captcha.value = "";
	  document.getElementById("captchaImage").src = '/system/modules/com.gridnine.opencms.modules.krafttag/elements/captcha.jsp?width=90&height=40&random=' + (Math.random() * 1000);
  
	} 
	catch (e) 
	{
	 throw e;
 	} 
		
	}
	
    var onError = function(url, error)  {
		//alert("Error: " + error);
		
    };
    
	if (trim(name.value) != ""){
		doXmlRequest(
				'/system/modules/com.gridnine.opencms.modules.swh/pages/add_name.jsp?name=' + encode(name.value, "utf8") + "&captcha=" + captcha.value,
				onSuccess,
				null,
				onError,
				requestBody
		);
	}
	else {
		alert("Provide not empty name!");
		name.value = "";
		name.focus();
	}
}

