// Copyright (C) 2008 Daniel Bergström <daniel@octocode.com>

var image = null;
var n_images = 0;
var image_url = null;
var currentIdx = -1;
var scrollToIdx = 1;
var gallery_blank_url = 'gallery/gallery-blank.png';

var IDX_FILENAME    = 0;
var IDX_EXT         = 1;
var IDX_WIDTH       = 2;
var IDX_HEIGHT      = 3;
var IDX_WALLPAPER   = 4;
var IDX_DATE        = 5;
var IDX_DESCRIPTION = 6;

function object_position(obj)
{
  if(!obj.offsetParent) {
    return [0, 0];
  }

  var top = obj.offsetTop;
  var left = obj.offsetLeft;

  while(obj = obj.offsetParent) {
    top  += obj.offsetTop;
    left += obj.offsetLeft;
  }

  return [left, top];
}

function fetch_present_image()
{
  var lock = document.getElementById('present-lock');

  if(!lock) {
    return null;
  }

  var present = document.getElementById('present');
  var pos = object_position(lock);

  if(present) {
    var image = document.getElementById('present-image');
    present.style.left = (pos[0] - 1) + 'px';
    present.style.display = 'block';
    return image;
  }

  present = document.createElement('div');
  present.id = 'present';
  present.style.left = (pos[0] - 1) + 'px';
  present.style.display = 'block';

  var body = document.getElementsByTagName('body');
  body[0].appendChild(present);

  var contents = document.createElement('div');
  contents.id = 'present-contents';
  present.appendChild(contents);

  var action = document.createElement('div');
  action.id = 'present-action';
  contents.appendChild(action);

  var action_back = document.createElement('div');
  action_back.id = 'action-back';
  action_back.className = 'back-not-available';
  action_back.title = "Föregående bild";
  action.appendChild(action_back);

  var action_forward = document.createElement('div');
  action_forward.id = 'action-forward';
  action_forward.className = 'forward-not-available';
  action_forward.title = "Nästa bild";
  action.appendChild(action_forward);

  var action_exit = document.createElement('div');
  action_exit.id = 'action-exit';
  action_exit.onclick = new Function('doHideGallery()');
  action_exit.title = "Stäng";
  action.appendChild(action_exit);

  var action_info = document.createElement('div');
  action_info.id = 'action-info';
  action_info.className = 'info-not-available';
  action_info.title = "Visa/göm bildinformation";
  action.appendChild(action_info);

  var action_zoom = document.createElement('div');
  action_zoom.id = 'action-zoom';
  action_zoom.className = 'zoom-not-available';
  action_zoom.title = "Förstora";
  action.appendChild(action_zoom);

  var chooser = document.createElement('div');
  chooser.id = 'present-chooser';
  action.appendChild(chooser);

  var pactions = document.createElement('div');
  pactions.className = 'actions';
  chooser.appendChild(pactions);

  var action_list_back = document.createElement('div');
  action_list_back.id = 'action-list-back';
  action_list_back.className = 'list-back-not-available';
  action_list_back.title = "Rulla höger";
  pactions.appendChild(action_list_back);

  var action_list_forward = document.createElement('div');
  action_list_forward.id = 'action-list-forward';
  action_list_forward.className = 'list-forward-not-available';
  action_list_forward.title = "Rulla vänster";
  pactions.appendChild(action_list_forward);

  var pscrollarea = document.createElement('div');
  pscrollarea.id = 'present-scroll-area';
  chooser.appendChild(pscrollarea);

  var pscrollview = document.createElement('div');
  pscrollview.id = 'present-scroll-view';
  pscrollarea.appendChild(pscrollview);

  var pscroll = document.createElement('div');
  pscroll.id = 'present-scroll';
  pscrollview.appendChild(pscroll);

  var imgdiv = document.createElement('div');
  imgdiv.id = 'present-image-area';
  contents.appendChild(imgdiv);

  var img = document.createElement('img');
  img.id = 'present-image';
  img.onclick = new Function('doHideGallery();');
  imgdiv.appendChild(img);

  return img;
}

function sensitive_set(val)
{
  var present = document.getElementById('present-overlay');
  var height = 100;

  var page = document.getElementById('page');

  if(page) {
    height = (page.offsetHeight + 40);
  }

  if(!present) {
    present = document.createElement('div');
    present.id = 'present-overlay';
    present.style.height = height + 'px';

    var body = document.getElementsByTagName('body');
    body[0].appendChild(present);
  }

  if(val == 1) {
    if(present.style.display == 'block') {
      return;
    }

    present.style.height = height + 'px';
    present.style.display = 'block';
    setTimeout("sensitive_update()", 50);
  } else {
    present.style.display = 'none';
    present.style.opacity = 0;
    present.style.MozOpacity = 0;
    present.style.KhtmlOpacity = 0;
    present.style.filter = 'alpha(opacity=0)';
  }
}

function sensitive_update()
{
  var present = document.getElementById('present-overlay');

  if(!present) {
    return;
  }

  present.style.display = 'block';

  var speed = Math.round(2000 / 100); // 500 ms

  for(n = 0; n < 71; n++) {
    setTimeout("change_opacity('present-overlay'," + n + ")", (n * speed));
  }
}

function handler_gallery_query(http_request)
{
  if(!http_request || (http_request.readyState != 4)) {
    return;
  }

  var xml = http_request.responseXML;

  if(!xml) {
    return;
  }

  var gallery = null;

  for(var n = 0; n < xml.childNodes.length; n++) {
    if(xml.childNodes[n].nodeName == 'gallery') {
      gallery = xml.childNodes[n];
      break;
    }
  }

  if(gallery == null) {
    return;
  }

  images = new Array();
  n_images = 0;

  for(var n = 0; n < gallery.childNodes.length; n++) {
    var gnode = gallery.childNodes[n];

    if(gnode.nodeName == '#text') {
      continue;
    }

    if(gnode.nodeName == 'image-path') {
      image_url = gnode.firstChild.nodeValue;
      continue;
    }

    if(gnode.nodeName != 'image-list') {
      continue;
    }

    for(var i = 0; i < gnode.childNodes.length; i++) {
      var image = gnode.childNodes[i];

      if((image.nodeName != 'image') && (image.nodeName != 'img')) {
        continue;
      }

      var filename = null, width = null, height = null, has_wallpaper = false;
      var date = null, description = null;

      for(var f = 0; f < image.childNodes.length; f++) {
        var inode = image.childNodes[f];

        switch(inode.nodeName) {
          case 'filename': {
            filename = inode.firstChild.nodeValue;
            break;
          }
          case 'width': {
            width = parseInt(inode.firstChild.nodeValue);
            break;
          }
          case 'height': {
            height = parseInt(inode.firstChild.nodeValue);
            break;
          }
          case 'has-wallpaper': {
            has_wallpaper = true;
            break;
          }
          case 'date': {
            date = inode.firstChild.nodeValue;
            break;
          }
          case 'description': {
            description = inode.firstChild.nodeValue;
            break;
          }
        }
      }

      if((filename == null) || (width == null) || (height == null) ||
         (width == 0) || (height == 0) || (filename.length <= 4)) {
        continue;  // required fields not set or valid
      }

      var name = filename.substring(0, (filename.length - 4));
      var ext = filename.substring((filename.length - 4), filename.length);;

      images[n_images++] = new Array(name, ext, width, height, has_wallpaper,
                                     date, description);
    }
  }

  if(!n_images) {
    return;
  }

  if((pscroll = document.getElementById('present-scroll'))) {
    var ref = (pscroll.style ? pscroll.style : pscroll);

    if(ref.resizeTo) {
      ref.resizeTo((n_images * 52), 50);
    }

    var px = (document.childNodes ? 'px' : 0);
    ref.width = (n_images * 52);
    ref.pixelWidth = (n_images * 52);

    for(var n = 0; n < n_images; n++) {
      var img = document.createElement('img');

      if(image_url) {
        img.src = image_url + '/';
      } else {
        img.src = '';
      }

      img.src += images[n][IDX_FILENAME] + '_tiny' + images[n][IDX_EXT];
      img.width = 50;
      img.height = 50;
      img.onclick = new Function('doShowImage(' + n + ')');
      pscroll.appendChild(img);
    }
  }

  doShowImage(0);
  doScrollTo(0);
  document.captureEvent = Event.MOUSEUP | Event.MOUSEMOVE;
}

function presentImage(gallery_url)
{
  sensitive_set(1);

  currentIdx = -1;
  scrollToIdx = 0;

  var img = fetch_present_image();

  if(img) {
    img.width = 0;
    img.height = 0;
    img.style.opacity = 0;
    img.style.MozOpacity = 0;
    img.style.filter = 'alpha(opacity=0)';
    img.src = gallery_blank_url;
  }

  if((pscroll = document.getElementById('present-scroll'))) {
    while(pscroll.childNodes[0]) {
      pscroll.removeChild(pscroll.childNodes[0]);
    }
  }

  if((button = document.getElementById('action-zoom'))) {
    button.className = 'zoom-not-available';
    button.onclick = null;
  }

  if((button = document.getElementById('action-info'))) {
    button.className = 'info-not-available';
    button.onclick = null;
  }

  if((button = document.getElementById('action-forward'))) {
    button.className = 'forward-not-available';
    button.onclick = null;
  }

  if((button = document.getElementById('action-back'))) {
    button.className = 'back-not-available';
    button.onclick = null;
  }

  if((button = document.getElementById('action-list-forward'))) {
    button.className = 'list-forward-not-available';
    button.onclick = null;
  }

  if((button = document.getElementById('action-list-back'))) {
    button.className = 'list-back-not-available';
    button.onclick = null;
  }

  http_query(gallery_url, handler_gallery_query);
  return false;
}

function doShowImage(imgidx)
{
  if(imgidx == currentIdx) {
    return;
  }

  var img = fetch_present_image();
  var imgarea = document.getElementById('present-image-area');

  if(!img || !imgarea) {
    return;
  }

  img.style.opacity = 0;
  img.style.MozOpacity = 0;
  img.style.KhtmlOpacity = 0;
  img.style.filter = 'alpha(opacity=0)';
  img.src = gallery_blank_url;

  currentIdx = imgidx;
  doScrollTo(imgidx - 1);

  if((button = document.getElementById('action-zoom'))) {
    if(images[imgidx][IDX_WALLPAPER] == true) {
      button.className = 'zoom-available';
      button.onclick = new Function('return doZoomImage()');
    } else {
      button.className = 'zoom-not-available';
      button.onclick = null;
    }
  }

  if((button = document.getElementById('action-info'))) {
    if((images[imgidx][IDX_DATE] != null) ||
       (images[imgidx][IDX_DESCRIPTION] != null)) {
      button.className = 'info-available';
      button.onclick = new Function('return doShowInfo()');
    } else {
      button.className = 'info-not-available';
      button.onclick = null;
    }
  }

  if((button = document.getElementById('action-forward'))) {
    if(imgidx < (n_images - 1)) {
      button.className = 'forward-available';
      button.onclick = new Function('doShowForward()');
    } else {
      button.className = 'forward-not-available';
      button.onclick = null;
    }
  }

  if((button = document.getElementById('action-back'))) {
    if(imgidx != 0) {
      button.className = 'back-available';
      button.onclick = new Function('doShowBack()');
    } else {
      button.className = 'back-not-available';
      button.onclick = null;
    }
  }

  doUpdateInfo();
  setTimeout("timedShowImageResize()", 20);
}

function inner_height()
{
  if(self.innerHeight) {
    return self.innerHeight;
  }

  if(document.documentElement && document.documentElement.clientHeight) {
    return document.documentElement.clientHeight;
  }

  if(document.body) {
    return document.body.clientHeight;
  }
}

function timedShowImageResize()
{
  var img = document.getElementById('present-image');

  if(!img) {
    return;
  }

  var area = document.getElementById('present-image-area');
  var offset = [0, 0];

  if(area) {
    offset = object_position(area);
  }

  var width = images[currentIdx][IDX_WIDTH];
  var height = images[currentIdx][IDX_HEIGHT];
  var innerHeight = inner_height();
  

  if((offset[1] + height) > (innerHeight - 1)) {
    var diff = (innerHeight - offset[1] - 1) / height;
    width = width * diff;
    height = height * diff;
  }

  img.width = width;
  img.height = height;
  setTimeout("timedShowImageFinalize()", 20);
}

function timedShowImageFinalize()
{
  var img = document.getElementById('present-image');

  if(!img) {
    return;
  }

  if(image_url) {
    img.src = image_url + '/';
  } else {
    img.src = '';
  }

  img.src += images[currentIdx][IDX_FILENAME] + images[currentIdx][IDX_EXT];

  var speed = Math.round(500 / 100); // 500 ms

  for(n = 0; n < 101; n++) {
    setTimeout("change_opacity('present-image'," + n + ")", (n * speed));
  }
}

function change_opacity(id, opacity)
{
  var img = document.getElementById(id);
  
  if(img) {
    img.style.opacity = (opacity / 100);
    img.style.MozOpacity = (opacity / 100);
    img.style.KhtmlOpacity = (opacity / 100);
    img.style.filter = "alpha(opacity=" + opacity + ")";
  }
}

function doShowForward()
{
  if((currentIdx + 1) >= n_images) {
    return;
  }

  doShowImage(currentIdx + 1);
}

function doShowBack()
{
  if((currentIdx - 1) < 0) {
    return;
  }

  doShowImage(currentIdx - 1);
}

function doZoomImage()
{
  var url = '';

  if(image_url) {
    url = image_url + '/';
  }

  url += images[currentIdx][IDX_FILENAME] + '_huge' +
    images[currentIdx][IDX_EXT];

  ref = window.open(url, "gallery_zoom",
                    'toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,copyhistory=no,resizable=yes');

  ref.focus();

  return false;
}

function doHideGallery()
{
  var present = document.getElementById('present');

  if(present) {
    present.style.display = 'none';
  }

  doHideInfo();

  sensitive_set(0);
}

/* Scroll Image List ******************************************************** */

var mouseDown = false;

function mousePressScroll(left)
{
  if(mouseDown) {
    return;
  }

  document.onmousedown = dummy;
  document.onmouseup = mouseReleasedScroll;
  mouseDown = true;

  if(left) {
    doScrollLeft(true);
  } else {
    doScrollRight(true);
  }
}

function doScrollLeft(buttonDown)
{
  if(buttonDown && !mouseDown) {
    return;
  }

  doScrollTo(scrollToIdx - 1);

  if(mouseDown) {
    setTimeout('doScrollLeft(true)', 200);
  }
}

function doScrollRight(buttonDown)
{
  if(buttonDown && !mouseDown) {
    return;
  }

  doScrollTo(scrollToIdx + 1);

  if(mouseDown) {
    setTimeout('doScrollRight(true)', 200);
  }
}

function doScrollTo(idx)
{
  var scrollDiv = document.getElementById('present-scroll');

  if(!scrollDiv) {
    return;
  }

  if(idx < 0) {
    idx = 0;
  }

  if(idx >= (n_images - 2)) {
    idx = n_images - 3;
  }

  scrollToIdx = idx;
  scrollDiv.style.marginLeft = -((scrollToIdx * 50) + ((scrollToIdx + 1) * 2)) + 'px';

  if((button = document.getElementById('action-list-forward'))) {
    if(idx < (n_images - 3)) {
      button.className = 'list-forward-available';
      button.onmousedown = new Function('mousePressScroll(false)');
    } else {
      button.className = 'list-forward-not-available';
      button.onmousedown = null;
    }
  }

  if((button = document.getElementById('action-list-back'))) {
    if(idx != 0) {
      button.className = 'list-back-available';
      button.onmousedown = new Function('mousePressScroll(true)');
    } else {
      button.className = 'list-back-not-available';
      button.onmousedown = null;
    }
  }
}

function mouseReleasedScroll(event)
{
  mouseDown = false;
  document.onmousedown = null;
  document.onmouseup = null;
}

/* Image Information Window ************************************************* */

var active_id = null;
var currentX = 0;
var currentY = 0;
var cursorOffsetX = null;
var cursorOffsetY = null;
var info_window = null;
var has_last_position = 0;
var lastLeft = 0;
var lastTop = 0;

function fetch_present_info()
{
  var infocont = document.getElementById('information-contents');

  if(infocont) {
    return infocont;
  }

  var info = document.createElement('div');
  info.id = 'image-information';

  var header = document.createElement('div');
  header.className = 'frame-header';
  info.appendChild(header);

  var title = document.createElement('div');
  title.className = 'frame-title';
  title.onmousedown = new Function('doMoveInfo()');
  header.appendChild(title);

  title.appendChild(document.createTextNode("Bildinformation"));

  var button_close = document.createElement('div');
  button_close.className="frame-close";
  button_close.onclick = new Function('return doHideInfo()');
  header.appendChild(button_close);

  var contents = document.createElement('div');
  contents.id = "information-contents";
  info.appendChild(contents);

  var body = document.getElementsByTagName('body');
  body[0].appendChild(info);

  return contents;
}

function doUpdateInfo()
{
  var contents = document.getElementById('information-contents');

  if(!contents) {
    return null;
  }

  while(contents.childNodes[0]) {
    contents.removeChild(contents.childNodes[0]);
  }

  var image_num = document.createElement('div');
  image_num.className = 'image-info-image-number';
  contents.appendChild(image_num);
  image_num.appendChild(document.createTextNode((currentIdx + 1) + '/' +
                                                n_images));

  var image_date = document.createElement('div');
  image_date.className = 'image-info-image-date';
  contents.appendChild(image_date);
  image_date.appendChild(document.createTextNode(images[currentIdx][IDX_DATE]));

  var image_desc = document.createElement('div');
  image_desc.className = 'image-info-image-description';
  contents.appendChild(image_desc);
  image_desc.appendChild(document.createTextNode(images[currentIdx][IDX_DESCRIPTION]));
}

function doShowInfo()
{
  var infocont = fetch_present_info();
  info_window = document.getElementById('image-information');

  if(!infocont || !info_window) {
    return true;
  }

  if(info_window.style.display == 'block') {
    info_window.style.display = 'none';
    return false;
  }

  if(!has_last_position) {
    var present = document.getElementById('present');
    var area = document.getElementById('present-image-area');

    if(present && area) {
      info_window.style.left = (present.offsetLeft + area.offsetLeft + 5)+'px';
      info_window.style.top = (present.offsetTop + area.offsetTop + 5) + 'px';
    }
  }

  doUpdateInfo();
  info_window.style.display = 'block';
  return false;
}

function doHideInfo(id)
{
  if(info_window) {
    info_window.style.display = 'none';

    has_last_position = 1;
    lastLeft = info_window.style.left;
    lastTop = info_window.style.top;
  }

  return false;
}

function doMoveInfo()
{
  if(info_window) {
    document.onmousedown = dummy;
    document.onmouseup = mouseReleased;
    document.onmousemove = mousePosition;
  }
}
function mousePosition(event)
{
  if(!info_window) {
    return true;
  }

  if(!event) {
    currentX = (window.event.clientX + document.body.scrollLeft +
                document.documentElement.scrollLeft);
    currentY = (window.event.clientY + document.body.scrollTop +
                document.documentElement.scrollTop);
  } else {
    currentX = event.pageX;
    currentY = event.pageY;
  }

  if(cursorOffsetX == null) {
    cursorOffsetX = info_window.offsetLeft - currentX;
    cursorOffsetY = info_window.offsetTop - currentY;
  }

  info_window.style.left = (currentX + cursorOffsetX) + 'px';
  info_window.style.top = (currentY + cursorOffsetY) + 'px';
  return false;
}

function mouseReleased(event)
{
  document.onmouseup = null;
  document.onmousemove = null;
  document.onmousedown = null;
  cursorOffsetX = null;
  cursorOffsetY = null;
}

function dummy()
{
  return false;
}

/* HTTP Query XML Document ************************************************** */

function http_query(url, handler)
{
  var http_request = http_request_new();
  http_request.open('GET', url, true);
  http_request.setRequestHeader("If-Modified-Since", new Date(0));
  http_request.onreadystatechange = function() { handler(http_request); };
  http_request.send(null);
}

function http_request_new()
{
  if(window.XMLHttpRequest) {
    var http_request = new XMLHttpRequest();

    if(http_request.overrideMimeType) {
      http_request.overrideMimeType('text/xml');
    }

    return http_request;
  }

  if(window.ActiveXObject) {
    try {
      return new ActiveXObject("Msxml3.XMLHTTP");
    } catch(e) { }

    try{
      return new ActiveXObject("MSXML2.XMLHTTP.3.0");
    } catch(e) { }

    try {
      return new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) { }

    try {
      return new ActiveXObject("Microsoft.XMLHTTP");
    } catch(e) { }
  }

  return null;
}

