//$Id: gallerix.js,v 1.6 2008/02/28 04:28:31 silviogutierrez Exp $


//Gallerix Namespace
var Gallerix = Gallerix || {};
Gallerix.fn = Gallerix.fn || {};
Gallerix.settings = Gallerix.settings || {};


$(document).ready(function() {  
  
  Gallerix.init();
  
  if (Gallerix.settings.view == 'grid' && !Gallerix.pid) {
    Gallerix.switchModes();
    //The last argument ensures we stay in grid mode even after fetching.
    Gallerix.fetch(Gallerix.settings.getURL + Gallerix.initial, false, true);    
  }
  else {
    $('#gallerix-viewer').show();
    Gallerix.fetch(Gallerix.settings.getURL + Gallerix.initial);    
    
  }
  
 
});




/**
 * Bootstrap. Loads in settings, activates flags and switches into the 
 * correct mode. Any elements already in the DOM related to Gallerix
 * are activated.
 *
 */
Gallerix.init = function() {
  var path = window.location.href;
  Gallerix.pid = path.split('#')[1]; //We want to know what pid the user provided, if any.  
  Gallerix.pid = Gallerix.pid != 'undefined' ? Gallerix.pid : 0; //If undefined, ignore the pid.

  //Load settings.
  Gallerix.settings = Drupal.settings['gallerix'];
  Gallerix.gridLoaded = false;
  Gallerix.mode = 'viewer';
  Gallerix.initial = Gallerix.pid ? Gallerix.pid : Gallerix.settings.defaultImage;
  Gallerix.seed = '';
  
  //Initialize the flag system.
  Gallerix.resetFlags();
  
  $('.gallerix-grid-link').click(function () {
      
    Gallerix.switchModes();

    return false;
  });
  
  
  Gallerix.activateLinks();
}





/**
 * Creates or resets buffering flags for each component.
 *
 */
Gallerix.resetFlags = function() {
  Gallerix.preparationFlags = {};
  Gallerix.callbackFlags = {};

  for (var component in Gallerix.settings.preparations) {
    Gallerix.preparationFlags[component] = false;
  }  
  
  for (var component in Gallerix.settings.callbacks) {
    Gallerix.callbackFlags[component] = false;
  }
  
  
}


/**
 * Flag a component indicating it's ready.
 *
 */
Gallerix.flag = function(component) {
  
  switch (Gallerix.state) {
    case 'preparation': {
      var callback = 'transition';      
      var flagType = 'preparationFlags';
      break;
    }
    case 'callback': {
      var callback = 'finalize';
      var flagType = 'callbackFlags';
      break;
    }
   
  
  }
  
  Gallerix[flagType][component] = true;
   
  if (Gallerix.checkFlags(flagType)) {
    Gallerix[callback]();
  }

}





/**
 * Checks all flags. If all flags are true, carry on with transition.
 *
 */
Gallerix.checkFlags = function(flagType) {
  
  for (var component in Gallerix[flagType]) {
    if (!Gallerix[flagType][component]) {
      return false;
    }
  }
  
  

  return true;
}



/**
 * Go through each link, add fading and fetching behavior.
 * This function can be called multiple times, since it will only
 * apply behaviors to new elements in the DOM. 
 *
 */
Gallerix.activateLinks = function() {
  $('.gallerix-picture-link').each(function() {
      if (!$(this).is('.activated')) {
        $(this).click(function() {


          Gallerix.fetch(this.href);     
          return false;
        });
        
        $(this).css('opacity', .6);
        
        
        
        var mouseover = function () {
          $(this).css('opacity', 1);
          return true;
        }
        var mouseout = function () {
          $(this).css('opacity', .6);
          return true;
        }       
        
        $(this).mouseover(mouseover);
        $(this).mouseout(mouseout);
        $(this).hover(mouseover, mouseout);
        $(this).addClass('activated');
        
      }
      
      
  });  
}





/**
 * Flag the grid for reloading.
 *
 */
Gallerix.reloadGrid = function() {
  Gallerix.gridLoaded = false;
  
}




/**
 * This function switches between the viewer mode, and the grid mode.
 *
 *   It keeps track of what mode Gallerix is in, and whether or not the grid
 *   has ever been loaded yet. Calling reloadGrid() will force this method to
 *   load the grid again.
 *
 */
Gallerix.switchModes = function() {
  Gallerix.mode = (Gallerix.mode == 'viewer') ? 'grid' : 'viewer';
  
  if (!Gallerix.gridLoaded) {
    $.get(Gallerix.settings.gridURL, null, function (data) {
      $('#gallerix-grid').html(data);
      
      $('#gallerix-viewer').hide();
      $('#gallerix-grid').show();
      Gallerix.gridLoaded = true;
      
      
      
      if (Gallerix.mode == 'viewer') {
        $('#gallerix-grid-link').html('All Photos');
        window.location.hash = "#" + (pid ? pid : "");
          
      }
      else {
        $('#gallerix-grid-link').html('Single Picture');  
        window.location.hash = "#";    
      }
        
      Gallerix.activateLinks();                    
    
    });
    
  }
  else {
    $('#gallerix-viewer').toggle();
    $('#gallerix-grid').toggle();
    
    if (Gallerix.mode == 'viewer') {
      $('#gallerix-grid-link').html('All Photos');
      window.location.hash = "#" + (Gallerix.pid ? Gallerix.pid : "");
        
    }
    else {
      $('#gallerix-grid-link').html('Single Picture');  
      window.location.hash = "#";    
    }
  }
  


}




/**
 * Preparation Callback.
 *
 * Fades out the main image to prepare it for replacement.
 *
 */
Gallerix.fn.hideImage = function() {
  $('#gallerix-loader').css('background-image', Gallerix.loaderImage);
  $('#gallerix-display').fadeTo(500, 0.001, function () {
  
    Gallerix.flag('gallerix_frame');   
  
  });
  

} 


/**
 * Callback.
 *
 * Fades in the main image after the AJAX request is done, and the buffer is loaded.
 *
 */
Gallerix.fn.showImage = function(image) {
 
  Gallerix.loaderImage = $('#gallerix-loader').css('background-image');   

  var imageBuffer = new Image(image['frameWidth'], image['frameHeight']);
  imageBuffer.onload = function() {
    _loadImage();
  };
  imageBuffer.src = image['framePath'] + Gallerix.seed;


  function _loadImage() {
    $('#gallerix-frame').attr({src: image.framePath + Gallerix.seed, width: image.frameWidth, height: image.frameHeight});
    $('#gallerix-display').fadeTo(500, 1);
    $('#gallerix-loader').show().css('background-image', 'none');    
    Gallerix.flag('gallerix_frame');  
  }

       
} 




/**
 * Callback.
 *
 * Updates all thumbnails once the AJAX request is done, and the buffer is loaded.
 *
 */
Gallerix.fn.updateThumbnails = function(image) {

  var thumbnails = image['thumbnails'];   
  
  var buffer = new Array();
  var size = 0;
  
  for (var thumbnail in thumbnails) {
    size++;
  }
  
  
  
  //Boolean array holding flags.
  var flags = new Array(size);
  var count = 0;
  
  
  /** 
   * Creates a buffering system. Everytime an image is loaded, a flag is
   * set in an array. Once every flag is set, thumbnails are uploaded.
   *
   */
  for (var thumbnail in thumbnails) {
    buffer[count] = new Image(1, 1);
    buffer[count].flag = count;
    buffer[count].onload = function () {
      
      
      flags[this.flag] = true;
      
      if (_checkFlags()) {     
        _updateThumbnails();
        Gallerix.flag('gallerix_links');         
        return true;
      }
    
    }
    buffer[count].src = thumbnails[thumbnail].path + Gallerix.seed;
    
    count++;
  }
  
  /**
   * Helper function goes through each thumbnail and updates it.
   *
   */
  function _updateThumbnails() {
    for (var thumbnail in thumbnails) {
      $('#' + thumbnail).attr('href', thumbnails[thumbnail].link).find('img').attr('src', thumbnails[thumbnail].path + Gallerix.seed).attr('title', thumbnails[thumbnail].caption);
    }
  };
  
  /** 
   * Makes sure all thumbnails have been cleared.
   *
   */
  function _checkFlags() {
    for (var x = 0; x < size; x++) {
      if (flags[x] == undefined) {
        return false;
      }
    }
    
    return true;
  };  



}




Gallerix.refresh = function(refresh) {

  if (refresh == undefined) {
    refresh = true;
  }
  
  Gallerix.fetch(Gallerix.settings.getURL + Gallerix.pid, refresh);   
  
}



/**
 *  The main function to fetch a picture. 
 *  
 *  All picture switching should be done through this function.
 *  Before fetching, this function will fire preparation callbacks.
 *
 * @param location is a URL including a validated PID.
 * @param refresh is a boolean which will force the browser not to cache.
 * @param grid indicates this function should not switch to single view.
 *        Instead, the picture will load in the background.
 */
Gallerix.fetch = function(location, refresh, grid) {

  //Prepare the random seed if requested.
  Gallerix.seed = refresh ? '?rand=' + Math.random() : '';
  
  //Reset all flags.
  Gallerix.resetFlags();
  
  Gallerix.state = 'preparation';
  
  //Update the global cycle variables.
  Gallerix.cycle = {};
  Gallerix.cycle.location = location;
  Gallerix.cycle.refresh = refresh;
  Gallerix.cycle.grid = grid;
  
  //Execute preparations for all components.
  for (prepare in Gallerix.settings.preparations) {
    Gallerix.fn[Gallerix.settings.preparations[prepare]]();
  }
  
}



Gallerix.transition = function() {
  if (Gallerix.mode == 'grid' && !Gallerix.cycle.grid) {
    Gallerix.switchModes();
  }     


  //Callback for request success.
  var update = function (data) {
  
    var image = Gallerix.parseJson(data);
    
    //Reset the message box.
    Gallerix.clearMessage();
    
    if (!Gallerix.cycle.grid) {
      window.location.hash = '#' + image['key'];    
    }

    Gallerix.pid = image['key'];
    
    Gallerix.state = 'callback';
    
    for (callback in Gallerix.settings.callbacks) {
      Gallerix.fn[Gallerix.settings.callbacks[callback]](image);
    }    
    
      
    
  }
  
  $.get(Gallerix.cycle.location, null, update);

}




Gallerix.finalize = function(image) {



}





