var theObject = null; //This gets a value as soon as a resize start
var tV = null;
var maxZIndex = 0;
var defaultImgSize = 380;
var minImgSize = 50;
var maxImgSize = 1400;
var centerCell;
var size = 40;
var imgWHRatio = 1;

var chrefs = [];
  chrefs["amp"] = 38;
  chrefs["nbsp"] = 160;
  chrefs["lt"] = 60;
  chrefs["gt"] = 62;
  chrefs["emdash"] = 45;
  chrefs["apostrophe"] = 39;
  chrefs["quote"] = 34;

function checkImageLoad(e) {
  var evt = new xEvent(e);
  var el = evt.target;
  if (el.tagName == "IMG") {
    var elParent = el.parentNode?el.parentNode:parentElement;
    if (elParent.tagName == "A") {      // if clicked on an image link
      var divBody = null; // where the image will go
      if (document.getElementById("imageViewerDiv") != null) {
        var containerDiv = document.getElementById("imageViewerDiv");
        var childEls = containerDiv.childNodes;
        for (var x = 0; x < childEls.length; x++) {
          var childEl = childEls[x];
          if (childEl.className == "winBody") {
            divBody = childEl;
          }
        }
      } else {
        var containerDiv = document.createElement('div');
        containerDiv.className = "draggable";
        containerDiv.id = "imageViewerDiv";
        containerDiv.style.zIndex = maxZIndex + 1; // max z-index so it's on top
        maxZIndex++; // update max z Index tracker
        containerDiv.style.position = "absolute";
        containerDiv.style.width = "400px";
        containerDiv.style.height = "400px";
        containerDiv.style.top = "200px";
        containerDiv.style.left = "200px";
        initDraggable(containerDiv);
        document.body.appendChild(containerDiv);
        var closeBtn = document.createElement('div');
        closeBtn.className = "titleBtn";
        closeBtn.innerHTML = "&#x00D7;";
        closeBtn.onclick = function () {
          deleteElem(containerDiv);
        }
        var openBtn = document.createElement('div');
        openBtn.className = "titleBtn2";
        openBtn.id = "openImageBtn";
        openBtn.innerHTML = "Open in new Window";
        openBtn.onclick = function () {
          var newWindow = window.open(elParent.getAttribute('href'), '_blank');
        }
        containerDiv.appendChild(closeBtn);
        containerDiv.appendChild(openBtn);
        var space = document.createTextNode(String.fromCharCode(chrefs["nbsp"]));
        var text = document.createTextNode(" Image Viewer");
        containerDiv.appendChild(space);
        containerDiv.appendChild(text);
        divBody = document.createElement('div');
        divBody.className = "winBody";
        containerDiv.appendChild(divBody);
        setBodySize(containerDiv); // make divBody size correct
        makeContentCentered(divBody);
      }
      var url = "#";
      // url = el.getAttribute("src"); // get url of image from 'src' attribute
      // get url of img from A 'href' attribute
      url = elParent.getAttribute('href');
      document.getElementById("openImageBtn").onclick = function () {
        var newWin = window.open(elParent.getAttribute('href'), '_blank');
      }
      divBody.style.overflow = "hidden";
      divBody.style.overflowY = "hidden";
      divBody.innerHTML = "LOADING IMAGE...";
      var img = document.createElement('img'); // make a new image
      img.onload = function (event) {
        deleteChildren(divBody);
        divBody.innerHTML = "";
        divBody.appendChild(img);
        imgWHRatio = img.offsetWidth/img.offsetHeight;
        imageResize(document.getElementById("imageViewerDiv"));
      }
      img.src = url;
      return false;
    }
  }
}

function imageResize (el) {
  // el is draggable div, winBody size is already set
  var sizeRatio = 1;
  var newW = 100; // width
  var newH = 100; // height
  var bodyW = 100;
  var bodyH = 100;
  var childEls = el.childNodes;
  for (var x = 0; x < childEls.length; x++) {
    var childEl = childEls[x];
    if (childEl.className == "winBody") {
      makeContentCentered(childEl); // center img just in case it isn't already
      bodyW = childEl.offsetWidth;
      bodyH = childEl.offsetHeight;
      var grandChildEls = childEl.childNodes;
      for (var y = 0; y < grandChildEls.length; y++) {
        if (grandChildEls[y].tagName == "IMG") {
          var image = grandChildEls[y];
          var imgW = image.offsetWidth;
          var imgH = image.offsetHeight;
          if ((imgW/imgH) >= 1) { // landscape
            if ((bodyW/bodyH) >= (imgW/imgH)) { // window will have extra space L and R
              newH = Math.max(Math.min(maxImgSize, bodyH - 4), minImgSize);
              newW = parseInt(imgWHRatio * newH); // convert float to integer
            } else { // window will have extra space T and B
              newW = Math.max(Math.min(maxImgSize, bodyW - 4), minImgSize);
              newH = parseInt(newW / imgWHRatio);
            }
          } else { // portrait
            if ((bodyH/bodyW) >= (imgH/imgW)) { // window will have extra space T and D
              newW = Math.max(Math.min(maxImgSize, bodyW - 4), minImgSize);
              newH = parseInt(newW / imgWHRatio);
            } else { // window will have extra space L and R
              newH = Math.max(Math.min(maxImgSize, bodyH - 4), minImgSize);
              newW = parseInt(imgWHRatio * newH);
            }
          }
          image.style.width = newW + "px";
          image.style.height = newH + "px";
        }
      }
    }
  }
}

function makeContentCentered (el) {
  el.style.lineHeight = el.offsetHeight + "px";
  el.style.textAlign = "center";
  el.style.fontSize = "20px";
}

function deleteElem (el) {
  if (el) {
    deleteChildren(el);
    var elParent = el.parentNode?el.parentNode:parentElement;
    elParent.removeChild(el);
  }
}

function deleteChildren (el) {
  if (el) {
    for (var x = el.childNodes.length - 1; x >= 0; x--) {
      var childEl = el.childNodes[x];
      if (childEl.hasChildNodes()) {
        deleteChildren(childEl);
      }
      el.removeChild(childEl);
    }
  }
}

function resizeObject() {
  this.el     = null; //pointer to the object
  this.dir    = "";   //type of current resize (n, s, e, w, ne, nw, se, sw)
  this.grabx  = null; //Some useful values
  this.graby  = null;
  this.width  = null;
  this.height = null;
  this.left  = null;
  this.top   = null;
  this.cursor = "default";
}

function trackVars() {
  this.enteredDiv = false;
  this.prevHeight = "0px";
  this.prevWidth = "0px";
}

function outFunction(e) {
  var evt = new xEvent(e);
  var el = evt.target;
  if (el.tagName == "IMG") {
    var elParent = el.parentNode?el.parentNode:parentElement;
    if (elParent.tagName == "A") {
      var elGrandParent = elParent.parentNode?elParent.parentNode:parentElement;
      if (elGrandParent.className == "thumbnail") {
        elGrandParent.style.borderColor = "#777777";
      }
    }
  }
}

function initTV () {
  tV = new trackVars();
}

function hoverFunction(e) {
  var xPos, yPos, offset;
  var dir = "";
  var evt = new xEvent(e);
  var el = evt.target;
  if (el.className == "draggable") {
    if (el == null) {
      return;
    }		
    xPos = evt.offsetX;
    yPos = evt.offsetY;

    offset = 8; //The distance from the edge in pixels

    if (yPos<offset) dir += "n";
    else if (yPos > el.offsetHeight-offset) dir += "s";
    if (xPos<offset) dir += "w";
    else if (xPos > el.offsetWidth-offset) dir += "e";
    if (dir == "") {
      if (tV.enteredDiv == false) {
        tV.enteredDiv = true;
        xAddEventListener(document, "mousemove", hoverFunction, false);
        xAddEventListener(document, "mouseout", resetCursor, false);
      }
      if (el.style.cursor.indexOf("resize") != -1) {
        el.style.cursor = "move";
      } 
      return;
    } else {
      if (tV.enteredDiv == false) {
        tV.enteredDiv = true;
        xAddEventListener(document, "mousemove", hoverFunction, false);
        xAddEventListener(document, "mouseout", resetCursor, false);
      }
      el.style.cursor = dir+"-resize";
    }
  } else if (el.tagName == "IMG") {
    var elParent = el.parentNode?el.parentNode:parentElement;
    if (elParent.tagName == "A") {
      var elGrandParent = elParent.parentNode?elParent.parentNode:parentElement;
      if (elGrandParent.className == "thumbnail") {
        elGrandParent.style.borderColor = "#dddd77";
      }
    }
  } else {
    if (tV.enteredDiv == true) {
      tV.enteredDiv = false;
      xRemoveEventListener(document,"mousemove", hoverFunction,false);
      xRemoveEventListener(document,"mouseout",resetCursor,false);
    }
  }
  dir = "";
}

function resetCursor(e) {
  var evt = new xEvent(e);
  var el = evt.target;
  if (el.className == "draggable") {
    if (el.style.cursor != "move") {
      el.style.cursor = "move";
    }
    if (tV.enteredDiv == true) {
      tV.enteredDiv = false;
    }
  }
  xRemoveEventListener(document,"mousemove",hoverFunction,false);
  xRemoveEventListener(document,"mouseout",resetCursor, false);
}

function checkResize(e) {
  var xPos, yPos, offset;
  var dir = "";
  var evt = new xEvent(e);
  var el = evt.target;
  if (el.className == "draggable") { // RESIZE
    if (el == null) {
      theObject = null;
      return;
    }		
    xPos = evt.offsetX;
    yPos = evt.offsetY;

    offset = 8; //The distance from the edge in pixels

    if (yPos<offset) dir += "n";
    else if (yPos > el.offsetHeight-offset) dir += "s";
    if (xPos<offset) dir += "w";
    else if (xPos > el.offsetWidth-offset) dir += "e";
    if (dir == "") return;

    theObject = new resizeObject();
		
    theObject.el = el;
    theObject.dir = dir;
    theObject.grabx = evt.pageX;
    theObject.graby = evt.pageY;
    theObject.width = el.offsetWidth;
    theObject.height = el.offsetHeight;
    theObject.left = el.offsetLeft;
    theObject.top = el.offsetTop;
    theObject.cursor = el.style.cursor;

    evt.returnValue = false;
    evt.cancelBubble = true;

    el.className = "resizable";

    xAddEventListener(document,'mousemove',doResize,false);
    xAddEventListener(document, 'mouseup', doUp, false);

    if (navigator.appName == "Netscape") {
      document.captureEvents(Event.MOUSEUP);
      document.onmouseup=doUp;
    }
  } else {
    return;
  }
}

function doUp(e) {
  var wins = document.getElementsByTagName("div");
  for (var i = 0; i < wins.length; i++) {
    var el = wins[i];
    if (el.className == "resizable") {
      el.className = "draggable";
      if (theObject != null) {
        el.style.cursor = theObject.cursor;
      }
    }
  }
  theObject = null;
  xRemoveEventListener(document, 'mouseup', doUp, false);
  xRemoveEventListener(document, 'mousemove', doResize, false);

  if (navigator.appName == "Netscape") {
    document.releaseEvents(Event.MOUSEUP);
  }
}

function doResize(e) {
  var el, xPos, yPos, str, xMin, yMin;
  xMin = 50;  //The smallest width possible
  yMin = 24; //             height

  var evt = new xEvent(e);
  el = evt.target;

  if(theObject != null) {
    if (el.className == "resizable") {
      str = theObject.dir;
      //Fix the cursor	
      if (str == "") str = "default";
      else str += "-resize";
      el.style.cursor = str;
    }

    //Dragging starts here
    if (theObject.dir.indexOf("e") != -1)
      theObject.el.style.width = Math.max(xMin, theObject.width + evt.pageX - theObject.grabx) + "px";
    if (theObject.dir.indexOf("s") != -1)
      theObject.el.style.height = Math.max(yMin, theObject.height + evt.pageY - theObject.graby) + "px";
    if (theObject.dir.indexOf("w") != -1) {
      theObject.el.style.left = Math.min(theObject.left + evt.pageX - theObject.grabx, theObject.left + theObject.width - xMin) + "px";
      theObject.el.style.width = Math.max(xMin, theObject.width - evt.pageX + theObject.grabx) + "px";
    }
    if (theObject.dir.indexOf("n") != -1) {
      theObject.el.style.top = Math.min(theObject.top + evt.pageY - theObject.graby, theObject.top + theObject.height - yMin) + "px";
      theObject.el.style.height = Math.max(yMin, theObject.height - evt.pageY + theObject.graby) + "px";
    }

    setBodySize(theObject.el);
    if (theObject.el.id == "imageViewerDiv") {
      imageResize(theObject.el);
    }

    evt.returnValue = false;
    evt.cancelBubble = true;
  } 
}

// initialize user interface buttons
function initUIBtns() {
  var myDivs = document.getElementsByTagName("div");
  var numDraggable = 0;
  var myBtns = new Array();
  var numBtns = 0;
  // this puts all uiBtn elements ON TOP of draggable divs (using z-index)
  for (var i = 0; i < myDivs.length; i++) {
    if (myDivs[i].className == "draggable") {
      numDraggable++;
    } else if (myDivs[i].className == "uiBtn") {
      myBtns[numBtns] = myDivs[i];
      numBtns++;
    } else if (myDivs[i].className == "titleBtn") {
      var text = myDivs[i].innerHTML;
      if (text == "+") {
        myDivs[i].innerHTML = "&#8211;";
      }
    }
  }
  for (var j = 0; j < numBtns; j++) {
    myBtns[j].style.zIndex = numDraggable + 1;
  }
  maxZIndex = numDraggable + 1; // update global max z Index tracker
}

// set size of winBody divs
function setBodySize(el) {
  var children = el.childNodes;
  for (var i = 0; i < children.length; i++) {
    if (children[i].className == "winBody") {
      var w = Math.max(1, el.offsetWidth - 16);
      children[i].style.width = w + "px";
      var h = Math.max(1, el.offsetHeight - 34);
      children[i].style.height = h + "px";
    }
  }
}

// define 'divDragStart' function
function divDragStart(el){
  var wins = document.getElementsByTagName("div");
  var level = el.style.zIndex;
  var draggableWins = new Array();
  var numWins = 0;
  for (var i = 0; i < wins.length; i++) {
    if (wins[i].className == "draggable") {
      draggableWins[numWins] = wins[i];
      numWins++;
    }
  }
  for (var i = 0; i < numWins; i++) {
    if (draggableWins[i]==el) {
      if (draggableWins[i].style.zIndex != numWins) {
        draggableWins[i].style.zIndex=numWins;
      }
    } else {
      if (draggableWins[i].style.zIndex > level) {
        draggableWins[i].style.zIndex = draggableWins[i].style.zIndex - 1;
      }
    }
  }
}
// move element
function divDrag(el,mdx,mdy){
  if (el.className == "draggable") {
    xMoveTo(el,xLeft(el)+mdx,xTop(el)+mdy);
    xOpacity(el,.4);
  }
}
// upon end of dragging
function divDragEnd(el){
  if (el.className == "draggable") {
    xOpacity(el,1);
  }
}

function minMax (btn) {
  var btnParent = btn.parentNode?btn.parentNode:parentElement;
  var text = "&#" + btn.innerHTML.charCodeAt(0) + ";";
  if (text=="&#8211;") {
    btn.innerHTML = "+";
    tV.prevHeight = btnParent.style.height;
    btnParent.style.height = "24px";
    var children = btnParent.childNodes;
    for (var i = 0; i < children.length; i++) {
      if (children[i].className == "winBody") {
        children[i].style.height = "0px";
        children[i].style.width = "0px";
	  }
    }
  } else {
    btn.innerHTML = "&#8211;";
    btnParent.style.height = tV.prevHeight;
    setBodySize(btnParent);
  }
}

function closeWin (btn) {
  var btnParent = btn.parentNode?btn.parentNode:parentElement;
  btnParent.style.visibility = "hidden";
  var showParentBtn = "show" + btnParent.id.charAt(btnParent.id.length-1);
  var showParentBtnElem = xGetElementById(showParentBtn);
  showParentBtnElem.className = 'uiBtn';
}

function show (id) {
  var el = xGetElementById(id);
  el.style.visibility = "visible";
  var elShowBtn = "show" + el.id.charAt(el.id.length-1);
  var elShowBtnElem = xGetElementById(elShowBtn);
  elShowBtnElem.className='uiBtnGrayed';
  divDragStart(el);
}

// create 'div1' element and assign events
function initDraggable1(){
  var div1=xGetElementById('draggable1');
  if(!div1){return};
  div1.style.zIndex = 1;
  div1.style.width = "493px";
  div1.style.height = "250px"; 
  xMoveTo(div1,10,50);
  xEnableDrag(div1,divDragStart,divDrag,divDragEnd);
  div1.style.visibility='visible';
  setBodySize(div1);
  var show1Btn = xGetElementById('show1');
  show1Btn.className='uiBtnGrayed';
}

// create 'div2' element and assign events
function initDraggable2(){
  var div2=xGetElementById('draggable2');
  if(!div2){return};
  div2.style.zIndex = 2;
  div2.style.width = "493px";
  div2.style.height = "250px";
  xMoveTo(div2,10,305);
  xEnableDrag(div2,divDragStart,divDrag,divDragEnd);
  div2.style.visibility='visible';
  setBodySize(div2);
  var show2Btn = xGetElementById('show2');
  show2Btn.className='uiBtnGrayed';
}

// create 'div3' element and assign events
function initDraggable3(){
  var div3=xGetElementById('draggable3');
  if(!div3){return};
  div3.style.zIndex = 3;
  div3.style.width = "265px";
  div3.style.height = "505px";
  xMoveTo(div3,508,50);
  xEnableDrag(div3,divDragStart,divDrag,divDragEnd);
  div3.style.visibility='visible';
  setBodySize(div3);
  var show3Btn = xGetElementById('show3');
  show3Btn.className='uiBtnGrayed';
}

function initDraggable(el) {
  xEnableDrag(el, divDragStart, divDrag, divDragEnd);
}

function initUI() {
  initUIBtns();
  initTV();
  document.onmousedown = checkResize;
  document.onmouseover = hoverFunction;
  document.onmouseout = outFunction;
  document.onclick = checkImageLoad;
}

function resetUI() {
  initUIBtns();
  // initialize 'dragging' DIV elements
  initDraggable1();
  initDraggable2();
  initDraggable3();
  initTV();
  document.onmousedown = checkResize;
  document.onmouseover = hoverFunction;
  document.onmouseout = outFunction;
  document.onclick = checkImageLoad;
}

// AJAX
// global album path
var albumPath = "";
// global request and XML document objects
var req;

// retrieve XML document (reusable generic function);
// parameter is URL string (relative or complete) to
// an .xml file whose Content-Type is a valid XML
// type, such as text/xml; XML source must be from
// same domain as HTML file
function getAlbum(album) {
  var currTime = new Date();
  var url = albumPath + album + "?ts=" + currTime.getTime();
  req=null
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest()
  } else if (window.ActiveXObject) {
    req = new ActiveXObject("Microsoft.XMLHTTP")
  }
  if (req != null) {
    req.onreadystatechange=processReqChange;
    req.open("GET",url,true);
    req.send(null);
  } else {
    alert("Your browser does not support XMLHTTP.")
  }
}

// handle onreadystatechange event of req object
function processReqChange() {
  // only if req shows "loaded"
  if (req.readyState == 4) {
    // only if "OK"
    if (req.status == 200) {
      loadHTMLFromResponse();
    } else {
      alert("There was a problem retrieving the XML data:\n" + req.status + req.statusText);
    }
  }
}

// fill photo widget with images and other elements from
// the current XML document
function showPhotos(el) {
  if (el.id == "showPhotosCambridge") {
    getAlbum("photosCambridge.html");
  } else if (el.id == "showPhotosJapan2007") {
    getAlbum("photosJapan2007.html");
  } else if (el.id == "showPhotosJapan2008") {
    getAlbum("photosJapan2008.html");
  } else if (el.id == "showPhotosE32005") {
    getAlbum("photosE32005.html");
  }// whatever, change names later
}

function loadHTMLFromResponse () {
  if (req.responseText) {
    var children = document.getElementById("draggable2").childNodes;
    for (var i = 0; i < children.length; i++) {
      if (children[i].className == "winBody") {
        var childElem = children[i];
        childElem.innerHTML = "";
        childElem.innerHTML = req.responseText; // later make "photos" instead of draggable2
      }
    }
  }
}
