// Scrolling Features object:
function SF(eRoot)
{
              
 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
  * method to get numeric value of scroll position (extract from NNNpx string)
  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */  

  this.fGetPosn = function() 
  {
    this.nPosition = parseInt(this.eSFLinks.style.left);
  };


 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
  * method to perform animated scroll from initial to final offset
  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */  
 
  this.doScroll = function(oSF)
  {
    this.fGetPosn();
    if (this.nPosition > this.nTgtPosn)
    {
     // right scroll
      oSF.nPosition -= oSF.nScrollAmount;
      oSF.nPosition = Math.max(oSF.nPosition, oSF.nTgtPosn);    // to land exactly on end of items
      oSF.eSFLinks.style.left = oSF.nPosition+"px";
      setTimeout(function () {oSF.doScroll(oSF);},1);
    } 
     
    else if (this.nPosition < this.nTgtPosn)
    {
     // left scroll
      oSF.nPosition += oSF.nScrollAmount;
      oSF.nPosition = Math.min(oSF.nPosition, oSF.nTgtPosn);    // to land exactly on end of items
      oSF.eSFLinks.style.left = oSF.nPosition+"px";
      setTimeout(function () {oSF.doScroll(oSF);},1);
    } 
  
  //  else done  
 
  };
  

 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
  *  event handler method: handles scroll control link clicks
  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */  
  
  this.clickScroll = function(eClick)
  {
    var elt = Event.findElement(eClick, 'a');
    Event.stop(eClick);
    var cCtrl = this.isCtrl(elt);
    this.fGetPosn();
    var nCurPg = 1 - this.nPosition / this.nWidthWindow;
       
    if (cCtrl == 'R')      this.nTgtPosn = this.nPosition - this.nWidthWindow;
    else if (cCtrl == 'L') this.nTgtPosn = this.nPosition + this.nWidthWindow;
    else                   this.nTgtPosn = (1 - cCtrl) * this.nWidthWindow;

    if ( (this.nTgtPosn >= this.nMaxScroll) && (this.nTgtPosn <= 0) &&
          (this.nTgtPosn != this.nPosition) )
    {
     // fix up link active/inactive styles before animation
      if ( (this.nTgtPosn < this.nPosition) )
      {
       // right scroll from 0 => activate left link
        if (this.nPosition == 0)
        {
          this.aCtrls[0].removeClassName("sf_img_linkL0");
          this.aCtrls[0].addClassName("sf_img_linkL1"); 
        }
       // right scroll to maximum scroll => deactivate right link
        if (this.nTgtPosn == this.nMaxScroll)
        {
          this.aCtrls[this.aCtrls.length-1].removeClassName("sf_img_linkR1");
          this.aCtrls[this.aCtrls.length-1].addClassName("sf_img_linkR0"); 
        }
      }
      else if ( (this.nTgtPosn > this.nPosition) )
      {
       // left scroll from maximum scroll => activate right link
        if (this.nPosition == this.nMaxScroll)
        {
          this.aCtrls[this.aCtrls.length-1].removeClassName("sf_img_linkR0");
          this.aCtrls[this.aCtrls.length-1].addClassName("sf_img_linkR1"); 
        }
       // left scroll to 0 => deactivate left link
        if (this.nTgtPosn == 0)
        {
          this.aCtrls[0].removeClassName("sf_img_linkL1");
          this.aCtrls[0].addClassName("sf_img_linkL0"); 
        }
      }
      if (!isFinite(cCtrl))
      {
       // dummy up "to" page if page link not hit (left/right arrow)
        cCtrl = 1 - this.nTgtPosn / this.nWidthWindow;
      }
     // "to" page link => inactive
      this.aCtrls[cCtrl].removeClassName("sf_pg_link1");
      this.aCtrls[cCtrl].addClassName("sf_pg_link0"); 
     // "from" page link => active 
      this.aCtrls[nCurPg].removeClassName("sf_pg_link0");
      this.aCtrls[nCurPg].addClassName("sf_pg_link1"); 
 
      this.doScroll(this);
 
    }  
    return false;
   };
   
 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
  * method to extract command from scroll control link
  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */  

  this.isCtrl = function(elt)
  {
   // return code of control link (L = left, R = right, 1 = page 1, etc)
    return /.*\#(\w+)$/.exec(elt.href)[1];
  }; 


 // event handler: change appearance for hover 
  this.hoverfn = function(eMouse)
  {
    var elt = Event.findElement(eMouse, 'a');
   // find which tab triggered mouse event 
    for (var i = 0; i < this.aLinks.length; i++)
    {
      if (this.aLinks[i] == elt)  break;
    }
   // change style by changing class:
    if (this.aLinks[i].className == "sf_item")
      this.aLinks[i].className = "sf_item_hover";
    Event.stop(eMouse);
    return false;
  };

 // event handler: revert to normal unselected appearance when hover ends 
  this.unhoverfn = function(eMouse)
  {
    var elt = Event.findElement(eMouse, 'a');
   // find which tab triggered mouse event 
    for (var i = 0; i < this.aLinks.length; i++)
    {
      if (this.aLinks[i] == elt)  break;
    }
   // change style by changing class:
    if (this.aLinks[i].className == "sf_item_hover")
      this.aLinks[i].className = "sf_item";
    Event.stop(eMouse);
    return false;
  }


 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
  * constructor code: executed when object instantiated
  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */  

  this.aCtrls = new Array;
  this.aLinks = new Array;
  this.featuresHTML  = "";      // dynamically-built html of items to scroll

  this.nWidthWindow  = 0;       // width of scroll window: init width of bucket, 
                                //   then shrinks to exact fit around visible items
  this.nWidthSep     = 0;       // width of item separators (goes between visible items)
  this.nWidthItem    = 0;       // width of one scrolled item (link)
  this.nWidthLinks   = 0;       // total width of scrollable area (items with separators)
                                //   (overflow is hidden right/left)
  this.nItemsPerWind = 0;       // number of items visible at one time

  this.bFirst = true;           // flag for first time scroll event handler called
  this.nPosition = 0;           // position (left edge) of scrollable area (initially 0)
  this.nTgtPosn = 0;            // target position for current scrolling action     
  this.nScrollAmount = 20;      // number of pixels to scroll per setTimeout call
  this.nMaxScroll = 0;          // maximum right-scrolled position (negative--items pulled left) 
 
  if (_scrollingFeaturesArray.length < 1) return;
  
  this.eSFWindow = eRoot.getElementsByClassName("sf_window")[0];
  this.nWidthWindow = this.eSFWindow.offsetWidth; 
 // kludgey: add empty item and separator to DOM to determine widths, then clear
  this.featuresHTML = "<a class=sf_item></a><div class=sf_sep></div>";
  this.eSFWindow.innerHTML = this.featuresHTML;
  this.featuresHTML = "";
  this.nWidthSep = this.eSFWindow.getElementsByClassName("sf_sep")[0].offsetWidth;
  this.nWidthItem = this.eSFWindow.getElementsByClassName("sf_item")[0].offsetWidth;
  this.eSFWindow.innerHTML = "";

 // compute: width of links window; number of items per window 
  this.nWidthWindow = this.nWidthItem;
  this.nItemsPerWind = 1;
  while (this.nWidthWindow + this.nWidthSep + this.nWidthItem < this.eSFWindow.offsetWidth)
  {
    this.nWidthWindow += this.nWidthSep + this.nWidthItem;
    this.nItemsPerWind++; 
  }
 // shrink window tight around maximum items that will fit
  this.eSFWindow.style.width = (this.nWidthWindow)+"px";
  
 // build up html of scrollable items; place separator between each visible pair 
  this.featuresHTML = "<div class=sf_links>";
  var i;
  for (i = 0; i < _scrollingFeaturesArray.length; i++) 
  {
    this.featuresHTML += "<a href="+ _scrollingFeaturesArray[i].url + " class=sf_item>";
    this.featuresHTML += "<span class=hd2>" + _scrollingFeaturesArray[i].cat + "</span>"
    this.featuresHTML += "<span class=hd1>" + _scrollingFeaturesArray[i].hd + " </span>"
    if (_scrollingFeaturesArray[i].thumb != '')
    { this.featuresHTML += "<img src=" + _sImageDirectory + _scrollingFeaturesArray[i].thumb + " alt=" + _scrollingFeaturesArray[i].hd +" />"; }
    this.featuresHTML += "<span class=desc>" + _scrollingFeaturesArray[i].desc + "</span>"
    this.featuresHTML += "</a>";
    this.nWidthLinks += this.nWidthItem;
    if ((i+1) % this.nItemsPerWind != 0) 
    {
      this.featuresHTML += "<div class=sf_sep></div>";
      this.nWidthLinks += this.nWidthSep
    }
  }
  while (i % this.nItemsPerWind != 0)
  {
    this.featuresHTML += "<a class=sf_item></a><div class=sf_sep></div>";
    this.nWidthLinks += this.nWidthItem;
    if ((++i) % this.nItemsPerWind != 0) 
    {
      this.nWidthLinks += this.nWidthSep
    }
  }
 // insert scrollable band into scroll window
  this.featuresHTML += "</div>";
  this.eSFWindow.innerHTML = this.featuresHTML;
 
 // set hover state handlers for scrollable links
  this.aLinks = this.eSFWindow.getElementsByTagName("a");
  for (var i = 0; i < this.aLinks.length; i++)
  {
    Event.observe(this.aLinks[i], 'mouseover', this.hoverfn.bindAsEventListener(this));
    Event.observe(this.aLinks[i], 'mouseout', this.unhoverfn.bindAsEventListener(this));
  }
  
// set up & activate scrolling arrow controls (if there number of features requires hori scroll
  if (_scrollingFeaturesArray.length > this.nItemsPerWind) 
  { 
    var eCtrl = eRoot.getElementsByClassName("sf_ctrl")[0];
    this.featuresHTML = eCtrl.innerHTML;  
    this.featuresHTML += "<a class=sf_img_linkL0 href=#L></a>";
  
    this.featuresHTML += "<a class=sf_pg_link0 href=#1>1</a>";
  
  
    for ( var i = 1; i < this.nWidthLinks / this.nWidthWindow; i++ )
      this.featuresHTML += "<a class=sf_pg_link1 href=#" + (i+1) +">" + (i+1) + "</a>";
   
    this.featuresHTML += "<a class=sf_img_linkR1 href=#R></a>";
    
    eCtrl.innerHTML = this.featuresHTML;
    
    eCtrl.style.display = "block";

    this.aCtrls =  eCtrl.getElementsByTagName("a");
    for ( var i = 0; i < this.aCtrls.length; i++ )
    {
      Event.observe(this.aCtrls[i], "click", this.clickScroll.bindAsEventListener(this));
    } 
  } 
 
  this.eSFLinks = this.eSFWindow.getElementsByClassName("sf_links")[0]
  this.eSFLinks.style.left = "0px";
  this.eSFLinks.style.width = (this.nWidthLinks)+"px";
  this.nMaxScroll = this.nWidthWindow - this.nWidthLinks;
  this.fGetPosn();
  
}


function prepare_SF()
{
 // locate all elements (s/b divs) that are Scrolling Features containers
 // create Scrolling Features object for each

  var aeSFC = document.getElementsByClassName("sf_container");
  for (var i = 0; i< aeSFC.length; i++)
  {
    new SF(aeSFC[i]);
  }
}

// now called from one place with other window-load events
//  to ensure sequencing

/*****************************************************************
  initialization function: attach event handlers upon load
  using Prototype.js x-browser W3C event handler implementation
*****************************************************************/

// Event.observe(window, 'load', function()
// {
 // prepare any scrolling feature objects:
//  prepare_SF();
// });
