// ---------------------------------------------------------------------
// $Id: dom-prototype.js,v 1.3 2008/10/14 00:26:37 cvsuser Exp $
// ---------------------------------------------------------------------
// Convenience DOM enhancements. Picks up where Prototype left off.
//
// Requires prototype.js.
// ---------------------------------------------------------------------

/*@cc_on @*/     // Who doesn't love IE?

// ---------------------------------------------------------------------
// Add a bunch of CSS code to the document.
// From http://yuiblog.com/blog/2007/06/07/style/
//
// Prototype doesn't have a function like this one yet!

function dnAddCss (cssCode) {
    var styleElement = document.createElement("style");
    styleElement.type = "text/css";
    
    if (styleElement.styleSheet) {
        styleElement.styleSheet.cssText = cssCode;
    } else {
        styleElement.appendChild(document.createTextNode(cssCode));
    }
    
    document.getElementsByTagName("head")[0].appendChild(styleElement);
};

// ---------------------------------------------------------------------
// Loads a JavaScript script by writing out a script tag, but checks
// that it hasn't already loaded it before doing so.

function dnLoadScript (url) {
    if (!window.dnLoadScript.seen) window.dnLoadScript.seen = { };
    if (window.dnLoadScript.seen[url]) return;
    document.write("<script type='text/javascript' src='"+url+"'></script>");
    window.dnLoadScript.seen[url] = true;
}

// ---------------------------------------------------------------------
// Safari and Opera have problems with the img.complete property. To work
// around this, call dnImageCompleteWatch() on an img element before
// assigning it a (new) src. Then call dnImageComplete to test if the image
// has finished loading.
//
// Prototype doesn't seem to have anything for this yet.

function dnImageCompleteWatch (img) {
    if (img.complete != null) return img;
    img.dnImageComplete = false;
    img.onload = function (e) { img.dnImageComplete = true; };
    return img;
};

function dnImageComplete (img) {
    if (img.complete != null) return img.complete;
    if (img.dnImageComplete != null) return img.dnImageComplete;
    return false;
};

// ---------------------------------------------------------------------
// Create, show and hide iframe shields for a specified overlay to fix
// the z-index bug and windowed elements in IE6.
//
// Does scriptaculous have anything that does this?

function enableShieldedOverlayForIE (elem) {
    /*@if (@_jscript_version <= 5.6)
    var id = $(elem).identify();
    var iframeShield = $(id + ":iframeShield");
    if (!iframeShield) {
        iframeShield = document.createElement("iframe");
        iframeShield.id = id + ":iframeShield";
        iframeShield.style.position = "absolute";
        var zIndex = dnGetStyle($(id), "zIndex");
        if (zIndex) iframeShield.style.zIndex = parseInt(zIndex);
        iframeShield.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
        $(id).parentNode.insertBefore(iframeShield, $(id));
    }
    iframeShield.style.width = $(id).offsetWidth + "px";
    iframeShield.style.height = $(id).offsetHeight + "px";
    iframeShield.style.left = $(id).style.left;
    iframeShield.style.top = $(id).style.top;
    iframeShield.style.display = "block";
    @end @*/
};

function disableShieldedOverlayForIE (elem) {
    /*@if (@_jscript_version <= 5.6)
    var id = $(elem).identify();
    var iframeShield = $(id + ":iframeShield");
    if (iframeShield) iframeShield.style.display = "none";
    @end @*/
};

// ---------------------------------------------------------------------
// Standard cookie routines.
// From http://www.quirksmode.org/js/cookies.html
//
// Prototype doesn't seem to provide these. There may be a case that 
// these are in fact broken, because they should use url encoding.

function dnCreateCookie(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 dnReadCookie(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 dnDeleteCookie(name) {
	createCookie(name,"",-1);
};



// ---------------------------------------------------------------------
// DEPRICATED FUNCTIONS
//
// Every function below this point is depricated. Since you're already
// using Prototype, you should use the appropriate Prototype method
// to accomplish what these functions do. They're only still in here
// to provide backwards compatability.
// ---------------------------------------------------------------------


// ---------------------------------------------------------------------
// Get the computed style property of an element.
// From http://www.quirksmode.org/dom/getstyles.html
//
// This function is broken, and depricated! Use Prototype's
// Element.getStyle() instead, which properly works around browser
// incompatabilities.

function dnGetStyle (elem, prop) {
    var x = $(elem);
    if (x.currentStyle)
        var y = x.currentStyle[prop];
	else if (window.getComputedStyle)
        var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(prop);
    return y;
};

// ---------------------------------------------------------------------
// dnXhr() performs an asynchronous HTTP request.
//
// Depricated. All new code should use the Prototype Ajax methods.

function dnXhr (url, params, callback, method, headers) {
    // Let's create a new XMLHttpRequest object.
    var xhr = null;
    if (window.XMLHttpRequest) {
        try { xhr = new XMLHttpRequest(); }
        catch (e) { xhr = null; }
    }
    else if (window.ActiveXObject) {
       	try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); }
       	catch (e) {
            try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
            catch (e) { xhr = null; }
    	}
    }
    if (!xhr) return null;
    
    // Save the XHR object for the callback and for potential abort() calls.
    if (!dnXhr.pending) dnXhr.pending = [];
    var xhrId = dnXhr.pending.length;
    dnXhr.pending.push({"url": url, "xhr": xhr});

    // Default to POST. Make sure params is defined.
    if (!method) method = "post";
    if (!params) params = { };

    // Prevent IE from caching responses to POSTs by making sure there is
    // at least always one parameter.
    if (/^post$/i.test(method)) params.__dnXhrIECacheBust__ = 1;
    
    // Convert the parameters into a query string.
    var q = dnXhr._createQueryString(params);
    
    // Add the query string to url if we're doing GET.
    if (q != "" && /^get$/i.test(method)) url += "?" + q;
    
    // Set up the callback.
    xhr = null;  // Keep this from getting in the closure: avoids IE's bad GC.
    dnXhr.pending[xhrId].xhr.onreadystatechange = function () {
        var xhr = window.dnXhr.pending[xhrId].xhr;
        
        // Get the status, and catch any errors FF throws.
        var status = -1;
        try { status = xhr.status; } catch (e) { };
        
        if (xhr.readyState == 4) {
            window.dnXhr.pending[xhrId] = null;
            if (status == 200) {
                if (callback) callback(xhr);
            } else {
                try {
                    if (console && console.error)
                        console.error("XMLHttpRequest error: "+ xhr.statusText);
                }
                catch (e) { }
            }
        }
    };
    xhr = dnXhr.pending[xhrId].xhr;  // Restore the xhr variable.
    
    // Kick off the request.
    xhr.open(method, url, true);
    if (headers) for (var h in headers) { xhr.setRequestHeader(h, headers[h]); }
    if (/^post$/i.test(method)) {        
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send(q);
    }
    else xhr.send(null);
    return xhr;
};

dnXhr.abortAll = function () {
    if (!window.dnXhr.pending) return;
    for (var i = window.dnXhr.pending.length - 1; i >= 0; i--) {
        var o = window.dnXhr.pending[i];
        if (!o) continue;
        if (o.xhr) o.xhr.abort();
    }
};

dnXhr.abortForUrl = function (url) {
    if (!window.dnXhr.pending) return;
    for (var i = window.dnXhr.pending.length - 1; i >= 0; i--) {
        var o = window.dnXhr.pending[i];
        if (!o) continue;
        if (o.url != url) continue;
        o.xhr.abort();
    };
};

dnXhr._createQueryString = function (params) {
    var keys = [];
    for (var key in params) { keys.push(key); }
    keys.sort();
    
    var q = "";
    for (var i = 0; i < keys.length; i++) {
        var name = encodeURIComponent(keys[i]);
        var value = params[keys[i]];

        if (typeof value == "function") continue;
        if (typeof value == "object") {
            for (var j in value) {
                if (typeof value[j] == "function") continue;
                q += name + "=" + encodeURIComponent(value[j]) + "&";
            }
        }
        else {
            q += name + "=" + encodeURIComponent(value) + "&";
        }
    };
    
    return q.replace(/&$/, "");
};

// ---------------------------------------------------------------------
// Do a same-site javascript include. (Use xsinclude.js for doing
// doing cross site includes.)
//
// Depricated. Use Ajax.Updater instead!

function dnXhrInclude (divConf, url, query) {
    if (!divConf || !url) return false;
    if (!divConf.id) return false;
    if (!divConf.style) divConf.style = "display:none"
    
    // Create and write out the div.
    var div = "<div id=\"" + divConf.id + "\" ";
    div += "style=\"" + divConf.style + "\" ";
    if (divConf["class"]) div += "class=\"" + divConf["class"] + "\" ";
    div += "></div>";
    document.write(div);
    
    var f = function () {
        dnXhr(url, query, function (xhr) {
            // Ideally, we would just put the response from the xhr object
            // into div.innerHTML, but supposedly IE6 has problems with
            // with inserting form or form related elements via innerHTML.
            // I haven't been able to duplicate these problems, but just to
            // be on the safe side, the following method should avoid them.
            var div = $(divConf.id);
            var divCopy = div.cloneNode(false);
            divCopy.innerHTML = xhr.responseText;
            
            div.id = divCopy.id + ":dnXhrInclude";
            div.parentNode.insertBefore(divCopy, div);
            div.parentNode.removeChild(div);
            
            divCopy.style.display = "block";
        }, "get");
    };
    
    dnAddEvent(window, "dndomload", f);
};

// ---------------------------------------------------------------------
// Functions that have been rewritten to take advantage of Prototype,
// while still maintaining backwards compatability. Consider them all
// depricated.

function dnGetElementsByClassName(className, tag, elem){
    var selector = "." + className;
    if (tag) selector = tag + selector;
    if (elem) return $(elem).select(selector);
    else return $$(selector);
};

function dnAddEvent(obj, type, fn) {
    if (type == "dndomload")
        return Event.observe(document, "dom:loaded", fn);
    else if (obj && $(obj).observe)
        return $(obj).observe(type, fn);
    else
        return Event.observe(obj, type, fn);
};

function dnRemoveEvent(obj, type, fn) {
    return $(obj).stopObserving(type, fn);
};

function dnStopPropagation (e) {
    return Event.stop(e);
};

function dnContains (parent, child) {
    return $(child).descendantOf(parent);
};

function dnFindPos(obj) {
    return $(obj).cumulativeOffset();
};

function dnConcatNodeLists () {
    var result = [];
    $A(arguments).each(function (nodelist) {
        result.push($A(nodelist));
    });
    return result;
};

// ---------------------------------------------------------------------

