/*
 * Picax - A Picasa WebFacade
 * Copyright (C) 2007 David Landwehr <david@landwehr.dk>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
function pw__string_trim(value) {
   var temp = value;
   var obj = /^(\s*)([\W\w]*)(\b\s*$)/;
   if (obj.test(temp)) { temp = temp.replace(obj, '$2'); }
   var obj = / +/g;
   temp = temp.replace(obj, " ");
   if (temp == " ") { temp = ""; }
   return temp;
}

function pw__getFirstElementValue(element, name) {
  var e = element.getElementsByTagName(name);
  if (e.length>0) {
    if ((e=e.item(0).firstChild)!=null) {
      return pw__string_trim(e.nodeValue);
    }
  }
  return "";
} 

function pw__removeAllChildren(element) {
  while (element.firstChild!=null) {
    element.removeChild(element.firstChild);
  }
}

function pw__showImage(owner, imageThumbnail, imageElement) {
  if (owner.image_current_thumbnail!=null) {
     owner.image_current_thumbnail.parentNode.className = owner.image_current_thumbnail.parentNode.className.replace(/pw-image-thumbnails-selected/,"");
  }
  owner.image_current = imageElement;
  owner.image_current_thumbnail = imageThumbnail;
  imageThumbnail.parentNode.className = imageThumbnail.parentNode.className+ " pw-image-thumbnails-selected";
  owner.image_showing.src = owner.album_url + '/' + pw__getFirstElementValue(imageElement, 'itemLargeImage');
  owner.image_showing.style.width = pw__getFirstElementValue(imageElement, 'itemWidth')+"px";
  owner.image_showing.style.height = pw__getFirstElementValue(imageElement, 'itemHeight')+"px";

  owner.image_display_background.style.width = (65+parseInt(pw__getFirstElementValue(imageElement, 'itemWidth')))+"px";
  owner.image_display_background.style.height = (70+parseInt(pw__getFirstElementValue(imageElement, 'itemHeight')))+"px";
  

  // Set the caption for the photo
  pw__removeAllChildren(owner.image_caption);
  owner.image_caption.appendChild(document.createTextNode(pw__getFirstElementValue(imageElement, 'itemCaption')));

  owner.image_display.style.display = "block";
  owner.image_display_background.style.display = "block";
  
  var count = 0;
  var runner  = imageElement;
  while (runner!=null) {
    if (runner.nodeName == 'image'||runner.nodeName == 'img') {
      count++;
    }
    runner = runner.previousSibling;
  }
  owner.image_current_number = runner;
  pw__removeAllChildren(owner.image_count);
  owner.image_count.appendChild(document.createTextNode(count+" / " + owner.image_total_count));
}

function pw__nextImage() {
  var im = this.image_current;
  if (im!=null) {
    while ((im=im.nextSibling)!=null && im.nodeName!='image' && im.nodeName!='img');
    if (im!=null) {
      // We must assume that we can locate the thumbnail image element also
       var s = this.image_current_thumbnail.parentNode;
       pw__showImage(this, s=s.nextSibling.firstChild, im);
       return true;
    }
  }
  return false;
}

function pw__previousImage() {
  var im = this.image_current;
  if (im!=null) {
    while ((im=im.previousSibling)!=null && im.nodeName!='image' && im.nodeName!='img');
    if (im!=null) {
      // We must assume that we can locate the thumbnail image element also
       var s = this.image_current_thumbnail.parentNode;
       pw__showImage(this, s=s.previousSibling.firstChild, im);
       return true;
    }
  }
  return false;
}

function pw__createHttpRequest() {
  var httpRequest;
  if (window.XMLHttpRequest) {
    httpRequest = new XMLHttpRequest();
    if (httpRequest.overrideMimeType) {
      httpRequest.overrideMimeType('text/xml');
    }
  } else if (window.ActiveXObject) {
    try {
      httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {}
    }
  }

  if (!httpRequest) {
    return null;
  }
  
  return httpRequest;
}

function pw__createElement(name, className) {
  var element = document.createElement(name);
  element.className = className;
  return element;
}

function pw__setAlbumTitle(owner, title) {
  pw__removeAllChildren(owner.album_title);
  owner.album_title.appendChild(document.createTextNode(title));  

}

function pw__getPath(url) {
  var i = url.lastIndexOf('/');
  if (i!=-1) {
    return url.substring(0, i);
  }
  return url;
}

function pw__createThumbnail(owner, image, baseUrl) {
    var twidth = pw__getFirstElementValue(image, 'itemThumbnailWidth');
    var theight = pw__getFirstElementValue(image, 'itemThumbnailHeight');
    
    var img = !owner.showShadow ? document.createElement('div') : document.createElement('img');
    if (!owner.showShadow) {
      img.style.width = (twidth-10) + "px";
      img.style.height = (theight-10) + "px";
      img.style.backgroundImage = "url(" + baseUrl + '/'+ pw__getFirstElementValue(image, 'itemThumbnailImage')+")";
      img.style.backgroundPosition = "-4px -4px";
      
      img.className = "pw-image-shadeless";
    } else {
      img.src = baseUrl + '/'+ pw__getFirstElementValue(image, 'itemThumbnailImage');
      img.alt = pw__getFirstElementValue(image, 'itemCaption');
      img.style.display= "block";
      img.className = "pw-image-shaded";
    }
    
    img.style.marginTop = (4+((92-theight)/2))+"px";
    img.style.marginLeft = (4+((92-twidth)/2))+"px";
    return img;
}

function pw__layoutThumbnails() {
  var images = this.albumXML.getElementsByTagName('image');
  this.image_total_count = images.length;
  
  var image;
  var i;
  var imageContainer = this.image_thumbnails;
  pw__removeAllChildren(imageContainer);
         
  for (i=0; i < images.length; i++) {
    image = images.item(i);
    var div = pw__createElement('div', 'pw-image-thumbnail');
    var img = pw__createThumbnail(this, image, this.album_url);
    div.appendChild(img);
    imageContainer.appendChild(div);
    img.albumOwner = this;
    img.imageElement = image;
    img.onclick = function() {
      pw__showImage(this.albumOwner, this, this.imageElement);
    }
  }
}


function pw__findAlbumElement(element) {
  while(element!=null && element.album_owner==null) {
    element = element.parentNode;
  } 
  if (element!=null)
    return element.album_owner;
  return null;
}

function pw__startSlideshow() {
  if (this.slidetimer!=null) {
    this.stopSlideshow();
  }
  this.image_start_slideshow.className += " pw-image-slideshow-start-inactivate"; 
  this.image_stop_slideshow.className = this.image_stop_slideshow.className.replace(/ pw-image-slideshow-stop-inactivate/, "");
    
  var owner = this;
  this.slidetimer = setInterval(function() {
    if (!owner.nextImage()) {
      owner.stopSlideshow();
    }
  }, 4000);
}

function pw__stopSlideshow() {
  if (this.slidetimer!=null) {
    this.image_start_slideshow.className = this.image_start_slideshow.className.replace(/ pw-image-slideshow-start-inactivate/, ""); 
    this.image_stop_slideshow.className += " pw-image-slideshow-stop-inactivate";
    clearTimeout(this.slidetimer);
    this.slidetimer = null;
  }
}

function pw__setShadow(shadow) {
  if (this.showShadow != shadow) {
    this.showShadow = shadow;
    if (this.albumXML!=null) {
      this.layoutThumbnails();
    }
  }
}

var pw__http = pw__createHttpRequest();
var pw__queue = new Array();
var pw__http_in_use = false;

function pw__load(owner, callbackStart, callbackDone, callbackError, url, fromHttp) {
    if ((!pw__http_in_use && pw__queue.length==0) || fromHttp) {
      pw__http_in_use = true;
      callbackStart(owner, url, pw__http);
      pw__http.open('GET', url, true);
	  pw__http.onreadystatechange = function() { 
	    if (pw__http.readyState == 4) {
	      if (pw__http.status == 200) {
	         callbackDone(owner, url, pw__http);
	        } 
	        if (pw__queue.length>0) {
	          var _url = pw__queue.pop();
              var _callbackError = pw__queue.pop();
              var _callbackDone = pw__queue.pop();
              var _callbackStart = pw__queue.pop();
              var _owner = pw__queue.pop();
              setTimeout(function() {pw__load(_owner, _callbackStart, _callbackDone, _callbackError, _url, true);}, 0);
	        } else {
	          pw__http_in_use = false;
	        }
	    }
	  };
	  pw__http.send(null);
  } else {
    pw__queue.push(owner);
    pw__queue.push(callbackStart);
    pw__queue.push(callbackDone);
    pw__queue.push(callbackError);
    pw__queue.push(url);
  }
}

function pw__loadErrorHandler(owner, url, httpRequest) {
  alert('Load error');
}

function pw__loadStartHandler(owner, url, httpRequest) {
  owner.loading.style.display = "block";
  owner.image_load_or_content.style.display = "none";
  pw__setAlbumTitle(owner, 'Please Wait...');  
}

function pw__loadEndHandler(owner) {
  owner.loading.style.display = "none";
  owner.image_load_or_content.style.display = "block";
}

function pw__loadAlbumDone(owner, url, httpRequest) {
  owner.albumXML = httpRequest.responseXML;
  owner.album_url = pw__getPath(url);
  owner.layoutThumbnails(url);
  owner.setAlbumPageVisible(false);
  pw__loadEndHandler(owner);
}

function pw__loadAlbum(url) {
  pw__load(this, pw__loadStartHandler, pw__loadAlbumDone, pw__loadErrorHandler, url+'/index.xml', false);
}

function pw__loadAlbumForIndex() {
  var album = pw__findAlbumElement(this);
  if (album!=null && this.albumXMLElement!=null) {
    pw__removeAllChildren(album.image_copyright);
    album.image_copyright.appendChild(document.createTextNode(pw__getFirstElementValue(this.albumXMLElement, 'copyright')));
    album.loadAlbum(pw__getFirstElementValue(this.albumXMLElement, 'path'));
  }
}

function pw__createAlbumElement(owner, xmlElement) {
    var album = pw__createElement('a', 'pw-index-item');
    var album_thumb = pw__createElement('div', 'pw-index-thumb');
    var album_name = pw__createElement('div', 'pw-index-name');
    var album_date = pw__createElement('div', 'pw-index-date');
    album.albumXMLElement = xmlElement;
    album.onclick = pw__loadAlbumForIndex;
    
    album.appendChild(album_thumb);
    if (pw__getFirstElementValue(xmlElement, 'itemThumbnailImage')!="") {
      album_thumb.appendChild(pw__createThumbnail(owner, xmlElement, pw__getFirstElementValue(xmlElement, 'path')));
    }
    
    album.appendChild(album_name);
    album.appendChild(album_date);
    
    album_name.appendChild(document.createTextNode(pw__getFirstElementValue(xmlElement, 'name')));
    album_date.appendChild(document.createTextNode(pw__getFirstElementValue(xmlElement, 'date')));
    
    return album;
}

function pw__loadAlbumIndexDone(owner, url, httpRequest) {
  owner.album_indexXML = httpRequest.responseXML;
  pw__removeAllChildren(owner.image_albums);
  var albums = owner.album_indexXML.getElementsByTagName('album');
  var i=0;
  for (;i<albums.length; i++) {
    owner.image_albums.appendChild(pw__createAlbumElement(owner, albums.item(i)));
  }
  pw__loadEndHandler(owner);
  owner.setAlbumPageVisible(true);
  pw__setAlbumTitle(owner, 'Albums');
}

function pw__loadAlbumIndex(url) {
  pw__load(this, pw__loadStartHandler, pw__loadAlbumIndexDone, pw__loadErrorHandler, url, false);

}

function pw__setAlbumPageVisible(visible) {
  if (visible && this.album_tab.className.indexOf('pw-albums-tab-selected')==-1) {
    this.image_albums.style.display = "block";
    this.image_thumbnails.style.display = "none";
    this.album_tab.className += " pw-albums-tab-selected";
    this.pictures_tab.className = this.pictures_tab.className.replace(/ pw-pictures-tab-selected/, "");
    pw__setAlbumTitle(this, 'Albums'); 
  } else if (!visible && this.pictures_tab.className.indexOf('pw-pictures-tab-selected')==-1) {
    this.image_albums.style.display = "none";
    this.image_thumbnails.style.display = "block";
    this.album_tab.className = this.album_tab.className.replace(/ pw-albums-tab-selected/, "");
    this.pictures_tab.className += " pw-pictures-tab-selected";
    if (this.albumXML!=null) {
      pw__setAlbumTitle(this, pw__getFirstElementValue(this.albumXML, 'albumName'));
    } else {
      pw__setAlbumTitle(this, 'No Album Loaded');
    }
  }
}

var pw__y;
var pw__x;
var pw__d;
var pw__dy;
var pw__dx;
var pw__temp;
var pw__olddocumentmove;
var pw__olddocumentup;

function pw__dragmouseup(e) {
  document.onmousemove = pw__olddocumentmove;
  document.onmouseup = pw__olddocumentup;  
}

function pw__dragmousemove(e) {
  if (!e) e = window.event;
  pw__d.style.left = pw__dx + e.clientX - pw__x + "px";
  pw__d.style.top  = pw__dy + e.clientY - pw__y + "px";
  return false;
}

function pw__dragmousedown(e) {
  if (!e) e = window.event;
  var temp = (typeof e.target != "undefined")?e.target:e.srcElement;
  if (temp==this) {
    temp = temp.parentNode;
    pw__d = temp;
    pw__dx = parseInt(pw__d.style.left+0);
    pw__dy = parseInt(pw__d.style.top+0);
    pw__x = e.clientX;
    pw__y = e.clientY;
    pw__olddocumentmove = document.onmousemove;
    pw__olddocumentup = document.onmouseup;
    document.onmousemove = pw__dragmousemove;
    document.onmouseup = pw__dragmouseup;
    return false; 
  }
}

function PicasaAlbum(element) {
  this.album_element = element;
  this.image_current_thumbnail = null;
  this.albumXML = null;
  this.image_total_count = 0;
  this.image_current_number = 0;
  this.album_element.album_owner = this;
  this.showShadow = false;  
  
  this.album_element.className += " pw-gallery";
  
  // Create the elements
  this.album_title = pw__createElement('h1', 'pw-album-title');
  this.image_display = pw__createElement('div', 'pw-image-display');
  this.image_display_background = pw__createElement('div', 'pw-image-display-background');
  this.image_container = pw__createElement('div', 'pw-image-container');
  this.image_caption = pw__createElement('div', 'pw-image-caption');
  this.image_showing = pw__createElement('img', 'pw-image-showing');
  this.image_copyright = pw__createElement('div', 'pw-image-copyright');
  
  this.image_load_or_content = pw__createElement('div', '');
  
  this.image_albums = pw__createElement('div', 'pw-image-albums');
  this.image_thumbnails = pw__createElement('div', 'pw-image-thumbnails');
  this.image_thumbnails_end = pw__createElement('div', 'pw-image-thumbnails-end');
  this.loading = pw__createElement('div', 'pw-loading');
  this.loading_img_container = pw__createElement('div', '');
  this.loading_img_loader = pw__createElement('img', '');
  this.loading_img_loader.src = "pw_loading.gif";
  
  this.image_controls = pw__createElement('div', 'pw-image-control');
  this.image_close = pw__createElement('a', 'pw-image-close');
  this.image_next = pw__createElement('a', 'pw-image-next');
  this.image_count = pw__createElement('a', 'pw-image-count');
  this.image_previous = pw__createElement('a', 'pw-image-previous');
  this.image_start_slideshow = pw__createElement('a', 'pw-image-slideshow-start');
  this.image_stop_slideshow = pw__createElement('a', 'pw-image-slideshow-stop');
  
  var owner = this;
  
  // Setup functionality on the elements
  this.image_close.onclick = function() {
    owner.stopSlideshow();
    owner.image_display_background.style.display = "none";
    owner.image_display.style.display = "none";
    if (owner.image_current_thumbnail!=null) {
      owner.image_current_thumbnail.parentNode.className = owner.image_current_thumbnail.parentNode.className.replace(/pw-image-thumbnails-selected/,"");
      owner.image_current_thumbnail = null;
    }
  }
  
  this.image_next.onclick = function() {
    owner.nextImage();
  }
  
  this.image_previous.onclick = function() {
    owner.previousImage();
  }

  this.image_start_slideshow.onclick = function() {
    owner.startSlideshow();
  }
  
  this.image_stop_slideshow.onclick = function() {
    owner.stopSlideshow();
  }

  this.image_display_background.onmousedown = pw__dragmousedown;
  
  this.image_stop_slideshow.className += " pw-image-slideshow-stop-inactivate";
  
  // Setup the Document
  pw__removeAllChildren(this.album_element);
  
  // Tab pane
  this.main_tab = pw__createElement('div', 'pw-main-tab');
  this.album_tab = pw__createElement('a', 'pw-albums-tab');
  this.seperator = pw__createElement('div', 'pw-seperator-tab');
  this.pictures_tab = pw__createElement('a', 'pw-pictures-tab');
  
  this.main_tab.appendChild(this.album_tab);
  this.main_tab.appendChild(this.seperator);
  this.main_tab.appendChild(this.pictures_tab);
  this.album_element.appendChild(this.main_tab);  
  
  this.album_tab.onclick = function() {
    owner.setAlbumPageVisible(true);
  }
  
  this.pictures_tab.onclick = function() {
    owner.setAlbumPageVisible(false);
  }
  
  // Loading page
  this.loading.appendChild(this.loading_img_container);
  this.loading_img_container.appendChild(this.loading_img_loader);
  this.loading.appendChild(document.createTextNode("Loading Album"));
  
  // Buttons
  this.image_controls.appendChild(this.image_previous);
  this.image_controls.appendChild(pw__createElement('div', 'pw-image-dark-sep'));
  this.image_controls.appendChild(this.image_stop_slideshow);
  this.image_controls.appendChild(pw__createElement('div', 'pw-image-dark-sep'));
  this.image_controls.appendChild(this.image_start_slideshow);
  this.image_controls.appendChild(pw__createElement('div', 'pw-image-dark-sep'));
  this.image_controls.appendChild(this.image_next);
  this.image_controls.appendChild(pw__createElement('div', 'pw-image-dark-sep'));
  this.image_controls.appendChild(this.image_close);
  
  // Setup the gallery
  this.album_element.appendChild(this.album_title);
  this.album_element.appendChild(this.loading);
  this.album_element.appendChild(this.image_display);
  this.album_element.appendChild(this.image_load_or_content);
  
  this.image_load_or_content.appendChild(this.image_albums);
  this.image_load_or_content.appendChild(this.image_thumbnails);
  this.image_load_or_content.appendChild(this.image_thumbnails_end);
  
  this.image_display.appendChild(this.image_display_background);
  this.image_display.appendChild(this.image_controls);
  this.image_display.appendChild(this.image_container);
  
  this.image_container.appendChild(this.image_count);
  this.image_container.appendChild(this.image_caption);
  this.image_container.appendChild(this.image_showing);
  this.image_container.appendChild(this.image_copyright);
  
  // Expose API
  this.loadAlbumIndex = pw__loadAlbumIndex;
  this.loadAlbum = pw__loadAlbum;
  this.layoutThumbnails = pw__layoutThumbnails;
  this.nextImage = pw__nextImage;
  this.previousImage = pw__previousImage;
  this.startSlideshow = pw__startSlideshow;
  this.stopSlideshow = pw__stopSlideshow;
  this.setAlbumPageVisible = pw__setAlbumPageVisible;
  this.setShadow = pw__setShadow;
}

