// All rights reserved, Jenna “Blueberry” Fox, http://creativepony.com/

// a bite sized chunk of fading images over the top of each other abstraction
var ImageFadeEffect = new Class({
  initialize: function (container, effectOptions) {
    this.container = $(container);
    this.effectOptions = effectOptions || {};
    this.current = false;
  },
  
  fadeTo: function(image) {
    image.setStyles({
      'position': 'absolute',
      'z-index': (this.current ? this.current.getStyle('z-index') : 0).toInt() + 1
    });
    
    this.effectOptions.onComplete = function(prev) {
      if (prev == this.current) {
        this.container.getElements('img').each(function (item) {
          if (this.current != item) item.remove();
        }.bind(this));
      }
    }.bind(this, image);
    
    this.effect = image.effect('opacity', this.effectOptions);
    this.effect.set(0);
    
    if (this.current) {
      image.injectAfter(this.current);
    } else {
      image.injectInside(this.container);
    }
    
    this.current = image;
    this.effect.start(1);
  }
});



// navigation widget with the arrow thingies which uses ImageFadeEffect
var ImageBook = new Class({
  options: {
    makeUrl: function(group, subgroup, picture) {
      return 'images/' + group + '/' + subgroup + '/' + picture;
    }
  },
  future: [],
  current: false,
  group: 'default',
  
  
  initialize: function(container, options) {
    this.setOptions(options);
    this.effect = new ImageFadeEffect(container);
  },
  
  
  loadData: function(data, group, subgroup) {
    this.future = new Array();
    this.current = false;
    this.group = group;
    
    // we store in here the stuff before the group we're starting with which we then process after
    var doAfter = new Array();
    var doFirst = new Array(); // same deal but opposite
    var areWeThereYet = false;
    
    // first we need to extract the needed information from the data source
    data.each(function (item) {
      if (item[0] == subgroup) areWeThereYet = true;
      
      item[1].sort().each(function(picture) {
        
        if (areWeThereYet)
          doFirst.push({subgroup: item[0], name: picture});
        else
          doAfter.push({subgroup: item[0], name: picture});
        
      });
    });
    
    // now we combine the images in to one long list
    this.future.push.apply(this.future, doFirst);
    this.future.push.apply(this.future, doAfter);
    
    // grab the first item
    this.current = this.future.shift();
    
    // show it!
    this.effect.fadeTo(this.imageFor(this.current));
    this.preload();
  },
  
  
  showNext: function() {
    if (!this.isNextAvailable()) return;
    this.future.push(this.current);
    this.current = this.future.shift();
    
    this.effect.fadeTo(this.imageFor(this.current));
    this.preload();
  },
  
  showPrevious: function() {
    if (!this.isPreviousAvailable()) return;
    this.future.unshift(this.current);
    this.current = this.future.pop();
    
    this.effect.fadeTo(this.imageFor(this.current));
    this.preload();
  },
  
  
  isNextAvailable: function() {
    return (this.current.subgroup == this.future[0].subgroup);
  },
  
  isPreviousAvailable: function() {
    return (this.current.subgroup == this.future.getLast().subgroup);
  },
  
  
  // create the image element for a certain object from 'future'
  imageFor: function(object) {
    return new Element('img', {'src': this.options.makeUrl(this.group, object.subgroup, object.name)});
  },
  
  
  // starts preloading images surrounding this.current
  preload: function() {
    this.imageFor(this.future[0]); // next image
    this.imageFor(this.future.getLast()); // next image
  }
  
});

ImageBook.implement(new Options);



// handles the UI of the previous and next buttons
function animateAnArrow(name, availableCheckFunc) {
  var button = $(name);
  var effect = button.effect('opacity', {wait: false, onComplete: function() { this.start(0.01); }});
  effect.set(0.01);
  
  button.addEvent('mouseenter', function() { if (availableCheckFunc()) { effect.start(1); } });
}


// requests the ajax data stuff for the ImageBook
function loadTheAjax() {
  var splitgroups = window.location.hash.toString().replace('#', '').split('/');
  var group = splitgroups.shift();
  var subgroup = splitgroups.shift();
  window.lastProcessedHash = window.location.hash.toString();

  new Json.Remote('images/ImageBookReader.php?group=' + group, { method: 'get',
    onComplete: function(data) {
      window.imagebook.loadData(data, group, subgroup);
    }
  }).send();
}


// finally, waits for the page to finish loading, then makes all this code start doing stuff!
window.addEvent('load', function() {
  
  window.imagebook = new ImageBook('imagebook');
  
  loadTheAjax();
  
  // this thing checks for if the hash ever changes and updates it as needed, checks every 0.5 secs
  (function() {
    if (window.location.hash.toString() != window.lastProcessedHash) {
      loadTheAjax();
    }
  }).periodical(500)
  
  animateAnArrow('prev_button', imagebook.isPreviousAvailable.bind(imagebook));
  animateAnArrow('next_button', imagebook.isNextAvailable.bind(imagebook));
  
  $('prev_button').addEvent('click', imagebook.showPrevious.bind(imagebook));
  $('next_button').addEvent('click', imagebook.showNext.bind(imagebook));
});