// Initialize the scroller

// Global variable declaration
var scrollAnim = { source: 0, target:0, timer:0, running: false }
var scrollContainer
var scrollDuration
var scrollDirection
var scrollItems
var scrollPositions

// Takes as arguments the name of the container, the direction (h or v) and the duration in number of frames
// It's presumed the container has one child node which in turn houses all the 'item' nodes (eg. <ul> followed by a series of <li>s)
function init_scroller( sContainer, direction, duration ) {
  scrollContainer = $(sContainer)
  scrollDuration = duration
  scrollDirection = ( direction == 'v' ? 'v' : 'h' ) // Allow direction to be set to vertical but default to horizontal
  scrollItems = scrollContainer.immediateDescendants()[0].immediateDescendants()
  scrollPositions = new Array()

  scrollItems.each( function(item) {
      // Determine the item's position in the array
      pos = scrollItems.indexOf(item)
      // Determine the width or height of preceeding items
      offset = 0
      for( i=0; i<pos; i++ ) {
        if( scrollDirection == 'h' ) {
          offset += scrollItems[i].getWidth()
        } else {
          offset += scrollItems[i].getHeight()
        }
      }
      scrollPositions[scrollItems.indexOf(item)] = offset
    }
  )
  log( "Registered " + scrollItems.size() + " items at positions " + scrollPositions )
}

function get_target( id ) {
  return scrollPositions[scrollItems.indexOf($(id))]
}


function start_scroll( id ) {
  // Don't allow change of target if the animation is already running
  // if( scrollAnim.running )
  //  return false

  // The current position becomes the source
  scrollAnim.source = ( scrollDirection == 'h'? scrollContainer.scrollLeft : scrollContainer.scrollTop )

  // Set the new target
  scrollAnim.target = get_target( id )

  // Make sure the source and target aren't the same
  if( scrollAnim.source == scrollAnim.target )
    return false

  // The timer is reset to 0
  scrollAnim.timer = 0

  // Mark the start of the animation
  scrollAnim.running = true

  // Start the actual scroll loop
  do_scroll();
}

function do_scroll() {
  if( scrollAnim.timer <= scrollDuration && scrollAnim.running ) {
    // Determine which way to scroll and apply the new left or top offset
    if( scrollDirection == 'h' ) {
      scrollContainer.scrollLeft = sineInOut(scrollAnim.timer, scrollAnim.source, scrollAnim.target, scrollDuration)
    } else {
      scrollContainer.scrollTop = sineInOut(scrollAnim.timer, scrollAnim.source, scrollAnim.target, scrollDuration)
    }
    // Increment the timer by one frame
    scrollAnim.timer++
    // Repeat the loop again in 1/100th of a second
    setTimeout('do_scroll()',10)
  } else {
    // Make sure the last loop sets the scroll position to the requested target
    if( scrollDirection == 'h' ) {
      scrollContainer.scrollLeft = scrollAnim.target
    } else {
      scrollContainer.scrollTop = scrollAnim.target
    }
    // Stop the animation
    scrollAnim.running = false
  }
}

// Linear and non-linear calculations for animation - From http://www.robertpenner.com/easing/
//
// t = time, b = begin, e = end, d = duration
function linear(t, b, e, d) {
  c = e - b;
  return c*t/d + b;
}

function sineInOut(t, b, e, d) {
  c = e - b;
  return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
}

function cubicIn(t, b, e, d) {
  c = e - b;
  return c*(t/=d)*t*t + b;
}

function cubicOut(t, b, e, d) {
  c = e - b;
  return c*((t=t/d-1)*t*t + 1) + b;
}

function cubicInOut(t, b, e, d) {
  c = e - b;
  if ((t/=d/2) < 1) return c/2*t*t*t + b;
  return c/2*((t-=2)*t*t + 2) + b;
}

// Utilities
//

// Check whether we're looking at Internet Explorer
function is_explorer() {
  if( navigator.userAgent.indexOf('MSIE') != -1 ) {
    return true
  } else {
    return false
  }
}
// Check whether we're looking at Mozilla Firefox
function is_firefox() {
  if( navigator.userAgent.indexOf('Firefox') != -1 ) {
    return true
  } else {
    return false
  }
}

// Send something to Firebug's log
function log( message ) {
  if( is_firefox() ) {
    console.log( message );
  }
}
