/**
 * Routines for interacting with users via error/warning notifications.
 *
 * This file was originally written by Chris Petersen for several different open
 * source projects.  It is distrubuted under the GNU General Public License.
 * I (Chris Petersen) have also granted a special LGPL license for this code to
 * several companies I do work for on the condition that these companies will
 * release any changes to this back to me and the open source community as GPL,
 * thus continuing to improve the open source version of the library.  If you
 * would like to inquire about the status of this arrangement, please contact
 * me personally.
 *
 * 
 * 
 * 
 * 
 * @copyright   Silicon Mechanics
 * @license     LGPL
 *
 * @package     SiMech
 * @subpackage  Shared-OSS
 * @subpackage  Javascript
 *
 * @uses        browser.js
 * @uses        prototype.js
 *
/**/

/**
 * Notify the user of an error.
 *
 * @deprecated function, should be replaced by direct call to js_user_errors()
/**/
    function error_notify(title, text) {
        js_user_errors({'title':title,'items':[text]});
    }

/**
 * Create the js_user_errors element to display errors created from other areas
 * of javascript code.  The parameters can take any of the three following
 * formats:
 *
 *      "Some long error message"
 *      {'title':'My Errors','items':['err1', 'err2']}
 *      ['err1','err2']
 *
/**/
    function js_user_errors(errors, warnings, notices) {
        var div = $('js_user_errors');
        if (div) {
            div.style.visibility = 'hidden';
            div.style.display    = '';
            div.innerHTML        = '';
        }
        else {
            div = document.createElement('DIV');
            Element.extend(div);
            div.id               = 'js_user_errors';
            div.style.visibility = 'hidden';
            div.addClassName('user_errors');
            div.addClassName('js');
            document.body.appendChild(div);
        }
    // Fill the div with the appropriate data
        if (errors) {
            var ediv = document.createElement('DIV');
            Element.extend(ediv);
            ediv.addClassName('error');
        // String
            if (typeof errors == 'string') {
                ediv.innerHTML = errors;
            }
        // Object or Array
            else if (typeof errors == 'object') {
                var h3 = document.createElement('H3');
                Element.extend(h3);
                if (errors.title) {
                    h3.innerHTML = errors.title;
                    errors = errors.items;
                }
                else
                    h3.innerHTML = 'Error:';
                ediv.appendChild(h3);
                if (errors instanceof Array && errors.length > 0) {
                    var ul = document.createElement('UL');
                    Element.extend(ul);
                    for (var i = 0, len = errors.length; i < len; ++i) {
                        var li = document.createElement('LI');
                        Element.extend(li);
                        li.innerHTML = errors[i];
                        ul.appendChild(li);
                    }
                    ediv.appendChild(ul);
                }
            }
        // And don't forget to add it to the document
            div.appendChild(ediv);
        }
        if (warnings) {
            var wdiv = document.createElement('DIV');
            Element.extend(wdiv);
            wdiv.addClassName('warning');
        // String
            if (typeof warnings == 'string') {
                wdiv.innerHTML = warnings;
            }
        // Object or Array
            else if (typeof warnings == 'object') {
                var h3 = document.createElement('H3');
                Element.extend(h3);
                if (warnings.title) {
                    h3.innerHTML = warnings.title;
                    warnings = warnings.items;
                }
                else
                    h3.innerHTML = 'Warning:';
                wdiv.appendChild(h3);
                if (warnings instanceof Array && warnings.length > 0) {
                    var ul = document.createElement('UL');
                    Element.extend(ul);
                    for (var i = 0, len = warnings.length; i < len; ++i) {
                        var li = document.createElement('LI');
                        Element.extend(li);
                        li.innerHTML = warnings[i];
                        ul.appendChild(li);
                    }
                    wdiv.appendChild(ul);
                }
            }
        // And don't forget to add it to the document
            div.appendChild(wdiv);
        }
        if (notices) {
            var ndiv = document.createElement('DIV');
            Element.extend(ndiv);
            ndiv.addClassName('notice');
        // String
            if (typeof notices == 'string') {
                ndiv.innerHTML = notices;
            }
        // Object or Array
            else if (typeof notices == 'object') {
                var h3 = document.createElement('H3');
                Element.extend(h3);
                if (notices.title) {
                    h3.innerHTML = notices.title;
                    notices = notices.items;
                }
                else
                    h3.innerHTML = 'Notice:';
                ndiv.appendChild(h3);
                if (notices instanceof Array && notices.length > 0) {
                    var ul = document.createElement('UL');
                    Element.extend(ul);
                    for (var i = 0, len = notices.length; i < len; ++i) {
                        var li = document.createElement('LI');
                        Element.extend(li);
                        li.innerHTML = notices[i];
                        ul.appendChild(li);
                    }
                    ndiv.appendChild(ul);
                }
            }
        // And don't forget to add it to the document
            div.appendChild(ndiv);
        }
    // Add the commands div
        var cdiv = document.createElement('DIV');
        Element.extend(cdiv);
        cdiv.id = 'user_errors_commands';
        cdiv.innerHTML = '<a id="hide_js_user_errors" class="dismiss" onclick="hide_js_user_errors()">Dismiss</a>';
        div.appendChild(cdiv);
    // Show the message(s)
        display_user_errors('js_user_errors');
    }

/**
 * Provide fancy javascript display of an already-rendered user_errors element
/**/
    function display_user_errors(div_id) {
    // Make sure browser is defined
        if (!browser) {
            alert('Developer Error:  browser.js is needed for notify.js, but was not loaded.');
            return;
        }
    // Default value for div_id
        if (!div_id) {
            if ($('js_user_errors') && $('js_user_errors').style.visibility == 'visible')
                div_id = 'js_user_errors';
            else
                div_id = 'user_errors';
        }
    // Get some info about the window so we can position the notification appropriately
        var window_width = 0, window_height = 0;
        if (window.innerHeight) {                                                     // all except Explorer
            window_width  = window.innerWidth;
            window_height = window.innerHeight;
        }
        else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
            window_width  = document.documentElement.clientWidth;
            window_height = document.documentElement.clientHeight;
        }
        else if (document.body) {                                                     // other Explorers
            window_width  = document.body.clientWidth;
            window_height = document.body.clientHeight;
        }
    // Do we need to create a buffer to go beneath the error?
        var buffdiv = $('user_errors_buffer');
        if (buffdiv) {
            buffdiv.style.visibility = 'hidden';
            buffdiv.style.display    = '';
        }
    // IE < 7 gets position:absolute with magic onscroll movement
        if (browser.is_ie && browser.v_ie < 7)
            buffdiv.style.position = 'absolute';
        else
            buffdiv.style.position = 'fixed';
    // Show the commands div
        $('user_errors_commands').style.display = '';
    // Load the error div
        var div = $(div_id);
        div.style.zIndex     = 9999;
        div.style.visibility = 'hidden';
        div.style.display    = '';
        div.addClassName('js');
    // IE < 7 gets position:absolute with magic onscroll movement
        if (browser.is_ie && browser.v_ie < 7)
            div.style.position = 'absolute';
        else
            div.style.position = 'fixed';
    // Add the special IE event handlers to reposition the error handlers
    // if the user tries to scroll the page, etc.
        if (browser.is_ie && browser.v_ie < 7) {
            Event.observe(window,   'scroll', display_user_errors);
            Event.observe(document, 'click',  display_user_errors);
        }
    // Center the div on the page
        var top  = parseInt((window_height - div.offsetHeight) / 2);
        var left = parseInt((window_width  - div.offsetWidth)  / 2);
    // IE gets special position:absolute treatment to account for scrolling
        if (browser.is_ie && browser.v_ie < 7) {
            div.style.top      = (top  + document.documentElement.scrollTop)  + 'px';
            div.style.left     = (left + document.documentElement.scrollLeft) + 'px';
            buffdiv.style.top  = document.documentElement.scrollTop  + 'px';
            buffdiv.style.left = document.documentElement.scrollLeft + 'px';
            buffdiv.style.height = window_height + 'px';
            buffdiv.style.width  = window_width  + 'px';
        }
        else {
            div.style.top      = top  + 'px';
            div.style.left     = left + 'px';
            buffdiv.style.top  = '0px';
            buffdiv.style.left = '0px';
        }
    // Show the divs
        buffdiv.style.visibility = 'visible';
        div.style.visibility     = 'visible';
    // Focus the appropriate button, or at least steal focus from the main page
    // so users don't accidentally trigger something if they press enter to
    // dismiss the error/warning.  This doesn't seem to actually focus the
    // element in FF, but at least it seems to take focus away from anything
    // else in the page, too.
        if ($('reset_user_errors'))
            $('reset_user_errors').focus();
        else if ($('hide_user_errors'))
            $('hide_user_errors').focus();
        else if ($('hide_js_user_errors'))
            $('hide_js_user_errors').focus();
        else if ($('user_errors_commands'))
            $('user_errors_commands').focus();
    }

/**
 * Return the the error notification box created by display_user_errors() to
 * its non-javascript state.
/**/
    function reset_user_errors() {
    // Hide the things that we don't need anymore
        $('user_errors_buffer').style.display   = 'none';
        $('user_errors_commands').style.display = 'none';
    // Undo as much as we can
        var div = $('user_errors');
        div.style.height = '';
        div.style.width  = '';
        div.style.top    = '';
        div.style.right  = '';
        div.style.bottom = '';
        div.style.left   = '';
        div.style.zIndex = 1;
        div.removeClassName('js');
        div.style.position       = 'relative';
    // Remove the special IE events
        if (browser.is_ie && browser.v_ie < 7) {
            Event.stopObserving(window,   'scroll', display_user_errors);
            Event.stopObserving(document, 'click',  display_user_errors);
        }
    }

/**
 * Dismiss the error notification box created by js_user_errors()
/**/
    function hide_js_user_errors() {
        if ($('js_user_errors'))
            $('js_user_errors').style.display     = 'none';
        if ($('user_errors_buffer'))
            $('user_errors_buffer').style.display = 'none';
    // Remove the special IE events
        if (browser.is_ie && browser.v_ie < 7) {
            Event.stopObserving(window,   'scroll', display_user_errors);
            Event.stopObserving(document, 'click',  display_user_errors);
        }
    }

/**
 * Dismiss the error notification box created by display_user_errors()
/**/
    function hide_user_errors() {
        if ($('user_errors'))
            $('user_errors').style.display        = 'none';
        if ($('user_errors_buffer'))
            $('user_errors_buffer').style.display = 'none';
    // Remove the special IE events
        if (browser.is_ie && browser.v_ie < 7) {
            Event.stopObserving(window,   'scroll', display_user_errors);
            Event.stopObserving(document, 'click',  display_user_errors);
        }
    }

