var slideshow_lock = false;

Effect.ShakeVertical = function(element) {
  element = $(element);
  var oldStyle = {
    top: Element.getStyle(element, 'top'),
    left: Element.getStyle(element, 'left') };
      return new Effect.Move(element, 
        { x:  0, y: 10, duration: 0.05, afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x: 0, y: -20, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x:  0, y: 20, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x: 0, y: -20, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x:  0, y: 20, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x: 0, y: -10, duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
        undoPositioned(effect.element);
        setStyle(effect.element, oldStyle);
  }}}) }}) }}) }}) }}) }});
}

PeriodicalExecuter.prototype.registerCallback = function() {
  this.intervalID = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
}

PeriodicalExecuter.prototype.stop = function() {
  clearInterval(this.intervalID);
}


function slideshow_unlock()
{
  slideshow_lock = false;
}

var Slideshow = Class.create();

Slideshow.prototype = {
  initialize: function(photos, duration, hide_infobox){
    if(!duration)
      this.duration = 3;
    else
      this.duration = duration;
   
    this.photos = photos;
    this.current = 0;

    this.old = this.current;
    this.photo = $("photos-slide-image");
    
    this.playing = false;
    this.locktime = 500;

    this.hide_infobox = (hide_infobox ? true : false);

    if(hide_infobox && $('photo-info'))
      {
	  Element.hide('photo-info');
      }

    Event.observe('photo-current', 'click', this.show.bindAsEventListener(this));
    Event.observe("photos-slide-play", 'click', this.play.bindAsEventListener(this));
    /* safari just sucks */
    $('photos-slide-play').onclick = function() {return false;};

    Event.observe("photos-slide-next", 'click', this.next.bindAsEventListener(this));
    /* safari just sucks */
    $('photos-slide-next').onclick = function() {return false;};

    Event.observe("photos-slide-prev", 'click', this.prev.bindAsEventListener(this));
    /* safari just sucks */
    $('photos-slide-prev').onclick = function() {return false;};

    var els = document.getElementsByClassName("photoThumb", "li");
    els_len = els.length;
    for(var i=0; i<els_len; i++)
      {
	  Event.observe(els[i].firstChild, 'click', this.thumb.bindAsEventListener(this));
	   /* safari just sucks */
	  els[i].firstChild.onclick = function() {return false;};
      }

    this.jumpToAnchor();
  },

  jumpToAnchor: function()
  {
    var url = new String(document.location).split('#');
    if(url.length > 1)
    {
      var anchor = decodeURIComponent(url[url.length-1]);
      for(var i=0; i<this.photos.length; i++)
	{
	  if(this.photos[i]["title"] == anchor)
	    {
	      this.current = i;
	      this.refresh();
	      break;
	    }
	}
    }
  },

  buildNext: function()
    {
      var next = (this.current + 1) % this.photos.length;
      var cache = new Ajax.Request(this.photos[next]["normal"], {method: 'get'});
      var cache_thumb = new Ajax.Request(this.photos[next]["small"], {method: 'get'});
    },

  refresh: function(){
    this.setCurrent();
    this.buildNext();    
  },
    
  /** thumb
   * node.id must have the following format:
   * photo-thumb-n where n is the photo id
   */
  thumb: function(event){
    var node = Event.element(event).parentNode.parentNode;

    if(node.tagName != 'LI')
      return false;

    if(slideshow_lock && !this.playing)
      {
	if(event)
	  Event.stop(event);
	return false;
      }

    var thumb_id = parseInt(node.id.split('-')[2]);

    if(thumb_id != this.current)
    {
      slideshow_lock = true;
    
      if(this.playing)
	{
	  this.timer.stop();
	}
      this.old = this.current;
      this.current = thumb_id;

      this.refresh();

      slideshow_lock = false;
      if(this.playing)
	{
	  this.timer.registerCallback();
	}
    }
    if(event)
      Event.stop(event);

    return false;
  },

  setInfo: function(title, description)
    {
      $('photos-slide-counter').firstChild.data = (this.current+1)+"/"+this.photos.length;
	  
      if(!this.hide_infobox && $('photo-info'))
	{
	  $('photo-info-title').firstChild.data = title;
	  var photo_info_description = $('photo-info-description');
	  if(!photo_info_description.firstChild)
	    {
	      dsc_text = document.createTextNode(description);
	      photo_info_description.appendChild(dsc_text);
	    }
	  else
	    photo_info_description.firstChild.data = description;

	  new Effect.Highlight('photo-info', {startcolor:'#fff666', endcolor:'#ffef86'});
	}
    },

  setCurrent: function()
    {
      //first thing to do to avoid lightbox bug
      this.photo.firstChild.setAttribute("href", this.photos[this.current]["normal"]);

      
      new Effect.ShakeVertical('photo-thumb-'+this.current);

      this.photo.firstChild.firstChild.setAttribute("src", this.photos[this.current]["small"]);
      this.photo.firstChild.firstChild.setAttribute("alt", this.photos[this.current]["title"]);
      this.photo.firstChild.firstChild.setAttribute("title", this.photos[this.current]["title"]);

      this.setInfo(this.photos[this.current]["title"], this.photos[this.current]["description"]);

      $('photo-thumb-'+this.old).firstChild.firstChild.id = null;
      $('photo-thumb-'+this.current).firstChild.firstChild.setAttribute('id', 'photo-current-thumb');

      var pos = Position.cumulativeOffset($('photo-current-thumb'))[0] - Position.cumulativeOffset($('photos-slide-list'))[0];
      var middle_pos = Element.getDimensions('photos-slide-list').width/2;
      $('photos-slide-list').scrollLeft = pos-middle_pos;
    },

  next: function(event){
      if(event)
	{
	  Event.stop(event);
	}

    if(event)
      var node = Event.element(event);

    if(slideshow_lock && !this.playing)
      {
	return;
      }
    slideshow_lock = true;

    if(node)
    {
      //reinit the interval timer
      if(this.playing)
	{
	  this.timer.stop();
	}
    }

    this.old = this.current; 
    this.current++;
    if(this.current ==  this.photos.length)
    {		
      this.current = 0;
    }

    this.refresh();
    if(node)
    {
      window.setTimeout("slideshow_unlock()", this.locktime);
    
      if(this.playing)
	{
	  this.timer.registerCallback();
	}
    }
  },
      
  prev: function(event){
      if(event)
	{
	  Event.stop(event);
	}

    var node = Event.element(event);
    if(slideshow_lock && !this.playing)
      {
	return;
      }
    slideshow_lock = true;
    
    if(node)
    {
      //reinit the interval timer
      if(this.playing)
	{
	  this.timer.stop();
	}
    }

    this.old = this.current;
    if(this.current == 0)
    {
      this.current = this.photos.length;
    }
    this.current = (this.current - 1);

    this.refresh();

    if(node)
    {	
      window.setTimeout("slideshow_unlock()", this.locktime);
    
      if(this.playing)
	{
	  this.timer.registerCallback();
	}
    }
  },
  
  play: function(event)
    {
      if(event)
	{
	  Event.stop(event);
	}

      if(!this.playing)
      {
	this.setPlaying(true);
	this.timer = new PeriodicalExecuter(this.next.bind(this), this.duration);
      }
      else
      {
	this.pause();
      }
    },
  
  show: function(event)
    {
      this.pause(event);
    },

  pause: function(event)
    {
      if(this.playing)
      {
	this.setPlaying(false);
      }
    },
  
  setPlaying: function(state)
    {
      if(this.timer)
	this.timer.stop();
      
      if(state)
      {
	$('photos-slide-play').className += 'photosSlideshowActive';
	spaces = '';
	for(var i=0; i<((friendlyalbum.message['play'].length)-(friendlyalbum.message['pause'].length)); i++)
	  {
	    spaces += ' ';
	  }
	$('photos-slide-play').firstChild.data = friendlyalbum.message['pause']+spaces;
	$('photos-slide-play').style.backgroundImage = 'url(images/pause.png)';
	$('photos-slide-state').firstChild.data = friendlyalbum.message['state_playing'];
      }
      else
      {
	$('photos-slide-play').className = '';
	slideshow_lock = false;
	$('photos-slide-play').firstChild.data = friendlyalbum.message['play'];
	$('photos-slide-play').style.backgroundImage = 'url(images/play.png)';
	$('photos-slide-state').firstChild.data = friendlyalbum.message['state_paused'];
      }
      this.playing = state;
    }
}

function loadSlideshow(url)
{
  
  var myAjax = new Ajax.Request(
				url, 
      {
	method: 'get', 
	onComplete: function(req)
	{
	  var json_raw_data = req.responseText; 
	  eval("var json_data = ("+json_raw_data+")");
	  var slideshow = new Slideshow(json_data['photos'], json_data['duration'], json_data['hide_infobox']);
	},
	onFailure: function()
	{
	  alert("Impossible to fetch the url")
	    }
      });
  
}


