﻿if (jsStartLoad('Utils')) {

// ====
// General stuff

function addListener(obj, event, fn) {
    var domLoad=((obj == window)&&(event=='_domload'));
    if (domLoad){event = 'load';}
    if (obj.addEventListener) {
        if (domLoad)
		    document.addEventListener('DOMContentLoaded', function(){dropListener(obj, event, fn); fn();}, false);
	    obj.addEventListener(event, fn, false);
    }
    else if (obj.attachEvent) {
        if (domLoad) {
            document.attachEvent('onreadystatechange', function() {domReady(obj, event, fn, arguments.callee);});
        }
	    obj.attachEvent('on'+event, fn);
    }
}
function dropListener(obj, event, fn) {
    if (obj.removeEventListener) {
	    obj.removeEventListener(event, fn, false);
    }
    else if (obj.detachEvent) {
	    obj.detachEvent('on'+event, fn);
    }
}
function domReady(obj, event, fn, listener) {
    if (document.readyState == 'complete') {
        dropListener(document, 'onreadystatechange', listener);
        dropListener(obj, event, fn);
        fn();
    }
}
// trim() all inputs in a form
function trimForm(form) {
    var els = form.elements;
    for (var i = 0; i < els.length; i++) {
        var el = els[i];
        if (el.nodeName.match(/(input|textarea)/i))
            el.value = el.value.trim();
    }
}
// show or hide all spans inside box that have class 'hint'
function showHints(box, show) {
	var spans = box.getElementsByTagName('span');
	for (var i = 0; i < spans.length; i++) {
		if (spans[i].className.match('hint')) {
			spans[i].style.visibility = (show ? 'visible' : 'hidden');
		}
	}
}
// show or hide the rollup div inside el's containing box
function rollUpDn(el) {
    var box = myBox(el);
    document.body.appendChild(document.body.lastChild); // ie<=7 layout hack
    var rollUp = firstClass(box, 'rollUp');
    if (el.rollOpen) {
        el.rollOpen = false;
        el.className = el.className.replace(/Open/, 'Closed');
        rollUp.style.display = '';
    }
    else {
        el.rollOpen = true;
        el.className = el.className.replace(/Closed/, 'Open');
        rollUp.style.display = 'block';
    }
}
// Find the containing "box" (any container with class "box")
function myBox(el) {
    while (el) {
        if (el.className.match('box')) break;
        el = el.parentNode;
    }
    return el;
}
// Find the containing form (nb. use el.form for inputs)
function myForm(el) {
    while (el) {
        if (el.tagName && el.tagName.toLowerCase() == 'form') break;
        el = el.parentNode;
    }
    return el;
}

// Submit the form given el being any element inside it
function submitMe(el) {
    el = myForm(el);
    if (el) el.submit();
    return (el != null);
}

// First element in box of class cls
function firstClass(box, cls) {
    var els = box.getElementsByTagName('*');
    for (var i = 0; i < els.length; i++) {
        if (els[i].className.match(cls)) return els[i];
    }
    return null;
}

// Search [box] for [tag] element named [name]
function boxEl(box, tag, name) {
    var els = box.getElementsByTagName(tag);
    for (var i = 0; i < els.length; i++) {
        if (els[i].name == name) return els[i];
    }
    return null;
}

// Iterate through box's els; display='' els w className in array show; display='none' els w className in array hide
function showHide(box, show, hide) {
    var els = box.getElementsByTagName('*');
    for (var i = 0; i < els.length; i++) {
        if (show) for (var j = 0; j < show.length; j++) {
            if (els[i].className.match(show[j]))
                els[i].style.display = '';
        }
        if (hide) for (var j = 0; j < hide.length; j++) {
            if (els[i].className.match(hide[j]))
                els[i].style.display = 'none';
        }
    }
}

// ====
// Downloading files / locations from the server

// Thanks http://en.design-noir.de/webdev/JS/XMLHttpRequest-IE/ !
/*@cc_on @if (@_win32 && @_jscript_version >= 5) if (!window.XMLHttpRequest)
window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP') }
@end @*/

function getRq(url, onFinish, ctxt, nocache) {
    var rq;
    if (url) {
        try {
            rq = new XMLHttpRequest();
            rq.open("GET", url, true);
            if (nocache) {
                rq.setRequestHeader('Cache-Control', 'no-cache');
            }
            //rq.setRequestHeader('Connection', 'close'); // do we need this? No! It causes ie to hang on readystate 3
            // http://skeymedia.com/ie6-ajax-hang-on-readystate-3/ (seems only to have been happening on POSTs though)
            if (onFinish) {
                rq.onreadystatechange = function() { if (rq.readyState == 4) { onFinish(rq, ctxt); rq = null; ctxt = null; } }
            }
            rq.send(null);
            setTimeout(finishRequest, 50);
        } catch (e) { }
    }
    return rq;
}
// onFinish: function(XMLHttpRequest, ctxt)
function postRq(url, onFinish, ctxt, form) {
    var parms = getAll(form);
    var rq;
    if (url) {
        try {
            rq = new XMLHttpRequest();
            rq.open("POST", url, true);
            rq.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            rq.setRequestHeader('Content-length', parms.length);
            //rq.setRequestHeader('Connection', 'close'); // do we need this? No! It causes ie to hang on readystate 3
            // http://skeymedia.com/ie6-ajax-hang-on-readystate-3/
            if (onFinish) {
                rq.onreadystatechange = function() { if (rq.readyState == 4) { onFinish(rq, ctxt); rq = null; ctxt = null; } }
            }
            rq.send(parms);
            setTimeout(finishRequest, 50);
        } catch (e) { }
    }
    return rq;
}
// return urlencoded name=value pairs string for all inputs on the form
function getAll(form) {
    var str = '';
    if (form) {
        var els = form.elements;
        for (var i = 0; i < els.length; i++) {
            with (els[i]) {
                str += URLEncode(name) + '=' + URLEncode(value) + '&';
            }
        }
    }
    return str;
}
// Why isn't this built in? Maybe it is - encodeURIComponent()? encodeURI()? http://xkr.us/articles/javascript/encode-compare/
function URLEncode(plain) {
    var safe = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "-_.!~*'()";
    var hex = "0123456789ABCDEF";

    var coded = '';
	plain = plain.replace(/\r\n/g,'\n');

    for (var i = 0; i < plain.length; i++) {
        var ch = plain.charAt(i);
        if (ch == ' ') {
            coded += '+'; // x-www-urlcoded uses '+' not '%20'
        } else if (safe.indexOf(ch) != -1) {
            coded += ch;
        } else {
            var charCode = ch.charCodeAt(0);
            coded += '%';
            coded += hex.charAt((charCode >> 4) & 0xF);
            coded += hex.charAt(charCode & 0xF);
        }
    }
    return coded;
}

// Thanks http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
function WinSize() {
	this.w = f_clientWidth();
	this.h = f_clientHeight();
	this.x = f_scrollLeft();
	this.y = f_scrollTop();
}
function f_clientWidth() {
	return f_filterResults (
		window.innerWidth ? window.innerWidth : 0,
		document.documentElement ? document.documentElement.clientWidth : 0,
		document.body ? document.body.clientWidth : 0
	);
}
function f_clientHeight() {
	return f_filterResults (
		window.innerHeight ? window.innerHeight : 0,
		document.documentElement ? document.documentElement.clientHeight : 0,
		document.body ? document.body.clientHeight : 0
	);
}
function f_scrollLeft() {
	return f_filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function f_scrollTop() {
	return f_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}


// ====
// Tracking the mouse position

var mouseX = 0, mouseY = 0;

//document.onmousemove = getMousePosition;
function getMousePosition(e) {
	if (!e) e = window.event;
	if (e.pageX || e.pageY) {
		mouseX = e.pageX;
		mouseY = e.pageY;
	}
	else if (e.clientX || e.clientY) { // ie
		mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
	return true;
}

// getMousePosition for ie fails before document.body exists so set listener onload
function listenForMouseMoves() {
    addListener(document, 'mousemove', getMousePosition);
}

addListener(window, '_domload', listenForMouseMoves);

// Cancel event bubbling
function noBubble(e) {
	if (!e) e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

// ====
// Dates

function DateToString(dpDate) {
    var d, m, y;
    d = '0' + dpDate.getDate();
    m = '0' + (dpDate.getMonth() + 1);
    y = dpDate.getFullYear();
    d = d.substring(d.length - 2);
    m = m.substring(m.length - 2);
    return d + '/' + m + '/' + y;
}
function StringToDate(dateString) {
    var vals, d, m, y;
    var str = dateString.replace(/[ \.\-\\]/g, '/'); // replace common separators ( .-\) with /
    var result;
    if (!str.match('/')) { // no separators maybe it's longhand
        result = new Date(dateString);
    }
    else {
        vals = str.split('/');
        try {
            d = parseInt(vals[0], 10);
            m = parseInt(vals[1], 10) - 1;
            y = parseInt(vals[2], 10);
            result = new Date(y, m, d);
        }
        catch (e) { result = 0; }
    }
    if (isNaN(result)) result = 0;
    return result;
}

} // Utils

