var HOST = 'golem.ph.utexas.edu';

// Copyright (c) 1996-1997 Athenia Associates.
// http://www.webreference.com/js/
// License is granted if and only if this entire
// copyright notice is included. By Tomer Shiran.

//Adapted by J. Distler for XHTML compatibility, Mar 2003.

function setCookie (name, value, expires, path, domain, secure) {
    var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
    document.cookie = curCookie;
}

 function getCookie (name) {
    var prefix = name + '=';
    var c = document.cookie;
    if (!c)
      return '';
    var nullstring = '';
    var cookieStartIndex = c.indexOf(prefix);
    if (cookieStartIndex == -1)
        return nullstring;
    var cookieEndIndex = c.indexOf(";", cookieStartIndex + prefix.length);
    if (cookieEndIndex == -1)
        cookieEndIndex = c.length;
    return unescape(c.substring(cookieStartIndex + prefix.length, cookieEndIndex));
}

function fixDate (date) {
    var base = new Date(0);
    var skew = base.getTime();
    if (skew > 0)
        date.setTime(date.getTime() - skew);
}

function setIEcookie () {
    var now = new Date();
    fixDate(now);
    now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
    setCookie('ieLuser', 'luser', now, '/', HOST, '');
}

function warnIE() {
   var havemp = false;
   var temp, version;
   if ( (navigator.appName == "Microsoft Internet Explorer" ) && !(navigator.userAgent.indexOf("Opera") > -1) ) {
      if ( !getCookie('ieLuser') ) {
          setIEcookie ();
          window.open('/~distler/blog/ie.html', 'InternetExploder',
                    'width=460,height=246,scrollbars=no,resizable=yes,status=no');
      } else {
        if ( navigator.userAgent.indexOf("MathPlayer") > -1)
		         { havemp = true; }
        temp=navigator.appVersion.split("MSIE");
        version=parseFloat(temp[1]);
        if ( (version >= 6.0) && !havemp && !getCookie('hateMP') ) {
           window.open('/~distler/blog/mp.html', 'MathPlayer',
                    'width=460,height=146,scrollbars=no,resizable=yes,status=no');
        }
      }
  }
}

function OpenComments (c) {
    window.open(c,
                    Math.round(Math.random()*10000),
                    'width=600,height=480,scrollbars=yes,resizable=yes,status=yes');
}

function OpenRSS () {
    window.open('/~distler/blog/rss.html',
         'RSS', 'width=305,height=190,scrollbars=no,resizable=yes,status=no');
}

function styleAbbr() {
	var oldBodyText, newBodyText, reg
	if ( (navigator.appName == "Microsoft Internet Explorer" ) && !(navigator.userAgent.indexOf("Opera") > -1) ) {
		oldBodyText = document.body.innerHTML;
		reg = /<(ABBR|ACRONYM)([^>]+)>([^<]+)<\/(ABBR|ACRONYM)>/g;
		newBodyText = oldBodyText.replace(reg, '<$1 $2><SPAN class=\"abbr\" $2>$3</SPAN></$4>');
		document.body.innerHTML = newBodyText;
	}
}

/*
* Based on Simon Willison's blockquotes.js
*   http://simon.incutio.com/archive/2002/12/20/#blockquoteCitations
*/
function extractBlockquoteCitations() {
  var quotes = document.getElementsByTagName('blockquote');
  for (i = 0; i < quotes.length; i++) {
    var cite = quotes[i].getAttribute('cite');
    if (cite && cite != '') {
      var newlink = createElement('a');
      newlink.setAttribute('href', cite);
      newlink.setAttribute('title', cite);
      newlink.appendChild(document.createTextNode('#'));
      var newspan = createElement('span');
      newspan.setAttribute('class','blockquotesource');
      newspan.appendChild(newlink);
      var foo = quotes[i].lastChild;
      if (foo.nodeType == 1) {
        foo.appendChild(newspan);
      } else {
        foo.previousSibling.appendChild(newspan);
      }
    }
  }
}

/*
 * 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:
 */
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 = 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 = createElement('span');
        key1.appendChild(document.createTextNode('Shift'));
        key1.setAttribute('style',keystyle + 'margin-left:48px;');
        dlparent.appendChild(key1);
        dlparent.appendChild(document.createTextNode('+'));
        var key2 = 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 = 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 = 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);
}

/*
    Written by Jonathan Snook, http://www.snook.ca/jonathan
    Add-ons by Robert Nyman, http://www.robertnyman.com
*/
function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }  
    }
    return (arrReturnElements)
}

/*  SwitchComments
 *  Switch between threaded and chronological view of the comments.
 *  Copyright, 2006 Jacques Distler. All rights reserved.
 *  This software is free for noncommercial use, so long as this copyright notice is preserved.
 */

savedComments = new Object;
sortedComments = new Object;
parentComments = new Object;

function viewchronological() {
   parentComments.replaceChild(sortedComments, savedComments);
   var dethread = document.getElementById('dethread');
   var dethread2 = document.getElementById('dethread2');
   dethread.setAttribute('value', 'view threaded');
   dethread.onclick = viewthreaded;
   dethread.onkeypress  = function() {
          if(window.event.keyCode == 13) {viewthreaded;return false;} };
   dethread2.setAttribute('value', 'view threaded');
   dethread2.onclick = viewthreaded;
   dethread2.onkeypress  = function() {
          if(window.event.keyCode == 13) {viewthreaded;return false;} };
}

function viewthreaded() {
   parentComments.replaceChild(savedComments, sortedComments);
   var dethread = document.getElementById('dethread');
   var dethread2 = document.getElementById('dethread2');
   dethread.setAttribute('value', 'view chronologically');
   dethread.onclick = viewchronological;
   dethread.onkeypress  = function() {
          if(window.event.keyCode == 13) {viewchronological;return false;} };
   dethread2.setAttribute('value', 'view chronologically');
   dethread2.onclick = viewchronological;
   dethread2.onkeypress  = function() {
          if(window.event.keyCode == 13) {viewchronological;return false;} };
}

function setupComments () {
/* This is designed to be executed on page-load.
 * The original threaded comments go in the savedComments object
 * The de-threaded comments go into the sortedComments object
 */
  savedComments = document.getElementById('comments').nextSibling.nextSibling;
  sortedComments = createElement('div');
  sortedComments.setAttribute('class', 'blogbody');
  parentComments = savedComments.parentNode;
  var comments = getElementsByClassName(savedComments, 'div', 'comments-body');
  var trackbacks = getElementsByClassName(savedComments, 'div', 'trackback');
  var commentIDs = new Array();
  for (i=0; i<comments.length; i++) {
     commentIDs[i] = String(comments[i].getAttribute('id'));
  }
  commentIDs.sort();
  var commentsHash = new Array();
  for (i=0; i<comments.length; i++) {
     commentsHash[comments[i].getAttribute('id')] = comments[i].cloneNode(true);
  }
  for (i=0; i<trackbacks.length; i++) {
     sortedComments.appendChild(trackbacks[i].cloneNode(true));
  }
  for (i=0; i<comments.length; i++) {
     sortedComments.appendChild(commentsHash[commentIDs[i]]);
  }

  if (comments.length > 2) {
    var dethread = createElement('input');
    dethread.setAttribute('id', 'dethread');
    dethread.setAttribute('type', 'button');
    dethread.setAttribute('value', 'view chronologically');
    dethread.onclick = viewchronological;
    dethread.onkeypress  = function() {
          if(window.event.keyCode == 13) {viewchronological;return false;} };
    var dethread2 = dethread.cloneNode(false);
    dethread2.setAttribute('id', 'dethread2');
    dethread2.onclick = viewchronological;
    dethread2.onkeypress  = function() {
          if(window.event.keyCode == 13) {viewchronological;return false;} };
    document.getElementById('comments').appendChild(dethread);
    getElementsByClassName(document, 'p', 'newpost')[0].appendChild(dethread2);
  }
}

function createElement(element) {
  if (typeof document.createElementNS != 'undefined') {
    return document.createElementNS('http://www.w3.org/1999/xhtml', element);
  } else {
    return document.createElement(element);
  }
}

function mactionWorkarounds() {
  $$('maction[actiontype="tooltip"]').each( function(mtool){
     Element.writeAttribute(mtool, 'title',
       Element.firstDescendant(mtool).nextSibling.firstChild.data);
     });
  $$('maction[actiontype="statusline"]').each( function(mstatus){
     var v = Element.firstDescendant(mstatus).nextSibling.firstChild.data;
     Event.observe(mstatus, 'mouseover', function(){window.status =  v;});
     Event.observe(mstatus, 'mouseout',  function(){window.status = '';});
     });
}


window.onload = function (){
	warnIE();
	styleAbbr();
	initializeAccessKeys();
	extractBlockquoteCitations();
        mactionWorkarounds();
	setupComments();
	if ( (navigator.appName == "Microsoft Internet Explorer" ) && !(navigator.userAgent.indexOf("Opera") > -1) ) {
//		document.body.style.behavior = 'url(\"/~distler/blog/csshover.htc\")';
		document.body.style.background = '#BCD';
	}
};