//---------------------------------------------------------------------------
// 'Block' Tiny Encryption Algorithm
//
// Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab
//            http://www.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html (1994)
//            http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps (1997)
//            http://www.cl.cam.ac.uk/ftp/users/djw3/xxtea.ps (1998)
//
// JavaScript implementation: Chris Veness, Movable Type Ltd: www.movable-type.co.uk
//
// encrypt: Use 128 bits (16 chars) of string 'key' to encrypt string 'val'
//          (note key & val must be strings not string objects)
//           - return encrypted text as string
//
function encrypt(val, key)
{
    // 'escape' val so chars outside ISO-8859-1 work in single-byte packing, but
    // keep spaces as spaces (not '%20') so encrypted text doesn't grow too long!
    var v = strToLongs(escape(val).replace(/%20/g,' '));
    var k = strToLongs(key.slice(0,16)); var n = v.length;

    if (n == 0) return("");  // nothing to encrypt
    if (n == 1) v[n++] = 0;  // algorithm doesn't work for n<2 so fudge by adding nulls

    // TEA routine as per Wheeler & Needham, Oct 1998

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = 0;

    while (q-- > 0) {  // 6 + 52/n operations gives between 6 & 32 mixes on each word
        sum += delta;
        e = sum>>>2 & 3;
        for (var p = 0; p < n-1; p++) {
            y = v[p+1];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
            z = v[p] += mx;
        }
        y = v[0];
        mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
        z = v[n-1] += mx;
    }

    // note: unsigned right-shift '>>>' is used in place of original '>>',
    // due to lack of 'unsigned' type declaration in JavaScript

    return(escape(longsToStr(v)));
}


//
// decrypt: use 128 bits of string 'key' to decrypt string 'val' encrypted as per above
//
function decrypt(val, key)
{
    var v = strToLongs(unescape(val)); var k = strToLongs(key.slice(0,16)); var n = v.length;

    if (n == 0) return("");

    // TEA routine as per Wheeler & Needham, Oct 1998

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;

    while (sum != 0) {
        e = sum>>>2 & 3;
        for (var p = n-1; p > 0; p--) {
            z = v[p-1];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
            y = v[p] -= mx;
        }
        z = v[n-1];
        mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
        y = v[0] -= mx;
        sum -= delta;
    }

    var s = longsToStr(v);
    if (s.indexOf("\x00") != -1) {
        // strip trailing null chars resulting from filling 4-char blocks
        s = s.substr(0, s.indexOf("\x00"));
    }

    return unescape(s);
}


// supporting functions

function strToLongs(s) {  // convert string to array of longs, each containing 4 chars
    // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
    var l = new Array(Math.ceil(s.length/4))
    for (var i=0; i<l.length; i++) {
        l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) +
               (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
    }
    return l;  // note running off the end of the string generates nulls since
}              // bitwise operators treat NaN as 0

function longsToStr(l) {  // convert array of longs back to string
    var a = new Array(l.length);
    for (var i=0; i<l.length; i++) {
        a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF,
                                 l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
    }
    return a.join('');  // use Array.join() rather than repeated string appends for efficiency
}
// end Encryption Algorithm
//---------------------------------------------------------------------------



var clock;
function clockInit() {
	var infoWrap = document.createElement(div);

	clock = infoWrap.appendChild(document.createElement(div));
	clock.appendChild(document.createTextNode('GMT: '));
	clock.appendChild(document.createTextNode('00:00:00'));

	/* Insert Calendar tool here when needed (see wiki documentation) */

	var l = document.createElement('li');
	l.appendChild(infoWrap);
	document.getElementById('needToKnow').appendChild(l);
	clockTick();
}
function clockTick() {
 var dt = new Date();
 var def = dt.getTimezoneOffset()/60;
 var gmt = (dt.getHours() + def);
 var _GMT = check24(((gmt) > 24) ? ((gmt) - 24) : (gmt));
 clock.childNodes[1].nodeValue = (ifZero(_GMT) + ":" + ifZero(dt.getMinutes()) + ":" + ifZero(dt.getSeconds()));
 setTimeout("clockTick()", 1000);
}


var a, div, h;
if(document.getElementsByTagName("HTML")) {
	a = "A";
	div = "DIV";
	h = "H3";
}
else if(document.getElementsByTagName("html:html")) {
	a = "html:a";
	div = "html:div";
	h = "html:h3";
}
else {
	a = "a";
	div = "div";
	h = "h3";
}
function onLoadF() { initLinks(); clockInit(); oldestProp(); euclideanSpace(); }
function ifZero(num) { return ((num <= 9) ? ("0" + num) : num); }
function check24(hour) { return (hour >= 24) ? hour - 24 : hour; }

window.onload = onLoadF;