/**
 * Depends on jquery.mousewheel.js and xbrowser.js
 */


/**
 * Animate from firstNum to lastNum
 * calls setFunction on every step
 * calls finishCallback if finished
 * duration can be set in miliseconds
 */
function swingAnim(firstNum, lastNum, setFunction, finishCallback, duration)
{
  if (!swingAnim.anims) swingAnim.anims = [];
  if (!swingAnim.cnt) swingAnim.cnt = 1;
  
  var idx = swingAnim.cnt++;
  swingAnim.anims[idx] =
  {
    firstNum:       firstNum,
    diff:           lastNum - firstNum,
    setFunction:    setFunction,
    finishCallback: finishCallback,
    duration:       (typeof duration == 'undefined') ? 500 : duration,
    startTime:      now(),
    timer:          null,
    timeStep:       10
  };
  
  swingAnim.animFv = function(idx)
  {
    var opt = swingAnim.anims[idx];
    var p = (now() - opt.startTime) / opt.duration;
    if (p >= 1)
    {
      opt.setFunction(opt.diff + opt.firstNum);
      if (opt.finishCallback) opt.finishCallback();
      delete(swingAnim.anims[idx]);
    }
    else
    {
      opt.setFunction(((-Math.cos(p*Math.PI)/2) + 0.5) * opt.diff + opt.firstNum);
      opt.timer = setTimeout(function()
      {
        swingAnim.animFv(idx);
      }, opt.timeStep);
    }
  };
  
  swingAnim.stop = function(idx)
  {
    if (!swingAnim.anims[idx]) return;
    
    var opt = swingAnim.anims[idx];
    if (opt.timer) clearTimeout(opt.timer);
    if (opt.finishCallback) opt.finishCallback();
    delete(swingAnim.anims[idx]);
  }

  swingAnim.anims[idx].timeStep = Math.max(20, Math.round(swingAnim.anims[idx].duration / 100));
  swingAnim.animFv(idx);
  return idx;
}


/**
 * Scrolls the window animated to an Y coordinate
 */
function scrollWindowToPosition(y, d)
{
  if (scrollWindowToPosition.running)
  {
    swingAnim.stop(scrollWindowToPosition.running);
    return;
  }
    
  y = Math.max(0, Math.min(window.getScrollMaxY(), y));
  scrollWindowToPosition.running = swingAnim(window.getScrollY(), y,
    function(v)
    {
      window.scrollTo(window.getScrollX(), v);
    },
    function()
    {
      scrollWindowToPosition.running = false;
    },
    d ? d : 1000);
}


$(window).bind('mousewheel', function(){
  if (scrollWindowToPosition.running)
  {
    swingAnim.stop(scrollWindowToPosition.running);
    return;
  }
});


/**
 * Scrolls the window animated in Y direction to a DOM object
 */
function scrollWindowToElement(obj, margin, duration)
{
  if (typeof margin == 'undefined') margin = 0;
  var y = elementOffsetPosition(obj).y - margin;
  y = Math.max(0, Math.min(window.getScrollMaxY(), y));
  scrollWindowToPosition(y, duration);
}

/**
 * Tells the position of a DOM element to the left-top corner of the page
 */
function elementOffsetPosition(obj)
{
	var curleft = curtop = 0;
  if (obj.offsetParent)
  {
    do
    {
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    }
    while (obj = obj.offsetParent);
  }
  return {x: curleft, y: curtop};
}

function now(){
	return +new Date;
}




