  //
  // This holds the information for all photos in the album. It is loaded from the "filmstrip" on start-up.
  //
  var allImages = new Array();

  //
  // These track the view mode, the photos per page, page number, etc.
  //
  var viewMode = 'Info';
  var prevPhotosPerPage = 999;  // Set to a very large number, so that we will initially re-draw the screen.
  var currPageNum = 1;
  var currPageStartPic = 0;
  var currentPic = null;
  var currNatWidth = 0;
  var currNatHeight = 0;
  var currCntnrWidth = 0;
  var currCntnrHeight = 0;

  //
  // These are used for the filmstrip.
  // Thanks to Patrick Hunlock for the filmstrip scripts and tutorial.
  //   http://www.hunlock.com/blogs/Flickr_Filmstrips_in_Javascript
  //
  var _landingZone = null;           // Table which creates the filmstrip bondary
  var _filmstrip = null;             // Our filmstrip layer
  var _topOffset = 0;                // Y position of the table in the web page
  var _leftOffset = 0;               // X position of the table in the web page.
  var _totalOffset = 0;              // Current X offset of the filmstrip.
  var _filmWidth = 0;                // Width of filmstrip in pixels.
  var _totalChange = 0;              // Total pixels moved/changed
  var _savedTarget = null;           // Target object of drag event
  var _orgCursor = null;             // Original cursor Style
  var _dragXOffset = 0;              // X offset of the move event
  var _dragYOffset = 0;              // Y offset of the move event
  var _scrollOK = false;             // True if we can scroll filmstrip
  var _originalOffset=0;             // Original offset (before drag event)

  //
  // Basic page functions...
  //

  //
  // Called by the onLoad event of the window. This sets up internal data
  // and displays the initial view of the album (i.e. changes it from the
  // default Non-JavaScript view to the fully DHTML view).
  //
  function init( )
  {        	  	  
      getBrowserType( );
      getThumbList( );
      setPageMode( viewMode );
      setPageSize( );      
      revalidateLogin();
  }
  
  function revalidateLogin(key)
  {
      //
      // Try to get the security cookie (if set). This is set when we are in an album, and we are logged in, and
      // we exit the album page. This lets us get value if we're going 'back' in the browser history to this page
      // from an album. The life time for the cookie is very short, so it won't be available anywhere else.
      //
      var tmpSecurityKey = null;
      if( document.getElementById('albuminitialhidden').initialcode.value.length > 0 )
      {
          tmpSecurityKey = document.getElementById('albuminitialhidden').initialcode.value;
      }

      var tmpStr = readCookie("bbphotoAdminsecureKey");
      if( null != tmpStr )
      {     
	      tmpSecurityKey = tmpStr;
	      eraseCookie("bbphotoAdminsecureKey");
      }
	 
      var albumId = document.getElementById('albuminitialhidden').albumId.value;

	 //
	 // Make an AJAX call to validate the security key, and reset it.
	 //	If the key is set, ask the login service to  validate, and re-set the footer,
	 //
	 if( tmpSecurityKey ) 
	 {
	     var params = "action=validateLogin" +
	                   "&logintype=album" +
	                   "&albumId=" + albumId;
         
         try
         {	                  
	         currSecurityKey = tmpSecurityKey; 
             sendAjaxRequest( params, loginWebSvcUrl , function(responseXML){              
                  // look for the h3 with the id of 'success' if there, continue, else pop up error alert.
                  if( null != responseXML.getElementsByTagName('success')[0] )
                  {                  
                      // Find all script elements. 
                      var scriptElements = responseXML.getElementsByTagName('script');
                  
                      for( var idx = 0; idx < scriptElements.length; ++idx )
                      {
                          var scriptText = getTextNode(scriptElements[idx]);
                          
                          // Eval all script elements.
                          eval(scriptText);                           
                      }
                  }
                  else
                  {
                      var errorMsgNode = responseXML.getElementsByTagName('error')[0]
                      if( null != errorMsgNode )
                      {
                          var errorText = getTextNode(errorMsgNode);
                          alert( errorText );
                          var adminitm = parent.document.getElementById('bbphotoadminitm');
	                      adminitm.innerHTML = "<a id='bbphotologinbtn' onClick='doLoginForm(\"album\"); return false;'><img src='/log_in.png' alt='[Log In]'></a>"	  	  
	                      currSecurityKey = "";
                      }
                  }              
              } );
              
          }
          catch( err ) 
          {
	          alert('Unable to re-validate login. XHR failed.');
              var adminitm = parent.document.getElementById('bbphotoadminitm');
	          adminitm.innerHTML = "<a id='bbphotologinbtn' onClick='doLoginForm(\"album\"); return false;'><img src='/log_in.png' alt='[Log In]'></a>"	  	  
	          currSecurityKey = "";
	      }	      	     
	 }
	 else
	 {
          var adminitm = parent.document.getElementById('bbphotoadminitm');
          adminitm.innerHTML = "<a id='bbphotologinbtn' onClick='doLoginForm(\"album\"); return false;'><img src='/log_in.png' alt='[Log In]'></a>"	  	  
	      currSecurityKey = "";
	 }  
  }
  
  
  //
  // Retrieves the thumbnails for the album, and stores them for later use (mainly
  // by the pager, and the setPageSize methods)
  //
  function getThumbList( )
  {
      _filmWidth = 0;

      //
      // The filmstrip section on the HTML page is going to be our master list. Let's load the images
      // from there. The alt for the image is the file comment, the name attribute is the image name, and
      // the source (of the thumbnail) will be used to calculate the src for the full-size image.
      //
      // We're placing these in arrays for convenience later, when we set up and use the pager mechanism.
      //

      var filmstrip = document.getElementById('filmstripcntnr');
      if( filmstrip )
      {
          var imgArray = filmstrip.getElementsByTagName('img');
          var idx = 0;

          allImages.splice(1,allImages.length);

          for( var x = 0; x < imgArray.length; x++ )
          {
              allImages[idx] = imgArray[x];
              idx++;
          }
          return true;
      }
      else
      {
          alert('No items in the thumbs list.');
          return false;
      }
  }

  function getStyle(x,styleProp)
  {
      var y = 0;

      if (x.currentStyle)
          y = x.currentStyle[styleProp];
      else if (window.getComputedStyle)
          y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
      return y;
  }


  //
  // This is the main functionality for this photo album...
  // This method is called on every page resize, or every change of view mode. It
  // determines the size of the conatiner element that holds the album, and then
  // updates the HTML of the container to show the appropriate number of thumbnails.
  // It also updates the pager on the screen as well to show the appropriate
  // number of pages.
  //
  // For IE (and other browsers that will make a container the minimum or maximum possible
  // size, even when a relative size (percentage, etc) is given, you must resize the containing
  // div / frame / table / etc. on every 'onresize' event before calling this..
  //
  function setPageSize( )
  {

      //
      // First, lets determine if we need scrollbars or not. Since we're going to be
      // using the selector in several places, lets get a reference up front, and keep it
      // around for a while.
      //
      var numPerPage = document.getElementById('numperpageselector').value;

      //
      // If we're doing 'auto' for the page mode, we don't want / need scroll bars. Else, keep them.
      //
      if( numPerPage != 'auto' )
      {
          document.getElementById("bbphotocontainer").style.overflow = 'auto';
      }
      else
      {
          document.getElementById('bbphotocontainer').scrollTop = 0;
          document.getElementById("bbphotocontainer").style.overflow = 'hidden';
      }

      //
      // Now, lets setermine the size of the current view space.
      // We're going to be reusing the references to these objects,
      // so we may as well keep them around.
      //
      var container = document.getElementById('bbphotocontainer');
      var title = document.getElementById('bbphototitle');
      var comment = document.getElementById('bbphotodesc');
      var topbar = document.getElementById('bbphototopbar');
      var bottombar = document.getElementById('bbphotobottombar');
      var bbphotobottomstop = document.getElementById('bbphotobottomstop');

      var availHeight = 0;
      var availWidth = 0;

      availHeight = container.offsetHeight -
                    title.offsetHeight -
                    comment.offsetHeight -
                    topbar.offsetHeight -
                    bottombar.offsetHeight -
                    3.5 * bbphotobottomstop.offsetHeight - 37; // Fixup for padding / border / margin errors.

      availHeight = Math.floor( availHeight );

      //
      // For IE, we want 2.5 times the height of a <p> element, not 3.5
      //
      // Also, fix up IE error in reporting border / padding / margin widths...
      //
      if( isIe && !isIE7)
      {
           availHeight += bbphotobottomstop.offsetHeight;
           availHeight += 14;
      }


      availWidth = (document.getElementById("bbphotobody")).offsetWidth - 12;

      //
      // If in film mode, we need to resize the bbphotofilmpreviewcntnr, bbphotofilmpreview, and bbphotofilmdetailPic
      // For this, we need to know the size of the bbphotofilmcomment, bbphotofilmtitle, and the landingZone and
      // remove these sizes from the height available.
      //
      if( viewMode == 'Film' )
      {
          var availHeight = availHeight -
                            document.getElementById('bbphotofilmcomment').offsetHeight -
                            document.getElementById('bbphotofilmtitle').offsetHeight -
                            document.getElementById('landingZone').offsetHeight - 24  - 5 - 5; // Fixup for padding / border / margin errors.

          //
          // For filmstrip, we want the width of the outer container, not the inner one.
          //
          var availWidth = container.offsetWidth - 24; // gives us some padding.

          if( isIe )
          {
              // availHeight -= 8;    // Fixup for IE differences in reporting borders, padding, and margins...
              // availHeight -= 27;
              availWidth -= 12;
          }

          //
          // Set the globals for this (we'll use this in the fimstrip to scale the
          // preview image to the proper size, without having to recalculate it again.
          //
          currCntnrWidth = availWidth;
          currCntnrHeight = availHeight;

          //
          // Now, we need to scale the selected picture (if any) to fit into the available space.
          //
          var picHeight = 600;
          var picWidth = 800;

          if( null != currentPic )
          {
              picWidth = currNatWidth;
              picHeight = currNatHeight;
          }

          //
          // And make sure to keep the proper aspect ratio.
          //
          if( picHeight > 0 )
          {
              var pixRatio = (picWidth * 1.0) / (picHeight * 1.0);

              if( picHeight > availHeight )
              {
                  picHeight = availHeight;
                  picWidth = Math.floor(pixRatio *picHeight);
              }
              if( picWidth > availWidth )
              {
                  picWidth = availWidth;
                  picHeight = Math.floor(picWidth / pixRatio);
              }
          }
          else
          {
              //
              // If there was no picture visible, then don't worry about it.
              //
              picWidth = 0;
              picHeight = 0;
          }

          //
          // Now, we resize all of the filmstrip components so that they fit the window size
          // and the picture size.
          //
          document.getElementById('bbphotofilmcomment').style.width = picWidth + 24;
          document.getElementById('bbphotofilmtitle').style.width  = picWidth + 24;

          document.getElementById('bbphotofilmdetailPic').style.height = picHeight;
          document.getElementById('bbphotofilmdetailPic').style.width = picWidth;

          document.getElementById('bbphotofilmpreview').style.height = picHeight;
          document.getElementById('bbphotofilmpreview').style.width = picWidth;

          document.getElementById('bbphotofilmpreviewcntnr').style.width = picWidth + 24;
          document.getElementById('bbphotofilmpreviewcntnr').style.height = picHeight + 24 +
                   document.getElementById('bbphotofilmcomment').offsetHeight +
                   document.getElementById('bbphotofilmtitle').offsetHeight;


          //
          // Finally, we need to re-bind the filmstrip scroller to the table again.
          //
          bindStrip();

          return
      }

      //
      // Ok, in normal (i.e. info or thumb) mode, based on the elements (since the size can be changed by the style),
      //  get the size of the picture, and it's associated info...
      //
      var pictframes = new Array();
      var list = document.getElementById('bbphotobody').childNodes;
      for( var e = 0; e < list.length; ++ e )
      {
          if( list[e].className == 'bbphotoimageframe' || list[e].className == 'bbphotoimageframeover' ||
              list[e].className == 'bbphotoimageframeinvisible' || list[e].className == 'bbphotoimageframeinvisibleover' )
          {
              pictframes[pictframes.length] = list[e];
          }
      }

      var pictwidth = 0;
      var pictheight = 0;
      
      if( pictframes.length > 0 )
      {
          pictwidth = (pictframes[0]).offsetWidth;
      	  pictheight = (pictframes[0]).offsetHeight;
  	  }
  	  
      //
      // Now, figure out how many of these items we can set into the window.
      //
      var rows = 0;
      var cols = 0;

      if( pictwidth > 0 && pictheight > 0 )
      {
          cols = Math.floor(availWidth / pictwidth);
          rows = Math.floor(availHeight / pictheight);
      }

      var currentPhotosPerPage = rows * cols;
      
      //
      // If we have fewer pictures than what will fit into the page, we don't need to 
      // show the page selecter.
      //
      if( currentPhotosPerPage >= allImages.length )
      {
          document.getElementById('bbphotobottombar').style.display = 'none';
      }
      else
      {
          document.getElementById('bbphotobottombar').style.display = '';
      }

      //
      // Note, we have a "Photos per Page" drop-down that we need to look at.
      // This overrides the rows * cols setting from above...
      //
      if( numPerPage != 'auto' )
      {
          if( numPerPage == 'all' )
          {
              currentPhotosPerPage = allImages.length;
          }
          else if( null != numPerPage && NaN != parseInt( numPerPage ) )
          {
              currentPhotosPerPage = parseInt( numPerPage );
          }
      }

      //
      // So, now that we know how large the view area is (the container), we can
      // add or remove pictures based on that size, and the previous Photos Per
      // Page (keeps us from re-writing too many times).
      //
      if( currentPhotosPerPage > prevPhotosPerPage )
      {
          //
          // We can now show more pictures, so add photos to the page, and
          // reconfigure the pager.
          //

          //
          // So, let's get our starting point (how many images we currently have on the page)
          //
          var i = pictframes.length;

          //
          // We're going to use innerHTML as it's easier to use, and works better in general.
          var objBody = document.getElementById("bbphotobody");
          var strnHtml = objBody.innerHTML;

          //
          // Make sure to keep the same style as we currently have...
          // We have to do this based on the viewMode as we may or may not have an example item in the document...
          //
          var currThumbStyle = 'bbphotoimageframe';
          if( viewMode == 'Thumb' )
          {
              currThumbStyle = 'bbphotoimageframeinvisible';
          }

          //
		  // If the currPageStartPic plus the currentPhotosPerPage is way larger than the end
		  // of the photos list, we should fill in the rest of the list, and then work backwards.
		  // That way, we'll always have a nearly full page. 
		  //
		  if( currPageStartPic + currentPhotosPerPage > allImages.length )
		  {
		      strnHtml = "";
			  currPageStartPic = allImages.length - currentPhotosPerPage;
			  i = 0;
		  }
		  
          //
          // Now, set up the actual items.
          //
          var currPic;
          for(; (i < currentPhotosPerPage ) && (i + currPageStartPic < allImages.length); ++i )
          {
             //
             // Get our current picture (based on the starting picture number for this page, and our counter
             //
             currPic = i + currPageStartPic;

             //
             // add the HTML for the item.
             //
             strnHtml += getThumbHtml( allImages[currPic] );
          }

          //
          // Now, add all of the items to the parent's inner HTML.
          //
          objBody.innerHTML = strnHtml;

          //
          // Set our photos per page indicator, this way we're not re-doing all of this work each time we resize.
          //
          prevPhotosPerPage =  currentPhotosPerPage;
          
          //
          // Now, calculate the new pager string ( << < 1 2 3 4 ... x > >> )
      	  // and highlight the current page.
      	  //
      	  setPagerHtml( );
          
	      //
       	  // Ok, now, since we may be in thumbnail mode, or info mode for that matter,
    	  // we need to go through and set the display property correctly for those items
	      // that we wouldn't change the class for... Since we already have a method for this,
    	  // we'll just go ahead and call it, instead of re-inventing the wheel here...
          //
	      setPageMode( viewMode )
	  }
      else if( currentPhotosPerPage < prevPhotosPerPage )
      {
          //
          // We now can show fewer photos per page, so take some away, and
          // reconfigure the pager.
          //

          //
          // Get our starting point (the number of elements currently on the page.
          //
          var i = pictframes.length-1;
          var objBody = document.getElementById("bbphotobody");

          //
          // Now, use the DOM methods to remove some of them (but not all of them)...
          //
          for(; (i >= currentPhotosPerPage) && (i > 0); --i )
          {
              objBody.removeChild(pictframes[i]);
          }
          
          

          //
          // Set our photos per page indicator, this way we're not re-doing all of this work each time we resize.
          //
          prevPhotosPerPage =  currentPhotosPerPage;

          //
          // Now, calculate the new pager string ( << < 1 2 3 4 ... x > >> )
      	  // and highlight the current page.
      	  //
      	  setPagerHtml( );
          
	      //
       	  // Ok, now, since we may be in thumbnail mode, or info mode for that matter,
    	  // we need to go through and set the display property correctly for those items
	      // that we wouldn't change the class for... Since we already have a method for this,
    	  // we'll just go ahead and call it, instead of re-inventing the wheel here...
          //
	      setPageMode( viewMode )
     }
  	  

      return true;
  }

  //
  // This method fires when we select thumbs mode.
  // It sets the styles appropriately, moves back to page 1, and then adds / removes
  // pictures from the display as necessary to fill the available area...
  //
  function thumbsBtnClicked( )
  {
      setThumbMode(  );
      drawPage( 1 );
      setPageSize( );
  }

  //
  // This method fires when we select info mode.
  // It sets the styles appropriately, moves back to page 1, and then adds / removes
  // pictures from the display as necessary to fill the available area...
  //
  function infoBtnClicked()
  {
      setInfoMode();
      drawPage( 1 );
      setPageSize( );
  }

  //
  // This method fires when we select filmstrip mode.
  // It sets the styles appropriately, and then resizes everything to
  // fit the current screen size.
  //
  function filmBtnClicked()
  {
      setFilmMode();
      setPageSize();
  }

  //
  // This method is called by the init method internally to call the appropriate
  // methods for setting the page display mode.
  //
  function setPageMode( pageMode )
  {
      if( pageMode == 'Thumb' )
      {
          setThumbMode();
      }
      else if( pageMode == 'Info' )
      {
          setInfoMode();
      }
      else if( pageMode == 'Film' )
      {
          setFilmMode();
      }

      return true;
  }

  //
  // This changes the view to thumbnail mode (removing the image title and caption
  // and the associated borders) by changing the display property and style
  // of the appropriate elements.
  //
  function setThumbMode(  )
  {
      viewMode = 'Thumb';

      document.onmousedown = null;

      //
      // Bring back the bbphotoinfoframe spans (set display to none.)
      //
      document.getElementById('bbphotobody').style.display='block';

      //
      // Hide the filmstrip.
      //
      document.getElementById('bbphotofilmpreviewcntnr').style.display='none';
      document.getElementById('bbphotofilmcntnr').style.display='none';

      //
      // Show the pager(s)
      //
      var items = getElementsByStyleClass('bbphotopager');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='inline';
      }

      var items = getElementsByStyleClass('bbphotopagerspacer');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='none';		  		  
      }
	  
      //
      // Show the num per page dropdown box.
      //
      document.getElementById('numperpage').style.display='inline';

      //
      // Remove the bbphotoinfoframe spans (set display to none.)
      //
      var items = getElementsByStyleClass('bbphotoinfoframe');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='none';
      }

      //
      // Change the image frame to the invisible class (this is made a
      // class in its own right so that we can go back and forth between
      // the bordered version (info mode) and the borderless version
      // (thumbnail mode).
      //
      var items = getElementsByStyleClass('bbphotoimageframe');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].className = 'bbphotoimageframeinvisible';
      }

      return true;
  }

  //
  // This sets the display to Info Mode, showing the text information in the
  //  bbphotoinfoframe element (image title and caption currently). It does this
  //  by setting the display modes of the relevent items to either block / inline
  //  or none (for the filmstrip items).
  //
  function setInfoMode(  )
  {
      viewMode = 'Info';

      document.onmousedown = null;

      //
      // Bring back the bbphotoinfoframe spans (set display to none.)
      //
      document.getElementById('bbphotobody').style.display='block';

      //
      // Shoe the pager(s)
      //
      var items = getElementsByStyleClass('bbphotopager');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='inline';
      }

      var items = getElementsByStyleClass('bbphotopagerspacer');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='none';		  		  
      }
      //
      // Show the num per page dropdown
      //
      document.getElementById('numperpage').style.display='inline';

      //
      // Hide the filmstrip.
      //
      document.getElementById('bbphotofilmpreviewcntnr').style.display='none';
      document.getElementById('bbphotofilmcntnr').style.display='none';

      //
      // Since this is the info mode, we need to show the info frame.
      //
      var items = getElementsByStyleClass('bbphotoinfoframe');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='block';
      }

      //
      // Change the image frame to the normal class (this is made a
      // class in its own right so that we can go back and forth between
      // the bordered version (info mode) and the borderless version
      // (thumbnail mode).
      //
      var items = getElementsByStyleClass('bbphotoimageframeinvisible');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].className = 'bbphotoimageframe';
      }

      return true;
  }

  //
  // Set to filmstrip mode. In this mode, we hide the top section of the page,
  // and replace it with the preview picture. We also show the fimlstrip
  // itself, and enable the drag handler. In this mode, the pager bars and the
  // num per page dropdown are not needed, so they are hidden.
  //
  function setFilmMode( )
  {
      viewMode = 'Film';

      document.getElementById('bbphotobody').style.display='none';

      document.getElementById('bbphotofilmpreviewcntnr').style.display='block';

      document.getElementById('bbphotofilmcntnr').style.display='block';

      var items = getElementsByStyleClass('bbphotopager');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='none';
      }

      var items = getElementsByStyleClass('bbphotopagerspacer');
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].style.display='inline';		  		  
      }	
	  
      document.getElementById('numperpage').style.display='none';

      if( currentPic == null )
      {
          showPic(allImages[0]);
      }

      document.getElementById("bbphotocontainer").style.overflow = 'hidden';

      bindStrip();

      document.onmousedown = dragHandler;

      return true;
  }

  //
  // This method is called when the slideshow button is clicked on. It starts
  // the lightbox plugin object, and sets it with the appropriate picture
  // (the 1st one on the page)
  //
  function startSlideshow(startBtn)
  {
      fancyslideshow=true; myLightbox.start(startBtn); return false;
  }

  //
  // This method is called when one of the page number links is clicked on.
  // We have this as a separate method from drawPage in case we need to add
  // additional steps. It's always a good idea to break these out...
  //
  function setPage( pagenum )
  {
      drawPage( pagenum );

      //
      // Ok, now, since we may be in thumbnail mode, or info mode for that matter,
      // we need to go through and set the display property correctly for those items
      // that we wouldn't change the class for... Since we already have a method for this,
      // we'll just go ahead and call it, instead of re-inventing the wheel here...
      //
      // We call this here instead of in drawPage since we have several other
      // methods that call drawPage and then call setPageSize, which also calls
      // setPageMode. We don't want to waste time calling it twice, so we factor
      // it out and set it here.
      //
      setPageMode( viewMode )

      return true;
  }

  //
  // This script re-displays the page from scratch, clearing the items in the
  // 'bbphotobody' element, and re-writes the new items.
  // It is used when changing the page. A page number (from 1 to the max page number)
  // is passed in, and it displays that page. The prevPhotosPerPage global is used
  // to determine the starting picture number for the current page.
  // Finally, the script also updates the pager bar to show the current page in
  // the middle of the pager bar, and highlights the current page number.
  //
  function drawPage( pagenum )
  {
     var objBody = document.getElementById("bbphotobody");

     //
     // Make sure we're not re-displaying the current page again... Also, skip
     // this method if we're in fimlstrip mode ( the thumbs container isn't visible)
     //
     if( pagenum != currPageNum && objBody.style.display != 'none')
     {
         //
         // Determine what the start picture number should be for the current page
         //
         currPageStartPic = prevPhotosPerPage * (pagenum -1);

         //
         // Don't let them go past the last page4 If the number is bad, just
         // display the final page.
         //
         if( currPageStartPic > allImages.length )
         {
             currPageStartPic = allImages.length - prevPhotosPerPage - 1;

             pagenum = Math.ceil(allImages.length / prevPhotosPerPage );
         }

         //
         // Now, draw the page. Use the correct style for the current view.
         //
         var currThumbStyle = 'bbphotoimageframe';
         if( viewMode == 'Thumb' )
         {
             currThumbStyle = 'bbphotoimageframeinvisible';
         }

         var strnHtml = "";
         for(var i = currPageStartPic; (i < currPageStartPic + prevPhotosPerPage ) && (i < allImages.length); ++i )
         {
             strnHtml += getThumbHtml( allImages[i] );
         }

         objBody.innerHTML = strnHtml;

         //
         // We need to remember which page we're on.
         //
         currPageNum = pagenum;

         //
         // Now, reposition the pager (with the current page in the middle) and
         // highlight the current page.
         //
         setPagerHtml( );
     }
     return true;
  }

  function setActivePicture( item )
  {
      //
      // This click event will be on the container span for our image. We need to get a reference to the picture we are looking at.
      //
      fancyslideshow=false;
      myLightbox.start((item.childNodes[0]).childNodes[0]);
      return false;
  }

  function setMouseOver( item )
  {
      item.style.cursor='pointer';

      if( item.className == 'bbphotoimageframe')
      {
          item.className = 'bbphotoimageframeover';
      }
      else if( item.className == 'bbphotoimageframeinvisible' )
      {
          item.className = 'bbphotoimageframeinvisibleover';
      }
  }

  function setMouseOut( item )
  {
      item.style.cursor='default';

      if( item.className == 'bbphotoimageframeover')
      {
          item.className = 'bbphotoimageframe';
      }
      else if( item.className == 'bbphotoimageframeinvisibleover' )
      {
          item.className = 'bbphotoimageframeinvisible';
      }
  }

  //
  // This function takes a thumbnail reference, checks the current view mode,
  // and generates the appropriate HTML to display the thumbnail correctly.
  // It then returns the HTML to the caller.
  //
  function getThumbHtml( imgObj )
  {
      if( !imgObj )
         return "";
         
      var currThumbStyle = 'bbphotoimageframe';
      if( viewMode == 'Thumb' )
      {
          currThumbStyle = 'bbphotoimageframeinvisible';
      }

      var tmpstrhtml = "<span class='" + currThumbStyle + "' onClick='setActivePicture(this)' onMouseOver='setMouseOver(this)' onMouseOut='setMouseOut(this)'>" +
                     "<span class='bbphotoimagebrdr'><img src='" + imgObj.src + "' alt='" + imgObj.name + "' class='bbphotothmbimg'>" +
                     "</span><span class='bbphotoinfoframe'><h3 class='bbphotoimgttl'>" + imgObj.name + "</h3><p class='bbphotoimgdesc'>" + imgObj.alt + "</p></span></span> ";

      return tmpstrhtml;
  }

  function setPagerHtml( )
  {
      //
      // Now, calculate the new pager string ( << < 1 2 3 4 ... x > >> )
      //
      var numPhotos = allImages.length;

      
      var numPages = Math.ceil( (( numPhotos * 1.0 ) / prevPhotosPerPage ));

      var pagerString = "";
      
      
      //
      // If we have more than 8 pages, we want to add the << and >> links to the pager.
      //
      if( numPages > 8 )
      {
          pagerString += "<a href='#' class='bbphotopageranchor' onClick='setPage(1);return false;'>&lt;&lt;</a>" +
                         "<a href='#' class='bbphotopageranchor' onClick='setPage( currPageNum - 1 );return false;'>&lt;</a>";
      }

      //
      // Now write out the links for the pages. Make sure we have 8 items at most in the list, with
      // our current page in the middle (unless we're near the beginning or the end)
      //
      if( numPages > 1 )
      {
          var startPageNum = currPageNum - 5;
          if( startPageNum < 1 )
          {
              startPageNum = 1;
          }

          for( var i = startPageNum; i < startPageNum + 8 && i <= numPages; ++ i )
          {
              pagerString += "<a href='#' onClick='setPage( " + i + " );return false;' class='";

              if( i == currPageNum )
              {
                  pagerString += "bbphotopagercurranchor";
              }
              else
              {
                  pagerString += "bbphotopageranchor";
              }

              pagerString += "'> " + i + " </a>";
          }
      }

      //
      // If we have more than 8 pages, we want to add the << and >> links to the pager.
      //
      if( numPages > 8 )
      {
          pagerString += "<a href='#'class='bbphotopageranchor' onClick='setPage( currPageNum + 1 );return false;'>&gt;</a>" +
                         "<a href='#' class='bbphotopageranchor' onClick='setPage("+ numPages +");return false;'>&gt;&gt;</a>";
      }
      
      //
	  // If there are no pages, we still need a non-breaking space, so that we get the correct width.
	  //
	  if( numPages <= 1 )
	  {
	      pagerString = " &nbsp; ";
	  }
      
      //
      // And set the pager string on the web page.
      //
      var items = getElementsByStyleClass('bbphotopager');
      
      for (var cnt = 0; cnt < items.length; cnt++)
      {
          items[cnt].innerHTML = pagerString;
      }
      
      return true;
  }

  function scrollHandler(e)
  {
      //
      // This function handles the draging of the filmstrip from left to right\
      //

      if( e == null ) // Get event data
      {
          e = window.event;
      }

      //
      // Calculate total movement
      //
      _totalChange=( _dragXoffset - e.clientX );

      //
      // Is mouse down and scroll enabled?
      //
      if( e.button <= 1 && _scrollOK )
      {
          //
          // Find the distance mouse has moved
          //
          _totalOffset = _originalOffset + ( _dragXoffset - e.clientX );

          //
          // Are we scrolling too far left?
          //
          if ((_totalOffset) < 0)
          {
              _totalOffset=0; // Yes, set the offset to 0
              _originalOffset=0; // and the original
              _dragXoffset=e.clientX; // and reset the mouse.
              _totalChange=20; // Simulate a move so we don't open a pic.
          }

          //
          // Are we too far right?
          //
          if ((_totalOffset+_landingZone.offsetWidth)>=(_filmWidth-5))
          {
              _totalOffset=(_filmWidth-_landingZone.offsetWidth-5); // Yes, set offset to max
              _originalOffset=(_filmWidth-_landingZone.offsetWidth-5);// and the original
              _dragXoffset=e.clientX; // reset the mouse
              _totalChange=20; // Simulate a move so we don't open a pic.
          }

          //
          // Set the visible clip here.
          //
          _filmstrip.style.clip='rect(0 '+(_landingZone.offsetWidth+_totalOffset-2)+' 73 '+(_totalOffset+1)+')';

          //
          // And set the left offset
          //
          _filmstrip.style.left=(_leftOffset-_totalOffset)+'px';

          //
          // return false so the browser won't try to do it's events!
          //
          return false;
      }
  }

  function cleanup(e)
  {
      //
      // called when user releases a mouse button after a drag event
      //

      _scrollOK = false; // Setting this to false disables scrollHandler
      _savedTarget.style.cursor=_orgCursor; // Change back to the original cursor shape
      document.onmousemove=null; // Disable the mousemove handler
      document.onmouseup=null; // Disable the mouseup handler
  }

  //
  // These functions control the scrolling of the filmstrip bar in
  // filmstrip mode.
  //
  // Thanks to Patrick Hunlock for the script.
  //   http://www.hunlock.com/blogs/Flickr_Filmstrips_in_Javascript
  //

  function dragHandler(e)
  {
      _totalChange = 0; // Total pixels moved

      var cursorType = '-moz-grabbing'; // Set hand to "grab"

      //
      // Package event for IE
      //
      if( e == null )
      {
          e = window.event;
          cursorType='w-resize';
      }

      var target = e.target != null ? e.target : e.srcElement; // Get the target object

      //
      //Handle filmstrip
      //
      if( target.className == "bbphotofilmstrip" || target.className == "bbphotofilmthumb" )  // Check if event over filmstrip
      {
          _savedTarget=target; // This is our target object
          _orgCursor=target.style.cursor; // This was our orginal cursor
          _originalOffset=_totalOffset; // Mark the current offset
          target.style.cursor=cursorType; // Set mouse to grab if possible
          _scrollOK=true; // flag filmstrip as scrollable
          _dragXoffset=e.clientX; // remember original X position

          //
          // Set the mouse handler.
          //
          document.onmousemove = scrollHandler;

          //
          // Clean up the handler when the user lets go...
          //
          document.onmouseup = cleanup;

          //
          // return FALSE -- IMPORTANT. Keeps the browser from doing anything (click, etc).
          //
          return false;
      }
  }

  function findPos(obj)
  {
      //
      // Credit for this function: http://www.quirksmode.org/js/findpos.html
      // Visit the URL for a complete tutorial on this function
      //
      var curleft = 0;
      var curtop = 0;
      var curwidth = 0;
      var curheight = 0;

      if (obj.offsetParent)
      {
          curleft = obj.offsetLeft
          curtop = obj.offsetTop
          curwidth = obj.offsetWidth;
          curheight = obj.offsetHeight;

          obj = obj.offsetParent;
          while (obj)
          {
              curleft += obj.offsetLeft;
              curtop += obj.offsetTop;
              obj = obj.offsetParent;
          }
      }

      return [curleft,curtop,curwidth,curheight];
  }

  function bindStrip()
  {
      if( null == _landingZone )
      {
          _landingZone= document.getElementById('landingZone');
      }


      if( null == _filmstrip )
      {
          _filmstrip = document.getElementById('filmstrip');
      }


      //
      // Calculate how big the filmstrip should be...
      //
      _filmWidth = 0;
      var filmstrip = document.getElementById('filmstripcntnr');
      if( filmstrip )
      {
          var imgArray = filmstrip.getElementsByTagName('img');
          for( var x = 0; x < imgArray.length ; x++ )
          {
              _filmWidth += imgArray[x].width + 5;
          }
          //_filmWidth += 5;
      }

      //
      // moves filmstrip into the landingZone table.
      //

      ofs = findPos(_landingZone);

      // Find the left/top & width of table

     _filmstrip.style.top=(ofs[1]+1)+'px';

      // Set filmstrip's top location

      _filmstrip.style.left=(ofs[0]+1)+'px';

      // Set filmstrip's left location

      _topOffset = ofs[1];

      // Remember top offset globally

      _leftOffset= ofs[0];

      // Remember the left offset globally
      // The next line crops the filmstrip and shows only a small section of it

      _filmstrip.style.clip='rect(0 '+(_landingZone.offsetWidth+_totalOffset-2)+' 72 '+(_totalOffset+1)+')';
      _filmstrip.style.left=(_leftOffset-_totalOffset)+'';
  }

  function showPic(idx)
  {
      // User scrolled, not a click event so return.
      if((_totalChange<-2)||(_totalChange>2))
      {
          return false;
      }

      // If we clicked on an invalid area (i.e. not an image we were looking for) return.
      if( idx == null )
      {
          return false;
      }

      // if we're clicking on the same image again, return.
      if( null != currentPic &&
          getImageNameFromThumb(idx.src) == currentPic.src &&
          idx.name == currentPic.name )
      {
          return false;
      }

      detail = document.getElementById('bbphotofilmpreviewcntnr');

      if (detail.style.display == 'block')
      {
          showWaitCursor();
          
          imgPreloader = new Image();

          // once image is preloaded, resize image container
          imgPreloader.onload=function()
          {
              //
              // Let's keep this around, as we'll need this later for the
              // screen resize event (setPageSize method)
              //
              currNatWidth = imgPreloader.width;
              currNatHeight = imgPreloader.height;

              var pixRatio = (imgPreloader.width * 1.0) / (imgPreloader.height * 1.0);

              if( imgPreloader.height > currCntnrHeight )
              {
                  imgPreloader.height = currCntnrHeight;
                  imgPreloader.width = Math.floor(pixRatio * imgPreloader.height);
              }
              if( imgPreloader.width > currCntnrWidth )
              {
                  imgPreloader.width = currCntnrWidth;
                  imgPreloader.height = Math.floor(imgPreloader.width / pixRatio);
              }

              document.getElementById('bbphotofilmcomment').style.width = imgPreloader.width + 12;
              document.getElementById('bbphotofilmtitle').style.width  = imgPreloader.width + 12;

              document.getElementById('bbphotofilmdetailPic').style.width = imgPreloader.width;
              document.getElementById('bbphotofilmdetailPic').style.height = imgPreloader.height;

              document.getElementById('bbphotofilmpreview').style.width = imgPreloader.width;
              document.getElementById('bbphotofilmpreview').style.height = imgPreloader.height;

              document.getElementById('bbphotofilmpreviewcntnr').style.width = imgPreloader.width + 12;
              document.getElementById('bbphotofilmpreviewcntnr').style.height = imgPreloader.height + 12 +
              document.getElementById('bbphotofilmcomment').offsetHeight +
              document.getElementById('bbphotofilmtitle').offsetHeight;

              document.getElementById('bbphotofilmdetailPic').src = imgPreloader.src;
              document.getElementById('bbphotofilmdetailPic').alt = imgPreloader.alt;

              document.getElementById('bbphotofilmcomment').innerHTML = imgPreloader.alt;
              document.getElementById('bbphotofilmtitle').innerHTML = imgPreloader.name;

              bindStrip();
              
              hideWaitCursor();
          }

          imgPreloader.alt = idx.alt;
          imgPreloader.name = idx.name;
          imgPreloader.src = getImageNameFromThumb(idx.src);

          currentPic=imgPreloader;
      }
  }

function saveAlbumCallback( tstKey, newKey, albumarraylist)
{
    //
    // This method being called indicates that the save was successful, and we need to update the actual displayed album with the data
    // from the admin window... SO, we need to walk the DOM and get the needed items, and add them to the page.
    //
    if( tstKey != currSecurityKey )
    {
        alert('Invalid security key was returned. Unable to re-display album.')
        return false;
    }

    currSecurityKey = newKey;

    //
    // Step 1: Set the album title and caption. No need to get this from the server, as it is already known, and can't change
    //
    document.title = document.getElementById('albumname').value;
    document.getElementById('bbphototitle').innerHTML = document.getElementById('albumname').value;
    document.getElementById('bbphotodesc').innerHTML = document.getElementById('albumcomment').value;

    //
    // Step 2: Clear the filmstrip DIV and re-add the images (in the proper order).
    //
    var filmstripHTML = "";
    var indx = albumarraylist.indexOf('|')
    while( indx > -1 )
    {
	    var nextPipe = albumarraylist.indexOf('|', indx+1);
        var title = albumarraylist.substr(indx + 1, nextPipe - indx -1 );

        indx = nextPipe;
        var nextPipe = albumarraylist.indexOf('|', indx+1);
        var caption = albumarraylist.substr(indx+1, nextPipe - indx -1 );

        indx = nextPipe;
        var nextPipe = albumarraylist.indexOf('|', indx+1);
        var thumb = "";
        if( nextPipe > -1 )
        {
            thumb = albumarraylist.substr(indx+1, nextPipe - indx -1 );
        }
        else
        {
	        thumb = albumarraylist.substr(indx+1);
        }
        indx = nextPipe;

        filmstripHTML = filmstripHTML + " <img src='" + thumb + "' name='" + title + "' alt='" + caption + "' class='bbphotofilmthumb' id='lightbox[gallery]' onMouseUp='showPic(this)' >\n"
    }

    document.getElementById('filmstripcntnr').innerHTML = filmstripHTML;

    //
    // Step 3: Call getThumbList() to clear the AllImages array, and re-load it.
    //
    getThumbList();

    //
    // Step 4: If we are in info or thumb mode, set the currPageNum to 0 and call setPage() to draw page 1.
    //         Else, if in thumb mode, call bindStrip().
    //
    if( viewMode == 'Thumb' ||  viewMode == 'Info' )
    {
        currPageNum = 0;
        setPage(1);
    }
    else if( viewMode == 'Film' )
      bindStrip();

    //
    // Step 5. Close the admin window.
    //
    closeAdminOverlay();
}

 function saveSecureKey()
  {
      var date = new Date();
      date.setTime(date.getTime()+(5*60*1000)); // give it 5 minutes...
      var expires = "; expires="+date.toGMTString();

      document.cookie = "bbphotoAdminsecureKey="+currSecurityKey+expires+"; path=/";
  }

function getElementsByStyleClass (className)
{
  var all = document.all ? document.all : document.getElementsByTagName('*');

  var elements = new Array();

  for (var e = 0; e < all.length; e++)
    if (all[e].className == className)
      elements[elements.length] = all[e];

    return elements;
}

function baseName(file)
{
  var Parts = file.split('\\');

  if( Parts.length < 2 )
    Parts = file.split('/');

  return Parts[ Parts.length -1 ];
}

// Removes leading whitespaces
function LTrim( value ) {

    var re = /\s*((\S+\s*)*)/;
    return value.replace(re, "$1");

}

// Removes ending whitespaces
function RTrim( value ) {

    var re = /((\s*\S+)*)\s*/;
    return value.replace(re, "$1");

}

// Removes leading and ending whitespaces
function trim( value ) {

    return LTrim(RTrim(value));

}

