
var myWindow = window;
//Hack for milonic
myWindow.disableMouseMove=true;

var eventHandlerWatch=new Object();

//This should let us map from objects to handles  
var eventObjectHandleMap=new Object();
// and vice versa
var eventHandleObjectMap=new Object();

function getElement(psID) {
  if(document.all) {
    return document.all[psID];
  } else {
    return document.getElementById(psID);
  }
}
 
function registerEventHandler(myObject, myEvent, myFunction){
  //Get or create handle for this object
  var objectHandle = eventObjectHandleMap[myObject];
  if(objectHandle == undefined){
    objectHandle = new String("obj_"+Uniq());
    //alert("must allocate new object handle: "+objectHandle);
    eventObjectHandleMap[myObject]=objectHandle;
    
    //its a new object so it's not in the handle->object map either
    eventHandleObjectMap[objectHandle]=myObject;
  }else{
    //alert("found existing handle: "+objectHandle);
  }
	

  var newEvent=new Object();
  //I think this one got it wrong:
  //var eventSource=eventHandlerWatch[myObject];
  var eventSource=eventHandlerWatch[objectHandle];
  if(eventSource==undefined){
    eventSource=new Object();
    //alert("allocating new event source:"+objectHandle);
    eventHandlerWatch[objectHandle]=eventSource;
  }else{
    //alert("found existing event source:"+objectHandle);

  }

  newEvent.myObject = myObject;
  newEvent.myEvent = myEvent;
  myObject.myChainFunction = null;
  //Why did I do this???
  //alert("myEvent: "+myEvent);
  //myWindow[myEvent] = myHandler2;
  //myObject[myEvent] = myHandler;

  
  //--bjw This is the one that should work: (it does now!)
  var newFuncStr = myFunction.toString();
  var newFuncStr = newFuncStr.replace(/SOURCEEVENT/gm, myEvent);
  var newFunName= new String("func"+Uniq());

  var repStr = "unction "+newFunName+" (";
  var newFunction = newFuncStr.replace(/unction .+\(/gm, repStr);
  //var newFunction = newFuncStr.replace(/unction .+/gm,"unction x ");
  //alert( newFunction);
  eval(newFunction);
  var myNewFunc;
  //return;
  eval("myNewFunc = "+newFunName+";");
  //alert(newFunName);
  //alert("myNewFunc:"+myNewFunc);
  
  //myObject[myEvent] = myNewFunc; //newFunction;
  //alert(newFunction);
  //alert("typeof(myNewFunc):"+typeof(myNewFunc));

  //newEvent.myFunction = myFunction;
  //myObject.myEvent=myFunction;
  newEvent.myFunction = myNewFunc;
  myObject[myEvent]=myNewFunc;


  //alert("myWindow['onresize']: "+myWindow['onresize']);
  //alert("myObject[myEvent] == myWindow['onresize']: "+(myObject[myEvent] == myWindow['onresize']));
  //alert("myObject == myWindow: "+(myObject == myWindow));
  

  //eventHandlerWatch[myObject]=newEvent;

  eventSource[myEvent]=newEvent;

  var msg="events:";
  for(var prop in eventSource){
    msg+= " "+prop;
  }
  //alert(msg);

  //alert("newEvent.myObject==myWindow:"+(newEvent.myObject==myWindow));
  //alert("eventHandlerWatch[myObject][myEvent].myObject==myWindow:"+(eventHandlerWatch[myObject][myEvent].myObject==myWindow));
  //alert("eventHandlerWatch[myObject][myEvent].myFunction:"+(eventHandlerWatch[myObject][myEvent].myFunction));

}

//Our interval handler is going to check for replacement of event handlers
//we are watching and add our own
var flag = 1;
function stIntervalHandler(){
  var x=0;
  for(var myEventSrc in eventHandlerWatch){
    for(var myEventHandler in eventHandlerWatch[myEventSrc]){

      var myEventEntry=eventHandlerWatch[myEventSrc][myEventHandler];
      var myEventObj = myEventEntry['myObject'];
      x++;
      var myEvent = myEventEntry['myEvent'];
      var myFunction = myEventEntry['myFunction'];

      x = myWindow;
      if(0)
	alert("myEventObj[myEvntSrc][myEvent]: "+myEventObj[myEventSrc][myEvent]);
      var eventObjFunc=myEventObj[myEvent];
      if(myFunction != eventObjFunc){
	
	//Chain in the new handler
	myEventEntry['myChainFunction']= myEventObj[myEvent];
	myEventObj[myEvent]=myFunction;
      }
    }
  }
}

//add our interval hander 10x per second
//Needs to happen rapidly because if we don't see it, we could lose it
myWindow.setInterval(stIntervalHandler, 10);
//We enabled an alert, so make it not too annoying
//myWindow.setInterval(stIntervalHandler, 5000);

function getDocSrc(myDocument){
  var sendHTML;
  if(myDocument.documentElement.outerHTML != null){
    sendHTML = myDocument.documentElement.outerHTML;
  }else{
    sendHTML = myDocument.documentElement.innerHTML;
  }
  return sendHTML;
}

function getElementFromObj(obj){
  var id;
  if(obj.id == undefined){
    obj.id =Uniq();
  }
  id = obj.id;
  var element = getElement(id);
  return element;
}

function Uniq(){
  var mydate = new Date;
  var myday = mydate.getDate();
  var mymonth = mydate.getMonth()+1;
  var myyear = ((mydate.getYear() < 100) ? "19" : "") + mydate.getYear();
  var myyear = myyear.substring(2,4);
  var myhour = mydate.getHours();
  var myminutes = mydate.getMinutes();
  var myseconds = mydate.getSeconds();
  if(myday < 10) myday = "0" + myday;
  if(mymonth < 10) mymonth = "0" + mymonth;
  if(myhour < 10) myhour = "0" + myhour;
  if(myminutes < 10) myminutes = "0" + myminutes;
  if(myseconds < 10) myseconds = "0" + myseconds;
  var datearray = new Array(mymonth,myday,myyear,myhour,myminutes,myseconds);
  var uniq = "";
  for(i=0;i<datearray.length;i++){
    for(z=0;z<2;z++){
      var which = Math.round(Math.random()*1);
      if(which==0){
	x = String.fromCharCode(64 + (Math.round(Math.random()*25)+1));
      }
      else{
	x = String.fromCharCode(47 + (Math.round(Math.random()*9)+1));
      }
      uniq += x;
    }
    uniq += datearray[i];
  }
  return uniq;
}

function createRequestObject() {
    var ro;
    var browser = navigator.appName;
    if(browser == "Microsoft Internet Explorer"){
        ro = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        ro = new XMLHttpRequest();
    }
    return ro;
}

var END_OF_INPUT = -1;

var base64Chars = new Array(
    'A','B','C','D','E','F','G','H',
    'I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X',
    'Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n',
    'o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3',
    '4','5','6','7','8','9','+','/'
);

var reverseBase64Chars = new Array();
for (var i=0; i < base64Chars.length; i++){
    reverseBase64Chars[base64Chars[i]] = i;
}

var base64Str;
var base64Count;
function setBase64Str(str){
    base64Str = str;
    base64Count = 0;
}
function readBase64(){    
    if (!base64Str) return END_OF_INPUT;
    if (base64Count >= base64Str.length) return END_OF_INPUT;
    var c = base64Str.charCodeAt(base64Count) & 0xff;
    base64Count++;
    return c;
}
function encodeBase64(str){
    setBase64Str(str);
    var result = '';
    var inBuffer = new Array(3);
    var lineCount = 0;
    var done = false;
    while (!done && (inBuffer[0] = readBase64()) != END_OF_INPUT){
        inBuffer[1] = readBase64();
        inBuffer[2] = readBase64();
        result += (base64Chars[ inBuffer[0] >> 2 ]);
        if (inBuffer[1] != END_OF_INPUT){
            result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]);
            if (inBuffer[2] != END_OF_INPUT){
                result += (base64Chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
                result += (base64Chars [inBuffer[2] & 0x3F]);
            } else {
                result += (base64Chars [((inBuffer[1] << 2) & 0x3c)]);
                result += ('=');
                done = true;
            }
        } else {
            result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30)]);
            result += ('=');
            result += ('=');
            done = true;
        }
        lineCount += 4;
        if (lineCount >= 76){
            result += ('\n');
            lineCount = 0;
        }
    }
    return result;
}
function readReverseBase64(){   
    if (!base64Str) return END_OF_INPUT;
    while (true){      
        if (base64Count >= base64Str.length) return END_OF_INPUT;
        var nextCharacter = base64Str.charAt(base64Count);
        base64Count++;
        if (reverseBase64Chars[nextCharacter]){
            return reverseBase64Chars[nextCharacter];
        }
        if (nextCharacter == 'A') return 0;
    }
    return END_OF_INPUT;
}

function ntos(n){
    n=n.toString(16);
    if (n.length == 1) n="0"+n;
    n="%"+n;
    return unescape(n);
}

function decodeBase64(str){
    setBase64Str(str);
    var result = "";
    var inBuffer = new Array(4);
    var done = false;
    while (!done && (inBuffer[0] = readReverseBase64()) != END_OF_INPUT
        && (inBuffer[1] = readReverseBase64()) != END_OF_INPUT){
        inBuffer[2] = readReverseBase64();
        inBuffer[3] = readReverseBase64();
        result += ntos((((inBuffer[0] << 2) & 0xff)| inBuffer[1] >> 4));
        if (inBuffer[2] != END_OF_INPUT){
            result +=  ntos((((inBuffer[1] << 4) & 0xff)| inBuffer[2] >> 2));
            if (inBuffer[3] != END_OF_INPUT){
                result +=  ntos((((inBuffer[2] << 6)  & 0xff) | inBuffer[3]));
            } else {
                done = true;
            }
        } else {
            done = true;
        }
    }
    return result;
}


function get_scroll_x(document){
  if (document.all)
  {
    if (!document.documentElement.scrollLeft)
      scrollX = document.body.scrollLeft;
    else
      scrollX = document.documentElement.scrollLeft;
  }   
  else
  {
    scrollX = myWindow.pageXOffset;
  }
  return scrollX;
}

function get_scroll_y(document){
  if (document.all)
  {
    if (!document.documentElement.scrollTop)
      scrollY = document.body.scrollTop;
    else
      scrollY = document.documentElement.scrollTop;
  }   
  else
  {
    scrollY = myWindow.pageYOffset;
  }
  return scrollY;
}

function get_window_height(window, document){
  //http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  //These properties supported in all DOM browsers, but mean different things depending on 
  //strict or quirks mode
  if(window.innerHeight != undefined){
    return(window.innerHeight);
  }else{
    if((document.documentElement.clientHeight==undefined)||(document.documentElement.clientHeight==0)){
      //we are in IE 5/6 quirks mode or IE 4
      return(document.body.clientHeight);
    }else{
      //This should work in all other known cases
      return(document.documentElement.clientHeight);
    }
  }
}

function get_window_width(window, document){
  //http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  //These properties supported in all DOM browsers, but mean different things depending on 
  //strict or quirks mode
  if(window.innerWidth != undefined){
    return(window.innerWidth);
  }else{
    if((document.documentElement.clientWidth==undefined)||(document.documentElement.clientWidth==0)){
      //we are in IE 5/6 quirks mode or IE 4
      return(document.body.clientWidth);
    }else{
      //This should work in all other known cases
      return(document.documentElement.clientWidth);
    }
  }
}
