/*
//////////////////////////////////////////////////////////////////////////////
// 
// Copyright (c) May 2005
// 
// All rights reserved. This material contains unpublished,
// copyrighted work, which includes confidential and proprietary
// information of HyperTrust NV
// 
// HyperTrust NV, Geldenaaksebaan 329, 3001 Leuven, Brabant, BELGIUM
// 
// $Revision: $
// Last modified by $Author: $ on $Date:  $
// 
///////////////////////////////////////////////////////////////////////////////
*/

// Make sure we are notified when the page is loaded.
HTAddEvent(window, 'load', OnWindowLoad);


///////////////////////////////////////////////////////////////////////////////
// Global Data
///////////////////////////////////////////////////////////////////////////////
var ga_photos = null;
var g_slideshow_panel = null;
var g_vcr_panel = null;
var g_slideshow_delay = 2500;
var g_strip_start_index = 0;
var g_slide_index = 0;
var g_timer_scroll = null;
var g_timer_slideshow = null;

///////////////////////////////////////////////////////////////////////////////
// The PixPublisher class
///////////////////////////////////////////////////////////////////////////////
/*
Constructor.
*/
function PixPublisher( i_unique, i_num_photos )
{
  // Store the 'unique' that identifies us from other publisher instances
  this.Unique = i_unique;  
  
  // Build the array of photos inside this publisher
  this.Photos = new Array(i_num_photos);
  
  // Setup default panels
  this.SlideShowPanel   = null;
  this.VCRPanel         = null;
  this.SlideShowDelay   = 2500;
  this.StripStartIndex  = 0;
  this.SlideIndex       = 0;
  
  // Setup the publisher timers
  this.TimerScroll      = null;
  this.TimerSlideShow   = null;
  
  // Setup the function table
  this.Create = PixPublisher_Create;
}

//-------------------------------------------------------------------------
function PixPublisher_Create( )
{
}


///////////////////////////////////////////////////////////////////////////////
// The PixPhoto class
///////////////////////////////////////////////////////////////////////////////
/*
Constructor.

i_url:              The URL to the original photo.
i_thumb40x40_url:   The URL to the 40x40 thumbnail
i_thumb120x120_url: The URL to the 120x120 thumbnail
*/
function PixPhoto( i_unique, i_url, i_thumb40x40_url, i_thumb120x120_url )
{
  // Store the 'unique' that separates us from other publisher instances
  this.Unique = i_unique;  
  
  // Store the given URLs for further processing
  this.URL = i_url;
  this.Thumb40x40URL    = i_thumb40x40_url;
  this.Thumb120x120URL  = i_thumb120x120_url;
/*  
  // Load the thumbnails
  this.Thumb40x40       = new Image(40, 40);  
  this.Thumb40x40.src   = i_thumb40x40_url;
  this.Thumb120x120     = new Image();  
  this.Thumb120x120.src = i_thumb120x120_url;
*/  
  // Build the method table
  this.IsLoaded       = PixPhoto_IsLoaded;
  this.PreLoad        = PixPhoto_PreLoad;
  this.PreLoadThumbs  = PixPhoto_PreLoadThumbs;
}

//-------------------------------------------------------------------------
/*
Checks whether the Pix photo has been loaded.
Returns true when loaded, false when not loaded.
*/
function PixPhoto_IsLoaded( )
{
  if (!this.Original.complete)
    return false;
  if (!this.Thumb40x40.complete)
    return false;
  if (!this.Thumb120x120.complete)
    return false;
  return true;
}

//-----------------------------------------------------------------------------
function PixPhoto_PreLoad( )
{
  // Load the original image
  if (!this.Original)
  {
    this.Original     = new Image();
    this.Original.src = this.URL;
  }
}

//-----------------------------------------------------------------------------
function PixPhoto_PreLoadThumbs( )
{
  // Load the thumbnails
  if (!this.Thumb40x40)
  {
    this.Thumb40x40     = new Image(40, 40);  
    this.Thumb40x40.src = this.Thumb40x40URL;
  }
  if (!this.Thumb120x120)
  {
    this.Thumb120x120     = new Image();  
    this.Thumb120x120.src = this.Thumb120x120URL;
  }
}


///////////////////////////////////////////////////////////////////////////////
// The PixPanel class
///////////////////////////////////////////////////////////////////////////////
/*
Constructor.

i_id:         The ID of the panel.
i_state:      The current state of the panel. Can be "shown" or "hidden".
i_min_size:   The minimum size of the panel.
i_max_size:   The maximum size of the panel.
i_anim_mode:  The animation mode. 0 = smooth, 1 = click
*/
function PixPanel( i_id, i_state, i_min_size, i_max_size, i_anim_mode )
{
  // Initialize data members
  this.m_id         = i_id;
  this.m_state      = i_state;
  this.m_min_size   = i_min_size;
  this.m_max_size   = i_max_size;
  this.m_anim_mode  = i_anim_mode;
  
  // Determine current size
  if (i_state == "hidden")
    this.m_cur_size = i_min_size;
  else
    this.m_cur_size = i_max_size;
    
  // Determine the location and visibility of the panel 
  // based on the layer it represents.
  var layer = HTGetElementByID(this.m_id);
  if (layer != null)
    this.Location = HTGetLocation(layer);
  else
    this.Location = {X:0, Y:0};
//  alert(this.m_id + " : X=" + this.Location.X + ", Y=" + this.Location.Y);
  
  // Build method table
  this.Animate    = PixPanel_Animate;
  this.Show       = PixPanel_Show;
  this.Hide       = PixPanel_Hide;
  this.Switch     = PixPanel_Switch;
  this.Paint      = PixPanel_Paint;
  this.IsVisible  = PixPanel_IsVisible;
  this.OnShown    = null;
  this.OnShowing  = null;
  this.OnHidden   = null;
  this.OnHiding   = null;
  
  // Paint the layer
  this.Paint();
}

//-----------------------------------------------------------------------------
/*
Checks whether the panel is shown or showing.
*/
function PixPanel_IsVisible( )
{
  return (this.m_state == "shown" || this.m_state == "showing");
}

//-----------------------------------------------------------------------------
/*
Animates the panel.

i_panel:  Optional panel reference. Will be undefined when called from within
          panel itself.
*/
function PixPanel_Animate( i_panel )
{
  // Check from where this method has been called
  if (!i_panel)
  {
    if (!this)
      return;
    i_panel = this;
  }

  // Determine the direction and move the panel
  if (i_panel.m_state == "showing")
  {
    // Determine the delta to move...
    // Try starting quick, and slowing down to the end
    var delta = i_panel.m_max_size - i_panel.m_cur_size;
    delta  = Math.round(delta / 20);
    
    // Animation mode modifiers
    if (i_panel.m_anim_mode == 0)
    {
      // Smooth version 
      if (delta < 1)
        delta = 1;
    }
    else
    {
      // 'click' version
      if (delta < 1)
        delta = i_panel.m_max_size - i_panel.m_cur_size;
    } 
    
    // Move the panel            
    i_panel.m_cur_size = i_panel.m_cur_size + delta;
    if (i_panel.m_cur_size >= i_panel.m_max_size)
    {
      i_panel.m_state = "shown";
      i_panel.m_cur_size = i_panel.m_max_size;  // Just to align everything correctly!
    }
  }
  else if (i_panel.m_state == "hiding")
  {
    // Determine the delta to move...
    // Try starting quick, and slowing down to the end
    var delta = i_panel.m_cur_size - i_panel.m_min_size;
    delta  = Math.round(delta / 20);
    
    // Animation mode modifiers
    if (i_panel.m_anim_mode == 0)
    {
      // Smooth version 
      if (delta < 1)
        delta = 1;
    }
    else
    {
      // 'click' version
      if (delta < 1)
        delta = i_panel.m_cur_size - i_panel.m_min_size;
    }
    
    // Move the panel            
    i_panel.m_cur_size = i_panel.m_cur_size - delta;
    if (i_panel.m_cur_size <= i_panel.m_min_size)
    {
      i_panel.m_state = "hidden";
      i_panel.m_cur_size = i_panel.m_min_size;  // Just to align everything correctly!
    }
  }
  else
  {
    // No animation needs to be done anymore
    return;
  }
  
  // Paint the panel
  i_panel.Paint();
  
  // Determine whether we need to continue animating
  if (i_panel.m_state == "shown")
  {
    if (i_panel.OnShown)
      i_panel.OnShown(i_panel);
  }
  else if (i_panel.m_state == "hidden")
  {
    if (i_panel.OnHidden)
      i_panel.OnHidden(i_panel);
  }
  else
  {
    // Start the next animation cycle
    setTimeout(function(){PixPanel_Animate(i_panel)}, 10);  
  }    
}

//-----------------------------------------------------------------------------
/*
Paints the panel = makes it visible and positions it correctly.
*/
function PixPanel_Paint( )
{
  // Retrieve the layer for the panel
  var layer = HTGetElementByID(this.m_id);
  if (layer == null)
    return;
    
  // Show the layer
  var clip_size = this.m_max_size - this.m_cur_size;
  layer.style.left  = this.Location.X + "px";
  layer.style.top   = (this.Location.Y-clip_size) + "px";
  layer.style.clip  = "rect(" + clip_size + "px 468px " + this.m_max_size + "px 0px)";
  layer.style.visibility = "visible";
  
}

//-----------------------------------------------------------------------------
/*
Shows the panel (using animation).
If the panel is already shown, we do nothing.
*/
function PixPanel_Show( )
{
  // If the panel is already shown, we do not need to do anything...
  if (this.m_state == "shown")
  {
    if (this.OnShown)
      this.OnShown(this);
    return;
  }
  
  // Call event handler, if any
  if (this.OnShowing)
    this.OnShowing(this);
    
  // Animate the panel
  this.m_state = "showing";
  this.Animate( );  
}

//-----------------------------------------------------------------------------
/*
Hides the panel (using animation).
If the panel is already shown, we do nothing.
*/
function PixPanel_Hide( )
{
  // If the panel is already hidden, we do not need to do anything...
  if (this.m_state == "hidden")
  {
    if (this.OnHidden)
      this.OnHidden(this);
    return;
  }
    
  // Call event handler, if any
  if (this.OnHiding)
    this.OnHiding(this);
    
  // Animate the panel
  this.m_state = "hiding";
  this.Animate( );  
}

//-----------------------------------------------------------------------------
/*
Switches the panel (using animation).
If the panel is hidden, it is shown and vice versa.
*/
function PixPanel_Switch( )
{
  // Determine the new state
  if (this.m_state == "hidden" || this.m_state == "hiding")
    this.m_state = "showing";
  else if (this.m_state == "shown" || this.m_state == "showing")
    this.m_state = "hiding";
    
  // Animate the panel
  this.Animate( );  
}

///////////////////////////////////////////////////////////////////////////////
// Global Methods
///////////////////////////////////////////////////////////////////////////////
function PixShowSlideshow( )
{
  g_layer_slideshow.Show();
  PixStartSlideshow( );
}

//-----------------------------------------------------------------------------
function PixHideSlideshow( )
{
  g_layer_vcr.Hide();
  PixStopSlideshow( );
}

//-----------------------------------------------------------------------------
function PixSwitchSlideshow( )
{
  if (g_layer_slideshow.IsVisible())
    PixHideSlideshow( );
  else
    PixShowSlideshow( );
}

//-----------------------------------------------------------------------------
/*
This methods paints the current slide photo on the slideshow canvas.
*/
function PixUpdateSlideshowImage( )
{
  // Retrieve the photo to display
  // and pre-load it.
  var photo = ga_photos[g_slide_index];
  if (!photo)
    return;
  photo.PreLoad();
    
  // Also pre-load the previous and the next photo
  if (g_slide_index < ga_photos.length-1)  
  {
    var next_photo = ga_photos[g_slide_index+1];
    if (next_photo)
      next_photo.PreLoad();
  }
  if (g_slide_index > 0)  
  {
    var prev_photo = ga_photos[g_slide_index-1];
    if (prev_photo)
      prev_photo.PreLoad();
  }
    
  // Display the image inside the slideshow layer
  var image = HTGetElementByID("PixImageSlideshow");
  if (image)
  {
    image.src = photo.Original.src;
    HTSetDimensions(image, photo.Original.width, photo.Original.height);
  }
}

//-----------------------------------------------------------------------------
function PixStartSlideshow( )
{
  // Start the auto-slideshow, if not already done
  if (g_timer_slideshow == null)
    g_timer_slideshow = setTimeout(PixRunSlideshow, g_slideshow_delay);
}

//-----------------------------------------------------------------------------
function PixStopSlideshow( )
{
  // Stop the auto-slideshow, if not already done
  if (g_timer_slideshow != null)
  {
    clearTimeout(g_timer_slideshow);
    g_timer_slideshow = null;
  }
}

//-----------------------------------------------------------------------------
function PixRunSlideshow( )
{
  // Go to the next slide
  PixGoToNextSlide( );
  
  // Prepare the next cycle
  g_timer_slideshow = setTimeout(PixRunSlideshow, g_slideshow_delay);
}

//-----------------------------------------------------------------------------
function PixGoToNextSlide( )
{
  // Only go to the next slide when the current slide has been loaded
  var photo = ga_photos[g_slide_index];  
  if (photo)
  {
    if (!photo.Original.complete)
      return;
  }

  // Go to the next slide, and wrap when at the end
  g_slide_index++;
  if (g_slide_index >= ga_photos.length)
    g_slide_index = 0;
    
  // Update the slideshow    
  PixUpdateSlideshowImage();
  
  // Make sure the photo is also visible in the strip
  PixScrollStripPhotoIntoView( );
/* 
  // Also zoom in on the current strip photo 
  var photo_id = g_slide_index - g_strip_start_index + 1;
  PixZoomOnPhoto(photo_id);
*/  
}

//-----------------------------------------------------------------------------
function PixGoToPrevSlide( )
{
  // Go to the next slide, and wrap when at the beginning
  g_slide_index--;
  if (g_slide_index < 0)
    g_slide_index = ga_photos.length - 1;
    
  // Update the slideshow    
  PixUpdateSlideshowImage();
  
  // Make sure thhe photo is also visible in the strip
  PixScrollStripPhotoIntoView( );
/* 
  // Also zoom in on the current strip photo 
  var photo_id = g_slide_index - g_strip_start_index + 1;
  PixZoomOnPhoto(photo_id);
*/  
}

//-----------------------------------------------------------------------------
function PixScrollStripPhotoIntoView( )
{
  // Make sure the strip contains the photo of the current slide.
  if (g_slide_index < g_strip_start_index)
    g_strip_start_index = g_slide_index;
  else if (g_slide_index > g_strip_start_index + 10)
    g_strip_start_index = g_slide_index - 10;
  else
    return;
    
  // Update the strip
  for(i=1; i<=11; i++)
  {
    var photo = ga_photos[g_strip_start_index+i-1];
    if (!photo)
      continue;
    photo.PreLoadThumbs();
    
    var image = HTGetElementByID("PixPhoto-" + i);
    if (image)
      image.src = photo.Thumb40x40.src;
  }    
}

//-----------------------------------------------------------------------------
function PixDoScrollStripLeft( )
{
  // Maybe we can no longer scroll left?
  if (ga_photos.length <= 11)
    return;
  if (g_strip_start_index == 0)
    return;
  
  // Perform scrolling
  g_strip_start_index--;
  
  // Update the strip
  for(i=1; i<=11; i++)
  {
    var photo = ga_photos[g_strip_start_index+i-1];
    if (!photo)
      continue;
    photo.PreLoadThumbs();
    
    var image = HTGetElementByID("PixPhoto-" + i);
    if (image)
      image.src = photo.Thumb40x40.src;
  }    
  
  // Also zoom on the current photo
  PixZoomOnPhoto(1);
  
  // Finally, schedule a new scroll action
  g_timer_scroll = setTimeout(PixDoScrollStripLeft, 250);
}

//-----------------------------------------------------------------------------
function PixScrollStripLeft( i_initial_delay )
{
  // Maybe we can no longer scroll left?
  if (ga_photos.length <= 11)
    return false;
  if (g_strip_start_index == 0)
    return false;
  
  // Finally, schedule the scroll action
  g_timer_scroll = setTimeout(PixDoScrollStripLeft, i_initial_delay);
  return true;
}

//-----------------------------------------------------------------------------
function PixDoScrollStripRight( )
{
  // Maybe we can no longer scroll right?
  if (ga_photos.length <= 11)
    return;
  if (g_strip_start_index == ga_photos.length-11)
    return;
    
  // Perform scrolling
  g_strip_start_index++;
  
  // Update all the photos
  for(i=1; i<=11; i++)
  {
    var photo = ga_photos[g_strip_start_index+i-1];
    if (!photo)
      continue;
    photo.PreLoadThumbs();
    
    var image = HTGetElementByID("PixPhoto-" + i);
    if (image)
      image.src = photo.Thumb40x40.src;
  }    
  
  // Also zoom on the current photo
  PixZoomOnPhoto(11);
  
  // Finally, schedule a new scroll action
  g_timer_scroll = setTimeout(PixDoScrollStripRight, 250);
}

//-----------------------------------------------------------------------------
function PixScrollStripRight( i_initial_delay )
{
  // Maybe we can no longer scroll right?
  if (ga_photos.length <= 11)
    return false;
  if (g_strip_start_index == ga_photos.length-11)
    return false;
    
  // Finally, schedule the scroll action
  g_timer_scroll = setTimeout(PixDoScrollStripRight, i_initial_delay);
  return true;
}

//-----------------------------------------------------------------------------
function PixZoomOnPhoto( i_photo_id )
{
  // We do nothing as long the thumbnail has not been loaded yet
  var photo = ga_photos[g_strip_start_index + i_photo_id-1];
  if (!photo || !photo.Thumb120x120 || !photo.Thumb120x120.complete)
    return;

  // Update the middle thumb nail       
  var mthumb = HTGetElementByID("PixImageThumbMiddle");
  HTSetDimensions(mthumb, photo.Thumb120x120.width, photo.Thumb120x120.height);
  mthumb.src = photo.Thumb120x120.src;
  
  // Show the middle layer  
  var image = HTGetElementByID("PixPhoto-" + i_photo_id);
  var mlayer = HTGetElementByID("PixLayerThumb");
  var x = i_photo_id * 41 - 60;
  var y = 4+20-photo.Thumb120x120.height/2;
  var position = HTGetPosition(image);
  if (position.Y + y < 0)
    y = -position.Y;
  HTSetLocation(mlayer, x, y);
  mlayer.style.visibility = "visible";
}


///////////////////////////////////////////////////////////////////////////////
// Event Handlers
///////////////////////////////////////////////////////////////////////////////
function OnMouseOverPhoto( i_image )
{
  // Maybe the photos have not been created?
  if (ga_photos == null)
    return;
    
  // Retrieve the selected photo
  var id_prefix = "PixPhotoSil-";
  var photo_id = parseInt(i_image.id.substr(id_prefix.length));
    
  // Zoom on the selected photo
  PixZoomOnPhoto(photo_id);
  
  // Scroll when we touch the first and last photo
  if (photo_id == 1)
  {
    if (PixScrollStripLeft(750))
      return;
  } 
  else if (photo_id == 11)
  {
    if (PixScrollStripRight(750))
      return;
  }
}

//-----------------------------------------------------------------------------
function OnMouseOutPhoto( i_image )
{
  var mlayer = document.getElementById("PixLayerThumb");
  if (mlayer != null)
    mlayer.style.visibility = "hidden";
/*    
  var llayer = document.getElementById("PixLayerThumbLeft");
  if (llayer != null)
    llayer.style.visibility = "hidden";
    
  var rlayer = document.getElementById("PixLayerThumbRight");
  if (rlayer != null)
    rlayer.style.visibility = "hidden";
*/    
  if (g_timer_scroll != null)
  {
    clearTimeout(g_timer_scroll);
    g_timer_scroll = null;
  }
}

//-----------------------------------------------------------------------------
function OnClickPhoto( i_image )
{
  // Maybe the photos have not been created?
  if (ga_photos == null)
    return;

  // Retrieve the selected photo
  var id_prefix = "PixPhotoSil-";
  var photo_id = parseInt(i_image.id.substr(id_prefix.length));
  
  // Remember the current photo for the VCR
  g_slide_index = g_strip_start_index + photo_id - 1;
  
  // Update the slideshow
  PixUpdateSlideshowImage( );
  
  // Drop the slideshow down
  g_layer_slideshow.Show();
}

//-----------------------------------------------------------------------------
function OnClickVCRPrev( )
{
  PixGoToPrevSlide();
}

//-----------------------------------------------------------------------------
function OnClickVCRPlay( )
{
  PixStartSlideshow();
}

//-----------------------------------------------------------------------------
function OnClickVCRPause( )
{
  PixStopSlideshow();
}

//-----------------------------------------------------------------------------
function OnClickVCRStop( )
{
  PixStopSlideshow();
  PixHideSlideshow();
}

//-----------------------------------------------------------------------------
function OnClickVCRNext( )
{
  PixGoToNextSlide();
}

//-----------------------------------------------------------------------------
function OnShownSlideshowPanel( i_panel )
{
  g_layer_vcr.Show( );  
}

//-----------------------------------------------------------------------------
function OnHiddenVCRPanel( i_panel )
{
  // Start hiding the slideshow panel
  g_layer_slideshow.Hide( );  
}

//-----------------------------------------------------------------------------
function OnHidingVCRPanel( i_panel )
{
  // Hide the VCR silhouette layer too
  var layer = HTGetElementByID("PixLayerVCRSilhouette");
  if (layer)
    layer.style.visibility = "hidden";
}

//-----------------------------------------------------------------------------
function OnShownVCRPanel( i_panel )
{
  // Show the VCR silhouette layer too
  var layer = HTGetElementByID("PixLayerVCRSilhouette");
  if (layer)
    layer.style.visibility = "visible";
}

//-----------------------------------------------------------------------------
function OnWindowLoad() 
{
  // Maybe the photos have not been created?
  if (typeof(ga_photos) == "undefined")
    return;
  if (ga_photos == null)
    return;

  // Build the panels
  g_layer_slideshow = new PixPanel("PixLayerSlideshow", "hidden", 16, 480, 1);
  g_layer_slideshow.OnShown = OnShownSlideshowPanel;
  g_layer_vcr = new PixPanel("PixLayerVCR", "hidden", 0, 48, 0);
  g_layer_vcr.OnHidden  = OnHiddenVCRPanel;
  g_layer_vcr.OnHiding  = OnHidingVCRPanel;
  g_layer_vcr.OnShown   = OnShownVCRPanel;

  // Show the thumbnails
  for(p=1; p<=11; p++)
  {
    var photo = ga_photos[p-1];
    if (p == 1)
    {
      var big_image = HTGetElementByID("PixImageSlideshow");
      if (big_image)
      {
        photo.PreLoad();
        big_image.src = photo.Original.src;
        HTSetDimensions(big_image, photo.Original.width, photo.Original.height);
      }
    }

    if (p <= 11)
    {    
      var image = HTGetElementByID("PixPhoto-" + p);
      if (image)
      {
        photo.PreLoadThumbs();
        image.src = photo.Thumb40x40.src;
        HTSetDimensions(image, photo.Thumb40x40.width, photo.Thumb40x40.height);
      }
    }
  }
  
  // Show the strip
  var layer = HTGetElementByID("PixLayerThumbStrip");
  layer.style.visibility = "visible";
  
  // Sometimes, in IE, the dynamic content layout is lost when the user resizes the 
  // browser window. In order to restore the layout of the page, we must re-paint 
  // some of the layers when the resize event occurs.
  setTimeout("HTAddEvent(window, 'resize', OnWindowResize)", 1000);
}

//-----------------------------------------------------------------------------
function OnWindowResize( )
{
  var layer = document.getElementById("PixLayerThumb");
  if (layer == null)
    return;
  layer.style.visibility = "visible";
  layer.style.visibility = "hidden";
}
