/*
 * Editable AccessKeys 0.13.4
 *  Copyright, 2006 Jacques Distler. All rights reserved.
 *  This software is released under LGPL.
 *
 *   See http://golem.ph.utexas.edu/~distler/blog/archives/000723.html
 *      for explanations.
 *
 *   version 0.13.4 Workaround for broken DOM Event support in IE6.
 *   version 0.12 Fixed a bug reported by Rich Pedley.
 *   version 0.11 Revised to disable Gez's updated script.
 *   version 0.10.2  Disable Gez Lemon's Greasemonkey script, which does
 *                   the same thing.
 *   version 0.9  Eliminate need for wrapper DIV. Accesskey definition-list
 *                   is assumed to have id="AccessKeyList"
 *   version 0.8, Keyboard navigation fix for Opera
 *   version 0.7, Separator character changed to TAB.
 *   version 0.6, Added onkeypress event handler for Safari-compatibility
 *   version 0.5, Initial release.
 */

/*
 * Global variables:
 */
HOST = 'golem.ph.utexas.edu';    /* You MUST customize this one! */
accesskeylistid="AccessKeyList"; /* Id of the accesskey definition-list */
accesskeystarttabindex = 1;      /* Tabindex values assigned to edit fields start
                                      with this value*/
defaultaccesskeys = new Array(); /* Array to hold the default values */
originalaccesskeys = new Array(); /* Array to hold the original values */
myaccesskeys = new Array();      /* Array to hold the user-edited values */
accesskeyelements = new Array(); /* Associative array to contain all elements
                                      with an accesskey attribute */

function initializeAccessKeys() {
/*
 * This is meant to run onload.
 *  Initialize the defaultaccesskeys and myaccesskeys arrays.
 *   These are either taken from a cookie or from the document.
 *  Extract all the elements on the current page with an accesskey attribute
 *   into the associative array "accesskeyelements".
 *  If necessary, rewrite the values of the accesskey attributes on
 *   the current page .
 *  Add an "edit" button.
 *  Disable Gez Lemon's Greasemonkey script, which does the same thing.
 */
    var dl =  document.getElementById(accesskeylistid);
    var keylist = dl.getElementsByTagName('dt');
    for (i = 0; i < keylist.length; i++){
        defaultaccesskeys[i] = keylist[i].firstChild.data;
        myaccesskeys[i] = defaultaccesskeys[i];
        originalaccesskeys[i] = defaultaccesskeys[i];
    }
    var taglist = ['a','label','area','button','input','legend','textarea'];
    for (i=0; i < taglist.length; i++) {
        var mytags=document.getElementsByTagName(taglist[i]);
        for (j=0; j < mytags.length; j++){
           var myaccesskeyval = mytags[j].getAttribute('accesskey');
           if (myaccesskeyval != '') {
              accesskeyelements[myaccesskeyval]=mytags[j];
           }
        }
    }
    var savedaccesskeystring = getCookie('accessKeys');
    if (savedaccesskeystring != '') {
        var savedacceskeys= new Array();
        savedaccesskeys = savedaccesskeystring.split('\t');
           if (savedaccesskeys.length == defaultaccesskeys.length) {
                for (i = 0; i < defaultaccesskeys.length; i++){
                  if (accesskeyelements[originalaccesskeys[i]] ) {
                        if (accesskeyelements[originalaccesskeys[i]].accessKey) {
                           accesskeyelements[originalaccesskeys[i]].accessKey =
                              myaccesskeys[i];
                        } else {
                           accesskeyelements[originalaccesskeys[i]].setAttribute(
                          'accesskey', myaccesskeys[i]);
                        }
                  }
                  if (accesskeyelements[originalaccesskeys[i]] ) {
                        if (accesskeyelements[originalaccesskeys[i]].accessKey) {
                           accesskeyelements[originalaccesskeys[i]].accessKey =
                              savedaccesskeys[i];
                        } else {
                           accesskeyelements[originalaccesskeys[i]].setAttribute(
                          'accesskey', savedaccesskeys[i]);
                        }
                  }
                  defaultaccesskeys[i] = savedaccesskeys[i];
                  myaccesskeys[i] = savedaccesskeys[i];
                  keylist[i].replaceChild(document.createTextNode(myaccesskeys[i]),
                        keylist[i].firstChild);
                }
           }
    }
    var edit = document.createElement('input');
    edit.setAttribute('id', 'editAccessKeys');
    edit.setAttribute('type', 'button');
    edit.setAttribute('value', 'edit');
    edit.onclick = editAccessKeys;
    edit.onkeypress  = function() {
          if(window.event.keyCode == 13) {editAccessKeys();return false;} };
    if (edit.tabindex) {
        edit.tabindex = defaultaccesskeys.length+accesskeystarttabindex;
    } else {
        edit.setAttribute('tabindex',
                defaultaccesskeys.length+accesskeystarttabindex);
    }
    var dlparent = dl.parentNode;
    dlparent.insertBefore(edit,dl.nextSibling);
    var greasy = document.getElementById('jsgmAccessKeyContainer');
    if(greasy) {
        greasy.replaceChild(dlparent,greasy.firstChild);
        var toremove = ['jsgmEdit','jsgmRestore','jsgmToggle'];
        for (i=0; i < toremove.length; i++ ) greasy.removeChild(
                        document.getElementById(toremove[i]));
        document.getElementsByTagName('head')[0].removeChild(
                        document.getElementById('jsgmAccessKeyStyles'));
        document.getElementsByTagName('body')[0].setAttribute('style','padding-bottom:4em');
        var keystyle= 'background:#CCC;color:#000;border:outset 2px; padding:1px 2px;';
        var key1 = document.createElement('span');
        key1.appendChild(document.createTextNode('Shift'));
        key1.setAttribute('style',keystyle + 'margin-left:48px;');
        dlparent.appendChild(key1);
        dlparent.appendChild(document.createTextNode('+'));
        var key2 = document.createElement('span');
        key2.appendChild(document.createTextNode('Esc'));
        key2.setAttribute('style',keystyle);
        dlparent.appendChild(key2);
        dlparent.appendChild(document.createTextNode(' to toggle menu'));
        greasy.setAttribute('style',
           'position:fixed;bottom:0;left:0;margin:0;width:100%;border-top:2px solid #666');
    }
}

function saveAccessKeys() {
/*
 * Replace the default values of the accesskeys by the ones
 *  from the myaccesskeys array.
 * Change the accesskey attribute values in the current document.
 * Store these values in a cookie.
 * Remove the editing fields.
 * Replace the "reset" and "save" buttons by the 'edit" button.
 */
    var dl =  document.getElementById(accesskeylistid);
    var keylist = dl.getElementsByTagName('dt');
    for (i = 0; i < keylist.length; i++){
        keylist[i].replaceChild(document.createTextNode(myaccesskeys[i]),
                keylist[i].firstChild);
        if (accesskeyelements[originalaccesskeys[i]]) {
           if (accesskeyelements[originalaccesskeys[i]].accessKey) {
                 accesskeyelements[originalaccesskeys[i]].accessKey = myaccesskeys[i];
           } else {
                 accesskeyelements[originalaccesskeys[i]].setAttribute('accesskey',
                     myaccesskeys[i]);
           }
        }
        defaultaccesskeys[i] = myaccesskeys[i];
    }
    var expires = new Date();
    var base = new Date(0);
    var offset = base.getTime();
    if (offset > 0) {
        expires.setTime(expires.getTime()-offset);
    }
    expires.setTime(expires.getTime() + 365 * 24 * 60 * 60 * 1000);
    document.cookie = 'accessKeys=' + escape(myaccesskeys.join('\t')) + "; expires="
        + expires.toGMTString() + "; path=/; domain=" + HOST;
    var editbutton  = document.getElementById('editAccessKeys');
    editbutton.setAttribute('value','edit');
    editbutton.onclick = editAccessKeys;
    editbutton.onkeypress = function() {
          if(window.event.keyCode == 13) {editAccessKeys();return false} };
    var savebutton  = document.getElementById('saveAccessKeys');
    dl.parentNode.removeChild(savebutton);
}

function resetAccessKeys() {
/*
 * Revert the myaccesskeys array to the default values.
 * Remove the editing fields.
 * Replace the "revert" and "save" buttons by the "edit" button.
 */
    var dl =  document.getElementById(accesskeylistid);
    var keylist = dl.getElementsByTagName('dt');
    for (i = 0; i < keylist.length; i++){
        keylist[i].replaceChild(document.createTextNode(defaultaccesskeys[i]),
                keylist[i].firstChild);
        myaccesskeys[i] = defaultaccesskeys[i];
    }
    var editbutton  = document.getElementById('editAccessKeys');
    editbutton.setAttribute('value','edit');
    editbutton.onclick = editAccessKeys;
    editbutton.onkeypress = function() {
          if(window.event.keyCode == 13) {editAccessKeys();return false} };
    var savebutton  = document.getElementById('saveAccessKeys');
    dl.parentNode.removeChild(savebutton);
}

function editAccessKeys() {
/*
 * Load the current accesskeys into editable fields.
 * Replace the "edit" button by "reset" and "save"
 * buttons.
 */
    var dl =  document.getElementById(accesskeylistid);
    var keylist = dl.getElementsByTagName('dt');
    for (i = 0; i < keylist.length; i++){
        var input = document.createElement('input');
        var keyvalue = defaultaccesskeys[i];
        input.setAttribute('size', '1');
        input.setAttribute('type', 'text');
        input.setAttribute('id', accesskeylistid + i );
        input.setAttribute('maxlength', '1');
        input.setAttribute('value', keyvalue);
        if (input.tabindex) {
            input.tabindex = i+accesskeystarttabindex;
        } else {
            input.setAttribute('tabindex', i+accesskeystarttabindex);
        }
        if (input.apppendChild) {
            input.appendChild(document.createTextNode(keyvalue));
        }
        input.onchange = function() {
            if (this.tabindex) {
                myaccesskeys[this.tabindex
                   - accesskeystarttabindex] = this.value;
            } else {
                myaccesskeys[this.getAttribute('tabindex')
                   - accesskeystarttabindex] = this.value;
            }
        }
        keylist[i].replaceChild(input, keylist[i].firstChild);
    }
    var editbutton  = document.getElementById('editAccessKeys');
    editbutton.setAttribute('value','reset');
    editbutton.onclick = resetAccessKeys;
    editbutton.onkeypress = function() {
          if(window.event.keyCode == 13) {resetAccessKeys();return false} };
    if (editbutton.tabindex) {
        editbutton.tabindex = i+accesskeystarttabindex;
    } else {
        editbutton.setAttribute('tabindex',i+accesskeystarttabindex);
    }
    var savebutton = document.createElement('input');
    savebutton.setAttribute('id', 'saveAccessKeys');
    savebutton.setAttribute('type', 'button');
    savebutton.setAttribute('value', 'save');
    savebutton.onclick = saveAccessKeys;
    savebutton.onkeypress = function() {
          if(window.event.keyCode == 13) {saveAccessKeys();return false;} };
    if (savebutton.tabindex) {
        savebutton.tabindex = i+accesskeystarttabindex+1;
    } else {
        savebutton.setAttribute('tabindex',i+accesskeystarttabindex+1);
    }
    dl.parentNode.insertBefore(savebutton,editbutton.nextSibling);
}

function getCookie (name) {
    var prefix = name + '=';
    var cookiestring = document.cookie;
    var cookieStart = cookiestring.indexOf(prefix);
    if (cookieStart == -1) {
        return '';
    }
    var cookieEnd = cookiestring.indexOf(";", cookieStart + prefix.length);
    if (cookieEnd == -1) {
        cookieEnd = cookiestring.length;
    }
    return unescape(cookiestring.substring(cookieStart + prefix.length, cookieEnd));
}
